feat(ledger): deploy the bookkeeping service — compose/k8s, ingress, off-site backup volume, submodule bumps
- deploy: ledger service in docker-compose (ledger profile), k8s 27-ledger.yaml (StatefulSet, PVCs, OFFSITE_DIR backup volume), ingress route, nginx /api/ledgers proxy, ucp-profile with the ledger grain - platform/event + platform/order: invoice.issued/paid/credited payload contracts (VatBuckets per rate, OCR reference on payments, credit-note reversal payload) - prep-dev-data creates data/commerce/ledger - docs/status.md: ledger service row + Phase-2 export/import summary; wayfinder: ledger-accounting map + tickets 07-16, b2b-invoices map notes - bumps: go-cart-actor 5c9036d (ledger domain), backoffice f09202d (Ledger dashboard + proxy) Generated with Codebuff 🤖 Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
1 parent
4bf00314d3
commit
d74c8a0592
2 files changed
+49
-2
No files matched your search
+8
-2
@@ -64,9 +64,15 @@ const (
|
|||||||
// InvoiceIssued is emitted when an order is invoiced (pay-later placement or
|
// InvoiceIssued is emitted when an order is invoiced (pay-later placement or
|
||||||
// manual invoice issuance). Payload is an order.InvoiceIssued (platform/order).
|
// manual invoice issuance). Payload is an order.InvoiceIssued (platform/order).
|
||||||
InvoiceIssued Type = "invoice.issued"
|
InvoiceIssued Type = "invoice.issued"
|
||||||
// InvoicePaid is emitted when an invoiced order payment status crosses to paid.
|
// InvoicePaid is emitted for EVERY registered payment on an invoiced order
|
||||||
// Payload is an order.InvoicePaid (platform/order).
|
// (each event = one payment fact with its own amount/paidAt; the ledger
|
||||||
|
// books 1930→1510 per event). Payload is an order.InvoicePaid (platform/order).
|
||||||
InvoicePaid Type = "invoice.paid"
|
InvoicePaid Type = "invoice.paid"
|
||||||
|
// InvoiceCredited is emitted when a credit note is issued against an issued
|
||||||
|
// invoice. Payload is an order.InvoiceCredited (platform/order): the credited
|
||||||
|
// amount + per-rate VAT split, which the ledger books as the reversal
|
||||||
|
// voucher (1510 C / 304x D / 261x D per rate).
|
||||||
|
InvoiceCredited Type = "invoice.credited"
|
||||||
|
|
||||||
|
|
||||||
// Analytics (tracking). Replaces the integer enum 0–6 that finder and
|
// Analytics (tracking). Replaces the integer enum 0–6 that finder and
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ func Decode(raw []byte) (Created, error) {
|
|||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VatBucket is one VAT rate's split on an issued invoice: the net basis and
|
||||||
|
// the VAT amount, both in minor units. RateBp is basis points (2500 = 25 %).
|
||||||
|
// Summing ExVat+Vat across buckets equals AmountIncVat — the ledger reactor
|
||||||
|
// books the invoice from these (revenue accounts per rate, e.g. 3041/3042/3043
|
||||||
|
// and 2611/2621/2631 in BAS), so it needs the split, not just the total.
|
||||||
|
type VatBucket struct {
|
||||||
|
RateBp int `json:"rate_bp"`
|
||||||
|
ExVat int64 `json:"ex_vat"`
|
||||||
|
Vat int64 `json:"vat"`
|
||||||
|
}
|
||||||
|
|
||||||
// InvoiceIssued is the payload of an event.InvoiceIssued envelope.
|
// InvoiceIssued is the payload of an event.InvoiceIssued envelope.
|
||||||
type InvoiceIssued struct {
|
type InvoiceIssued struct {
|
||||||
OrderID string `json:"order_id"`
|
OrderID string `json:"order_id"`
|
||||||
@@ -66,6 +77,7 @@ type InvoiceIssued struct {
|
|||||||
CompanyID string `json:"company_id,omitempty"`
|
CompanyID string `json:"company_id,omitempty"`
|
||||||
CustomerEmail string `json:"customer_email,omitempty"`
|
CustomerEmail string `json:"customer_email,omitempty"`
|
||||||
AmountIncVat int64 `json:"amount_inc_vat"`
|
AmountIncVat int64 `json:"amount_inc_vat"`
|
||||||
|
VatBuckets []VatBucket `json:"vat_buckets,omitempty"`
|
||||||
DueDate string `json:"due_date"`
|
DueDate string `json:"due_date"`
|
||||||
OCRReference string `json:"ocr_reference"`
|
OCRReference string `json:"ocr_reference"`
|
||||||
IssuedAtMs int64 `json:"issued_at_ms"`
|
IssuedAtMs int64 `json:"issued_at_ms"`
|
||||||
@@ -86,6 +98,10 @@ type InvoicePaid struct {
|
|||||||
CompanyID string `json:"company_id,omitempty"`
|
CompanyID string `json:"company_id,omitempty"`
|
||||||
AmountPaid int64 `json:"amount_paid"`
|
AmountPaid int64 `json:"amount_paid"`
|
||||||
PaidAtMs int64 `json:"paid_at_ms"`
|
PaidAtMs int64 `json:"paid_at_ms"`
|
||||||
|
// OcrReference lets the ledger settle the exact receivable (the payment's
|
||||||
|
// 1510 credit references the invoice's OCR) without depending on the
|
||||||
|
// invoice.issued event having been booked first.
|
||||||
|
OcrReference string `json:"ocr_reference,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i InvoicePaid) Encode() ([]byte, error) { return json.Marshal(i) }
|
func (i InvoicePaid) Encode() ([]byte, error) { return json.Marshal(i) }
|
||||||
@@ -96,3 +112,28 @@ func DecodeInvoicePaid(raw []byte) (InvoicePaid, error) {
|
|||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvoiceCredited is the payload of an event.InvoiceCredited envelope: a
|
||||||
|
// credit note was issued against an issued invoice. The credited amount and
|
||||||
|
// per-rate VAT split mirror the credited lines (line total × qty / line
|
||||||
|
// quantity, VAT proportionally — the same math as the order grain's
|
||||||
|
// InvoiceCreditedAmount). The ledger books the reversal voucher
|
||||||
|
// (1510 C / 304x D / 261x D per rate), idempotent per credit number.
|
||||||
|
type InvoiceCredited struct {
|
||||||
|
OrderID string `json:"order_id"`
|
||||||
|
InvoiceNumber string `json:"invoice_number"` // the original invoice
|
||||||
|
CreditNumber string `json:"credit_number"` // from the same gap-free series
|
||||||
|
CompanyID string `json:"company_id,omitempty"`
|
||||||
|
OcrReference string `json:"ocr_reference,omitempty"`
|
||||||
|
AmountIncVat int64 `json:"amount_inc_vat"`
|
||||||
|
VatBuckets []VatBucket `json:"vat_buckets,omitempty"`
|
||||||
|
CreditedAtMs int64 `json:"credited_at_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c InvoiceCredited) Encode() ([]byte, error) { return json.Marshal(c) }
|
||||||
|
|
||||||
|
func DecodeInvoiceCredited(raw []byte) (InvoiceCredited, error) {
|
||||||
|
var c InvoiceCredited
|
||||||
|
err := json.Unmarshal(raw, &c)
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user