Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ codeunit 28008 "E-Document PINT A-NZ Handler" implements IStructuredFormatReader
EDocument."Document Type" := EDocument."Document Type"::"Purchase Credit Memo";
EDocumentXMLHelper.SetStringValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cbc:ID', MaxStrLen(EDocumentPurchaseHeader."Sales Invoice No."), EDocumentPurchaseHeader."Sales Invoice No.");
EDocumentXMLHelper.SetStringValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cac:OrderReference/cbc:ID', MaxStrLen(EDocumentPurchaseHeader."Purchase Order No."), EDocumentPurchaseHeader."Purchase Order No.");
EDocumentXMLHelper.SetStringValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cac:BillingReference/cac:InvoiceDocumentReference/cbc:ID', MaxStrLen(EDocumentPurchaseHeader."Applies-to Ext. Invoice No."), EDocumentPurchaseHeader."Applies-to Ext. Invoice No.");
EDocumentXMLHelper.SetDateValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cbc:IssueDate', EDocumentPurchaseHeader."Document Date");
EDocumentXMLHelper.SetDateValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cac:PaymentMeans/cbc:PaymentDueDate', EDocumentPurchaseHeader."Due Date");
EDocumentXMLHelper.SetCurrencyValueInField(PINTANZXml, XmlNamespaces, '/cn:CreditNote/cbc:DocumentCurrencyCode', MaxStrLen(EDocumentPurchaseHeader."Currency Code"), EDocumentPurchaseHeader."Currency Code");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ codeunit 28007 "PINT A-NZ Import"
VendorNo := EDocumentImportHelper.FindVendorByNameAndAddress(VendorName, VendorAddress);
end;

local procedure GetVendorRelatedData(var TempXMLBuffer: Record "XML Buffer" temporary; RootPath: Text; var ABN: Code[11]; var GLN: Code[13]; var VATRegistrationNo: Text[20]; VendorParticipantId: Text; VendorName: Text; VendorAddress: Text)
local procedure GetVendorRelatedData(var TempXMLBuffer: Record "XML Buffer" temporary; RootPath: Text; var ABN: Code[11]; var GLN: Code[13]; var VATRegistrationNo: Text[20]; var VendorParticipantId: Text; var VendorName: Text; var VendorAddress: Text)
var
ABNSchemeIdTok: Label '0151', Locked = true;
GLNSchemeIdTok: Label '0088', Locked = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ codeunit 11039 "E-Document XRechnung Handler" implements IStructuredFormatReader
SchemeIDGLNTok: Label '0088', Locked = true;
InvoiceLineTok: Label 'cac:InvoiceLine', Locked = true;
CreditNoteLineTok: Label 'cac:CreditNoteLine', Locked = true;
UnsupportedXmlRootElementErr: Label 'Unsupported XML root element: %1.', Comment = '%1 = local name of the XML root element';

/// <summary>
/// Reads an XRechnung format XML document and converts it into a draft purchase document.
Expand All @@ -47,6 +48,7 @@ codeunit 11039 "E-Document XRechnung Handler" implements IStructuredFormatReader
StartEventNameTok: Label 'E-document XRechnung import started. Parsing basic information.', Locked = true;
begin
FeatureTelemetry.LogUsage('0000EXH', FeatureNameTok, StartEventNameTok);
ResetDraft(EDocument);
EDocumentPurchaseHeader.InsertForEDocument(EDocument);

XmlDocument.ReadFrom(TempBlob.CreateInStream(TextEncoding::UTF8), XRechnungXml);
Expand All @@ -59,14 +61,20 @@ codeunit 11039 "E-Document XRechnung Handler" implements IStructuredFormatReader
case UpperCase(XmlElement.LocalName()) of
'INVOICE':
begin
if XmlElement.NamespaceUri() <> DefaultInvoiceTok then
Error(UnsupportedXmlRootElementErr, XmlElement.LocalName());
PopulateEDocumentForInvoice(XRechnungXml, XmlNamespaces, EDocumentPurchaseHeader, EDocument);
ProcessDraft := Enum::"E-Doc. Process Draft"::"Purchase Invoice";
end;
'CREDITNOTE':
begin
if XmlElement.NamespaceUri() <> DefaultCreditNoteTok then
Error(UnsupportedXmlRootElementErr, XmlElement.LocalName());
PopulateEDocumentForCreditNote(XRechnungXml, XmlNamespaces, EDocumentPurchaseHeader, EDocument);
ProcessDraft := Enum::"E-Doc. Process Draft"::"Purchase Credit Memo";
end;
else
Error(UnsupportedXmlRootElementErr, XmlElement.LocalName());
end;

EDocumentPurchaseHeader.Modify(false);
Expand Down Expand Up @@ -336,8 +344,11 @@ codeunit 11039 "E-Document XRechnung Handler" implements IStructuredFormatReader
procedure ResetDraft(EDocument: Record "E-Document")
var
EDocPurchaseHeader: Record "E-Document Purchase Header";
EDocPurchaseLine: Record "E-Document Purchase Line";
begin
EDocPurchaseHeader.GetFromEDocument(EDocument);
EDocPurchaseHeader.Delete(true);
EDocPurchaseHeader.SetRange("E-Document Entry No.", EDocument."Entry No");
EDocPurchaseHeader.DeleteAll();
EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
EDocPurchaseLine.DeleteAll();
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ codeunit 148500 "XRechnung Structured Tests"
IsInitialized: Boolean;
EDocumentStatusNotUpdatedErr: Label 'The status of the EDocument was not updated to the expected status after the step was executed.';
TestFileTok: Label 'xrechnung/xrechnung-invoice-0.xml', Locked = true;
UnsupportedXmlRootElementErr: Label 'Unsupported XML root element: %1.', Comment = '%1 = local name of the XML root element';
MockCurrencyCode: Code[10];
MockDate: Date;

