Skip to content

Commit b0895f4

Browse files
Groenbech96AndriusAndruleviciusGMatuleviciuteMagnus Hartvig Grønbech
authored
PEPPOL 3.0 1P App (#5126)
New first party app for using PEPPOL to export sales and service documents. This only adds the app, next steps would be integration with existing steps in Base-app. # Architecture Design Pattern: Strategy via Enum + Interfaces The core design uses an extensible enum (PEPPOL 3.0 Format) that implements 11 specialized interfaces. This allows: Polymorphic behavior based on document type (Sales vs Service) Clean separation of concerns across different functional areas Extensibility for future document types or formats ┌─────────────────────────────────────────────────────────────────────┐ │ PEPPOL 3.0 Format (Enum) │ │ ┌─────────────────────┐ ┌─────────────────────────────────┐ │ │ │ PEPPOL 3.0 - Sales │ │ PEPPOL 3.0 - Service │ │ │ └─────────────────────┘ └─────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌─────────────────────────────────┐ │ │ │ Sales Validation │ │ Service Validation │ │ │ │ Sales Export Mgmt │ │ Services Export Mgmt │ │ │ └─────────────────────┘ └─────────────────────────────────┘ │ │ │ │ Default Implementation (shared): PEPPOL30 Management │ │ - Attachment Handler, Delivery Info, Document Info, Line Info │ │ - Monetary Info, Party Info, Payment Info, Tax Info │ │ - Posted Document Iterator │ └─────────────────────────────────────────────────────────────────────┘<html> ## Interfaces <img width="909" height="507" alt="image" src="https://github.com/user-attachments/assets/15d1c825-a5a1-4e25-89a1-431007c7d9c1" /> ## Folder Structure App/ ├── app.json # App manifest (ID range: 37200-37300) └── src/ ├── Management/ # Core shared logic │ ├── Codeunits/ │ │ ├── PEPPOL30Management.Codeunit.al # Public facade (implements 9 interfaces) │ │ ├── PEPPOL30ManagementImpl.Codeunit.al # Internal implementation │ │ ├── PEPPOL30SalesValidation.Codeunit.al # Sales validation (implements PEPPOL30 Validation) │ │ ├── PEPPOL30ServiceValidation.Codeunit.al # Service validation (implements PEPPOL30 Validation) │ │ ├── PEPPOL30ValidationImpl.Codeunit.al # Shared validation logic (Internal) │ │ ├── PEPPOL30Initialize.Codeunit.al # Electronic Document Format registration │ │ └── PEPPOL30Install.Codeunit.al # Install codeunit │ ├── Enums/ │ │ └── PEPPOL30Format.Enum.al # Central polymorphic enum │ └── Interfaces/ # 11 interface definitions │ ├── Sales/ # Sales-specific functionality │ ├── Codeunits/ │ │ ├── ExpSalesInvPEPPOL30.Codeunit.al # Sales Invoice export entry point │ │ ├── ExpSalesCrMPEPPOL30.Codeunit.al # Sales Credit Memo export entry point │ │ └── PEPPOL30SalesExportMgmt.Codeunit.al # Sales export management (implements PEPPOL30 Export Management) │ └── XmlPorts/ │ ├── SalesInvoicePEPPOL30.XmlPort.al # Invoice UBL XML generation │ └── SalesCrMemoPEPPOL30.XmlPort.al # Credit Memo UBL XML generation │ ├── Services/ # Service-specific functionality │ └── Codeunits/ │ ├── ExpServInvPEPPOL30.Codeunit.al # Service Invoice export entry point │ ├── ExpServCrMPEPPOL30.Codeunit.al # Service Credit Memo export entry point │ └── PEPPOL30ServicesExportMgmt.Codeunit.al # Service export management (implements PEPPOL30 Export Management) │ └── Setup/ # Configuration ├── CompanyInformation.TableExt.al # Adds PEPPOL format selection fields └── CompanyInformation.PageExt.al # UI for format selection Test/ ├── app.json └── src/ └── PEPPOL30ManagementTests.Codeunit.al # Comprehensive test coverage ## Key Components 1. Format Selection (Company Information) Two new fields allow configuration of PEPPOL format per document type: - PEPPOL 3.0 Sales Format - Format for Sales Invoices and Credit Memos - PEPPOL 3.0 Service Format - Format for Service Invoices and Credit Memos **This could be changed to its own setup page.** ## How export works Export Codeunit (e.g., Exp. Sales Inv. PEPPOL30) │ ├── 1. Get PEPPOL30 Validation interface from CompanyInfo format │ └── Call ValidateInvoice() / ValidateCreditMemo() │ ├── 2. Call GenerateXMLFile() │ └── Initialize XMLPort with format enum │ └── 3. XMLPort uses interfaces for all data: ├── Document Info Provider → GetGeneralInfoBIS() ├── Party Info Provider → GetAccountingSupplierPartyInfo() ├── Tax Info Provider → GetTaxTotalInfo() ├── Export Management → FindNextRec(), FindNextLineRec() └── ... (other providers) This Pull request related with microsoft/BusinessCentralApps#1595 Fixes [AB#563709](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/563709) --------- Co-authored-by: Andrius Andrulevičius <andrius.andrulevicius@companial.com> Co-authored-by: Andrius Andrulevičius <30231314+AndriusAndrulevicius@users.noreply.github.com> Co-authored-by: Grasiele Matuleviciute <131970463+GMatuleviciute@users.noreply.github.com> Co-authored-by: Grasiele Matuleviciute <grasiele.matuleviciute@companial.com> Co-authored-by: Magnus Hartvig Grønbech <magnushar@microsoft.com>
1 parent 24fb48d commit b0895f4

38 files changed

Lines changed: 13658 additions & 0 deletions
6.92 KB
Loading

src/Apps/W1/PEPPOL/App/app.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"id": "e1966889-b5fb-4fda-a84c-ea71b590e1a9",
3+
"name": "PEPPOL",
4+
"publisher": "Microsoft",
5+
"description": "Export sales invoices and credit memos in PEPPOL BIS 3.0 format for electronic invoicing compliance across Europe.",
6+
"brief": "PEPPOL BIS 3.0 electronic invoicing for sales documents.",
7+
"version": "28.0.0.0",
8+
"logo": "ExtensionLogo.png",
9+
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
10+
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
11+
"help": "https://go.microsoft.com/fwlink/?linkid=2104024",
12+
"url": "https://go.microsoft.com/fwlink/?LinkId=724011",
13+
"contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603",
14+
"propagateDependencies": true,
15+
"dependencies": [],
16+
"internalsVisibleTo": [],
17+
"platform": "28.0.0.0",
18+
"idRanges": [
19+
{
20+
"from": 37200,
21+
"to": 37300
22+
}
23+
],
24+
"application": "28.0.0.0",
25+
"features": [
26+
"NoImplicitWith",
27+
"TranslationFile"
28+
],
29+
"resourceExposurePolicy": {
30+
"allowDebugging": true,
31+
"allowDownloadingSource": true,
32+
"includeSourceInSymbolFile": true
33+
},
34+
"target": "Cloud"
35+
}

