feat: Implement mfr truncation fix and enhance invoice handling
Playwright Tests / test (push) Canceled after 0s
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.
This commit is contained in:
@@ -181,6 +181,36 @@ Confirming the preview modal posts to **`req/sconf`**
|
||||
`[InvoiceId] = fds__newInvoiceId(YEAR())` → format `R<year>-<0000>`
|
||||
(the draft only ever had the internal numeric `Id`). `Version` is bumped
|
||||
and any linked "replaces" bookkeeping (storno/credit chains) is updated.
|
||||
- **Invoice date** = `DateFinalized` — printed on the PDF and used as the
|
||||
e-invoice issue date (`InvoiceDates.IssueDate`, ADR 0032).
|
||||
- **Backdating (ADR 0032):** users with `fds_inv > 2` see a checkbox in the
|
||||
preview dialog (`inv/dpreview` returns `backdate`) to date the invoice to
|
||||
the last working day (Mon–Fri) of the previous month, as long as no
|
||||
invoice has been finalised after that day. `req/sconf` then passes
|
||||
`@backdate = 1`; `fds__fn_invoiceBackdate` is re-checked and the proc
|
||||
throws 60001 (nothing finalised) if it is no longer allowed. Number year and
|
||||
`DueDate` follow the backdated day. The proc serializes all finalisations
|
||||
(transaction + `sp_getapplock`) so the check and the numbering cannot
|
||||
interleave with a concurrent finalisation. The controller maps 60001 to
|
||||
the "create again without backdating" message; a 0-row result (already
|
||||
final/sent, e.g. double submit) is reported as "already finalised".
|
||||
- **Same date everywhere (ADR 0035):** invoice lists, revenue reports,
|
||||
the DATEV export (period + `Belegdatum`), request details and reminders
|
||||
all use `[dbo].[fds__fn_invoiceDate]` — `DateFinalized` as German
|
||||
calendar day, drafts fall back to `DateCreated` — so a backdated invoice
|
||||
appears in the previous month everywhere, including DATEV. The reminder
|
||||
PDF's own date follows the same rule (reminder `DateFinalized`).
|
||||
- **Abschlagsrechnungen (ADR 0034):** `IntInvoiceAllocation` lines carry the
|
||||
credited intermediate invoice in `reference_InvId` (seeded by
|
||||
`fds__prepInvoice` and `fds__prepStorno_recreate`, round-tripped by the
|
||||
editor as item `ref`); finalisation records it in
|
||||
`fds__invoice_details.AllocatedTo_InvId` so the same Abschlagsrechnung is
|
||||
not offered again. The claim only counts while the crediting invoice is
|
||||
alive: once it is cancelled (storno, or replaced via storno + recreate)
|
||||
`fds__fn_IntermediateIsAllocatedToOther` treats the Abschlagsrechnung as
|
||||
free again and the next finalisation takes the allocation over. A
|
||||
Stornorechnung (`'c'`) never claims an allocation, even though a storno
|
||||
copy mirrors the credit lines.
|
||||
2. On success (`IsFinal == true` returned), the controller:
|
||||
- Reloads the invoice via `LoadInvoiceAsync`.
|
||||
- Calls `StoreInvoiceDocumentFileAsync` → renders the **final** PDF
|
||||
@@ -283,7 +313,7 @@ Once an invoice is `IsFinal`, the request/invoice list menus
|
||||
| **View / display PDF** | `$inv.disp(id, 'inv')` | `inv/rdoc` | Renders page images for on-screen display only. If a finalised, non-external invoice has no stored PDF, it is regenerated and persisted first (ADR 0025) |
|
||||
| **Download / open PDF** | `req/idoc` or `inv/pget`-derived | `req/idoc` | Serves the stored (or freshly rendered) PDF inline |
|
||||
| **Mark paid / unpaid** | `$inv.setPyd`/`setUpd` | `inv/setpyd` / `inv/setupd` | `fds__setInvoicePayed` / `fds__setInvoiceUNPayed` |
|
||||
| **Storno (cancel)** | `$inv.storno` → `$inv.cSt` | `inv/storno` (mode `simple`/`copy`) | `fds__createStorno_simple` / `fds__createStorno_copy`; the replaced invoice is cross-linked (`Replaces_InvId`) and cancelled once the storno itself is finalised |
|
||||
| **Storno (cancel)** | `$inv.storno` → `$inv.cSt` (first `inv/pget`: refreshes mfr entities only for numeric mfr ids, no-op for Intranet ids) | `inv/storno` (mode `simple`/`copy`) | `fds__createStorno_simple` / `fds__createStorno_copy`; the replaced invoice is cross-linked (`Replaces_InvId`) and cancelled once the storno itself is finalised |
|
||||
| **Credit note** | `$inv.credit` → `$inv.cSt` | `inv/credit` (mode `credit`) | `fds__createCredit_simple` — same preview/finalise/email loop as a normal invoice |
|
||||
| **Continue editing a draft** | `$inv.cntInv` / `clCntInv` | `inv/get` | Only available while `isFinal == false`; re-opens the same stateless editor |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user