Compensation — data model, save, mirror, protocol
Validation of compensation items, numbering, the mirror compensation, filing the protocol PDF, the two kinds of delete and the rights.
The finance/compensation module records the offsetting of customer and supplier invoices. No settling transaction is created (transaction_id = 0); invoice balances are recalculated by transaction::recalcInvoiceOutstanding().
Data model
Table names carry the installation's own prefix in the database.
| Table | Role | Relation |
|---|---|---|
compensation | header: number, client, partner, date, status | mirror: same number on the partner client's side |
compensation_item | offset invoice and amount, side | invoice |
doc, doc_link | protocol PDF | linked first to the compensation, then to the invoices |
Save (save)
- Right:
canSave(route, id)(0 =add, >0 =edit); the client (on update both the existing and the new one) must be in scope. - Items (
prepareItems) from scope-filtered open invoices (searchOpenInvoices): each invoice once, must exist, belong to the client, be open, amount at most the open balance; both a receivable and a payable side are required and the two sides must be equal. - Number
KOMP-<year>-<4 digits>(for a mirror the original's), save, recalculation of invoice balances, mirror (syncMirror). - Protocol PDF (
pdftemplatecompensation_protocol, in the document's language), filed withDlbtdocstore::fileDocumentunder the client's “document” → “invoice” rule, links, renamed to its own number. A missing protocol is a warning, not an error. - On update
updateCompensation(): items, balances and mirror are refreshed, the protocol is regenerated. Manual regeneration: theprotocolendpoint (canAction(protocol)+ scope).
Errors: error_client, error_duplicate_invoice, error_invoice_missing, error_invoice_scope, error_invoice_settled, error_amount_over, error_no_items, error_one_sided, error_sides_differ, error_mirror_invoice, error_no_storage, error_protocol.
Deletion
One button; the right decides the mode: with delete a physical delete (header and items), then recalculation of invoice balances — the mirror compensation and the document are kept; with only statusdelete status = 9, then recalculation (the offset drops out). Errors: error_no_selection, error_not_found.
Permissions
- Layer 2:
list,add,edit,protocol,delete,statusdelete,debug— none is classified in the seeds (compensation_v1.sql).index()checks no right (the menu usescanSee(list)); opening the form does not deny access, it only sets read-only mode.searchinvoicesneedsaddoredit. - Layer 3:
getAllowedCompanyIds; deleted rows are shown only withcanSeeDeleted.