From 7309821c7a8c0d4bcc59e20a91ad65885889083e Mon Sep 17 00:00:00 2001 From: Pawel Tschudnowsky Date: Thu, 3 Jul 2025 12:26:33 +0200 Subject: [PATCH] Fix Product Country of origin closes #861 --- .../main/java/org/mustangproject/Product.java | 10 ++-- .../ZUGFeRD/DeSerializationTest.java | 49 ++++++++++++------- .../test/resources/Extended_fremdwaehrung.xml | 4 ++ 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index 4f0397ee..ef641dd0 100644 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -1,13 +1,10 @@ package org.mustangproject; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.*; import org.mustangproject.ZUGFeRD.IDesignatedProductClassification; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; import org.mustangproject.util.NodeMap; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import java.math.BigDecimal; import java.util.ArrayList; @@ -105,7 +102,10 @@ public class Product implements IZUGFeRDExportableProduct { classifications.add(new DesignatedProductClassification(classCode, className))); }); - nodeMap.getAsString("OriginTradeCounty").ifPresent(this::setCountryOfOrigin); + nodeMap.getAsNodeMap("OriginTradeCountry") + .flatMap(nodes -> nodes.getNode("ID")) + .map(Node::getTextContent) + .ifPresent(this::setCountryOfOrigin); } /*** diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java index bb41fb5a..c586df7a 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java @@ -21,6 +21,13 @@ */ package org.mustangproject.ZUGFeRD; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; +import org.mustangproject.*; +import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants; + import java.io.File; import java.io.IOException; import java.math.BigDecimal; @@ -29,28 +36,11 @@ import java.nio.file.Files; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.TimeZone; import javax.xml.xpath.XPathExpressionException; -import org.junit.FixMethodOrder; -import org.junit.experimental.theories.FromDataPoints; -import org.junit.runners.MethodSorters; -import org.mustangproject.Allowance; -import org.mustangproject.BankDetails; -import org.mustangproject.CalculatedInvoice; -import org.mustangproject.CashDiscount; -import org.mustangproject.Charge; -import org.mustangproject.Contact; -import org.mustangproject.Invoice; -import org.mustangproject.Item; -import org.mustangproject.Product; -import org.mustangproject.SchemedID; -import org.mustangproject.TradeParty; -import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants; +import static org.assertj.core.api.Assertions.assertThat; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class DeSerializationTest extends ResourceCase { @@ -71,6 +61,29 @@ public class DeSerializationTest extends ResourceCase { } + public void testProduct() throws IOException, XPathExpressionException, ParseException { + File inputCII = getResourceAsFile("Extended_fremdwaehrung.xml"); + var zii = new ZUGFeRDInvoiceImporter(); + zii.doIgnoreCalculationErrors(); + zii.fromXML(Files.readString(inputCII.toPath())); + var product = zii.extractInvoice() + .getZFItems()[0] + .getProduct(); + + assertThat(product.getCountryOfOrigin()).as("Product Country of origin") + .isEqualTo("DE"); + assertThat(product.getSellerAssignedID()).as("Product Seller assigned ID") + .isEqualTo("CO-123/V2A"); + assertThat(product.getBuyerAssignedID()).as("Product Buyer assigned ID") + .isEqualTo("Toolbox 0815"); + assertThat(product.getName()).as("Name") + .isEqualTo("Stahlcoil"); + + assertThat(product.getAttributes()).as("Product attributes") + .containsKey("LeoID") + .containsValue("704310.0105636504"); + } + public void testInvoiceLine() throws JsonProcessingException { File inputCII = getResourceAsFile("factur-x.xml"); boolean hasExceptions = false; diff --git a/library/src/test/resources/Extended_fremdwaehrung.xml b/library/src/test/resources/Extended_fremdwaehrung.xml index 4d10dea8..e5cb611d 100644 --- a/library/src/test/resources/Extended_fremdwaehrung.xml +++ b/library/src/test/resources/Extended_fremdwaehrung.xml @@ -131,6 +131,10 @@ costs, losses or damages could normally have been foreseen.--> CO-123/V2A Toolbox 0815 Stahlcoil + + LeoID + 704310.0105636504 + DE