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.

TableRoleRelation
compensationheader: number, client, partner, date, statusmirror: same number on the partner client's side
compensation_itemoffset invoice and amount, sideinvoice
doc, doc_linkprotocol PDFlinked first to the compensation, then to the invoices

Save (save)

  1. Right: canSave(route, id) (0 = add, >0 = edit); the client (on update both the existing and the new one) must be in scope.
  2. 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.
  3. Number KOMP-<year>-<4 digits> (for a mirror the original's), save, recalculation of invoice balances, mirror (syncMirror).
  4. Protocol PDF (pdftemplate compensation_protocol, in the document's language), filed with Dlbtdocstore::fileDocument under the client's “document” → “invoice” rule, links, renamed to its own number. A missing protocol is a warning, not an error.
  5. On update updateCompensation(): items, balances and mirror are refreshed, the protocol is regenerated. Manual regeneration: the protocol endpoint (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 uses canSee(list)); opening the form does not deny access, it only sets read-only mode. searchinvoices needs add or edit.
  • Layer 3: getAllowedCompanyIds; deleted rows are shown only with canSeeDeleted.