add more status updates

This commit is contained in:
2026-05-15 16:47:37 +03:00
parent 24624cc4d1
commit 2d2cf46f32
8 changed files with 189 additions and 23 deletions

View File

@@ -294,11 +294,12 @@ class Submission(models.Model):
currently owns the row, so the per-email cap and trust list don't
depend on the caller remembering to set it.
Additionally: when an UPDATE flips `status` to `rejected` from any
other state, this method queues `send_rejection_email()` via
`transaction.on_commit`. Centralising the email here means **every**
save path -- admin, the validation worker, ad-hoc shell, any future
view -- fires the email through a single hook. Plan.md §7.3.
Additionally: when an UPDATE flips `status` to a state with a
dedicated email (`rejected`, `printing`, `completed`), this method
queues the matching `send_*_email()` via `transaction.on_commit`.
Centralising the dispatch here means **every** save path -- admin,
the validation worker, ad-hoc shell, any future view -- fires the
email through a single hook. Plan.md §7.3.
"""
if not self.slug:
self.slug = self._generate_unique_slug()
@@ -319,27 +320,37 @@ class Submission(models.Model):
super().save(*args, **kwargs)
# Fire on TRANSITIONS only: an UPDATE that flips status to rejected.
# Don't fire on inserts that start out as rejected -- those should
# be impossible by design (plan.md §7.3 doesn't define a (none) ->
# rejected edge), and even if some weird path creates one we'd
# rather stay silent than spam a fresh victim.
if (
not is_new
and old_status != new_status
and new_status == self.Status.REJECTED
):
# Fire on TRANSITIONS only: an UPDATE that flips status into one of
# the email-bearing target states. Don't fire on inserts that start
# out in those states -- by plan.md §7.3 no submit-time edge lands
# in rejected/printing/completed, and even if some weird path did,
# we'd rather stay silent than send "your print is ready" to a fresh
# victim of a fixture/data-migration import.
if not is_new and old_status != new_status:
# Local imports keep this module out of the apps/submissions
# import-cycle (emails.py imports from here).
from django.db import transaction
from .emails import send_rejection_email
transaction.on_commit(
lambda sub=self, prev=old_status: send_rejection_email(
sub, previous_status=prev
)
from .emails import (
send_completed_email,
send_printing_email,
send_rejection_email,
)
if new_status == self.Status.REJECTED:
transaction.on_commit(
lambda sub=self, prev=old_status: send_rejection_email(
sub, previous_status=prev
)
)
elif new_status == self.Status.PRINTING:
transaction.on_commit(
lambda sub=self: send_printing_email(sub)
)
elif new_status == self.Status.COMPLETED:
transaction.on_commit(
lambda sub=self: send_completed_email(sub)
)
# Refresh the snapshot so a follow-up save on the same instance
# compares against the just-persisted state, not the original load.
self._original_status = new_status