diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java index 19770c2..7b07f82 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java @@ -77,6 +77,22 @@ public class InvoiceService { @Inject DocumentService documentService; + public ItemCollection findOutboundInvoiceByNumber(String invoiceNumber) { + ItemCollection result = null; + try { + String query = "($modelversion:rechnungsausgang*) AND (invoice.number:" + invoiceNumber + ")"; + List list; + list = documentService.find(query, 1, 0); + if (list != null && list.size() > 0) { + result = list.get(0); + } + } catch (QueryException e) { + e.printStackTrace(); + } + + return result; + } + /** * Liefert die Liste der Ausgehenden Währungen * 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 085de6d..9f09872 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 @@ -5,6 +5,7 @@ import java.io.FileNotFoundException; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Locale; import java.util.logging.Logger; @@ -31,6 +32,7 @@ import org.imixs.workflow.util.XMLParser; import org.w3c.dom.Element; import com.alexanderlogistics.BusinessPartnerService; +import com.alexanderlogistics.InvoiceService; import com.alexanderlogistics.InvoiceUtil; import jakarta.inject.Inject; @@ -93,6 +95,9 @@ public class KSeFAdapter implements SignalAdapter { @Inject BusinessPartnerService businessPartnerService; + @Inject + InvoiceService invoiceService; + /** * This method * @@ -156,12 +161,45 @@ public class KSeFAdapter implements SignalAdapter { TradeParty billingAddress = buildAddress(workitem, "buyer", model); model.setTradeParty(billingAddress); + // set Tax Type based on vatID + ((EInvoiceModelKSeF) model).setTaxType(workitem.getItemValueString("partner.vat")); + // Update Invoice Type (RodzajFaktury) -> VAT | KOR Element elementFa = model.findOrCreateChildNode(model.getRoot(), EInvoiceNS.KSEF, "Fa"); if (isKorrekturRechnung(workitem)) { ((EInvoiceModelKSeF) model).setRodzajFaktury("KOR"); logger.info("│ ├── invoice type=KOR"); + + // Set correction data (DaneFaKorygowanej) - required for KOR invoices + Element daneFaKorygowanej = model.findOrCreateChildNodeAfter( + elementFa, EInvoiceNS.KSEF, "DaneFaKorygowanej", "RodzajFaktury"); + + Date correctionInvoiceDate = workitem.getItemValueDate("invoice.date"); + // try to lookup original invoice by invoice.CorrectionInvoiceNumber + ItemCollection correctionInvoice = invoiceService + .findOutboundInvoiceByNumber(workitem.getItemValueString("invoice.CorrectionInvoiceNumber")); + if (correctionInvoice != null) { + correctionInvoiceDate = correctionInvoice.getItemValueDate("invoice.date"); + logger.info("│ ├── found original invoice, date: " + correctionInvoiceDate); + } else { + logger.info("│ ├── ⚠️ original invoice not found, using current date as fallback"); + } + // Original invoice date (DataWystFaKorygowanej) - required + if (correctionInvoiceDate != null) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + String sCorrectionDate = formatter.format(correctionInvoiceDate); + model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF, + "DataWystFaKorygowanej", sCorrectionDate); + } + + // Original invoice number (NrFaKorygowanej) - required + model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF, + "NrFaKorygowanej", workitem.getItemValueString("invoice.CorrectionInvoiceNumber")); + + // NrKSeFN = 1 means the original invoice was issued outside KSeF + model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF, "NrKSeFN", "1"); + } else { // normale rechnung ((EInvoiceModelKSeF) model).setRodzajFaktury("VAT"); diff --git a/office-alexander-logistics-app/src/test/resources/ksef/ksef-test06.xml b/office-alexander-logistics-app/src/test/resources/ksef/ksef-test06.xml new file mode 100644 index 0000000..4c3bf45 --- /dev/null +++ b/office-alexander-logistics-app/src/test/resources/ksef/ksef-test06.xml @@ -0,0 +1,145 @@ + + + + FA + 3 + 2025-12-04T17:00:46.126282515Z + Imixs eInvoice + + + + + 9552521552 + Alexander Global Logistics + + + PL + Gdanska 36 + 70-660 Szczecin + + + MBudas@alexander-logistics.com + + + + + + + + DE814745205 + Profor Fibre GmbH + + + DE + Domstraße 18 + 20095 Hamburg + + + D13006 + 2 + + 2 + + + + + EUR + 2025-12-04 + + 6543 + + 2026-01-03 + + + + 390.89 + + + + 390.89 + + + + 2 + + 2 + + 2 + + 2 + + + 1 + + + + 1 + + + 2 + + + 1 + + + + KOR + + + 1 + 0f8b3274-02f5-4e7c-a2f3-af1d2c48e6e8 + IM-POL-2510-059 + szt. + 1 + 0.00 + 0.00 + + + 2 + 7186ad2c-6a5f-4df2-9d66-f5d496c9c5a1 + IM-POL-2510-059 + szt. + 1 + -2052.20 + -2052.20 + + + 3 + 931a7d53-e50c-4cd1-82ab-480f2c7765e8 + IM-POL-2510-059 + szt. + 1 + 0.00 + 0.00 + + + 4 + d0805423-d2e1-42f0-80bd-9ca0171f2764 + IM-POL-2510-059 + szt. + 1 + 2443.09 + 2443.09 + + + 5 + d94d9030-4992-49f4-9e46-973a6f2b63e2 + IM-POL-2510-059 + szt. + 1 + 0.00 + 0.00 + + + + \ No newline at end of file