mcs150/workers: don't fill MCS-150 for non-form services; quiet ERPNext workflow advance

- MCS150UpdateHandler is the catch-all for many admin-assisted DOT services
  (UCR, MC authority, audit prep, ETA, name reservation, registered agent,
  annual report). It was filling an MCS-150 PDF for ALL of them -- e.g. a UCR
  order produced a wrong MCS-150 PDF. Now only MCS150_FORM_SLUGS fill the form;
  others get an admin-review todo (PDF 'not generated') for manual handling.
  Signature flow was already correctly scoped (UCR is not in DOT_SIGNING).
- handle_process_compliance_service forced the Sales Order workflow_state to
  'Review' via set_value, which bypasses ERPNext's allowed transitions and
  threw WorkflowPermissionError (Received -> Review) on every run. The Postgres
  fulfillment_status is the source of truth; the ERPNext workflow_state is a
  cosmetic mirror. Now try the proper apply_workflow action and stay quiet
  (debug, not warning) when no valid Review transition exists.
This commit is contained in:
justin 2026-06-10 17:22:38 -05:00
parent a04146da2b
commit a1db921c71
2 changed files with 34 additions and 11 deletions

View file

@ -1345,12 +1345,29 @@ def handle_process_compliance_service(payload: dict) -> dict:
except Exception as exc:
LOG.warning("Could not update entity checkup timestamp: %s", exc)
# Advance workflow to Review after processing
# Advance the ERPNext Sales Order workflow to "Review" (best-effort, purely
# cosmetic). The authoritative status for compliance orders is the Postgres
# compliance_orders.fulfillment_status; the ERPNext workflow_state is a
# secondary mirror. A direct set_value("workflow_state","Review") bypasses
# the workflow's allowed transitions and ERPNext rejects "Received -> Review"
# with a WorkflowPermissionError. Use the proper workflow action when one is
# available, and stay quiet if the transition isn't defined for the current
# state (it's non-fatal and shouldn't spam the logs on every run).
try:
client.set_value("Sales Order", order_name, "workflow_state", "Review")
LOG.info("Advanced %s to Review", order_name)
applied = False
for action in ("Processing Complete", "Submit for Review", "Ready for Review"):
try:
client.apply_workflow("Sales Order", order_name, action)
LOG.info("Advanced %s to Review via '%s'", order_name, action)
applied = True
break
except Exception:
continue
if not applied:
LOG.debug("Skipped ERPNext workflow advance for %s (no valid Review transition)",
order_name)
except Exception as exc:
LOG.warning("Could not advance workflow for %s: %s", order_name, exc)
LOG.debug("ERPNext workflow advance skipped for %s: %s", order_name, exc)
# ── Create compliance calendar deadlines for the customer ───────────
# After a filing is completed, create recurring deadline reminders

View file

@ -158,14 +158,20 @@ class MCS150UpdateHandler:
order_number, missing)
return []
# Step 1: Fill the official MCS-150 PDF
# Step 1: Fill the official MCS-150 PDF. Only services that actually file
# an MCS-150 produce the form; the other admin-assisted DOT services
# routed to this handler (UCR, MC authority, audit prep, ETA, name
# reservation, registered agent, annual report, etc.) must NOT generate
# an MCS-150 -- they are handled manually by an admin from the review
# todo created below.
pdf_path = None
try:
from scripts.document_gen.templates.mcs150_pdf_filler import fill_mcs150
pdf_path = fill_mcs150(intake, order_number=order_number)
LOG.info("[%s] Filled MCS-150 PDF: %s", order_number, pdf_path)
except Exception as exc:
LOG.error("[%s] PDF fill failed: %s", order_number, exc)
if slug in self.MCS150_FORM_SLUGS:
try:
from scripts.document_gen.templates.mcs150_pdf_filler import fill_mcs150
pdf_path = fill_mcs150(intake, order_number=order_number)
LOG.info("[%s] Filled MCS-150 PDF: %s", order_number, pdf_path)
except Exception as exc:
LOG.error("[%s] PDF fill failed: %s", order_number, exc)
# Step 2: Upload PDF to MinIO for storage
minio_path = None