Playwright Tests / test (push) Canceled after 0s
- 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.
65 lines
3.9 KiB
Markdown
65 lines
3.9 KiB
Markdown
---
|
|
status: Accepted
|
|
date: 2026-09-30
|
|
applyTo:
|
|
- "Fuchs_Database/dbo/Functions/fds__fn_IntermediateIsAllocatedToOther.sql"
|
|
- "Fuchs_Database/dbo/Stored Procedures/fds__setInvoiceFinal.sql"
|
|
- "Fuchs_Database/dbo/Stored Procedures/fds__prepInvoice.sql"
|
|
- "Fuchs_Database/dbo/Stored Procedures/fds__prepStorno_recreate.sql"
|
|
- "Fuchs_Database/dbo/Stored Procedures/fds__createStorno_*.sql"
|
|
- "Fuchs_Database/Scripts/2026-09-30_backfill_intermediate_invoice_allocations.sql"
|
|
supersededBy: ""
|
|
---
|
|
|
|
# 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_InvId` that points
|
|
at a cancelled invoice (`IsCanceled = 1`), at a non-existent invoice, or at the invoice that the
|
|
one being finalised replaces (`CanceledInvoice` line → `@Replaces`) is void: the Abschlagsrechnung
|
|
is offered again by `fds__prepInvoice` / `fds__prepStorno_recreate` and may be taken over by the
|
|
next finalisation. The single source of truth for "already credited elsewhere" is
|
|
`[dbo].[fds__fn_IntermediateIsAllocatedToOther]`; `fds__setInvoiceFinal`'s `existing` CTE 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_copy` mirrors the
|
|
cancelled invoice's `IntInvoiceAllocation` lines (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_recreate` emits its credit lines
|
|
with the same type as `fds__prepInvoice` (`IntInvoiceAllocation`, not `PartialInvoice`) and the
|
|
credited invoice in `reference_InvId`, and its `CanceledInvoice` line 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` / `DateCancelled` on the replaced invoice via the
|
|
regular `fds__setInvoiceFinal` bookkeeping (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_InvId` when 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 `PartialInvoice` for recreated credit lines and teach `fds__setInvoiceFinal` both types** —
|
|
rejected: one line type per meaning; `PartialInvoice` remains the Abschlagsbetrag charge line of an
|
|
intermediate invoice.
|