/*
* ZUGFeRD / Factur-X invoice processing example
*
* Scans a Domino database for unprocessed invoice documents,
* reads the attached PDF into memory, extracts the embedded invoice XML
* and stores selected invoice data back into the Domino document.
*/
/* Database and processing settings */
ZUGFeRD_DB_Path:="TEST\\TestDBMstr.NSF";
ZUGFeRD_DB_Search_Formula:="SELECT Form=\"ZUGFeRDDoc\" & @IsUnavailable(Status);";
XMLDoAttachFile:=0;
XMLAttachmentName:="Invoice.XML";
/* Find and process unprocessed invoice documents */
ZUGFeRD_DB_h:=@OpenDB(ZUGFeRD_DB_Path);
ZUGFeRD_DB_IDL:=@ScanDB(ZUGFeRD_DB_h;ZUGFeRD_DB_Search_Formula;@AnyAllDay;1;1);
ZUGFeRD_DB_IDL_Index:=1;
ZUGFeRD_DB_IDL_IndexEnd:=@Elements(ZUGFeRD_DB_IDL);
WHILE(ZUGFeRD_DB_IDL_Index <= ZUGFeRD_DB_IDL_IndexEnd){
ZUGFeRD_ThisDoc_ID:=@GetListElement(ZUGFeRD_DB_IDL;ZUGFeRD_DB_IDL_Index);
CALL:DoInvoiceDoc[GLOBAL](ZUGFeRD_DB_h;ZUGFeRD_ThisDoc_ID;XMLDoAttachFile;XMLAttachmentName);
@Increment(ZUGFeRD_DB_IDL_Index);
}
ZUGFeRD_DB_h:=@CloseDB(ZUGFeRD_DB_h);
/*
* Process a single invoice document
*/
DELFN:DoInvoiceDoc[GLOBAL]();
DEFFN:DoInvoiceDoc[GLOBAL](ZUGFeRD_DB_h;ZUGFeRD_ThisDoc_ID;XMLDoAttachFile;XMLAttachmentName)
{
ZUGFeRD_ThisDoc_Update:=0;
ZUGFeRD_ThisDoc_h:=@OpenNoteByID(ZUGFeRD_DB_h;ZUGFeRD_ThisDoc_ID;ZUGFeRD_ThisDoc_h);
/* Get the PDF attachment */
ZUGFeRD_ThisDoc_AttachmentNames:=@AttachmentNames(ZUGFeRD_ThisDoc_h);
ZUGFeRD_ThisDoc_AttachmentLengths:=@AttachmentLength(ZUGFeRD_ThisDoc_h);
IF(@Elements(ZUGFeRD_ThisDoc_AttachmentNames) > 0){
ZUGFeRD_ThisDoc_AttachmentName:=@GetListElement(ZUGFeRD_ThisDoc_AttachmentNames;1);
ZUGFeRD_ThisDoc_AttachmentLength:=@GetListElement(ZUGFeRD_ThisDoc_AttachmentLengths;1);
/* Extract the embedded invoice XML from the PDF */
CALL:GetInvoiceXML[GLOBAL](&ZUGFeRD_ThisDoc_h;&ZUGFeRD_ThisDoc_XML_BinBuffer;ZUGFeRD_ThisDoc_AttachmentName;ZUGFeRD_ThisDoc_AttachmentLength);
IF(@IsError(ZUGFeRD_ThisDoc_XML_BinBuffer)){
@LogReport("Unable to extract invoice XML";3);
@LogReport(ZUGFeRD_ThisDoc_XML_BinBuffer;3);
}ELSE{
/* Read selected invoice data from the XML */
CALL:InvoiceXMLGetInfo[GLOBAL](&ZUGFeRD_ThisDoc_XML_BinBuffer;&ZUGFeRD_ThisDoc_Update;
&InvoiceNumber[ZUGFeRD_ThisDoc_h];&InvoiceDateRaw[ZUGFeRD_ThisDoc_h];&Seller[ZUGFeRD_ThisDoc_h];&Buyer[ZUGFeRD_ThisDoc_h];
&Currency[ZUGFeRD_ThisDoc_h];&GrandTotal[ZUGFeRD_ThisDoc_h];&DueAmount[ZUGFeRD_ThisDoc_h]);
/* Optionally attach the extracted XML to the document */
IF(XMLDoAttachFile & ZUGFeRD_ThisDoc_Update){
@DetachOSFileFromNote(ZUGFeRD_ThisDoc_h;@AnyAllDay;XMLAttachmentName);
@CreateAttachmentFromBuffer(ZUGFeRD_ThisDoc_h;ZUGFeRD_ThisDoc_XML_BinBuffer;1;XMLAttachmentName);
}
}
ZUGFeRD_ThisDoc_XML_BinBuffer:=@DestroyBuffer(ZUGFeRD_ThisDoc_XML_BinBuffer);
}
/* Finalize and save successfully processed documents */
IF(ZUGFeRD_ThisDoc_Update){
InvoiceDate[ZUGFeRD_ThisDoc_h]:=@Time(
@TextToNumber(@Middle(InvoiceDateRaw[ZUGFeRD_ThisDoc_h];0;4));
@TextToNumber(@Middle(InvoiceDateRaw[ZUGFeRD_ThisDoc_h];4;2));
@TextToNumber(@Middle(InvoiceDateRaw[ZUGFeRD_ThisDoc_h];6;2));
0;0;0);
Status[ZUGFeRD_ThisDoc_h]:="Done";
}
ZUGFeRD_ThisDoc_h:=@CloseNote(ZUGFeRD_ThisDoc_h;ZUGFeRD_ThisDoc_Update);
}
/*
* Read the PDF attachment into a BINBUFFER and extract
* the embedded ZUGFeRD / Factur-X invoice XML
*/
DELFN:GetInvoiceXML[GLOBAL]();
DEFFN:GetInvoiceXML[GLOBAL](*ZUGFeRD_ThisDoc_h;*ZUGFeRD_ThisDoc_XML_BinBuffer;ZUGFeRD_ThisDoc_AttachmentName;ZUGFeRD_ThisDoc_AttachmentLength)
{
Read_Part_Max_Read:=30000;
ZUGFeRD_ThisDoc_Att_BinBuffer:=@CreateBuffer(ZUGFeRD_ThisDoc_AttachmentLength);
ZUGFeRD_ThisDoc_Att_h:=@OpenAttachedFile(ZUGFeRD_ThisDoc_h;ZUGFeRD_ThisDoc_AttachmentName;"RBN");
/* Read the PDF attachment in blocks */
ZUGFeRD_ThisDoc_Att_RemainRead:=ZUGFeRD_ThisDoc_AttachmentLength;
WHILE(ZUGFeRD_ThisDoc_Att_RemainRead > 0){
IF(ZUGFeRD_ThisDoc_Att_RemainRead > Read_Part_Max_Read){
ReadPartData:=@ReadAttachedFile(ZUGFeRD_ThisDoc_Att_h;"B";Read_Part_Max_Read);
@WriteBuffer(ZUGFeRD_ThisDoc_Att_BinBuffer;ReadPartData);
ZUGFeRD_ThisDoc_Att_RemainRead:=ZUGFeRD_ThisDoc_Att_RemainRead-Read_Part_Max_Read;
}ELSE{
ReadPartData:=@ReadAttachedFile(ZUGFeRD_ThisDoc_Att_h;"B";ZUGFeRD_ThisDoc_Att_RemainRead);
@WriteBuffer(ZUGFeRD_ThisDoc_Att_BinBuffer;ReadPartData);
ZUGFeRD_ThisDoc_Att_RemainRead:=ZUGFeRD_ThisDoc_Att_RemainRead-ZUGFeRD_ThisDoc_Att_RemainRead;
}
}
ZUGFeRD_ThisDoc_Att_h:=@CloseAttachedFile(ZUGFeRD_ThisDoc_Att_h);
/* Extract the embedded invoice XML directly from memory */
ZUGFeRD_ThisDoc_XML_BinBuffer:=@PDFExtractInvoiceXML(ZUGFeRD_ThisDoc_Att_BinBuffer);
ZUGFeRD_ThisDoc_Att_BinBuffer:=@DestroyBuffer(ZUGFeRD_ThisDoc_Att_BinBuffer);
}
/*
* Parse the invoice XML and extract selected header data
*/
DELFN:InvoiceXMLGetInfo[GLOBAL]();
DEFFN:InvoiceXMLGetInfo[GLOBAL](*ZUGFeRD_XML_BinBuffer;*ZUGFeRD_ThisDoc_Update;*InvoiceNumber;*InvoiceDateRaw;*Seller;*Buyer;*Currency;*GrandTotal;*DueAmount)
{
ZUGFeRD_ThisDoc_Update:=1;
InvoiceNumber:=InvoiceDateRaw:=Seller:=Buyer:=Currency:=GrandTotal:=DueAmount:=@Unavailable;
/* XML namespaces used by the CII invoice */
Prefixes:="rsm":"ram":"udt";
Namespaces:=
"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100":
"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100":
"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100";
/* Parse the XML document */
Doc:=@XMLParse(ZUGFeRD_XML_BinBuffer;1);
Root:=@XMLGetRoot(Doc);
IF(@IsError(Doc;Root)){
@LogReport("Doc:";3);
@LogReport(Doc;3);
@LogReport("Root:";3);
@LogReport(Root;3);
ZUGFeRD_ThisDoc_Update:=0;
}ELSE{
/* Invoice header fields to extract */
XPaths:="./rsm:ExchangedDocument/ram:ID":
"./rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString":
"./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerTradeParty/ram:Name":
"./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:BuyerTradeParty/ram:Name":
"./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode":
"./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:GrandTotalAmount":
"./rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:DuePayableAmount";
FieldNames:=@Explode("InvoiceNumber;InvoiceDateRaw;Seller;Buyer;Currency;GrandTotal;DueAmount";";");
/* Map each XPath result to the corresponding document field */
XPaths_Index:=1;
XPaths_IndexEnd:=@Elements(XPaths);
WHILE(XPaths_Index <= XPaths_IndexEnd){
ThisXPath:=@GetListElement(XPaths;XPaths_Index);
ThisFieldName:=@GetListElement(FieldNames;XPaths_Index);
Node:=@XMLSelectSingleNode(Root;ThisXPath;Prefixes;Namespaces);
Value:=@XMLGetContent(Node);
IF(@IsError(Node;Value)){
ZUGFeRD_ThisDoc_Update:=0;
@LogReport("Node:";3);
@LogReport(Node;3);
@LogReport("Value:";3);
@LogReport(Value;3);
}
@SetVar(ThisFieldName;Value);
@Increment(XPaths_Index);
}
}
@XMLRelease(Doc);
}
Originales, kommentiertes API-Engine-Beispielskript
Auf Smartphones und Tablets horizontal scrollen, um lange Zeilen zu lesen.
