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 66badbc..09e903b 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 @@ -146,7 +146,7 @@ public class KSeFAdapter implements SignalAdapter { * @param workitem * @throws PluginException */ - private void updateEInvoice(FileData fileDataXMLTemplate, ItemCollection workitem) throws PluginException { + public void updateEInvoice(FileData fileDataXMLTemplate, ItemCollection workitem) throws PluginException { try { EInvoiceModel model = EInvoiceModelFactory.read(new ByteArrayInputStream(fileDataXMLTemplate.getContent())); diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ksef/api/KSeFAPIService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ksef/api/KSeFAPIService.java index 7a20008..c10f8cd 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ksef/api/KSeFAPIService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ksef/api/KSeFAPIService.java @@ -426,8 +426,11 @@ public class KSeFAPIService { // Base64URL ohne Padding String base64Url = Base64.getUrlEncoder().withoutPadding().encodeToString(decoded); - // https://ksef-test.mf.gov.pl/api/v2 -> https://ksef-test.mf.gov.pl/client-app/ - baseURL = baseURL.replace("/api/v2", "/client-app/invoice"); + // Die Client App URL muss angepasst werden. Das /v2/ element aus der Basis URL + // muss mit 'client-app/invoice' ausgetauscht werden. + // Es entsteht dann https://api-test.ksef.mf.gov.pl/client-app/invoice/ + + baseURL = baseURL.replace("/v2", "/client-app/invoice"); // Build verification URL workitem.setItemValue("ksef.VerificationUrl", baseURL + "/" + kseFAuthManager.getKsefNip() + "/" + invoiceDate + "/" diff --git a/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/api/KSeFAdapterTest.java b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/api/KSeFAdapterTest.java new file mode 100644 index 0000000..ac004ca --- /dev/null +++ b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/api/KSeFAdapterTest.java @@ -0,0 +1,170 @@ +package com.alexanderlogistics.ksef.api; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.imixs.workflow.FileData; +import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.engine.DocumentService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.alexanderlogistics.BusinessPartnerService; +import com.alexanderlogistics.InvoiceService; +import com.alexanderlogistics.TestLoggerConfig; +import com.alexanderlogistics.einvoice.KSeFAdapter; + +/** + * Der KSeFAdapterTest prüft die Umwandlung einer Rechnung in die KSeF XML + * Struktur. + * + * Der Test simuliert eine Invoice und ruft dann den KSeFAdapter an um ein + * Output File zu erzeugen. + *

+ * Zum validieren kann man dann den validate_xml.sh Script hernehmen + * + */ + +@ExtendWith(MockitoExtension.class) +public class KSeFAdapterTest { + + private static Logger logger = Logger.getLogger(KSeFAdapterTest.class.getName()); + + private static final String TEMPLATE_FILE = "ksef/ksef.xml"; + private static final String OUTPUT_FILE = "ksef-output.xml"; + + ItemCollection workitem; + ItemCollection businessPartner; + + @Mock + private BusinessPartnerService businessPartnerService; + + @Mock + private DocumentService documentService; + + @Mock + private InvoiceService invoiceService; + + @InjectMocks + private KSeFAdapter adapter; + + @BeforeEach + void setup() throws Exception { + + TestLoggerConfig.setupTestLogger(); + // Prepare a workitem with typical invoice data + workitem = new ItemCollection(); + workitem.setItemValue("invoice.number", "FV/2025/001"); + workitem.setItemValue("invoice.date", LocalDate.of(2025, 2, 10)); + workitem.setItemValue("invoice.duedate", LocalDate.of(2025, 3, 10)); + workitem.setItemValue("invoice.currency", "PLN"); + workitem.setItemValue("invoice.total.net", 10000.00); + workitem.setItemValue("invoice.total.tax", 23.0); + workitem.setItemValue("invoice.total", 12300.00); + workitem.setItemValue("invoice.correction", "false"); + workitem.setItemValue("invoice.CorrectionInvoiceNumber", ""); + workitem.setItemValue("partner.id", "BP-001"); + workitem.setItemValue("partner.vat", "PL1234567890"); + + // Prepare child items (invoice line items) + List childItems = new ArrayList<>(); + ItemCollection lineItem1 = new ItemCollection(); + lineItem1.setItemValue("numpos", "1"); + lineItem1.setItemValue("datev.text", "Transport Berlin - Warsaw"); + lineItem1.setItemValue("datev.umsatz", 6000.00); + childItems.add(lineItem1.getAllItems()); + + ItemCollection lineItem2 = new ItemCollection(); + lineItem2.setItemValue("numpos", "2"); + lineItem2.setItemValue("datev.text", "Customs handling"); + lineItem2.setItemValue("datev.umsatz", 4000.00); + childItems.add(lineItem2.getAllItems()); + + workitem.setItemValue("_childitems", childItems); + + // Prepare mock business partner + businessPartner = new ItemCollection(); + businessPartner.setItemValue("partner.name", "Test Sp. z o.o."); + businessPartner.setItemValue("partner.country", "PL"); + businessPartner.setItemValue("partner.city", "Warszawa"); + businessPartner.setItemValue("partner.zip", "00-001"); + businessPartner.setItemValue("partner.address", "ul. Testowa 1"); + businessPartner.setItemValue("partner.vat", "PL1234567890"); + businessPartner.setItemValue("dbtr.number", "D-12345"); + } + + /** + * Erzeugt ein lokales XML File zum testen + */ + @Test + @DisplayName("Test Transform") + public void testTransform() throws Exception { + logger.info("==> Test: Upload Invoice XML"); + + // Arrange + when(businessPartnerService.getBusinessPartnerByID("BP-001")) + .thenReturn(businessPartner); + + FileData xmlTemplate = loadTemplateFromResources(TEMPLATE_FILE); + + // Act + adapter.updateEInvoice(xmlTemplate, workitem); + + // Assert - basic checks + assertNotNull(xmlTemplate.getContent(), "XML content should not be null after update"); + assertTrue(xmlTemplate.getContent().length > 0, "XML content should not be empty"); + + // Write output for manual inspection + writeOutputToResources(xmlTemplate, OUTPUT_FILE); + + } + + // ── Helper methods ────────────────────────────────────────────── + + /** + * Load the KSeF XML template from src/test/resources. + */ + private FileData loadTemplateFromResources(String filename) { + try (InputStream is = getClass().getClassLoader().getResourceAsStream(filename)) { + if (is == null) { + fail("Template file not found in test resources: " + filename + + "\nPlease place your KSeF XML template at: src/test/resources/" + filename); + } + byte[] content = is.readAllBytes(); + return new FileData(filename, content, "application/xml", null); + } catch (IOException e) { + fail("Failed to read template: " + e.getMessage()); + return null; + } + } + + /** + * Write the resulting XML to src/test/resources/output/ for manual inspection. + */ + private void writeOutputToResources(FileData fileData, String filename) throws IOException { + Path outputDir = Paths.get("src", "test", "resources", "output"); + Files.createDirectories(outputDir); + Path outputPath = outputDir.resolve(filename); + Files.write(outputPath, fileData.getContent()); + System.out.println("──────────────────────────────────────────────"); + System.out.println("Output written to: " + outputPath.toAbsolutePath()); + System.out.println("──────────────────────────────────────────────"); + } +} diff --git a/office-alexander-logistics-app/src/test/resources/ksef/ksef-old.xml b/office-alexander-logistics-app/src/test/resources/ksef/ksef-old.xml new file mode 100644 index 0000000..404f0ef --- /dev/null +++ b/office-alexander-logistics-app/src/test/resources/ksef/ksef-old.xml @@ -0,0 +1,119 @@ + + + + FA + 3 + 2025-11-19T16:43:15.545220735Z + Imixs eInvoice + + + + + 9552521552 + Alexander Global Logistics + + + PL + Gdanska 36 + 70-660 Szczecin + + + MBudas@alexander-logistics.com + + + + + + + + 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 + + + 1 + 2b141c75-7867-4975-846a-a2c2683e1fc5 + R IM-ZEL-2403-259 + szt. + 1 + 4128.00 + 4128.00 + 0 + + + + 2 + + 2 + + 2 + + 2 + + + 1 + + + + 1 + + + 2 + + + 1 + + + + VAT | ??? + + + \ No newline at end of file diff --git a/office-alexander-logistics-app/src/test/resources/ksef/ksef.xml b/office-alexander-logistics-app/src/test/resources/ksef/ksef.xml index 404f0ef..76e0401 100644 --- a/office-alexander-logistics-app/src/test/resources/ksef/ksef.xml +++ b/office-alexander-logistics-app/src/test/resources/ksef/ksef.xml @@ -1,119 +1,108 @@ - + - - FA - 3 - 2025-11-19T16:43:15.545220735Z - Imixs eInvoice - - - - - 9552521552 - Alexander Global Logistics - - - PL - Gdanska 36 - 70-660 Szczecin - - - MBudas@alexander-logistics.com - - - - - - + + + 9552521552 + Alexander Global Logistics + + + PL + Gdanska 36 + 70-660 Szczecin + + + MBudas@alexander-logistics.com + + + + + + + - - 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 - - - 1 - 2b141c75-7867-4975-846a-a2c2683e1fc5 - R IM-ZEL-2403-259 - szt. - 1 - 4128.00 - 4128.00 - 0 - - - - 2 - - 2 - - 2 - - 2 - - - 1 - - - - 1 - - - 2 - - - 1 - - - - VAT | ??? - - + #CDTR-NUMBER# + 2 + 2 + + + + + #CURRENCY# + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 2 + + + + 1 + + + + + 1 + + + + 2 + + + + 1 + + + + VAT + + + + + \ No newline at end of file diff --git a/office-alexander-logistics-app/src/test/resources/output/ksef-output.xml b/office-alexander-logistics-app/src/test/resources/output/ksef-output.xml new file mode 100644 index 0000000..c45f200 --- /dev/null +++ b/office-alexander-logistics-app/src/test/resources/output/ksef-output.xml @@ -0,0 +1,118 @@ + + + + FA + 3 + 2026-02-10T12:46:08.366684Z + Imixs eInvoice + + + + + 9552521552 + Alexander Global Logistics + + + PL + Gdanska 36 + 70-660 Szczecin + + + MBudas@alexander-logistics.com + + + + + + + + 1234567890 + Test Sp. z o.o. + + + PL + ul. Testowa 1 + 00-001 Warszawa + + + D-12345 + 2 + + 2 + + + + + PLN + 2025-02-10 + + FV/2025/001 + + 2025-03-10 + + + + 10000.00 + 2300.00 + 12300.00 + + + 2 + + 2 + + 2 + + 2 + + + 1 + + + + 1 + + + 2 + + + 1 + + + + VAT + + + 1 + 5a2dd34c-6592-40aa-aafc-80bac9c9b9c4 + Transport Berlin - Warsaw + szt. + 1 + 6000.00 + 6000.00 + + + 2 + d44bf6a0-758b-415b-b45a-d83052a2f2aa + Customs handling + szt. + 1 + 4000.00 + 4000.00 + + +