diff --git a/History.md b/History.md index 321335d9..c37b08ec 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,6 @@ +- 461 +- 463 + 2.13.0 ======= 2024-08-28 diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index 40922376..b953008c 100644 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -23,6 +23,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { protected String name, zip, street, location, country; protected String taxID = null, vatID = null; protected String ID = null; + protected String description = null; protected String additionalAddress = null; protected String additionalAddressExtension = null; protected List bankDetails = new ArrayList<>(); @@ -66,14 +67,14 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { Node currentItemNode = nodes.item(nodeIndex); if (currentItemNode.getLocalName() != null) { - String debcurrentChild = currentItemNode.getLocalName(); - if (debcurrentChild.equals("Party")) { + String currentUBLChild = currentItemNode.getLocalName(); + if (currentUBLChild.equals("Party")) { NodeList party = currentItemNode.getChildNodes(); for (int partyIndex = 0; partyIndex < party.getLength(); partyIndex++) { if (party.item(partyIndex).getLocalName() != null) { - String debCN = party.item(partyIndex).getLocalName(); - if (debCN.equals("PartyName")) { + String currentTopElementName = party.item(partyIndex).getLocalName(); + if (currentTopElementName.equals("PartyName")) { NodeList partyName = party.item(partyIndex).getChildNodes(); for (int partyNameIndex = 0; partyNameIndex < partyName.getLength(); partyNameIndex++) { @@ -86,7 +87,20 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } } } - if (debCN.equals("PostalAddress")) { + + // UBL only: formally it can have a name as well but BT27 party name *should* be stored in + // so overwrite if one exists + if (currentTopElementName.equals("PartyLegalEntity")) { + NodeList legal = party.item(partyIndex).getChildNodes(); + for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) { + if (legal.item(legalChildIndex).getLocalName() != null) { + if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) { + setName(legal.item(legalChildIndex).getTextContent()); + } + } + } + } + if (currentTopElementName.equals("PostalAddress")) { NodeList postal = party.item(partyIndex).getChildNodes(); for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) { @@ -144,7 +158,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } } - if (debCN.equals("Contact")) { + if (currentTopElementName.equals("Contact")) { NodeList contact = party.item(partyIndex).getChildNodes(); setContact(new Contact(contact)); @@ -155,19 +169,19 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } - if (debcurrentChild.equals("GlobalID")) { + if (currentUBLChild.equals("GlobalID")) { if (nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID") != null) { SchemedID gid = new SchemedID().setScheme(nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(nodes.item(nodeIndex).getTextContent()); addGlobalID(gid); } } - if (debcurrentChild.equals("DefinedTradeContact")) { + if (currentUBLChild.equals("DefinedTradeContact")) { NodeList contact = nodes.item(nodeIndex).getChildNodes(); setContact(new Contact(contact)); } - if (debcurrentChild.equals("PostalTradeAddress")) { + if (currentUBLChild.equals("PostalTradeAddress")) { NodeList postal = nodes.item(nodeIndex).getChildNodes(); for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) { if (postal.item(postalChildIndex).getLocalName() != null) { @@ -195,7 +209,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } - if (debcurrentChild.equals("SpecifiedTaxRegistration")) { + if (currentUBLChild.equals("SpecifiedTaxRegistration")) { NodeList taxChilds = nodes.item(nodeIndex).getChildNodes(); for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { if (taxChilds.item(taxChildIndex).getLocalName() != null) { @@ -286,8 +300,8 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { //nodes.item(i).getTextContent())) { - String debLN = nodes.item(nodeIndex).getLocalName(); - if (debLN.equals("Party")) { + String topElementName = nodes.item(nodeIndex).getLocalName(); + if (topElementName.equals("Party")) { // take one step back and parse from top parseFromUBL(nodes); return; @@ -302,6 +316,10 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { if (itemChilds.item(itemChildIndex).getLocalName().equals("Name")) { setName(itemChilds.item(itemChildIndex).getTextContent()); } + + if (itemChilds.item(itemChildIndex).getLocalName().equals("Description")) { + setDescription(itemChilds.item(itemChildIndex).getTextContent()); + } if (itemChilds.item(itemChildIndex).getLocalName().equals("GlobalID")) { if (itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID") != null) { SchemedID gid = new SchemedID().setScheme(itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(itemChilds.item(itemChildIndex).getTextContent()); @@ -560,6 +578,26 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } + /*** + * + * @return String the description, e.g. if it's a vat exempt company + */ + public String getDescription() { + return description; + } + + + /*** + * required, usually done in the constructor: the complete name of the organisation + * @param description human readable description + * @return fluent setter + */ + public TradeParty setDescription(String description) { + this.description = description; + return this; + } + + public String getZIP() { return zip; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java index 8af10dbb..a9977f01 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java @@ -112,12 +112,17 @@ public interface IZUGFeRDExportableTradeParty { } /** - * First and last name of the recipient + * e.g. first and last name of the owner * - * @return First and last name of the recipient + * @return full name of the party */ String getName(); + /** + * @return description, e.g. if it's a small company + */ + default String getDescription() { return null; } + /** * Postal code of the recipient * diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index eaefecaa..f98674c4 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -138,8 +138,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { + XMLTools.encodeXML(party.getGlobalID()) + ""; } xml += "" + XMLTools.encodeXML(party.getName()) + ""; - - if (party.getLegalOrganisation() != null && (profile == Profiles.getByName("EN16931") || profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { + if (party.getDescription() != null) { + xml += "" + XMLTools.encodeXML(party.getDescription()) + ""; + } + if (party.getLegalOrganisation() != null) { xml += " "; if (party.getLegalOrganisation().getSchemedID() != null) { xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java index 4235d8df..5156950f 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java @@ -60,7 +60,9 @@ public class ZF2PushTest extends TestCase { final String TARGET_REVERSECHARGEPDF = "./target/testout-ZF2PushReverseCharge.pdf"; public void testPushExport() { - + /*** + * This writes to a filename like an official sample, please consider when changing (probably better not?) + */ // the writing part String orgname = "Bei Spiel GmbH"; String number = "RE-20201121/508"; @@ -92,10 +94,14 @@ public class ZF2PushTest extends TestCase { fail("Exception should not be raised"); } + + // now check the contents (like MustangReaderTest) ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); assertTrue(zi.getUTF8().contains("DE88200800000970375700")); //the iban assertTrue(zi.getUTF8().contains("Max Mustermann")); //account holder + assertTrue(zi.getUTF8().contains("DueDateDateTime")); //account holder + assertTrue(zi.getUTF8().contains("20201212")); //account holder assertTrue(zi.getUTF8().contains("