From a4857119780655ad75fd4144ff1c65d853b3e872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Thu, 9 Apr 2026 16:43:31 +0200 Subject: [PATCH 01/12] Switch E-Document Core from obsoleted BaseApp PEPPOL objects to new PEPPOL App Replace references to obsoleted BaseApp PEPPOL codeunits and xmlports (PEPPOL Validation, PEPPOL Service Validation, PEPPOL Management, Serv. PEPPOL Management, Sales Invoice - PEPPOL BIS 3.0, Sales Cr.Memo - PEPPOL BIS 3.0) with their new PEPPOL App equivalents (PEPPOL30 Sales Validation, PEPPOL30 Service Validation, PEPPOL30, Sales Invoice - PEPPOL30, Sales Cr.Memo - PEPPOL30). Co-Authored-By: Claude Opus 4.6 (1M context) --- src/Apps/W1/EDocument/App/app.json | 9 ++++- .../EDocDataExchangeImpl.Codeunit.al | 14 +++---- .../EDocDEDPEPPOLSubscribers.Codeunit.al | 23 ++++++----- .../src/Format/EDocPEPPOLBIS30.Codeunit.al | 38 ++++++++++--------- .../Format/FinResultsPEPPOLBIS30.XmlPort.al | 10 ++--- 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/Apps/W1/EDocument/App/app.json b/src/Apps/W1/EDocument/App/app.json index 4ed9bcb273..e7ba0958cd 100644 --- a/src/Apps/W1/EDocument/App/app.json +++ b/src/Apps/W1/EDocument/App/app.json @@ -11,7 +11,14 @@ "url": "https://go.microsoft.com/fwlink/?LinkId=724011", "logo": "ExtensionLogo.png", "contextSensitiveHelpUrl": "https://learn.microsoft.com/en-us/dynamics365/business-central/", - "dependencies": [], + "dependencies": [ + { + "id": "e1966889-b5fb-4fda-a84c-ea71b590e1a9", + "name": "PEPPOL", + "publisher": "Microsoft", + "version": "29.0.0.0" + } + ], "internalsVisibleTo": [ { "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8c", diff --git a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al index 111e9a52fb..5cabd8d38f 100644 --- a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al @@ -10,7 +10,7 @@ using Microsoft.Foundation.Company; using Microsoft.Purchases.Document; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Sales.Peppol; +using Microsoft.Peppol; using Microsoft.Service.History; using System.IO; using System.Reflection; @@ -27,8 +27,8 @@ codeunit 6152 "E-Doc. Data Exchange Impl." implements "E-Document" SalesCrMemoHeader: Record "Sales Cr.Memo Header"; ServiceInvoiceHeader: Record "Service Invoice Header"; ServiceCrMemoHeader: Record "Service Cr.Memo Header"; - PEPPOLValidation: Codeunit "PEPPOL Validation"; - PEPPOLServiceValidation: Codeunit "PEPPOL Service Validation"; + PEPPOLValidation: Codeunit "PEPPOL30 Sales Validation"; + PEPPOLServiceValidation: Codeunit "PEPPOL30 Service Validation"; begin case SourceDocumentHeader.Number of Database::"Sales Header": @@ -39,22 +39,22 @@ codeunit 6152 "E-Doc. Data Exchange Impl." implements "E-Document" Database::"Sales Invoice Header": begin SourceDocumentHeader.SetTable(SalesInvoiceHeader); - PEPPOLValidation.CheckSalesInvoice(SalesInvoiceHeader); + PEPPOLValidation.ValidatePostedDocument(SalesInvoiceHeader); end; Database::"Sales Cr.Memo Header": begin SourceDocumentHeader.SetTable(SalesCrMemoHeader); - PEPPOLValidation.CheckSalesCreditMemo(SalesCrMemoHeader); + PEPPOLValidation.ValidatePostedDocument(SalesCrMemoHeader); end; Database::"Service Invoice Header": begin SourceDocumentHeader.SetTable(ServiceInvoiceHeader); - PEPPOLServiceValidation.CheckServiceInvoice(ServiceInvoiceHeader); + PEPPOLServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); end; Database::"Service Cr.Memo Header": begin SourceDocumentHeader.SetTable(ServiceCrMemoHeader); - PEPPOLServiceValidation.CheckServiceCreditMemo(ServiceCrMemoHeader); + PEPPOLServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); end; end; end; diff --git a/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al b/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al index d06a93424f..e14b6fb67c 100644 --- a/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al @@ -12,7 +12,7 @@ using Microsoft.Foundation.Attachment; using Microsoft.Sales.Customer; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Sales.Peppol; +using Microsoft.Peppol; using Microsoft.Service.History; using System.IO; using System.Utilities; @@ -451,7 +451,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" OriginCountryIdCode, OriginCountryIdCodeListID); - PEPPOLMgt.GetLineItemClassfiedTaxCategoryBIS( + PEPPOLMgt.GetLineItemClassifiedTaxCategoryBIS( SalesLine, ClassifiedTaxCategoryID, DummyVar, @@ -631,7 +631,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" TempSalesLineRounding.TransferFields(SalesLine); TempSalesLineRounding.Insert(); end else begin - PEPPOLMgt.GetTotals(SalesLine, TempVATAmtLine); + PEPPOLMgt.GetTaxTotals(SalesLine, TempVATAmtLine); PEPPOLMgt.GetTaxCategories(SalesLine, TempVATProductPostingGroup); end; until SalesInvoiceLine.Next() = 0; @@ -650,12 +650,12 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" if ServiceInvoiceLine.FindSet() then repeat PEPPOLMgt.TransferLineToSalesLine(ServiceInvoiceLine, SalesLine); - SalesLine.Type := ServPEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceInvoiceLine.Type); + SalesLine.Type := PEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceInvoiceLine.Type); if IsRoundingLine(SalesLine) then begin TempSalesLineRounding.TransferFields(SalesLine); TempSalesLineRounding.Insert(); end else begin - PEPPOLMgt.GetTotals(SalesLine, TempVATAmtLine); + PEPPOLMgt.GetTaxTotals(SalesLine, TempVATAmtLine); PEPPOLMgt.GetTaxCategories(SalesLine, TempVATProductPostingGroup); end; until ServiceInvoiceLine.Next() = 0; @@ -678,7 +678,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" TempSalesLineRounding.TransferFields(SalesLine); TempSalesLineRounding.Insert(); end else begin - PEPPOLMgt.GetTotals(SalesLine, TempVATAmtLine); + PEPPOLMgt.GetTaxTotals(SalesLine, TempVATAmtLine); PEPPOLMgt.GetTaxCategories(SalesLine, TempVATProductPostingGroup); end; until SalesCrMemoLine.Next() = 0; @@ -697,12 +697,12 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" if ServiceCrMemoLine.FindSet() then repeat PEPPOLMgt.TransferLineToSalesLine(ServiceCrMemoLine, SalesLine); - SalesLine.Type := ServPEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceCrMemoLine.Type); + SalesLine.Type := PEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceCrMemoLine.Type); if IsRoundingLine(SalesLine) then begin TempSalesLineRounding.TransferFields(SalesLine); TempSalesLineRounding.Insert(); end else begin - PEPPOLMgt.GetTotals(SalesLine, TempVATAmtLine); + PEPPOLMgt.GetTaxTotals(SalesLine, TempVATAmtLine); PEPPOLMgt.GetTaxCategories(SalesLine, TempVATProductPostingGroup); end; until ServiceCrMemoLine.Next() = 0; @@ -738,7 +738,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" ServiceInvoiceLine.FindFirst(); PEPPOLMgt.TransferLineToSalesLine(ServiceInvoiceLine, SalesLine); - SalesLine.Type := ServPEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceInvoiceLine.Type); + SalesLine.Type := PEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceInvoiceLine.Type); end; ProcessedDocType::"Sales Credit Memo": begin @@ -754,7 +754,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" ServiceCrMemoLine.FindFirst(); PEPPOLMgt.TransferLineToSalesLine(ServiceCrMemoLine, SalesLine); - SalesLine.Type := ServPEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceCrMemoLine.Type); + SalesLine.Type := PEPPOLMgt.MapServiceLineTypeToSalesLineType(ServiceCrMemoLine.Type); end; end; end; @@ -801,8 +801,7 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" #pragma warning restore AL0432 TempSalesLineRounding: Record "Sales Line" temporary; TempVATProductPostingGroup: Record "VAT Product Posting Group" temporary; - PEPPOLMgt: Codeunit "PEPPOL Management"; - ServPEPPOLMgt: Codeunit "Serv. PEPPOL Management"; + PEPPOLMgt: Codeunit "PEPPOL30"; ProcessedDocType: Enum "E-Document Type"; DocumentAttachmentNumber, ProcessedDocTypeInt : Integer; AdditionalDocumentReferenceID, AdditionalDocRefDocumentType, URI, Filename, MimeCode, EmbeddedDocumentBinaryObject : Text; diff --git a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al index 47a481b1d1..a9fb72fd9c 100644 --- a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al @@ -7,7 +7,7 @@ using Microsoft.Purchases.Document; using Microsoft.Sales.Document; using Microsoft.Sales.FinanceCharge; using Microsoft.Sales.History; -using Microsoft.Sales.Peppol; +using Microsoft.Peppol; using Microsoft.Sales.Reminder; using Microsoft.Service.Document; using Microsoft.Service.History; @@ -25,8 +25,8 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" ServiceCrMemoHeader: Record "Service Cr.Memo Header"; ReminderHeader: Record "Reminder Header"; FinChargeMemoHeader: Record "Finance Charge Memo Header"; - PEPPOLValidation: Codeunit "PEPPOL Validation"; - PEPPOLServiceValidation: Codeunit "PEPPOL Service Validation"; + PEPPOLValidation: Codeunit "PEPPOL30 Sales Validation"; + PEPPOLServiceValidation: Codeunit "PEPPOL30 Service Validation"; EDocPEPPOLValidation: Codeunit "E-Doc. PEPPOL Validation"; begin case SourceDocumentHeader.Number of @@ -38,22 +38,22 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" Database::"Sales Invoice Header": begin SourceDocumentHeader.SetTable(SalesInvoiceHeader); - PEPPOLValidation.CheckSalesInvoice(SalesInvoiceHeader); + PEPPOLValidation.ValidatePostedDocument(SalesInvoiceHeader); end; Database::"Sales Cr.Memo Header": begin SourceDocumentHeader.SetTable(SalesCrMemoHeader); - PEPPOLValidation.CheckSalesCreditMemo(SalesCrMemoHeader); + PEPPOLValidation.ValidatePostedDocument(SalesCrMemoHeader); end; Database::"Service Invoice Header": begin SourceDocumentHeader.SetTable(ServiceInvoiceHeader); - PEPPOLServiceValidation.CheckServiceInvoice(ServiceInvoiceHeader); + PEPPOLServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); end; Database::"Service Cr.Memo Header": begin SourceDocumentHeader.SetTable(ServiceCrMemoHeader); - PEPPOLServiceValidation.CheckServiceCreditMemo(ServiceCrMemoHeader); + PEPPOLServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); end; Database::"Reminder Header": begin @@ -68,7 +68,7 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" Database::"Service Header": begin SourceDocumentHeader.SetTable(ServiceHeader); - PEPPOLServiceValidation.CheckServiceHeader(ServiceHeader); + PEPPOLServiceValidation.Run(ServiceHeader); end; end; end; @@ -121,22 +121,24 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" local procedure GenerateInvoiceXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean) var - SalesInvoicePEPPOLBIS30: XMLport "Sales Invoice - PEPPOL BIS 3.0"; + SalesInvoicePEPPOL30: XMLport "Sales Invoice - PEPPOL30"; + PEPPOLFormat: Enum "PEPPOL 3.0 Format"; begin - SalesInvoicePEPPOLBIS30.Initialize(VariantRec); - SalesInvoicePEPPOLBIS30.SetGeneratePDF(GeneratePDF); - SalesInvoicePEPPOLBIS30.SetDestination(OutStr); - SalesInvoicePEPPOLBIS30.Export(); + SalesInvoicePEPPOL30.Initialize(VariantRec, PEPPOLFormat::"PEPPOL 3.0 - Sales"); + SalesInvoicePEPPOL30.SetGeneratePDF(GeneratePDF); + SalesInvoicePEPPOL30.SetDestination(OutStr); + SalesInvoicePEPPOL30.Export(); end; local procedure GenerateCrMemoXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean) var - SalesCrMemoPEPPOLBIS30: XMLport "Sales Cr.Memo - PEPPOL BIS 3.0"; + SalesCrMemoPEPPOL30: XMLport "Sales Cr.Memo - PEPPOL30"; + PEPPOLFormat: Enum "PEPPOL 3.0 Format"; begin - SalesCrMemoPEPPOLBIS30.Initialize(VariantRec); - SalesCrMemoPEPPOLBIS30.SetGeneratePDF(GeneratePDF); - SalesCrMemoPEPPOLBIS30.SetDestination(OutStr); - SalesCrMemoPEPPOLBIS30.Export(); + SalesCrMemoPEPPOL30.Initialize(VariantRec, PEPPOLFormat::"PEPPOL 3.0 - Sales"); + SalesCrMemoPEPPOL30.SetGeneratePDF(GeneratePDF); + SalesCrMemoPEPPOL30.SetDestination(OutStr); + SalesCrMemoPEPPOL30.Export(); end; local procedure GenerateFinancialResultsXMLFile(VariantRec: Variant; var OutStr: OutStream) diff --git a/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al b/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al index f96f18627c..c04da07340 100644 --- a/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al +++ b/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al @@ -4,7 +4,7 @@ using Microsoft.Finance.VAT.Calculation; using Microsoft.Finance.VAT.Setup; using Microsoft.Sales.Document; using Microsoft.Sales.FinanceCharge; -using Microsoft.Sales.Peppol; +using Microsoft.Peppol; using Microsoft.Sales.Reminder; using System.Utilities; @@ -1036,7 +1036,7 @@ xmlport 6100 "Fin. Results - PEPPOL BIS 3.0" trigger OnBeforePassVariable() begin - this.PEPPOLMgt.GetLineItemClassfiedTaxCategoryBIS( + this.PEPPOLMgt.GetLineItemClassifiedTaxCategoryBIS( this.GlobalSalesLine, ClassifiedTaxCategoryID, this.DummyVar, @@ -1179,7 +1179,7 @@ xmlport 6100 "Fin. Results - PEPPOL BIS 3.0" GlobalIssuedFinChargeMemoHeader: Record "Issued Fin. Charge Memo Header"; GlobalIssuedFinChargeMemoLine: Record "Issued Fin. Charge Memo Line"; TempVATProductPostingGroup: Record "VAT Product Posting Group" temporary; - PEPPOLMgt: Codeunit "PEPPOL Management"; + PEPPOLMgt: Codeunit "PEPPOL30"; SourceRecRef: RecordRef; DummyVar: Text; IsReminder: Boolean; @@ -1194,7 +1194,7 @@ xmlport 6100 "Fin. Results - PEPPOL BIS 3.0" if this.GlobalIssuedReminderLine.FindSet() then repeat this.CopyReminderLineToSalesLine(this.GlobalSalesLine, this.GlobalIssuedReminderHeader, this.GlobalIssuedReminderLine); - this.PEPPOLMgt.GetTotals(this.GlobalSalesLine, this.TempVATAmtLine); + this.PEPPOLMgt.GetTaxTotals(this.GlobalSalesLine, this.TempVATAmtLine); this.PEPPOLMgt.GetTaxCategories(this.GlobalSalesLine, this.TempVATProductPostingGroup); until this.GlobalIssuedReminderLine.Next() = 0; end; @@ -1204,7 +1204,7 @@ xmlport 6100 "Fin. Results - PEPPOL BIS 3.0" if this.GlobalIssuedFinChargeMemoLine.FindSet() then repeat this.CopyFinChargeMemoLineToSalesLine(this.GlobalSalesLine, this.GlobalIssuedFinChargeMemoHeader, this.GlobalIssuedFinChargeMemoLine); - this.PEPPOLMgt.GetTotals(this.GlobalSalesLine, this.TempVATAmtLine); + this.PEPPOLMgt.GetTaxTotals(this.GlobalSalesLine, this.TempVATAmtLine); this.PEPPOLMgt.GetTaxCategories(this.GlobalSalesLine, this.TempVATProductPostingGroup); until this.GlobalIssuedFinChargeMemoLine.Next() = 0; end; From e5491d9c6ad5cbc5c59ef126234ab87614307c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Fri, 10 Apr 2026 09:32:44 +0200 Subject: [PATCH 02/12] Fix AA0477: sort using Microsoft.Peppol in alphabetical order Co-Authored-By: Claude Opus 4.6 (1M context) --- .../App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al | 2 +- .../EDocDEDPEPPOLSubscribers.Codeunit.al | 2 +- .../W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al | 2 +- .../EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al index 5cabd8d38f..3c5e5bf97a 100644 --- a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al @@ -7,10 +7,10 @@ namespace Microsoft.eServices.EDocument.IO.Peppol; using Microsoft.eServices.EDocument; using Microsoft.Foundation.Attachment; using Microsoft.Foundation.Company; +using Microsoft.Peppol; using Microsoft.Purchases.Document; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Peppol; using Microsoft.Service.History; using System.IO; using System.Reflection; diff --git a/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al b/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al index e14b6fb67c..d0d0d2f30b 100644 --- a/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/DataExchange/PEPPOL Data Exchange Definition/EDocDEDPEPPOLSubscribers.Codeunit.al @@ -9,10 +9,10 @@ using Microsoft.Finance.GeneralLedger.Setup; using Microsoft.Finance.VAT.Calculation; using Microsoft.Finance.VAT.Setup; using Microsoft.Foundation.Attachment; +using Microsoft.Peppol; using Microsoft.Sales.Customer; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Peppol; using Microsoft.Service.History; using System.IO; using System.Utilities; diff --git a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al index a9fb72fd9c..0a6ce1edb1 100644 --- a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al @@ -3,11 +3,11 @@ namespace Microsoft.eServices.EDocument.IO.Peppol; using Microsoft.eServices.EDocument; using Microsoft.EServices.EDocument.Format; using Microsoft.Inventory.Transfer; +using Microsoft.Peppol; using Microsoft.Purchases.Document; using Microsoft.Sales.Document; using Microsoft.Sales.FinanceCharge; using Microsoft.Sales.History; -using Microsoft.Peppol; using Microsoft.Sales.Reminder; using Microsoft.Service.Document; using Microsoft.Service.History; diff --git a/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al b/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al index c04da07340..d93281d3d8 100644 --- a/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al +++ b/src/Apps/W1/EDocument/App/src/Format/FinResultsPEPPOLBIS30.XmlPort.al @@ -2,9 +2,9 @@ namespace Microsoft.EServices.EDocument.IO.Peppol; using Microsoft.Finance.VAT.Calculation; using Microsoft.Finance.VAT.Setup; +using Microsoft.Peppol; using Microsoft.Sales.Document; using Microsoft.Sales.FinanceCharge; -using Microsoft.Peppol; using Microsoft.Sales.Reminder; using System.Utilities; From 9e5aa646bb4eefde47f2213199b08136a9f3e6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Fri, 10 Apr 2026 14:41:17 +0200 Subject: [PATCH 03/12] Fix E-Document Demo Data to use new PEPPOL App codeunit Replace obsoleted "Exp. Sales Inv. PEPPOL BIS3.0" with "Exp. Sales Inv. PEPPOL30" and add PEPPOL dependency to E-Document Core Demo Data app.json. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../CreateEDocumentTransactions.Codeunit.al | 16 ++++++++-------- src/Apps/W1/EDocument/Demo Data/app.json | 6 ++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al b/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al index 20117a3c73..f8e3c15b3f 100644 --- a/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al +++ b/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al @@ -15,7 +15,7 @@ using Microsoft.Purchases.Posting; using Microsoft.Purchases.Vendor; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Sales.Peppol; +using Microsoft.Peppol; using Microsoft.Sales.Setup; using System.IO; using System.Utilities; @@ -142,7 +142,7 @@ codeunit 5376 "Create E-Document Transactions" SalesSetup: Record "Sales & Receivables Setup"; ContosoCustomer: Codeunit "Create Common Customer/Vendor"; CreateEDocTransactions: Codeunit "Create E-Document Transactions"; - ExportSalesInv: Codeunit "Exp. Sales Inv. PEPPOL BIS3.0"; + ExportSalesInv: Codeunit "Exp. Sales Inv. PEPPOL30"; TempBlob: Codeunit "Temp Blob"; TempBlobList: Codeunit "Temp Blob List"; OutStr: OutStream; @@ -170,7 +170,7 @@ codeunit 5376 "Create E-Document Transactions" CorrectSalesInvHeader(SalesInvHeader); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); @@ -200,7 +200,7 @@ codeunit 5376 "Create E-Document Transactions" Clear(TempBlob); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); @@ -220,7 +220,7 @@ codeunit 5376 "Create E-Document Transactions" Clear(TempBlob); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); @@ -245,7 +245,7 @@ codeunit 5376 "Create E-Document Transactions" Clear(TempBlob); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); @@ -268,7 +268,7 @@ codeunit 5376 "Create E-Document Transactions" Clear(TempBlob); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); @@ -288,7 +288,7 @@ codeunit 5376 "Create E-Document Transactions" Clear(TempBlob); TempBlob.CreateOutStream(OutStr); - ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr); + ExportSalesInv.GenerateXMLFile(SalesInvHeader, OutStr, "PEPPOL 3.0 Format"::"PEPPOL 3.0 - Sales"); TempBlobList.Add(TempBlob); SalesInvHeader.Delete(true); SalesHeader.Delete(); diff --git a/src/Apps/W1/EDocument/Demo Data/app.json b/src/Apps/W1/EDocument/Demo Data/app.json index 7f074178d1..dad9d6b296 100644 --- a/src/Apps/W1/EDocument/Demo Data/app.json +++ b/src/Apps/W1/EDocument/Demo Data/app.json @@ -23,6 +23,12 @@ "name": "Contoso Coffee Demo Dataset", "publisher": "Microsoft", "version": "29.0.0.0" + }, + { + "id": "e1966889-b5fb-4fda-a84c-ea71b590e1a9", + "name": "PEPPOL", + "publisher": "Microsoft", + "version": "29.0.0.0" } ], "internalsVisibleTo": [ From f827c11a7d11160f90bae22fc36e9ca32a243ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Fri, 10 Apr 2026 16:14:58 +0200 Subject: [PATCH 04/12] Fix AA0477: sort using Microsoft.Peppol in alphabetical order Co-Authored-By: Claude Opus 4.6 (1M context) --- .../3.Transactions/CreateEDocumentTransactions.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al b/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al index f8e3c15b3f..8f0c7b3c19 100644 --- a/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al +++ b/src/Apps/W1/EDocument/Demo Data/3.Transactions/CreateEDocumentTransactions.Codeunit.al @@ -10,12 +10,12 @@ using Microsoft.DemoTool.Helpers; using Microsoft.eServices.EDocument; using Microsoft.eServices.EDocument.Processing.Import; using Microsoft.Foundation.Company; +using Microsoft.Peppol; using Microsoft.Purchases.Document; using Microsoft.Purchases.Posting; using Microsoft.Purchases.Vendor; using Microsoft.Sales.Document; using Microsoft.Sales.History; -using Microsoft.Peppol; using Microsoft.Sales.Setup; using System.IO; using System.Utilities; From 5fb2b25a116a3222f9441f2a4327b1a815e3e2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Fri, 8 May 2026 20:42:34 +0200 Subject: [PATCH 05/12] Read PEPPOL 3.0 Format from setup in E-Document bridge Switches the W1 E-Document PEPPOL bridge from a hardcoded "PEPPOL 3.0 - Sales" format to the format selected on PEPPOL 3.0 Setup, and from a fixed "PEPPOL30 Sales/Service Validation" codeunit to an interface lookup via the configured "PEPPOL 3.0 Format" enum value. This lets country-localized PEPPOL apps (NO/BE/NA/DE) extend the format enum and have their custom validation, posted document iterator, document info provider, and party info provider implementations take effect for documents flowing through the E-Document framework, by selecting their format value on the PEPPOL 3.0 Setup page. Affected: * EDocPEPPOLBIS30.Codeunit.al: Check uses Interface "PEPPOL30 Validation" resolved per-direction from setup; Create dispatches sales/service invoices/credit memos to the appropriate format from setup; new GetSalesFormat/GetServiceFormat helpers * EDocDataExchangeImpl.Codeunit.al: same setup-driven interface lookup in Check Co-Authored-By: Claude Opus 4.7 (1M context) --- .../EDocDataExchangeImpl.Codeunit.al | 20 ++++--- .../src/Format/EDocPEPPOLBIS30.Codeunit.al | 59 +++++++++++++------ 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al index 3c5e5bf97a..7ec2b23fba 100644 --- a/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/DataExchange/EDocDataExchangeImpl.Codeunit.al @@ -27,34 +27,40 @@ codeunit 6152 "E-Doc. Data Exchange Impl." implements "E-Document" SalesCrMemoHeader: Record "Sales Cr.Memo Header"; ServiceInvoiceHeader: Record "Service Invoice Header"; ServiceCrMemoHeader: Record "Service Cr.Memo Header"; - PEPPOLValidation: Codeunit "PEPPOL30 Sales Validation"; - PEPPOLServiceValidation: Codeunit "PEPPOL30 Service Validation"; + PeppolSetup: Record "PEPPOL 3.0 Setup"; + SalesValidation: Interface "PEPPOL30 Validation"; + ServiceValidation: Interface "PEPPOL30 Validation"; begin + PeppolSetup.GetSetup(); + SalesValidation := PeppolSetup."PEPPOL 3.0 Sales Format"; + ServiceValidation := PeppolSetup."PEPPOL 3.0 Service Format"; + case SourceDocumentHeader.Number of Database::"Sales Header": begin SourceDocumentHeader.SetTable(SalesHeader); - PEPPOLValidation.Run(SalesHeader); + SalesValidation.ValidateDocument(SalesHeader); + SalesValidation.ValidateDocumentLines(SalesHeader); end; Database::"Sales Invoice Header": begin SourceDocumentHeader.SetTable(SalesInvoiceHeader); - PEPPOLValidation.ValidatePostedDocument(SalesInvoiceHeader); + SalesValidation.ValidatePostedDocument(SalesInvoiceHeader); end; Database::"Sales Cr.Memo Header": begin SourceDocumentHeader.SetTable(SalesCrMemoHeader); - PEPPOLValidation.ValidatePostedDocument(SalesCrMemoHeader); + SalesValidation.ValidatePostedDocument(SalesCrMemoHeader); end; Database::"Service Invoice Header": begin SourceDocumentHeader.SetTable(ServiceInvoiceHeader); - PEPPOLServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); + ServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); end; Database::"Service Cr.Memo Header": begin SourceDocumentHeader.SetTable(ServiceCrMemoHeader); - PEPPOLServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); + ServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); end; end; end; diff --git a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al index 0a6ce1edb1..3878891aa7 100644 --- a/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/Format/EDocPEPPOLBIS30.Codeunit.al @@ -25,35 +25,39 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" ServiceCrMemoHeader: Record "Service Cr.Memo Header"; ReminderHeader: Record "Reminder Header"; FinChargeMemoHeader: Record "Finance Charge Memo Header"; - PEPPOLValidation: Codeunit "PEPPOL30 Sales Validation"; - PEPPOLServiceValidation: Codeunit "PEPPOL30 Service Validation"; EDocPEPPOLValidation: Codeunit "E-Doc. PEPPOL Validation"; + SalesValidation: Interface "PEPPOL30 Validation"; + ServiceValidation: Interface "PEPPOL30 Validation"; begin + SalesValidation := GetSalesFormat(); + ServiceValidation := GetServiceFormat(); + case SourceDocumentHeader.Number of Database::"Sales Header": begin SourceDocumentHeader.SetTable(SalesHeader); - PEPPOLValidation.Run(SalesHeader); + SalesValidation.ValidateDocument(SalesHeader); + SalesValidation.ValidateDocumentLines(SalesHeader); end; Database::"Sales Invoice Header": begin SourceDocumentHeader.SetTable(SalesInvoiceHeader); - PEPPOLValidation.ValidatePostedDocument(SalesInvoiceHeader); + SalesValidation.ValidatePostedDocument(SalesInvoiceHeader); end; Database::"Sales Cr.Memo Header": begin SourceDocumentHeader.SetTable(SalesCrMemoHeader); - PEPPOLValidation.ValidatePostedDocument(SalesCrMemoHeader); + SalesValidation.ValidatePostedDocument(SalesCrMemoHeader); end; Database::"Service Invoice Header": begin SourceDocumentHeader.SetTable(ServiceInvoiceHeader); - PEPPOLServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); + ServiceValidation.ValidatePostedDocument(ServiceInvoiceHeader); end; Database::"Service Cr.Memo Header": begin SourceDocumentHeader.SetTable(ServiceCrMemoHeader); - PEPPOLServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); + ServiceValidation.ValidatePostedDocument(ServiceCrMemoHeader); end; Database::"Reminder Header": begin @@ -68,7 +72,8 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" Database::"Service Header": begin SourceDocumentHeader.SetTable(ServiceHeader); - PEPPOLServiceValidation.Run(ServiceHeader); + ServiceValidation.ValidateDocument(ServiceHeader); + ServiceValidation.ValidateDocumentLines(ServiceHeader); end; end; end; @@ -80,10 +85,14 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" begin TempBlob.CreateOutStream(DocOutStream); case EDocument."Document Type" of - EDocument."Document Type"::"Sales Invoice", EDocument."Document Type"::"Service Invoice": - GenerateInvoiceXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export"); - EDocument."Document Type"::"Sales Credit Memo", EDocument."Document Type"::"Service Credit Memo": - GenerateCrMemoXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export"); + EDocument."Document Type"::"Sales Invoice": + GenerateInvoiceXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export", GetSalesFormat()); + EDocument."Document Type"::"Service Invoice": + GenerateInvoiceXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export", GetServiceFormat()); + EDocument."Document Type"::"Sales Credit Memo": + GenerateCrMemoXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export", GetSalesFormat()); + EDocument."Document Type"::"Service Credit Memo": + GenerateCrMemoXMLFile(SourceDocumentHeader, DocOutStream, EDocumentService."Embed PDF in export", GetServiceFormat()); EDocument."Document Type"::"Issued Reminder", EDocument."Document Type"::"Issued Finance Charge Memo": GenerateFinancialResultsXMLFile(SourceDocumentHeader, DocOutStream); EDocument."Document Type"::"Sales Shipment": @@ -119,28 +128,42 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" CreatedDocumentLines.GetTable(TempPurchaseLine); end; - local procedure GenerateInvoiceXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean) + local procedure GenerateInvoiceXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean; PEPPOLFormat: Enum "PEPPOL 3.0 Format") var SalesInvoicePEPPOL30: XMLport "Sales Invoice - PEPPOL30"; - PEPPOLFormat: Enum "PEPPOL 3.0 Format"; begin - SalesInvoicePEPPOL30.Initialize(VariantRec, PEPPOLFormat::"PEPPOL 3.0 - Sales"); + SalesInvoicePEPPOL30.Initialize(VariantRec, PEPPOLFormat); SalesInvoicePEPPOL30.SetGeneratePDF(GeneratePDF); SalesInvoicePEPPOL30.SetDestination(OutStr); SalesInvoicePEPPOL30.Export(); end; - local procedure GenerateCrMemoXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean) + local procedure GenerateCrMemoXMLFile(VariantRec: Variant; var OutStr: OutStream; GeneratePDF: Boolean; PEPPOLFormat: Enum "PEPPOL 3.0 Format") var SalesCrMemoPEPPOL30: XMLport "Sales Cr.Memo - PEPPOL30"; - PEPPOLFormat: Enum "PEPPOL 3.0 Format"; begin - SalesCrMemoPEPPOL30.Initialize(VariantRec, PEPPOLFormat::"PEPPOL 3.0 - Sales"); + SalesCrMemoPEPPOL30.Initialize(VariantRec, PEPPOLFormat); SalesCrMemoPEPPOL30.SetGeneratePDF(GeneratePDF); SalesCrMemoPEPPOL30.SetDestination(OutStr); SalesCrMemoPEPPOL30.Export(); end; + local procedure GetSalesFormat(): Enum "PEPPOL 3.0 Format" + var + PeppolSetup: Record "PEPPOL 3.0 Setup"; + begin + PeppolSetup.GetSetup(); + exit(PeppolSetup."PEPPOL 3.0 Sales Format"); + end; + + local procedure GetServiceFormat(): Enum "PEPPOL 3.0 Format" + var + PeppolSetup: Record "PEPPOL 3.0 Setup"; + begin + PeppolSetup.GetSetup(); + exit(PeppolSetup."PEPPOL 3.0 Service Format"); + end; + local procedure GenerateFinancialResultsXMLFile(VariantRec: Variant; var OutStr: OutStream) var FinResultsPEPPOLBIS30: XMLport "Fin. Results - PEPPOL BIS 3.0"; From 1a1dd8be09edc0265b8f869853968c9968b2e30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Mon, 1 Jun 2026 20:47:04 +0200 Subject: [PATCH 06/12] Add DataClassification to PEPPOL 3.0 Setup fields 2 and 3 The Data Classs Demo Data Tests.TestDataSensitivities test fails for table 37202 when field-level DataClassification is missing; the table-level setting is not inherited by individual fields. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Apps/W1/PEPPOL/App/src/Setup/PEPPOL30Setup.Table.al | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Apps/W1/PEPPOL/App/src/Setup/PEPPOL30Setup.Table.al b/src/Apps/W1/PEPPOL/App/src/Setup/PEPPOL30Setup.Table.al index 0f994f85d4..3c136f2335 100644 --- a/src/Apps/W1/PEPPOL/App/src/Setup/PEPPOL30Setup.Table.al +++ b/src/Apps/W1/PEPPOL/App/src/Setup/PEPPOL30Setup.Table.al @@ -28,11 +28,13 @@ table 37202 "PEPPOL 3.0 Setup" { Caption = 'PEPPOL 3.0 Sales Format'; ToolTip = 'Specifies the PEPPOL 3.0 format to be used for electronic documents of type sales.'; + DataClassification = SystemMetadata; } field(3; "PEPPOL 3.0 Service Format"; Enum "PEPPOL 3.0 Format") { Caption = 'PEPPOL 3.0 Service Format'; ToolTip = 'Specifies the PEPPOL 3.0 format to be used for electronic documents of type service.'; + DataClassification = SystemMetadata; } } From a8d582c8719550b292dba8e4552bb60cbef9e9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Tue, 2 Jun 2026 06:50:26 +0200 Subject: [PATCH 07/12] Set Customer E-Mail in EDocument test library DE PEPPOL requires Sell-to E-Mail on the sales header. The shared E-Document test setup creates a customer without an email, causing Integration Tests (Avalara, etc.) to fail when posting sales documents in NAV_DE where PEPPOL30 DE Sales Validation runs. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al b/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al index adf51d6adf..b4695b6224 100644 --- a/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al @@ -92,6 +92,7 @@ codeunit 139629 "Library - E-Document" Customer.Validate("VAT Bus. Posting Group", VATPostingSetup."VAT Bus. Posting Group"); Customer."VAT Registration No." := LibraryERM.GenerateVATRegistrationNo(CountryRegion.Code); Customer.Validate(GLN, '1234567890128'); + Customer.Validate("E-Mail", 'edoc-test@contoso.com'); Customer."Document Sending Profile" := DocumentSendingProfile.Code; Customer.Modify(true); From 989503a50b64fbb38e3c59de5e93e0123a6de8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Tue, 2 Jun 2026 09:49:01 +0200 Subject: [PATCH 08/12] Force W1 PEPPOL 3.0 Service Format in EDoc Format Tests CheckEDocumentServiceOrderErrorForYourReferance asserts the W1 PEPPOL behavior that 'Your Reference' is mandatory on service orders. On NAV_DE the PEPPOL 3.0 Setup defaults to 'PEPPOL 3.0 - Service DE' which routes through PEPPOL30 DE Service Validation and intentionally omits the Your Reference check (DE deviation). Pin the setup to the W1 service format so the assertion is comparing against the same impl on every country. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Test/src/Processing/EDocFormatTests.Codeunit.al | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al index 7980fc4e21..cdf0992533 100644 --- a/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al @@ -13,6 +13,7 @@ using Microsoft.Finance.VAT.Setup; using Microsoft.Foundation.Address; using Microsoft.Foundation.Company; using Microsoft.Foundation.Reporting; +using Microsoft.Peppol; using Microsoft.Inventory.Item; using Microsoft.Purchases.History; using Microsoft.Purchases.Payables; @@ -51,6 +52,7 @@ codeunit 139519 "E-Doc. Format Tests" DocumentSendingProfile: Record "Document Sending Profile"; ServiceHeader: Record "Service Header"; ServiceMngmtSetup: Record "Service Mgt. Setup"; + Peppol30Setup: Record "PEPPOL 3.0 Setup"; LibraryERMCountryData: Codeunit "Library - ERM Country Data"; ExpectedErr: Text; WorkflowCode: Code[20]; @@ -58,6 +60,12 @@ codeunit 139519 "E-Doc. Format Tests" // [SCENARIO 608765] E-Documents: Check 'Your reference' not available in service documents in Belgian localisation Initialize(Enum::"Service Integration"::Mock); + // Force the W1 PEPPOL 3.0 service validation impl so that country-specific overrides (e.g. DE, + // which omits the Your Reference check) do not change the asserted W1 behavior. + Peppol30Setup.GetSetup(); + Peppol30Setup."PEPPOL 3.0 Service Format" := Peppol30Setup."PEPPOL 3.0 Service Format"::"PEPPOL 3.0 - Service"; + Peppol30Setup.Modify(); + // [WHEN] Team member create invoice and update company information. UpdateCompanyInformation(); LibraryLowerPermission.SetTeamMember(); From 103c4255525ce2afd116ab0687eacb19dd22d0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Wed, 3 Jun 2026 09:24:25 +0200 Subject: [PATCH 09/12] Add PEPPOL dependency to E-Document Core Tests app The Test app references Microsoft.Peppol namespace and PEPPOL 3.0 Setup table (added in 989503a5), but only depends on E-Document Core. Since E-Document Core does not set propagateDependencies, the PEPPOL dep does not flow through transitively. The IT build pipeline failed to compile because PEPPOL was not declared as a direct dependency. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Apps/W1/EDocument/Test/app.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Apps/W1/EDocument/Test/app.json b/src/Apps/W1/EDocument/Test/app.json index e182d37bc9..d16388289a 100644 --- a/src/Apps/W1/EDocument/Test/app.json +++ b/src/Apps/W1/EDocument/Test/app.json @@ -18,6 +18,12 @@ "publisher": "Microsoft", "version": "29.0.0.0" }, + { + "id": "e1966889-b5fb-4fda-a84c-ea71b590e1a9", + "name": "PEPPOL", + "publisher": "Microsoft", + "version": "29.0.0.0" + }, { "id": "5d86850b-0d76-4eca-bd7b-951ad998e997", "name": "Tests-TestLibraries", From 403e7e5dc4b922b254656793da9a574107c3a38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Wed, 3 Jun 2026 12:42:15 +0200 Subject: [PATCH 10/12] Sort Microsoft.Peppol using statement alphabetically Co-Authored-By: Claude Opus 4.7 (1M context) --- .../EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al index cdf0992533..2babe473a0 100644 --- a/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocFormatTests.Codeunit.al @@ -13,8 +13,8 @@ using Microsoft.Finance.VAT.Setup; using Microsoft.Foundation.Address; using Microsoft.Foundation.Company; using Microsoft.Foundation.Reporting; -using Microsoft.Peppol; using Microsoft.Inventory.Item; +using Microsoft.Peppol; using Microsoft.Purchases.History; using Microsoft.Purchases.Payables; using Microsoft.Purchases.Vendor; From 8ed7adf05eef06d080042281a8c16abc924ce5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hartvig=20Gr=C3=B8nbech?= Date: Thu, 4 Jun 2026 10:07:36 +0200 Subject: [PATCH 11/12] Set contact e-mail in EDocument test library to avoid Sell-to confirm SetupStandardSalesScenario sets the customer e-mail (required by DE PEPPOL), which populates "Sell-to E-Mail" on the sales header. On NAV_DK the OIOUBL "Sell-to Customer No." validation re-validates the sell-to contact, and base app raises the "contact has no e-mail address" confirm because the linked contact has no e-mail - failing the E-Document tests as Unhandled UI. Write the same e-mail directly onto the customer's contact (no Validate) so Contact."E-Mail" is never empty and the confirm condition is never met. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Test/src/LibraryEDocument.Codeunit.al | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al b/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al index b4695b6224..a866609a2a 100644 --- a/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/LibraryEDocument.Codeunit.al @@ -69,6 +69,8 @@ codeunit 139629 "Library - E-Document" CountryRegion: Record "Country/Region"; DocumentSendingProfile: Record "Document Sending Profile"; SalesSetup: Record "Sales & Receivables Setup"; + Contact: Record Contact; + ContactBusinessRelation: Record "Contact Business Relation"; WorkflowSetup: Codeunit "Workflow Setup"; WorkflowCode: Code[20]; begin @@ -96,6 +98,18 @@ codeunit 139629 "Library - E-Document" Customer."Document Sending Profile" := DocumentSendingProfile.Code; Customer.Modify(true); + // Set the same e-mail on the customer's contact. Validating the sell-to customer on a sales + // document copies the customer e-mail to "Sell-to E-Mail"; if the linked contact has no + // e-mail (e.g. via the OIOUBL "Sell-to Customer No." validation on NAV_DK) base app raises + // the "contact has no e-mail address" confirm, which fails these tests as Unhandled UI. + ContactBusinessRelation.SetRange("Link to Table", ContactBusinessRelation."Link to Table"::Customer); + ContactBusinessRelation.SetRange("No.", Customer."No."); + if ContactBusinessRelation.FindFirst() then + if Contact.Get(ContactBusinessRelation."Contact No.") then begin + Contact."E-Mail" := 'edoc-test@contoso.com'; + Contact.Modify(); + end; + // Create Item if StandardItem."No." = '' then begin VATPostingSetup.TestField("VAT Prod. Posting Group"); From b074ea0680611fdf2f3b3515f50a642c7db35cae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Jun 2026 07:23:19 +0000 Subject: [PATCH 12/12] Remove trailing whitespace in EDocPurchaseHeader table extension --- .../EDocument/App/src/Extensions/EDocPurchaseHeader.TableExt.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Apps/W1/EDocument/App/src/Extensions/EDocPurchaseHeader.TableExt.al b/src/Apps/W1/EDocument/App/src/Extensions/EDocPurchaseHeader.TableExt.al index a53da43d88..5f3c6ca303 100644 --- a/src/Apps/W1/EDocument/App/src/Extensions/EDocPurchaseHeader.TableExt.al +++ b/src/Apps/W1/EDocument/App/src/Extensions/EDocPurchaseHeader.TableExt.al @@ -50,5 +50,5 @@ tableextension 6169 "E-Doc. Purchase Header" extends "Purchase Header" internal procedure IsLinkedToEDoc(EDocumentToExclude: Record "E-Document"): Boolean begin exit(not IsNullGuid("E-Document Link") and ("E-Document Link" <> EDocumentToExclude.SystemId)); - end; + end; }