Skip to content

Commit 941e9cb

Browse files
CopilotGroenbech96
andauthored
Add missing BE Service format for PEPPOL export (#6312)
PR #6268 implements BE-specific PEPPOL export (Enterprise No. formatting/validation) but only for Sales documents. Service documents would fall through to W1 implementation, missing Belgium Enterprise No. support entirely. ## Changes - **Added** `PEPPOL30 BE Service Validation` codeunit (37312) - delegates to BE Sales validation via service→sales conversion (mirrors W1 pattern) - **Extended** `PEPPOL 3.0 Format BE` enum with `"PEPPOL 3.0 - BE Service"` value (37311) implementing BE Party Info Provider + BE Service Validation - **Updated** subscriber to set both `"PEPPOL 3.0 Sales Format"` and `"PEPPOL 3.0 Service Format"` on setup insert ## Format Selection Flow ```al // Export codeunits read setup and dispatch to format implementation Exp. Sales Inv. PEPPOL30 → Setup."PEPPOL 3.0 Sales Format" → PEPPOL30 BE → FormatEnterpriseNo ✓ Exp. Serv.Inv. PEPPOL30 → Setup."PEPPOL 3.0 Service Format" → PEPPOL30 BE → FormatEnterpriseNo ✓ (was: PEPPOL30 W1 → No Enterprise No.) ``` Both document types now apply BE-specific: - `FormatEnterpriseNo`: Prepends ISO code to numeric-only enterprise numbers - Validation: Accepts GLN **OR** VAT Reg No. **OR** Enterprise No. (W1 only accepts first two) <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Pull Request: #6268 > > Please analyse how/if this app correctly overrides behaviour of the W1 app when user executes the export of sales or services docs. > </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Groenbech96 <17690329+Groenbech96@users.noreply.github.com>
1 parent dd6778a commit 941e9cb

3 files changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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.BE;
6+
7+
using Microsoft.Peppol;
8+
using Microsoft.Sales.Document;
9+
using Microsoft.Service.Document;
10+
using Microsoft.Service.History;
11+
using System.Reflection;
12+
13+
codeunit 37312 "PEPPOL30 BE Service Validation" implements "PEPPOL30 Validation"
14+
{
15+
TableNo = "Service Header";
16+
InherentEntitlements = X;
17+
InherentPermissions = X;
18+
19+
var
20+
PEPPOL30BESalesValidation: Codeunit "PEPPOL30 BE Sales Validation";
21+
22+
trigger OnRun()
23+
begin
24+
ValidateDocument(Rec);
25+
ValidateDocumentLines(Rec);
26+
end;
27+
28+
procedure ValidateDocument(RecordVariant: Variant)
29+
var
30+
ServiceHeader: Record "Service Header";
31+
SalesHeader: Record "Sales Header";
32+
PEPPOL30: Codeunit "PEPPOL30";
33+
begin
34+
ServiceHeader := RecordVariant;
35+
PEPPOL30.TransferHeaderToSalesHeader(ServiceHeader, SalesHeader);
36+
SalesHeader."Shipment Date" := SalesHeader."Posting Date";
37+
PEPPOL30BESalesValidation.ValidateDocument(SalesHeader);
38+
end;
39+
40+
procedure ValidateDocumentLines(RecordVariant: Variant)
41+
var
42+
ServiceHeader: Record "Service Header";
43+
ServiceLine: Record "Service Line";
44+
begin
45+
ServiceHeader := RecordVariant;
46+
ServiceLine.SetRange("Document Type", ServiceHeader."Document Type");
47+
ServiceLine.SetRange("Document No.", ServiceHeader."No.");
48+
if ServiceLine.FindSet() then
49+
repeat
50+
ValidateDocumentLine(ServiceLine);
51+
until ServiceLine.Next() = 0;
52+
end;
53+
54+
procedure ValidateDocumentLine(RecordVariant: Variant)
55+
var
56+
ServiceLine: Record "Service Line";
57+
SalesLine: Record "Sales Line";
58+
PEPPOL30: Codeunit "PEPPOL30";
59+
begin
60+
ServiceLine := RecordVariant;
61+
PEPPOL30.TransferLineToSalesLine(ServiceLine, SalesLine);
62+
PEPPOL30BESalesValidation.ValidateDocumentLine(SalesLine);
63+
end;
64+
65+
procedure ValidateLineTypeAndDescription(RecordVariant: Variant): Boolean
66+
var
67+
ServiceLine: Record "Service Line";
68+
SalesLine: Record "Sales Line";
69+
PEPPOL30: Codeunit "PEPPOL30";
70+
begin
71+
ServiceLine := RecordVariant;
72+
PEPPOL30.TransferLineToSalesLine(ServiceLine, SalesLine);
73+
exit(PEPPOL30BESalesValidation.ValidateLineTypeAndDescription(SalesLine));
74+
end;
75+
76+
procedure ValidatePostedDocument(RecordVariant: Variant)
77+
var
78+
DataTypeMgt: Codeunit "Data Type Management";
79+
RecordRef: RecordRef;
80+
UnsupportedDocumentErr: Label 'The posted service document type is not supported for PEPPOL 3.0 validation.';
81+
begin
82+
if not DataTypeMgt.GetRecordRef(RecordVariant, RecordRef) then
83+
exit;
84+
85+
case RecordRef.Number() of
86+
Database::"Service Invoice Header":
87+
CheckServiceInvoice(RecordVariant);
88+
Database::"Service Cr.Memo Header":
89+
CheckServiceCreditMemo(RecordVariant);
90+
else
91+
Error(UnsupportedDocumentErr);
92+
end;
93+
end;
94+
95+
local procedure CheckServiceInvoice(ServiceInvoiceHeader: Record "Service Invoice Header")
96+
var
97+
SalesHeader: Record "Sales Header";
98+
SalesLine: Record "Sales Line";
99+
ServiceInvoiceLine: Record "Service Invoice Line";
100+
PEPPOL30: Codeunit "PEPPOL30";
101+
begin
102+
PEPPOL30.TransferHeaderToSalesHeader(ServiceInvoiceHeader, SalesHeader);
103+
SalesHeader."Document Type" := SalesHeader."Document Type"::Invoice;
104+
SalesHeader."Shipment Date" := SalesHeader."Posting Date";
105+
PEPPOL30BESalesValidation.ValidateDocument(SalesHeader);
106+
ServiceInvoiceLine.SetRange("Document No.", ServiceInvoiceHeader."No.");
107+
if ServiceInvoiceLine.FindSet() then
108+
repeat
109+
PEPPOL30.TransferLineToSalesLine(ServiceInvoiceLine, SalesLine);
110+
SalesLine."Document Type" := SalesLine."Document Type"::Invoice;
111+
PEPPOL30BESalesValidation.ValidateDocumentLine(SalesLine);
112+
until ServiceInvoiceLine.Next() = 0;
113+
end;
114+
115+
local procedure CheckServiceCreditMemo(ServiceCrMemoHeader: Record "Service Cr.Memo Header")
116+
var
117+
SalesHeader: Record "Sales Header";
118+
SalesLine: Record "Sales Line";
119+
ServiceCrMemoLine: Record "Service Cr.Memo Line";
120+
PEPPOL30: Codeunit "PEPPOL30";
121+
begin
122+
PEPPOL30.TransferHeaderToSalesHeader(ServiceCrMemoHeader, SalesHeader);
123+
SalesHeader."Document Type" := SalesHeader."Document Type"::"Credit Memo";
124+
SalesHeader."Shipment Date" := SalesHeader."Posting Date";
125+
PEPPOL30BESalesValidation.ValidateDocument(SalesHeader);
126+
ServiceCrMemoLine.SetRange("Document No.", ServiceCrMemoHeader."No.");
127+
if ServiceCrMemoLine.FindSet() then
128+
repeat
129+
PEPPOL30.TransferLineToSalesLine(ServiceCrMemoLine, SalesLine);
130+
SalesLine."Document Type" := SalesLine."Document Type"::"Credit Memo";
131+
PEPPOL30BESalesValidation.ValidateDocumentLine(SalesLine);
132+
until ServiceCrMemoLine.Next() = 0;
133+
end;
134+
}

src/Apps/BE/Peppol/App/src/PEPPOL30BESubscribers.Codeunit.al

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ codeunit 37314 "PEPPOL30 BE Subscribers"
1919
exit;
2020

2121
Rec."PEPPOL 3.0 Sales Format" := Rec."PEPPOL 3.0 Sales Format"::"PEPPOL 3.0 - BE Sales";
22+
Rec."PEPPOL 3.0 Service Format" := Rec."PEPPOL 3.0 Service Format"::"PEPPOL 3.0 - BE Service";
2223
Rec.Modify();
2324
end;
2425
}

src/Apps/BE/Peppol/App/src/PEPPOL30FormatBE.EnumExt.al

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,11 @@ enumextension 37310 "PEPPOL 3.0 Format BE" extends "PEPPOL 3.0 Format"
1515
"PEPPOL30 Validation" = "PEPPOL30 BE Sales Validation",
1616
"PEPPOL Posted Document Iterator" = "PEPPOL30 Sales Iterator";
1717
}
18+
value(37311; "PEPPOL 3.0 - BE Service")
19+
{
20+
Caption = 'PEPPOL 3.0 - BE Service';
21+
Implementation = "PEPPOL Party Info Provider" = "PEPPOL30 BE",
22+
"PEPPOL30 Validation" = "PEPPOL30 BE Service Validation",
23+
"PEPPOL Posted Document Iterator" = "PEPPOL30 Services Iterator";
24+
}
1825
}

0 commit comments

Comments
 (0)