Dépôt officiel du code source de l'ERP OpenConcerto
Blame | Last modification | View Log | RSS feed
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.supplychain.purchase.importer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder;
import com.lowagie.text.pdf.PRStream;
import com.lowagie.text.pdf.PdfArray;
import com.lowagie.text.pdf.PdfDictionary;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfString;
public class FacturXImporter {
public static final String TYPE_MINIMUM = "urn:factur-x.eu:1p0:minimum";
public static final String TYPE_BASIC = "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic";
public static final String RSM_NS = "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100";
public static final String RAM_NS = "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100";
public static final String UDT_NS = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100";
public FacturXImporter() {
}
public boolean importFromPDF(File file) throws IOException, JDOMException, ParseException {
Map<String, byte[]> files = new HashMap<>();
PdfReader reader = new PdfReader(new FileInputStream(file));
PdfDictionary root = reader.getCatalog();
PdfDictionary names = root.getAsDict(PdfName.NAMES); // may be null
PdfDictionary embeddedFilesDict = names.getAsDict(PdfName.EMBEDDEDFILES); // may be null
PdfArray embeddedFiles = embeddedFilesDict.getAsArray(PdfName.NAMES); // may be null
int len = embeddedFiles.size();
for (int i = 0; i < len; i += 2) {
PdfString name = embeddedFiles.getAsString(i); // should always be present
PdfDictionary fileSpec = embeddedFiles.getAsDict(i + 1); // ditto
PdfDictionary streams = fileSpec.getAsDict(PdfName.EF);
PRStream stream = null;
if (streams.contains(PdfName.UF))
stream = (PRStream) streams.getAsStream(PdfName.UF);
else
stream = (PRStream) streams.getAsStream(PdfName.F); // Default stream for backwards
// compatibility
if (stream != null) {
files.put(name.toUnicodeString(), PdfReader.getStreamBytes((PRStream) stream));
}
}
if (!files.containsKey("factur-x.xml")) {
return false;
}
SAXBuilder builder = new SAXBuilder();
Namespace nsRMS = Namespace.getNamespace(RSM_NS);
Namespace nsRAM = Namespace.getNamespace(RAM_NS);
Namespace nsUDT = Namespace.getNamespace(UDT_NS);
log(new String(files.get("factur-x.xml")));
Document document = (Document) builder.build(new ByteArrayInputStream(files.get("factur-x.xml")));
Element rootNode = document.getRootElement();
Element exchangedDocumentContext = rootNode.getChild("ExchangedDocumentContext", nsRMS);
Element guidelineSpecifiedDocumentContextParameter = exchangedDocumentContext.getChild("GuidelineSpecifiedDocumentContextParameter", nsRAM);
//
String type = guidelineSpecifiedDocumentContextParameter.getChildText("ID", nsRAM);
log("type de FacturX : " + type);
Element exchangedDocument = rootNode.getChild("ExchangedDocument", nsRMS);
String numeroFacture = exchangedDocument.getChildText("ID", nsRAM);
log("numéro de facture : " + numeroFacture);
// Type de facture
// 380 : Facture commerciale
// 381 : Avoir (note de crédit)
// 384 : Facture rectificative
// 386 : Facture d'acompte
String typeFacture = exchangedDocument.getChildText("TypeCode", nsRAM);
log("type de facture : " + typeFacture);
Element dateTimeString = exchangedDocument.getChild("IssueDateTime", nsRAM).getChild("DateTimeString", nsUDT);
if (!dateTimeString.getAttributeValue("format").equals("102")) {
throw new IllegalArgumentException("invalid date format : " + dateTimeString.getAttributeValue("format"));
}
String txtDateTimeString = dateTimeString.getText();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
Date dateFacture = df.parse(txtDateTimeString);
log("date de facture : " + dateFacture);
String commentaire = "";
if (exchangedDocument.getChild("IncludedNote", nsRAM) != null && exchangedDocument.getChild("IncludedNote").getChild("Content", nsRAM) != null) {
commentaire = exchangedDocument.getChild("IncludedNote", nsRAM).getChildText("Content", nsRAM);
}
log("commentaire : " + commentaire);
//
final Element supplyChainTradeTransaction = rootNode.getChild("SupplyChainTradeTransaction", nsRMS);
Element applicableHeaderTradeAgreement = supplyChainTradeTransaction.getChild("ApplicableHeaderTradeAgreement", nsRAM);
Element sellerTradeParty = applicableHeaderTradeAgreement.getChild("SellerTradeParty", nsRAM);
final String nomFournisseur = sellerTradeParty.getChildText("Name", nsRAM);
log("nom du fournisseur : " + nomFournisseur);
Element specifiedLegalOrganization = sellerTradeParty.getChild("SpecifiedLegalOrganization", nsRAM);
String siretFournisseur = specifiedLegalOrganization.getChildText("ID", nsRAM);
log("SIRET du fournisseur : " + siretFournisseur);
Element postalTradeAddress = sellerTradeParty.getChild("PostalTradeAddress", nsRAM);
String codePays = postalTradeAddress.getChildText("CountryID", nsRAM);
log("Code pays du fournisseur : " + codePays);
Element specifiedTaxRegistration = sellerTradeParty.getChild("SpecifiedTaxRegistration", nsRAM);
String tvaFournisseur = specifiedTaxRegistration.getChildText("ID", nsRAM);
log("TVA du fournisseur : " + tvaFournisseur);
//
// Element applicableHeaderTradeDelivery =
// supplyChainTradeTransaction.getChild("ApplicableHeaderTradeDelivery", nsRAM);
//
Element applicableHeaderTradeSettlement = supplyChainTradeTransaction.getChild("ApplicableHeaderTradeSettlement", nsRAM);
String codeDevise = applicableHeaderTradeSettlement.getChildText("InvoiceCurrencyCode", nsRAM);
log("code devise : " + codeDevise);
Element specifiedTradeSettlementHeaderMonetarySummation = applicableHeaderTradeSettlement.getChild("SpecifiedTradeSettlementHeaderMonetarySummation", nsRAM);
BigDecimal totalHT = new BigDecimal(specifiedTradeSettlementHeaderMonetarySummation.getChildText("TaxBasisTotalAmount", nsRAM));
BigDecimal totalTax = new BigDecimal(specifiedTradeSettlementHeaderMonetarySummation.getChildText("TaxTotalAmount", nsRAM));
BigDecimal totalTTC = new BigDecimal(specifiedTradeSettlementHeaderMonetarySummation.getChildText("GrandTotalAmount", nsRAM));
BigDecimal totalNetPayer = new BigDecimal(specifiedTradeSettlementHeaderMonetarySummation.getChildText("DuePayableAmount", nsRAM));
log("total HT : " + totalHT);
log("total TVA : " + totalTax);
log("total TTC : " + totalTTC);
log("total à payer : " + totalNetPayer);
return true;
}
private void log(String string) {
System.err.println(string);
}
public static void main(String[] args) throws Exception {
FacturXImporter i = new FacturXImporter();
i.importFromPDF(new File("test/FacturX/Facture_FR_MINIMUM.pdf"));
}
}