Expand Down Expand Up @@ -172,6 +173,79 @@ codeunit 148500 "XRechnung Structured Tests"
XRechnungStructuredValidations.AssertPurchaseDocument(Vendor."No.", PurchaseHeader, Item);
end;

[Test]
procedure TestXRechnungUnsupportedRootElement_IsRejected()
var
EDocument: Record "E-Document";
TempBlob: Codeunit "Temp Blob";
StructuredFormatReader: Interface IStructuredFormatReader;
XmlOutStream: OutStream;
begin
// [FEATURE] [E-Document] [XRechnung] [Import]
// [SCENARIO] An unsupported XRechnung document type is rejected instead of creating an empty draft
Initialize(Enum::"Service Integration"::"No Integration");
LibraryEDoc.CreateInboundEDocument(EDocument, EDocumentService);
TempBlob.CreateOutStream(XmlOutStream, TextEncoding::UTF8);
XmlOutStream.WriteText('<Reminder xmlns="urn:oasis:names:specification:ubl:schema:xsd:Reminder-2" />');
StructuredFormatReader := Enum::"E-Doc. Read into Draft"::XRechnung;

asserterror StructuredFormatReader.ReadIntoDraft(EDocument, TempBlob);

Assert.ExpectedError(StrSubstNo(UnsupportedXmlRootElementErr, 'Reminder'));
Assert.ExpectedErrorCode('Dialog');
end;

[Test]
procedure TestXRechnungUnexpectedRootNamespace_IsRejected()
var
EDocument: Record "E-Document";
TempBlob: Codeunit "Temp Blob";
StructuredFormatReader: Interface IStructuredFormatReader;
XmlOutStream: OutStream;
begin
// [FEATURE] [E-Document] [XRechnung] [Import]
// [SCENARIO] An Invoice from an unsupported namespace is rejected instead of creating an empty draft
Initialize(Enum::"Service Integration"::"No Integration");
LibraryEDoc.CreateInboundEDocument(EDocument, EDocumentService);
TempBlob.CreateOutStream(XmlOutStream, TextEncoding::UTF8);
XmlOutStream.WriteText('<Invoice xmlns="urn:unsupported:invoice" />');
StructuredFormatReader := Enum::"E-Doc. Read into Draft"::XRechnung;

asserterror StructuredFormatReader.ReadIntoDraft(EDocument, TempBlob);

Assert.ExpectedError(StrSubstNo(UnsupportedXmlRootElementErr, 'Invoice'));
Assert.ExpectedErrorCode('Dialog');
end;

[Test]
procedure TestXRechnungInvoice_ReadIntoDraftTwice_DoesNotDuplicateLines()
var
EDocument: Record "E-Document";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
LineCountAfterFirstRead: Integer;
begin
// [FEATURE] [E-Document] [XRechnung] [Import]
// [SCENARIO] Re-running Read into Draft resets the previous draft instead of appending duplicate lines

// [GIVEN] A valid XRechnung XML invoice document is read into a draft
Initialize(Enum::"Service Integration"::"No Integration");
SetupXRechnungEDocumentService();
CreateInboundEDocumentFromXML(EDocument, TestFileTok);
ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Read into Draft");

EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
LineCountAfterFirstRead := EDocumentPurchaseLine.Count();
Assert.IsTrue(LineCountAfterFirstRead > 0, 'The first read into draft should create purchase lines.');

// [WHEN] The document is read into a draft a second time
EDocument.Get(EDocument."Entry No");
ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Read into Draft");

// [THEN] The draft contains the same number of lines
EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
Assert.AreEqual(LineCountAfterFirstRead, EDocumentPurchaseLine.Count(), 'Re-reading the draft should not duplicate purchase lines.');
end;

[PageHandler]
procedure EDocumentPurchaseHeaderPageHandler(var EDocReadablePurchaseDoc: TestPage "E-Doc. Readable Purchase Doc.")
begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ codeunit 10766 "E-Document Factura-E Handler" implements IStructuredFormatReader
EDocumentXMLHelper.SetNumberValueInField(FacturaEXML, XmlNamespaces, '/namespace:Facturae/Invoices/Invoice/InvoiceTotals/InvoiceTotal', EDocumentPurchaseHeader.Total);
EDocumentXMLHelper.SetNumberValueInField(FacturaEXML, XmlNamespaces, '/namespace:Facturae/Invoices/Invoice/InvoiceTotals/TotalOutstandingAmount', EDocumentPurchaseHeader."Amount Due");
EDocumentXMLHelper.SetDateValueInField(FacturaEXML, XmlNamespaces, '/namespace:Facturae/Invoices/Invoice/InvoiceHeader/InvoiceDocumentReference/ReferencedDocumentDate', EDocumentPurchaseHeader."Due Date");
EDocumentXMLHelper.SetStringValueInField(FacturaEXML, XmlNamespaces, '/namespace:Facturae/Invoices/Invoice/InvoiceHeader/Corrective/InvoiceNumber', MaxStrLen(EDocumentPurchaseHeader."Purchase Order No."), EDocumentPurchaseHeader."Purchase Order No.");
EDocumentXMLHelper.SetStringValueInField(FacturaEXML, XmlNamespaces, '/namespace:Facturae/Invoices/Invoice/InvoiceHeader/Corrective/InvoiceNumber', MaxStrLen(EDocumentPurchaseHeader."Applies-to Ext. Invoice No."), EDocumentPurchaseHeader."Applies-to Ext. Invoice No.");

if VendorNo <> '' then
EDocumentPurchaseHeader."[BC] Vendor No." := VendorNo;
Expand Down
Loading