diff --git a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al index a8fbf99edd..03896103df 100644 --- a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al +++ b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al @@ -516,6 +516,7 @@ codeunit 13917 "Export ZUGFeRD Document" DataTypeManagement: Codeunit "Data Type Management"; HeaderRecordRef: RecordRef; HeaderTradeAgreementElement, SellerTradePartyElement, BuyerTradePartyElement, SpecifiedTaxRegistrationElement, IDElement : XmlElement; + SellerOrderReferencedDocumentElement: XmlElement; PostalTradeAddressElement, ContactElement : XmlElement; SellerIDAttr, BuyerIDAttr : XmlAttribute; CustomerNo: Code[20]; @@ -530,6 +531,7 @@ codeunit 13917 "Export ZUGFeRD Document" Contact: Text[100]; CustomerEmail: Text[250]; PhoneNumber: Text[30]; + OrderNo: Code[20]; SellerStreetName: Text; SellerAdditionalStreetName: Text; SellerCityName: Text; @@ -559,6 +561,7 @@ codeunit 13917 "Export ZUGFeRD Document" ReportSelections.FindEmailBodyUsageForCust("Report Selection Usage"::"S.Invoice", CustomerNo, TempBodyReportSelections); CustomerEmail := ReportSelections.GetEmailAddressExt("Report Selection Usage"::"S.Invoice".AsInteger(), RecordVariant, CustomerNo, TempBodyReportSelections); PhoneNumber := SalesInvoiceHeader."Sell-to Phone No."; + OrderNo := SalesInvoiceHeader."Order No."; RespCentrCode := SalesInvoiceHeader."Responsibility Center"; GetSellerContactInfo(SalesInvoiceHeader, SellerContactName, SellerPhoneNumber, SellerEmailAddress); end; @@ -578,6 +581,7 @@ codeunit 13917 "Export ZUGFeRD Document" ReportSelections.FindEmailBodyUsageForCust("Report Selection Usage"::"S.Cr.Memo", CustomerNo, TempBodyReportSelections); CustomerEmail := ReportSelections.GetEmailAddressExt("Report Selection Usage"::"S.Cr.Memo".AsInteger(), RecordVariant, CustomerNo, TempBodyReportSelections); PhoneNumber := SalesCrMemoHeader."Sell-to Phone No."; + OrderNo := SalesCrMemoHeader."Return Order No."; RespCentrCode := SalesCrMemoHeader."Responsibility Center"; GetSellerContactInfo(SalesCrMemoHeader, SellerContactName, SellerPhoneNumber, SellerEmailAddress); end; @@ -662,6 +666,15 @@ codeunit 13917 "Export ZUGFeRD Document" BuyerTradePartyElement.Add(SpecifiedTaxRegistrationElement); end; HeaderTradeAgreementElement.Add(BuyerTradePartyElement); + + // Seller Order Reference + if OrderNo <> '' then begin + SellerOrderReferencedDocumentElement := XmlElement.Create('SellerOrderReferencedDocument', XmlNamespaceRAM); + SellerOrderReferencedDocumentElement.Add(XmlElement.Create('IssuerAssignedID', XmlNamespaceRAM, OrderNo)); + HeaderTradeAgreementElement.Add(SellerOrderReferencedDocumentElement); + end; + + OnAfterInsertApplicableHeaderTradeAgreement(HeaderTradeAgreementElement, HeaderRecordRef); RootXMLNode.Add(HeaderTradeAgreementElement); end; @@ -1514,4 +1527,9 @@ codeunit 13917 "Export ZUGFeRD Document" local procedure OnBeforeAddCrMemoLineElement(var CrMemoLineElement: XmlElement; var SalesCrMemoLine: Record "Sales Cr.Memo Line"; Currency: Record Currency; CurrencyCode: Code[10]; PricesIncVAT: Boolean) begin end; + + [IntegrationEvent(false, false)] + local procedure OnAfterInsertApplicableHeaderTradeAgreement(var HeaderTradeAgreementElement: XmlElement; HeaderRecordRef: RecordRef) + begin + end; } diff --git a/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al b/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al index d000a07a89..ce2cc2c7b9 100644 --- a/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al +++ b/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al @@ -139,6 +139,25 @@ codeunit 13922 "ZUGFeRD XML Document Tests" VerifyBuyerReference(SalesInvoiceHeader."Your Reference", TempXMLBuffer, '/rsm:CrossIndustryInvoice'); end; + [Test] + procedure ExportPostedSalesInvoiceInZUGFeRDFormatVerifySellerOrderReference(); + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + TempXMLBuffer: Record "XML Buffer" temporary; + begin + // [SCENARIO] Export posted sales invoice from sales order creates electronic document in ZUGFeRD format with seller order reference + Initialize(); + + // [GIVEN] Create and Post Sales Invoice from Sales Order + SalesInvoiceHeader.Get(CreateAndPostSalesInvoiceFromOrder()); + + // [WHEN] Export ZUGFeRD Electronic Document. + ExportInvoice(SalesInvoiceHeader, TempXMLBuffer); + + // [THEN] ZUGFeRD Electronic Document is created with seller order reference + VerifySellerOrderReference(SalesInvoiceHeader."Order No.", TempXMLBuffer, '/rsm:CrossIndustryInvoice'); + end; + [Test] procedure ExportPostedSalesInvoiceInZUGFeRDFormatMandateBuyerReferenceAsYourReference(); var @@ -562,6 +581,25 @@ codeunit 13922 "ZUGFeRD XML Document Tests" VerifyBuyerReference(SalesCrMemoHeader."Your Reference", TempXMLBuffer, '/rsm:CrossIndustryInvoice'); end; + [Test] + procedure ExportPostedSalesCrMemoInZUGFeRDFormatVerifySellerOrderReference(); + var + SalesCrMemoHeader: Record "Sales Cr.Memo Header"; + TempXMLBuffer: Record "XML Buffer" temporary; + begin + // [SCENARIO] Export posted sales cr. memo from return order creates electronic document in ZUGFeRD format with seller order reference + Initialize(); + + // [GIVEN] Create and Post Sales Cr. Memo from Sales Return Order + SalesCrMemoHeader.Get(CreateAndPostSalesCrMemoFromReturnOrder()); + + // [WHEN] Export ZUGFeRD Electronic Document. + ExportCreditMemo(SalesCrMemoHeader, TempXMLBuffer); + + // [THEN] ZUGFeRD Electronic Document is created with seller order reference + VerifySellerOrderReference(SalesCrMemoHeader."Return Order No.", TempXMLBuffer, '/rsm:CrossIndustryInvoice'); + end; + [Test] procedure ExportPostedSalesCrMemoInZUGFeRDFormatMandateBuyerReferenceAsYourReference(); var @@ -1437,6 +1475,22 @@ codeunit 13922 "ZUGFeRD XML Document Tests" exit(LibrarySales.PostSalesDocument(SalesHeader, true, true)); end; + local procedure CreateAndPostSalesInvoiceFromOrder(): Code[20] + var + SalesHeader: Record "Sales Header"; + begin + SalesHeader.Get("Sales Document Type"::Order, CreateSalesDocumentWithLine("Sales Document Type"::Order, Enum::"Sales Line Type"::Item, false)); + exit(LibrarySales.PostSalesDocument(SalesHeader, true, true)); + end; + + local procedure CreateAndPostSalesCrMemoFromReturnOrder(): Code[20] + var + SalesHeader: Record "Sales Header"; + begin + SalesHeader.Get("Sales Document Type"::"Return Order", CreateSalesDocumentWithLine("Sales Document Type"::"Return Order", Enum::"Sales Line Type"::Item, false)); + exit(LibrarySales.PostSalesDocument(SalesHeader, true, true)); + end; + local procedure CreateAndPostSalesDocumentWithoutPhone(DocumentType: Enum "Sales Document Type"; LineType: Enum "Sales Line Type"): Code[20] var SalesHeader: Record "Sales Header"; @@ -1954,7 +2008,9 @@ codeunit 13922 "ZUGFeRD XML Document Tests" Assert.AreEqual(SalesInvoiceHeader."No.", GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); Path := DocumentTok + '/rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString'; Assert.AreEqual(FormatDate(SalesInvoiceHeader."Posting Date"), GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); - + // Verify Seller Order Reference is not present when invoice is posted directly (without order) + if SalesInvoiceHeader."Order No." = '' then + Assert.IsFalse(NodeExistsByPath(TempXMLBuffer, '/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerOrderReferencedDocument'), 'Seller Order Reference should not exist'); end; local procedure VerifyHeaderData(SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var TempXMLBuffer: Record "XML Buffer" temporary); @@ -1968,6 +2024,9 @@ codeunit 13922 "ZUGFeRD XML Document Tests" Assert.AreEqual(SalesCrMemoHeader."No.", GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); Path := DocumentCreditNoteTok + '/rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString'; Assert.AreEqual(FormatDate(SalesCrMemoHeader."Posting Date"), GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); + // Verify Seller Order Reference is not present when cr. memo is posted directly (without return order) + if SalesCrMemoHeader."Return Order No." = '' then + Assert.IsFalse(NodeExistsByPath(TempXMLBuffer, '/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerOrderReferencedDocument'), 'Seller Order Reference should not exist'); end; local procedure VerifyHeaderData(ServiceInvoiceHeader: Record "Service Invoice Header"; var TempXMLBuffer: Record "XML Buffer" temporary) @@ -2004,6 +2063,14 @@ codeunit 13922 "ZUGFeRD XML Document Tests" Assert.AreEqual(BuyerReference, GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); end; + local procedure VerifySellerOrderReference(OrderNo: Code[20]; var TempXMLBuffer: Record "XML Buffer" temporary; DocumentTok: Text); + var + Path: Text; + begin + Path := DocumentTok + '/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerOrderReferencedDocument/ram:IssuerAssignedID'; + Assert.AreEqual(OrderNo, GetNodeByPathWithError(TempXMLBuffer, Path), StrSubstNo(IncorrectValueErr, Path)); + end; + local procedure VerifySellerData(var TempXMLBuffer: Record "XML Buffer" temporary; DocumentTok: Text); begin VerifySellerData(TempXMLBuffer, DocumentTok, CompanyInformation.Address, CompanyInformation."Post Code", CompanyInformation.City);