src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30.Codeunit.al

Lines changed: 1061 additions & 0 deletions
Large diffs are not rendered by default.

src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Common.Codeunit.al

Lines changed: 378 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Peppol;
6+
7+
enum 37200 "PEPPOL 3.0 Format" implements "PEPPOL Attachment Provider",
8+
"PEPPOL Delivery Info Provider",
9+
"PEPPOL Document Info Provider",
10+
"PEPPOL Line Info Provider",
11+
"PEPPOL Monetary Info Provider",
12+
"PEPPOL Party Info Provider",
13+
"PEPPOL Payment Info Provider",
14+
"PEPPOL Posted Document Iterator",
15+
"PEPPOL Tax Info Provider",
16+
"PEPPOL30 Validation"
17+
{
18+
DefaultImplementation = "PEPPOL Attachment Provider" = "PEPPOL30",
19+
"PEPPOL Delivery Info Provider" = "PEPPOL30",
20+
"PEPPOL Document Info Provider" = "PEPPOL30",
21+
"PEPPOL Line Info Provider" = "PEPPOL30",
22+
"PEPPOL Monetary Info Provider" = "PEPPOL30",
23+
"PEPPOL Party Info Provider" = "PEPPOL30",
24+
"PEPPOL Payment Info Provider" = "PEPPOL30",
25+
"PEPPOL Tax Info Provider" = "PEPPOL30";
26+
Extensible = true;
27+
28+
value(0; "PEPPOL 3.0 - Sales")
29+
{
30+
Caption = 'PEPPOL 3.0 - Sales';
31+
Implementation = "PEPPOL30 Validation" = "PEPPOL30 Sales Validation",
32+
"PEPPOL Posted Document Iterator" = "PEPPOL30 Sales Iterator";
33+
}
34+
value(1; "PEPPOL 3.0 - Service")
35+
{
36+
Caption = 'PEPPOL 3.0 - Service';
37+
Implementation = "PEPPOL30 Validation" = "PEPPOL30 Service Validation",
38+
"PEPPOL Posted Document Iterator" = "PEPPOL30 Services Iterator";
39+
}
40+
}

