Appearance
Supplier Settlement
This document is the living decision record for supplier bank-payment allocation, document debt, FIFO, overpayment, and supplier advances.
Confirmed business rules
A document can receive payment only when Syrve/iiko reliably confirms
IsProcessed == trueandIsDeleted == false.Unknown processing state is blocked.
PaymentStatus,UnpaidAmount, candidate membership, and unpaid-batch membership are not evidence that a document was processed.The complete bank-transaction amount must have an accounting destination:
BankTransaction.Amount = DocumentSettlementAmount + SupplierAdvanceAmount.UnallocatedPaymentAmountmay exist in preview/draft only. Confirm, approve, posting preview, queue, dry-run, execute, and retry are blocked unless it is zero.A document may remain partially unpaid after the complete bank payment is allocated. Remaining document debt is not unallocated bank money.
Automatic allocation uses deterministic FIFO over eligible current debt.
Money exceeding eligible document debt is a required supplier advance. It must reach Syrve on a separate supplier-advance accounting operation and may not remain as a local balance.
A transport success is
Posted, notReconciled; independent readback must confirm every expected document remainder.
Current sources of truth
| Question | Current source |
|---|---|
| Document processed/deleted | List-record processed/deleted normalized into SyrveDocumentSnapshot |
| Current document debt | Refreshed snapshot UnpaidAmount and payment readback |
| Bank amount | Persisted BankTransaction.Amount |
| Confirmed allocation | Persisted PaymentAllocation plus ordered PaymentAllocationLine rows |
| External document write | SyrvePaymentPosting evidence and connector result |
| Reconciled document debt | Independent live readback matched to ExpectedUnpaidAmountAfter |
| Supplier advance | Syrve advance operation and readback — contract not yet available |
Allocation preview always replaces the caller-supplied preview amount with persisted BankTransaction.Amount. A reduced request value therefore cannot hide an unallocated remainder. Every later write boundary rereads that bank transaction. If it is missing or hidden by the deletion lifecycle, processing fails closed with bank_transaction_not_found; PaymentAllocation.TotalAmount is never used as a substitute source of truth.
Historical snapshot rows migrated before processing-state support remain IsProcessed = NULL and are ineligible until refreshed. Historical Posted/Reconciled allocations are not bulk-rewritten.
Canonical amounts
DocumentSettlementAmount: amount assigned to current document debt.SupplierAdvanceAmount: amount assigned to a real planned supplier-advance operation.UnallocatedPaymentAmount: signed bank money without an accounting destination.InvoiceDebtRemaining: document debt expected after the planned document settlements.
The canonical calculation is:
UnallocatedPaymentAmount = BankTransaction.Amount - DocumentSettlementAmount - SupplierAdvanceAmount.
No absolute-value conversion is used. A positive result has no accounting destination; a negative result over-assigns the bank transaction. Both block the financial workflow.
Examples:
| Bank payment | Document debt | Document settlement | Supplier advance | Unallocated | Debt remaining | Runnable now |
|---|---|---|---|---|---|---|
| 300000 | 300000 | 300000 | 0 | 0 | 0 | Yes |
| 250000 | 300000 | 250000 | 0 | 0 | 50000 | Yes |
| 350000 | 300000 | 300000 | 50000 required | 0 in the future plan | 0 | No, advance transport unavailable |
Legacy RemainingAmount, HasOverpayment, HasUnderpayment, and line IsOverpayment remain API compatibility fields. They are not accounting sources of truth.
FIFO foundation
SupplierSettlementAllocator is pure and deterministic. It has no database, connector, transport, clock, or side effects. Its eligibility filter requires:
- processed and not deleted;
- payment status
UnpaidorPartiallyPaid; - positive
UnpaidAmount; - supported direction/document type;
- matching supplier and currency.
Order:
- reliable
DueDate, if supplied; - otherwise
DocumentDate; - ordinal
ExternalDocumentId.
Current production snapshots do not expose a confirmed due date, so the application maps DocumentDate. The accounting choice of final FIFO date remains to be confirmed.
AutomaticFifo is generated only for a matched supplier when preview receives no explicit lines. Explicit lines imply the operator's manual allocation and are never replaced. Confirm persists AllocationMethod, exact amounts, and Sequence. Worker and retry consume the saved lines and never recalculate FIFO.
Workflow and safety boundaries
The same document eligibility and payment-completeness rules are evaluated at:
- candidate build and persisted candidate read;
- automatic safe proposal and workbench prepare;
- explicit preview lines;
- confirm;
- allocation approval;
- posting preview/approval/queue;
- dry-run;
- retry;
- worker preflight immediately before transport;
- reconciliation where current document state is relevant.
A snapshot regression to unknown, not processed, deleted, or no longer payable moves the active allocation to review/failure according to its current boundary. Queue creates no posting/outbox work, and worker does not call transport.
The worker atomically persists Posting, attempt count, claim timestamp, bounded lease, stable posting date, and stable request hash before the external call. A timeout, exception, or expired lease becomes WriteOutcomeUnknown; normal retry is disabled and readback is queued. Blind retry is forbidden.
Reconciliation compares every saved line's ExpectedUnpaidAmountAfter with independent readback. Only a complete match sets ReconciledAtUtc. A mismatch persists/links an anomaly and leaves the timestamp null. Until that successful readback, a Posted posting and its allocation remain Processing in the accountant workbench; idempotent replay does not report AlreadyCompleted. Workbench classification uses canonical UnallocatedPaymentAmount for incomplete/over-assigned bank-payment reasons. A line with IsPartialPayment = true and zero unallocated bank amount is not an attention reason: its positive InvoiceDebtRemaining is valid supplier debt.
Current transport boundary
Production document posting remains PaymentAllocation 1:1 SyrvePaymentPosting and uses the existing document-based connector contract, including saved split items for multi-document settlement. A single shared document-settlement PostingType, AccountId, and CashFlowArticleId is used for the bank payment.
SupplierSettlementPlan and SupplierSettlementPostingOperationPlanner are non-runtime foundation models for the future 1:N relationship:
- one document-settlement operation;
- one separate supplier-advance operation when required.
The advance operation is always TransportUnavailable/non-runnable. It has no external id, write/readback evidence, queue row, transport call, or local accounting ledger.
Unconfirmed rules
- Whether Syrve can perform supplier-level FIFO itself.
- Whether one Syrve operation can settle multiple documents atomically.
- The supplier-advance RPC/endpoint and XML request/response.
- Amount signs, account correspondence, cash-flow requirements, dates, and mandatory fields.
- Advance external id and readback.
- Full/partial application of advance to a processed document.
- Cancellation, reversal/storno, duplicate-call, timeout, RMS, and CHAIN behavior.
The required research prompt is IikoConnector: FIFO supplier settlement and supplier advances.
Prohibited temporary solutions
- Inventing supplier-level or advance RPC contracts.
- Sending an advance as an ordinary payment without a document.
- Treating
RemainingAmountorRequiredSupplierAdvanceAmountas a posted advance. - Creating a fake external advance id or returning fake success.
- Building a parallel local advance ledger as the accounting source of truth.
- Sending only the document portion of an overpaid bank transaction and retaining the remainder.
- Recalculating FIFO in the worker after confirm.
Migration path after verified traces
- Add source/trace-backed typed connector APIs for advance create, readback, apply, and reversal.
- Consume a new verified NuGet package; do not vendor connector source.
- Add persisted settlement plan and
1:Nposting-operation entities with independent idempotency, request hash, write/readback/reversal evidence, and status. - Keep document settlement and supplier advance as separate accounting groups and operations.
- Enable an advance operation only after create + independent readback + reversal contracts pass RMS/CHAIN tests.
- Define recovery for partial group success before allowing the combined plan into production.
- Add UI/API for advance only after runtime evidence is authoritative.