From dd70091057039ee6495b2b105fdea10c5a805021 Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Mon, 24 Nov 2025 23:20:18 +0100 Subject: [PATCH] Invoice Type (RodzajFaktury) -> VAT | KOR --- doc/KSeF/README.md | 103 ++++++++++ .../einvoice/KSeFAdapter.java | 34 +++- .../resources/ksef/example-invoice-KOR.xml | 100 ++++++++++ ...invoice-01.xml => example-invoice-VAT.xml} | 35 ++-- .../src/test/resources/ksef/ksef-test04.xml | 187 +++++++++--------- workflow/pl/e-invoice/templates/ksef.xml | 2 + 6 files changed, 350 insertions(+), 111 deletions(-) create mode 100644 office-alexander-logistics-app/src/test/resources/ksef/example-invoice-KOR.xml rename office-alexander-logistics-app/src/test/resources/ksef/{example-invoice-01.xml => example-invoice-VAT.xml} (86%) diff --git a/doc/KSeF/README.md b/doc/KSeF/README.md index 75f464c..e6f2c73 100644 --- a/doc/KSeF/README.md +++ b/doc/KSeF/README.md @@ -193,3 +193,106 @@ or to manual test a xml run: $ xmllint --noout --schema 'schemat-FA(3)-v1-0E.xsd' example-invoice-01.xml example-invoice-01.xml validates ``` + +# KSeF FA(3) Invoice Types: VAT vs. KOR + +This section explains the key differences between regular invoices (VAT) and correction invoices (KOR) in the Polish KSeF system using FA(3) structure. + +## Invoice Types + +### VAT - Regular Invoice + +Standard invoice documenting a sale or service delivery. + +### KOR - Correction Invoice + +Invoice that corrects a previously issued invoice (VAT, ZAL, or ROZ). + +--- + +## Key Differences + +| Element | VAT Invoice | KOR Invoice | +| ------------------------- | -------------------------- | --------------------------------------------- | +| **RodzajFaktury** | `VAT` | `KOR` | +| **P_2 (Invoice Number)** | `216525` | `216525-KOR` (with suffix) | +| **P_1 (Invoice Date)** | Original date (2024-04-03) | Correction date (2024-04-15) | +| **Amount Fields** | Absolute values | **Difference values** (negative or positive) | +| **DaneFaKorygowanej** | ❌ Not present | ✅ **Required** - references original invoice | +| **FaWiersz (Line Items)** | Original values | **New/corrected values** | + +--- + +## Critical: Amount Fields in KOR + +**KOR invoices show DIFFERENCES, not absolute amounts!** + +### Example: Correction from 4128.00 → 3500.00 EUR + +```xml + +4128.00 +0.00 +4128.00 +``` + +```xml + +-628.00 +-628.00 +``` + +⚠️ **Important:** + +- KOR uses different P_13/P_14 fields than VAT +- `P_13_1`, `P_14_1` → Used in VAT invoices +- `P_13_6_1`, `P_13_7`, etc. → Used in KOR invoices (for 0% rate, exempt, etc.) + +--- + +## DaneFaKorygowanej Element + +**Required in KOR invoices** - Must appear AFTER `KOR` + +```xml + + 2024-04-03 + 216525 + 1 + 9552521552-20240403-ABCDEF-123456-AB + +``` + +| Field | Description | +| ----------------------- | --------------------------------------------------------- | +| `DataWystFaKorygowanej` | Date of **original** invoice | +| `NrFaKorygowanej` | Number of **original** invoice | +| `NrKSeF` | Flag: `1` = original was in KSeF | +| `NrKSeFFaKorygowanej` | KSeF number of original invoice (mandatory if `NrKSeF=1`) | + +⚠️ **Critical:** The KSeF number must be saved when uploading the original VAT invoice! + +--- + +## FaWiersz in KOR + +**Line items show the NEW/CORRECTED values**, not differences: + +```xml + + + 4128.00 + 4128.00 + +``` + +```xml + + + 3500.00 + 3500.00 + 0 KR + +``` + +--- diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/einvoice/KSeFAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/einvoice/KSeFAdapter.java index 12842c3..37302a2 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/einvoice/KSeFAdapter.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/einvoice/KSeFAdapter.java @@ -117,7 +117,7 @@ public class KSeFAdapter implements SignalAdapter { updateEInvoice(xmlFileData, workitem); // append XML document - logger.info("│ ├── export KSeF e-invoice"); + logger.info("│ ├── attach KSeF e-invoice..."); workitem.addFileData(xmlFileData); } catch (PluginException e) { @@ -153,6 +153,17 @@ public class KSeFAdapter implements SignalAdapter { TradeParty billingAddress = buildAddress(workitem.getItemValueString("partner.id"), "buyer", model); model.setTradeParty(billingAddress); + // Update Invoice Type (RodzajFaktury) -> VAT | KOR + Element elementFa = model.findOrCreateChildNode(model.getRoot(), EInvoiceNS.KSEF, "Fa"); + + if (isKorrekturRechnung(workitem)) { + model.updateElementValue(elementFa, EInvoiceNS.KSEF, "RodzajFaktury", "KOR"); + logger.info("│ ├── invoice type=KOR"); + } else { + // normale rechnung + model.updateElementValue(elementFa, EInvoiceNS.KSEF, "RodzajFaktury", "VAT"); + logger.info("│ ├── invoice type=VAT"); + } // Update Rechnungssummen... if (workitem.getItemValueDouble("invoice.total.tax") > 0) { // wir haben eine Steuer! @@ -162,8 +173,7 @@ public class KSeFAdapter implements SignalAdapter { } // set currency - Element fa = model.findOrCreateChildNode(model.getRoot(), EInvoiceNS.KSEF, "Fa"); - model.updateElementValue(fa, EInvoiceNS.KSEF, "KodWaluty", + model.updateElementValue(elementFa, EInvoiceNS.KSEF, "KodWaluty", workitem.getItemValueString("invoice.currency")); // Update Invoice Items @@ -179,9 +189,6 @@ public class KSeFAdapter implements SignalAdapter { model.setNetTotalAmount(workitem.getItemValueDouble("invoice.total")); model.setGrandTotalAmount(workitem.getItemValueDouble("invoice.total")); - // References>AB230321 - // model.setOrderReferenceId(workitem.getItemValueString("order.number")); - // finally update the template file fileDataXMLTemplate.setContent(model.getContent()); @@ -191,6 +198,21 @@ public class KSeFAdapter implements SignalAdapter { } + /** + * Gibt True zurück wenn es eine korrektur rechnung ist + * + * InvoiceHeader/Correction=true + * InvoiceHeader/CorrectionInvoiceNumber !empty + * + * + * @param workitem + * @return + */ + private boolean isKorrekturRechnung(ItemCollection workitem) { + return ("true".equals(workitem.getItemValueString("invoice.correction")) + && !workitem.getItemValueString("invoice.CorrectionInvoiceNumber").isEmpty()); + } + /** * Erstellt ein TradeParty Objekt aus einer Liste von Adresszeilen. * diff --git a/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-KOR.xml b/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-KOR.xml new file mode 100644 index 0000000..1bbc4d3 --- /dev/null +++ b/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-KOR.xml @@ -0,0 +1,100 @@ + + + + FA + 3 + 2025-11-25T10:30:00Z + Imixs eInvoice + + + + + 9552521552 + Alexander Global Logistics GmbH + + + PL + Museumstr. 2-6 + 28195 Bremen + + + MBudas@alexander-logistics.com + + + + + 6621004747 + REGESTA Spolka Akcyjna + + + PL + ul. Nowowiejska 52a + 28-400 Pinczow + + D15231 + 2 + 2 + + + + + PLN + + + 2024-04-15 + + + 216525-KOR + + + 2024-06-02 + + + -628.00 + + + -628.00 + + + 2 + 2 + 2 + 2 + + 1 + + + 1 + + 2 + + 1 + + + + KOR + + + + 2024-04-03 + 216525 + 1 + 9552521552-20240403-ABCDEF-123456-AB + + + + + 1 + 8a8458dc-5b4f-462c-a964-8848d089a0f9 + R IM-ZEL-2403-259 + szt. + 1 + 3500.00 + 3500.00 + 0 KR + + + \ No newline at end of file diff --git a/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-01.xml b/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-VAT.xml similarity index 86% rename from office-alexander-logistics-app/src/test/resources/ksef/example-invoice-01.xml rename to office-alexander-logistics-app/src/test/resources/ksef/example-invoice-VAT.xml index 995e23a..c5b1544 100644 --- a/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-01.xml +++ b/office-alexander-logistics-app/src/test/resources/ksef/example-invoice-VAT.xml @@ -8,7 +8,7 @@ FA 3 2026-06-05T02:45:33.422866Z - Generator danych + Imixs eInvoice @@ -21,37 +21,46 @@ 28195 Bremen - Lucja17@example.net - 86-588-03-5531 + MBudas@alexander-logistics.com - 3861610227 - Błaszczak - Lenart + 6621004747 + REGESTA Spolka Akcyjna PL - al. Szewczyk 7247 - 84-642 Żelechów + ul. Nowowiejska 52a + 28-400 Pinczow - - Jakubina82@gmail.com - 75-461-31-12 - - KL-2936 + D15231 2 2 + + PLN + + 2025-07-17 - Lidzbark + + FA/GRQMB-#invoice_number#/05/2025 + + 2025-07-11 + + 10652.38 + + 2450.05 + + 13102.43 + 2 2 diff --git a/office-alexander-logistics-app/src/test/resources/ksef/ksef-test04.xml b/office-alexander-logistics-app/src/test/resources/ksef/ksef-test04.xml index de58cca..b4f2e0e 100644 --- a/office-alexander-logistics-app/src/test/resources/ksef/ksef-test04.xml +++ b/office-alexander-logistics-app/src/test/resources/ksef/ksef-test04.xml @@ -1,105 +1,108 @@ - - - FA - 3 - 2025-11-24T18:45:31.387561092Z - Imixs eInvoice - - - - - 9552521552 - Alexander Global Logistics - - - PL - Gdanska 36 - 70-660 Szczecin - - - MBudas@alexander-logistics.com - - - - - + + + FA + 3 + 2025-11-24T18:45:31.387561092Z + Imixs eInvoice + + + + + 9552521552 + Alexander Global Logistics + + + PL + Gdanska 36 + 70-660 Szczecin + + + MBudas@alexander-logistics.com + + + + + - 6621004747 - REGESTA Spolka Akcyjna - - - PL - ul. Nowowiejska 52a - 28-400 Pinczow - - - D15231 - 2 - - 2 - - - - - EUR - 2024-04-03 - - 216525 - - 2024-06-02 - - - 4128.00 - - 0.00 - - 4128.00 - - + D15231 + 2 + + 2 + + + + + EUR + 2024-04-03 + + 216525 + + 2024-06-02 + + + 4128.00 + + 0.00 + + 4128.00 + + - 2 - - 2 - - 2 - - 2 - - - 1 - - - - 1 - - - 2 - - - 1 - - - - VAT - - - 1 - 8a8458dc-5b4f-462c-a964-8848d089a0f9 - R IM-ZEL-2403-259 - szt. - 1 - 4128.00 - 4128.00 - - + 2 + + 2 + + 2 + + 2 + + + 1 + + + + 1 + + + 2 + + + 1 + + + + VAT + + + 1 + 8a8458dc-5b4f-462c-a964-8848d089a0f9 + R IM-ZEL-2403-259 + szt. + 1 + 4128.00 + 4128.00 + + \ No newline at end of file diff --git a/workflow/pl/e-invoice/templates/ksef.xml b/workflow/pl/e-invoice/templates/ksef.xml index aef19a5..7debe33 100644 --- a/workflow/pl/e-invoice/templates/ksef.xml +++ b/workflow/pl/e-invoice/templates/ksef.xml @@ -55,9 +55,11 @@ #CURRENCY# + + 0.00 0.00