src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al

Lines changed: 1340 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Peppol;
6+
7+
using Microsoft.Foundation.Company;
8+
9+
codeunit 37217 "PEPPOL 3.0 Subscribers"
10+
{
11+
InherentEntitlements = X;
12+
InherentPermissions = X;
13+
Access = Internal;
14+
15+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Company-Initialize", OnAfterInitElectronicFormats, '', false, false)]
16+
local procedure CompanyInitialize_OnAfterInitElectronicFormats()
17+
var
18+
PEPPOL30Initialize: Codeunit "PEPPOL30 Initialize";
19+
begin
20+
PEPPOL30Initialize.CreateElectronicDocumentFormats();
21+
end;
22+
23+
24+
25+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Peppol;
6+
7+
using Microsoft.Foundation.Reporting;
8+
9+
codeunit 37204 "PEPPOL30 Initialize"
10+
{
11+
Subtype = Install;
12+
InherentEntitlements = X;
13+
InherentPermissions = X;
14+
Access = Internal;
15+
16+
internal procedure CreateElectronicDocumentFormats()
17+
var
18+
ElectronicDocumentFormat: Record "Electronic Document Format";
19+
PEPPOLBIS3_ElectronicFormatDescriptionTxt: Label 'PEPPOL BIS3 Format (Pan-European Public Procurement Online)';
20+
PEPPOLBIS3_ElectronicFormatTxt: Label 'PEPPOL30', Locked = true;
21+
begin
22+
ElectronicDocumentFormat.InsertElectronicFormat(
23+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
24+
Codeunit::"Exp. Sales Inv. PEPPOL30", 0, ElectronicDocumentFormat.Usage::"Sales Invoice".AsInteger());
25+
26+
ElectronicDocumentFormat.InsertElectronicFormat(
27+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
28+
Codeunit::"Exp. Sales CrM. PEPPOL30", 0, ElectronicDocumentFormat.Usage::"Sales Credit Memo".AsInteger());
29+
30+
ElectronicDocumentFormat.InsertElectronicFormat(
31+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
32+
Codeunit::"PEPPOL30 Sales Validation", 0, ElectronicDocumentFormat.Usage::"Sales Validation".AsInteger());
33+
34+
ElectronicDocumentFormat.InsertElectronicFormat(
35+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
36+
Codeunit::"Exp. Serv.Inv. PEPPOL30", 0, ElectronicDocumentFormat.Usage::"Service Invoice".AsInteger());
37+
38+
ElectronicDocumentFormat.InsertElectronicFormat(
39+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
40+
Codeunit::"Exp. Serv.CrM. PEPPOL30", 0, ElectronicDocumentFormat.Usage::"Service Credit Memo".AsInteger());
41+
42+
ElectronicDocumentFormat.InsertElectronicFormat(
43+
PEPPOLBIS3_ElectronicFormatTxt, PEPPOLBIS3_ElectronicFormatDescriptionTxt,
44+
Codeunit::"PEPPOL30 Service Validation", 0, ElectronicDocumentFormat.Usage::"Service Validation".AsInteger());
45+
end;
46+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Peppol;
6+
using System.Upgrade;
7+
8+
codeunit 37215 "PEPPOL30 Upgrade"
9+
{
10+
Subtype = Upgrade;
11+
InherentEntitlements = X;
12+
InherentPermissions = X;
13+
Access = Internal;
14+
15+
16+
trigger OnUpgradePerCompany()
17+
var
18+
UpgradeTag: Codeunit "Upgrade Tag";
19+
PEPPOL30Initialize: Codeunit "PEPPOL30 Initialize";
20+
begin
21+
if UpgradeTag.HasUpgradeTag(InitialUpgradeTag()) then
22+
exit;
23+
24+
PEPPOL30Initialize.CreateElectronicDocumentFormats();
25+
UpgradeTag.SetUpgradeTag(InitialUpgradeTag());
26+
end;
27+
28+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerCompanyUpgradeTags, '', false, false)]
29+
local procedure OnGetPerCompanyUpgradeTags(var PerCompanyUpgradeTags: List of [Code[250]])
30+
begin
31+
PerCompanyUpgradeTags.Add(InitialUpgradeTag());
32+
end;
33+
34+
local procedure InitialUpgradeTag(): Text[250]
35+
begin
36+
exit('MS-121225-PEPPOL1P-APP-INSTALL');
37+
end;
38+
39+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Peppol;
6+
7+
/// <summary>
8+
/// Interface for validating sales documents against PEPPOL 3.0 compliance requirements.
9+
/// Provides comprehensive validation methods for sales headers, lines, and posted documents
10+
/// to ensure they meet PEPPOL electronic document standards and business rules.
11+
/// </summary>
12+
interface "PEPPOL30 Validation"
13+
{
14+
/// <summary>
15+
/// Validates a sales document for PEPPOL compliance.
16+
/// Checks required fields, currency codes, addresses, VAT registration numbers, and other PEPPOL requirements.
17+
/// </summary>
18+
procedure ValidateDocument(RecordVariant: Variant)
19+
20+
/// <summary>
21+
/// Validates all sales document lines for PEPPOL compliance.
22+
/// Checks line-specific requirements for electronic document transmission.
23+
/// </summary>
24+
procedure ValidateDocumentLines(RecordVariant: Variant)
25+
26+
/// <summary>
27+
/// Validates an individual sales document line for PEPPOL compliance.
28+
/// Checks unit of measure codes, descriptions, tax categories, and other line-specific requirements.
29+
/// </summary>
30+
procedure ValidateDocumentLine(RecordVariant: Variant)
31+
32+
/// <summary>
33+
/// Checks if a line has the required type and description for PEPPOL electronic documents.
34+
/// Validates that the line type and description meet PEPPOL requirements.
35+
/// </summary>
36+
procedure ValidateLineTypeAndDescription(RecordVariant: Variant): Boolean
37+
38+
/// <summary>
39+
/// Validates a posted sales credit memo for PEPPOL compliance.
40+
/// Performs validation checks on the credit memo header and related data.
41+
/// </summary>
42+
procedure ValidatePostedDocument(RecordVariant: Variant)
43+
44+
}

0 commit comments

Comments
 (0)