Skip to content

Commit

Permalink
impl, junit tests
Browse files Browse the repository at this point in the history
Issue #215
  • Loading branch information
rsoika committed Nov 26, 2024
1 parent 534cd40 commit e2a4592
Show file tree
Hide file tree
Showing 7 changed files with 838 additions and 195 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package org.imixs.archive.documents.einvoice;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.SecureRandom;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -15,7 +13,6 @@

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

Expand All @@ -27,18 +24,14 @@
* @author rsoika
*
*/
public class EInvoiceModel {
public abstract class EInvoiceModel {
protected static Logger logger = Logger.getLogger(EInvoiceModel.class.getName());

private static final SecureRandom random = new SecureRandom();
private static final Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();

private Document doc;
private Element crossIndustryInvoice;
private Element exchangedDocumentContext;
private Element exchangedDocument;
private Element supplyChainTradeTransaction;

private Element root;
// elements
protected String id = null;
protected String buyerReference = null;
Expand All @@ -50,28 +43,6 @@ public class EInvoiceModel {

private final Map<EInvoiceNS, String> URI_BY_NAMESPACE = new HashMap<>();
private final Map<EInvoiceNS, String> PREFIX_BY_NAMESPACE = new HashMap<>();
public static final String FILE_PREFIX = "file://";

/**
* This method instantiates a new BPMN model with the default BPMN namespaces
* and prefixes.
*
* @param doc
*/
private EInvoiceModel() {
setUri(EInvoiceNS.A, "urn:un:unece:uncefact:data:standard:QualifiedDataType:100");
setUri(EInvoiceNS.RSM, "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100");
setUri(EInvoiceNS.QDT, "urn:un:unece:uncefact:data:standard:QualifiedDataType:10");
setUri(EInvoiceNS.RAM, "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100");
setUri(EInvoiceNS.UDT, "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100");

setPrefix(EInvoiceNS.A, "a");
setPrefix(EInvoiceNS.RSM, "rsm");
setPrefix(EInvoiceNS.QDT, "qdt");
setPrefix(EInvoiceNS.RAM, "ram");
setPrefix(EInvoiceNS.UDT, "udt");

}

/**
* This method instantiates a new eInvoice model based on a given
Expand All @@ -83,73 +54,32 @@ private EInvoiceModel() {
* @param doc
*/
public EInvoiceModel(Document doc) {
this();
// this();
tradeParties = new LinkedHashSet<>();

if (doc != null) {
this.doc = doc;

crossIndustryInvoice = doc.getDocumentElement();

// parse the BPMN namespaces
NamedNodeMap defAttributes = crossIndustryInvoice.getAttributes();
for (int j = 0; j < defAttributes.getLength(); j++) {
Node node = defAttributes.item(j);

if (getPrefix(EInvoiceNS.A).equals(node.getLocalName())
&& !getUri(EInvoiceNS.A).equals(node.getNodeValue())) {
logger.fine("...set A namespace URI: " + node.getNodeValue());
setUri(EInvoiceNS.A, node.getNodeValue());
}
if (getPrefix(EInvoiceNS.RSM).equals(node.getLocalName())
&& !getUri(EInvoiceNS.RSM).equals(node.getNodeValue())) {
logger.fine("...set RSM namespace URI: " + node.getNodeValue());
setUri(EInvoiceNS.RSM, node.getNodeValue());
}
if (getPrefix(EInvoiceNS.QDT).equals(node.getLocalName())
&& !getUri(EInvoiceNS.QDT).equals(node.getNodeValue())) {
logger.fine("...set QDT namespace URI: " + node.getNodeValue());
setUri(EInvoiceNS.QDT, node.getNodeValue());
}
if (getPrefix(EInvoiceNS.RAM).equals(node.getLocalName())
&& !getUri(EInvoiceNS.RAM).equals(node.getNodeValue())) {
logger.fine("...set RAM namespace URI: " + node.getNodeValue());
setUri(EInvoiceNS.RAM, node.getNodeValue());
}
if (getPrefix(EInvoiceNS.UDT).equals(node.getLocalName())
&& !getUri(EInvoiceNS.UDT).equals(node.getNodeValue())) {
logger.fine("...set UDT namespace URI: " + node.getNodeValue());
setUri(EInvoiceNS.UDT, node.getNodeValue());
}

root = doc.getDocumentElement();
if (getRoot() != null) {
setNameSpaces();
parseContent();
}

exchangedDocumentContext = findChildNodeByName(crossIndustryInvoice, EInvoiceNS.RSM,
"ExchangedDocumentContext");
exchangedDocument = findChildNodeByName(crossIndustryInvoice, EInvoiceNS.RSM, "ExchangedDocument");
supplyChainTradeTransaction = findChildNodeByName(crossIndustryInvoice, EInvoiceNS.RSM,
"SupplyChainTradeTransaction");

// Load e-invoice standard data
loadDocumentCoreData();

}
}

public Document getDoc() {
return doc;
public void setNameSpaces() {
}

public Element getCrossIndustryInvoice() {
return crossIndustryInvoice;
public void parseContent() {
}

public Element getExchangedDocumentContext() {
return exchangedDocumentContext;
public Document getDoc() {
return doc;
}

public Element getExchangedDocument() {
return exchangedDocument;
public Element getRoot() {
return root;
}

public String getId() {
Expand Down Expand Up @@ -260,54 +190,6 @@ public Element findChildNodeByName(Element parent, EInvoiceNS ns, String nodeNam
}
}

public TradeParty parseTradeParty(Element tradePartyElement, String type) {
TradeParty tradeParty = new TradeParty(type);
Element element = null;

// Parse name
element = findChildNodeByName(tradePartyElement, EInvoiceNS.RAM,
"Name");
if (element != null) {
tradeParty.setName(element.getTextContent());
}

Element postalAddress = findChildNodeByName(tradePartyElement, EInvoiceNS.RAM,
"PostalTradeAddress");
if (postalAddress != null) {
element = findChildNodeByName(postalAddress, EInvoiceNS.RAM,
"PostcodeCode");
if (element != null) {
tradeParty.setPostcodeCode(element.getTextContent());
}
element = findChildNodeByName(postalAddress, EInvoiceNS.RAM,
"CityName");
if (element != null) {
tradeParty.setCityName(element.getTextContent());
}
element = findChildNodeByName(postalAddress, EInvoiceNS.RAM,
"CountryID");
if (element != null) {
tradeParty.setCountryId(element.getTextContent());
}
element = findChildNodeByName(postalAddress, EInvoiceNS.RAM,
"LineOne");
if (element != null) {
tradeParty.setStreetAddress(element.getTextContent());
}
}

Element specifiedTaxRegistration = findChildNodeByName(tradePartyElement, EInvoiceNS.RAM,
"SpecifiedTaxRegistration");
if (specifiedTaxRegistration != null) {
element = findChildNodeByName(specifiedTaxRegistration, EInvoiceNS.RAM,
"ID");
if (element != null) {
tradeParty.setVatNumber(element.getTextContent());
}
}
return tradeParty;
}

/**
* Returns the central logger instance
*
Expand All @@ -333,68 +215,6 @@ public static void debug(String message) {
logger.info(message);
}

private void loadDocumentCoreData() {
Element element = null;

// read invoice number
element = findChildNodeByName(exchangedDocument, EInvoiceNS.RAM, "ID");
if (element != null) {
id = element.getTextContent();
}

// read Date time
element = findChildNodeByName(exchangedDocument, EInvoiceNS.RAM, "IssueDateTime");
if (element != null) {
Element dateTimeElement = findChildNodeByName(element, EInvoiceNS.UDT, "DateTimeString");
if (dateTimeElement != null) {
String dateStr = dateTimeElement.getTextContent();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
issueDateTime = LocalDate.parse(dateStr, formatter);
}
}

// read Total amount
element = findChildNodeByName(supplyChainTradeTransaction, EInvoiceNS.RAM, "ApplicableHeaderTradeSettlement");
if (element != null) {
Element tradeSettlementElement = findChildNodeByName(element, EInvoiceNS.RAM,
"SpecifiedTradeSettlementHeaderMonetarySummation");
if (tradeSettlementElement != null) {
Element child = findChildNodeByName(tradeSettlementElement, EInvoiceNS.RAM, "GrandTotalAmount");
if (child != null) {
grandTotalAmount = new BigDecimal(child.getTextContent());
}
child = findChildNodeByName(tradeSettlementElement, EInvoiceNS.RAM, "TaxTotalAmount");
if (child != null) {
taxTotalAmount = new BigDecimal(child.getTextContent());
}
netTotalAmount = grandTotalAmount.subtract(taxTotalAmount).setScale(2, RoundingMode.HALF_UP);

}

}

// read ApplicableHeaderTradeAgreement - buyerReference
element = findChildNodeByName(supplyChainTradeTransaction, EInvoiceNS.RAM, "ApplicableHeaderTradeAgreement");
if (element != null) {
Element buyerReferenceElement = findChildNodeByName(element, EInvoiceNS.RAM,
"BuyerReference");
if (buyerReferenceElement != null) {
buyerReference = buyerReferenceElement.getTextContent();
}
Element tradePartyElement = findChildNodeByName(element, EInvoiceNS.RAM,
"SellerTradeParty");
if (tradePartyElement != null) {
tradeParties.add(parseTradeParty(tradePartyElement, "seller"));
}
tradePartyElement = findChildNodeByName(element, EInvoiceNS.RAM,
"BuyerTradeParty");
if (tradePartyElement != null) {
tradeParties.add(parseTradeParty(tradePartyElement, "buyer"));
}
}

}

/**
* Returns the namespace uri for a given namespace
*
Expand Down
Loading

0 comments on commit e2a4592

Please sign in to comment.