Import IncludedNotes on item extraction

similar to #554 but on item level
This commit is contained in:
ean
2024-11-27 12:58:36 +01:00
parent e9f9655b76
commit 4466439561
7 changed files with 242 additions and 2 deletions

View File

@@ -14,7 +14,7 @@ public class IncludedNote {
private static final String SUBJECT_CODE_START = "<ram:SubjectCode>"; private static final String SUBJECT_CODE_START = "<ram:SubjectCode>";
private static final String SUBJECT_CODE_END = "</ram:SubjectCode>"; private static final String SUBJECT_CODE_END = "</ram:SubjectCode>";
private IncludedNote(String content, SubjectCode subjectCode) { public IncludedNote(String content, SubjectCode subjectCode) {
this.content = content; this.content = content;
this.subjectCode = subjectCode; this.subjectCode = subjectCode;
} }

View File

@@ -12,7 +12,9 @@ import org.w3c.dom.NodeList;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List;
/*** /***
* describes any invoice line * describes any invoice line
@@ -37,6 +39,7 @@ public class Item implements IZUGFeRDExportableItem {
protected ArrayList<ReferencedDocument> additionalReference = null; protected ArrayList<ReferencedDocument> additionalReference = null;
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>(); protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>();
protected ArrayList<IZUGFeRDAllowanceCharge> Charges = new ArrayList<>(); protected ArrayList<IZUGFeRDAllowanceCharge> Charges = new ArrayList<>();
protected List<IncludedNote> includedNotes = null;
/*** /***
* default constructor * default constructor
@@ -125,6 +128,38 @@ public class Item implements IZUGFeRDExportableItem {
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference); icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
}); });
itemMap.getAsString("Note").ifPresent(this::addNote);
itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(adld -> {
List<IncludedNote> includedNotes = new ArrayList<>();
adld.getAllNodes("IncludedNote").forEach(item -> {
String subjectCode = "";
String content = null;
NodeList includedNodeChilds = item.getChildNodes();
for (int issueDateChildIndex = 0; issueDateChildIndex < includedNodeChilds.getLength(); issueDateChildIndex++) {
if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null)
&& (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("Content"))) {
content = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex));
}
if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null)
&& (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("SubjectCode"))) {
subjectCode = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex));
}
}
boolean foundCode = false;
for (SubjectCode code : SubjectCode.values()) {
if (code.toString().equals(subjectCode)) {
includedNotes.add(new IncludedNote(content, code));
foundCode = true;
break;
}
}
if (!foundCode) {
includedNotes.add(new IncludedNote(content, null));
}
});
addNotes(includedNotes);
});
} }
public Item addReferencedLineID(String s) { public Item addReferencedLineID(String s) {
@@ -372,4 +407,19 @@ public class Item implements IZUGFeRDExportableItem {
return detailedDeliveryPeriodTo; return detailedDeliveryPeriodTo;
} }
public IZUGFeRDExportableItem addNotes(Collection<IncludedNote> notes) {
if (notes == null) {
return this;
}
if (includedNotes == null) {
includedNotes = new ArrayList<>();
}
includedNotes.addAll(notes);
return this;
}
@Override
public List<IncludedNote> getNotesWithSubjectCode() {
return includedNotes;
}
} }

View File

@@ -36,5 +36,9 @@ public enum SubjectCode {
/** /**
* Discount and bonus agreements * Discount and bonus agreements
*/ */
AAK AAK,
/**
* Vehicle licence number
*/
ABZ
} }

View File

@@ -28,7 +28,9 @@ package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List;
import org.mustangproject.IncludedNote;
import org.mustangproject.Item; import org.mustangproject.Item;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -153,4 +155,7 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
return null; return null;
} }
default List<IncludedNote> getNotesWithSubjectCode() {
return null;
}
} }

View File

