The invoice entity, with every tax field and no tax engine

Featurekamo-shared-library
Ya
27 Agosti 2026, 23:21 UTC
Mwandishi
Kamo
Ahadi ya
c48342c

Kamo's own invoice, written only by InvoicingService. Nothing on it is supplied by a caller: every figure is derived from the lines on every write, which is the opposite of **************** where subtotal/tax/total are taken verbatim off the request and a total is derived only when two of the three are null — so a caller can post a populated order with total = 0. UX_INVOICE_ORG_NUMBER is the BACKSTOP, not the mechanism. The row lock in DocumentNumberService is the mechanism; this exists so that a future bug which bypasses the lock fails as a loud constraint violation rather than two customers holding the same invoice number. INVOICE_NUMBER is nullable because a DRAFT has none, and Postgres treats NULLs as distinct so drafts coexist under it. The four classification enums (SERVICE_LINE_TYPE / PROPERTY_CLASS / WORK_CLASS / CONTRACT_FORM) are carried even though nothing computes tax — B5: Kamo stores every tax field and computes none. They are NULL on every ServiceLineItem in production because the one writer, **************** sets only base-class fields. TAX_CLASS_ID is a UUID and never a Long: Offering.taxClassId is a Long against TaxClass's UUID key, a structurally impossible reference and a large part of why the tax tables have never been readable. Currency is on the header and never on a line; ServiceJob has money columns and no currency at all, so a job-derived invoice takes it from the org. AMOUNT_PAID / AMOUNT_DUE / PARTIALLY_PAID ship as SHAPE ONLY. Deposits and progress billing are deliberately out of BL2's scope: nothing in commerce models a deposit, milestone or retainage, and there is no partial-payment writer. There is no @PreUpdate immutability guard on a line, and that is deliberate: a callback fires at FLUSH, so the recompute finalize legitimately performs would be rejected by a guard that reads the parent's status at commit time. The guard lives in the service; the enforcement that survives bulk JPQL is the REVOKE. The repository extends Repository, not JpaRepository — a finalized invoice is a money event and the correction path is a credit note, not a delete. Observed failures, verbatim. RED (before the entities existed): InvoiceTotalsTest.java:[3,50] cannot find symbol CommerceInvoiceTest.java:[3,50] cannot find symbol (package **************** GREEN: Tests run: 62, Failures: 0, Errors: 0, Skipped: 0 — including the Spring context test, which builds the SessionFactory and so proves the BILL_TO_ prefix on EmbAddress does not collide.

Mabadiliko yote

Je, unaona nini kuhusu usafiri?

Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.

Kuwa Huru MileleMtazamo wa bei