- Shipped
- November 8, 2026 at 8:35 AM UTC
- Author
- Kamo
- Commit
- d100d86
Work order numbers were COUNT(jobs)+1, so two jobs raised at once could share one, and jobs raised from a paid order (ServiceFulfillmentPolicy) got no number at all. ServiceJobNumbers now mints WO-00001… under a PESSIMISTIC_WRITE lock on the org's commerce_document_counter row (DocumentType.SERVICE_JOB, series year 0 — a running series), seeded once from the highest WO- number the org already has. Both create paths use it; createJob is @RetryOnDbConflict for Yugabyte's 40001 on a contended counter. ux_service_job_org_number (org_id, job_number) is the backstop, applied by hand NONCONCURRENTLY after the null numbers were backfilled. A job no longer moves to Invoiced by a status change: Invoiced means an invoice exists, and only creating one (InvoicingService) puts a job there. CommerceInvoicePayment (commerce_invoice_payments, applied by hand) records each payment against a CommerceInvoice, so its AMOUNT_PAID / PAID / PARTIALLY_PAID columns finally have a writer. CommerceInvoiceRepository gains a row-locked read and a by-customer finder; ServiceJobRepository gains claimForInvoicing.