@@ -22,12 +22,15 @@ package org.mustangproject.ZUGFeRD;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.StringUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mustangproject.*; import org.mustangproject.*;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -397,4 +400,25 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
} }
@Test
public void testImportPositionIncludedNotes() throws FileNotFoundException, XPathExpressionException, ParseException {
File inputFile = getResourceAsFile("ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile));
Invoice invoice = zii.extractInvoice();
assertEquals(1, invoice.getZFItems().length);
assertEquals(8, invoice.getZFItems()[0].getNotesWithSubjectCode().size());
assertEquals("FB-LE 9999", invoice.getZFItems()[0].getNotesWithSubjectCode().stream().filter(note -> note.getSubjectCode().equals(SubjectCode.ABZ)).findFirst().get().getContent());
}
@Test
public void testImportXRechnungPositionNote() throws FileNotFoundException, XPathExpressionException, ParseException {
File inputFile = getResourceAsFile("TESTXRECHNUNG_INVDSS_012015776085.XML");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile));
Invoice invoice = zii.extractInvoice();
assertEquals(1, invoice.getZFItems().length);
assertFalse(invoice.getZFItems()[0].getNotes() == null);
assertEquals(1, invoice.getZFItems()[0].getNotes().length);
}
} }

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?><ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>2015776085</cbc:ID>
<cbc:IssueDate>2024-11-01</cbc:IssueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>#AAI# Wenn bereits bezahlt, nur zu den Akten legen. Für Verzug und Verzugszinsen gelten die Bestimmungen der §§ 286 - 288 BGB. Der Schuldner einer Entgeltforderung kommt spätestens in Verzug, wenn er nicht innerhalb von 30 Tagen nach Fälligkeit und Zugang einer Rechnung oder gleichwertigen Zahlungsaufstellung leistet. Die Lieferung von Waren und Fahrzeugen erfolgt unter Eigentumsvorbehalt.</cbc:Note>
<cbc:Note>#PAI# Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung.</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>02-ZZ987654-99</cbc:BuyerReference>
<cac:InvoicePeriod>
<cbc:StartDate>2024-11-01</cbc:StartDate>
<cbc:EndDate>2024-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>N/A</cbc:ID>
</cac:OrderReference>
<cac:ContractDocumentReference>
<cbc:ID>63435555</cbc:ID>
</cac:ContractDocumentReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="9930">DE238574172</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Alphabet Fuhrparkmanagement GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Lilienthalallee 26</cbc:StreetName>
<cbc:CityName>München</cbc:CityName>
<cbc:PostalZone>80786</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE238574172</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Alphabet Fuhrparkmanagement GmbH</cbc:RegistrationName>
<cbc:CompanyID>HRB 181098</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Yildiz Tolga</cbc:Name>
<cbc:Telephone>+49899--</cbc:Telephone>
<cbc:ElectronicMail>Tolga.Yildiz@alphabet.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="9930">N/A</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>00987654</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterweg 1</cbc:StreetName>
<cbc:CityName>Kiel</cbc:CityName>
<cbc:PostalZone>24105</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Muster GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Mustermann Max</cbc:Name>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:Delivery>
<cbc:ActualDeliveryDate>2024-11-30</cbc:ActualDeliveryDate>
<cac:DeliveryLocation>
<cbc:ID>00987654</cbc:ID>
<cac:Address>
<cbc:StreetName>Musterweg 1</cbc:StreetName>
<cbc:CityName>Kiel</cbc:CityName>
<cbc:PostalZone>24105</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:Address>
</cac:DeliveryLocation>
<cac:DeliveryParty>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
</cac:DeliveryParty>
</cac:Delivery>
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>DE34700700100156919301</cbc:ID>
<cbc:Name>Alphabet Fuhrparkmanagement GmbH</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>DEUTDEMMXXX</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung.</cbc:Note>
</cac:PaymentTerms>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">161.69</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">851.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">161.69</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">851.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">851.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1012.69</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1012.69</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:Note>#AAI# Finanzrate vom 01.11.2024 bis 30.11.2024 #ABZ/Kennzeichen#SH-9 18E #AKG/Fahrgestellnummer#WBY51EJ080CR55555 #BA/Kilometerstand#0 #AKV/LeasingNr#63435555</cbc:Note>
<cbc:InvoicedQuantity unitCode="C62">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">851.00</cbc:LineExtensionAmount>
<cac:InvoicePeriod>
<cbc:StartDate>2024-11-01</cbc:StartDate>
<cbc:EndDate>2024-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:Item>
<cbc:Description>FL-Rate</cbc:Description>
<cbc:Name>FL-Rate</cbc:Name>
<cac:SellersItemIdentification>
<cbc:ID>90101</cbc:ID>
</cac:SellersItemIdentification>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">851.00</cbc:PriceAmount>
<cbc:BaseQuantity>1.00</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>
</ubl:Invoice>