- Added a new SQL script to address the "String or binary data would be truncated" error in mfr sync by widening the Note fields in service objects and companies to NVARCHAR(MAX). - Updated the table types and associated stored procedures to accommodate the changes, ensuring compatibility with existing data. - Queued a re-sync for previously rejected rows due to truncation issues. - Created application logins for fuchs_fds and fuchs_web with placeholder passwords for initial setup. - Introduced functions for invoice backdating and invoice date retrieval to streamline invoice processing. - Developed a password generation function with customizable parameters for length and character types. - Added a random number generation function to support password creation.
3.9 KiB
status, date, applyTo, supersededBy
| status | date | applyTo | supersededBy | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Accepted | 2026-09-30 |
|
0034 — An Abschlagsrechnung credit follows the live invoice
Context
A Schlussrechnung credits the Abschlagsrechnungen (intermediate invoices, InvoiceType = 'i')
already paid for the same service requests via IntInvoiceAllocation lines. Finalising it records
the claim in fds__invoice_details.AllocatedTo_InvId of each credited intermediate so that
fds__prepInvoice does not offer the same Abschlagsrechnung again.
Until 2026-09-30 that claim was never actually written (the editor dropped reference_InvId, the
MERGE aborted on the NULL). The moment it is written, the question "what happens to the claim when
the crediting invoice is cancelled?" becomes real: a Storno (simple/copy) or a Storno + recreate
leaves AllocatedTo_InvId pointing at the cancelled invoice, and the next invoice for the same
service requests would silently bill the customer again for money already paid.
Decision
- A claim counts only while the crediting invoice is alive. An
AllocatedTo_InvIdthat points at a cancelled invoice (IsCanceled = 1), at a non-existent invoice, or at the invoice that the one being finalised replaces (CanceledInvoiceline →@Replaces) is void: the Abschlagsrechnung is offered again byfds__prepInvoice/fds__prepStorno_recreateand may be taken over by the next finalisation. The single source of truth for "already credited elsewhere" is[dbo].[fds__fn_IntermediateIsAllocatedToOther];fds__setInvoiceFinal'sexistingCTE is its set-based twin and must apply the same rule. - The link is not cleared on cancellation. Cancellation has several paths (storno simple/copy,
storno + recreate, the retired
fds__setInvoiceCancelled); rather than releasing the link in each, the readers ignore dead links. The last claimant therefore stays visible for auditing. - A Stornorechnung (
InvoiceType = 'c') never claims.fds__createStorno_copymirrors the cancelled invoice'sIntInvoiceAllocationlines (with their references) so the storno document shows them, but finalising the storno must not move the allocation onto it. - Storno + recreate carries the references.
fds__prepStorno_recreateemits its credit lines with the same type asfds__prepInvoice(IntInvoiceAllocation, notPartialInvoice) and the credited invoice inreference_InvId, and itsCanceledInvoiceline references the replaced invoice — otherwise the replacement neither takes over the credit nor records what it replaces.
Consequences
- The recreate flow now produces
Replaces_InvId/DateCancelledon the replaced invoice via the regularfds__setInvoiceFinalbookkeeping (it did not before: no reference reached the proc). - A second recreate (cancel the replacement, recreate again) keeps the credit because the claim on the replaced invoice is treated as void during the replacement's finalisation.
- The one-off backfill script records the earliest live claimant; it is consistent with this rule.
- An intermediate that is itself cancelled is not offered (unchanged).
Alternatives considered
- Release
AllocatedTo_InvIdwhen the crediting invoice is cancelled — rejected: four write paths to keep in sync, and the audit trail of who last credited the Abschlagsrechnung is lost. - Keep
PartialInvoicefor recreated credit lines and teachfds__setInvoiceFinalboth types — rejected: one line type per meaning;PartialInvoiceremains the Abschlagsbetrag charge line of an intermediate invoice.