Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3e81f6a
add EDocument app workspace
Dec 11, 2024
f4c11e2
add code analyzers settings to code workspace
Dec 12, 2024
26753b9
Merge pull request #1 from GMatuleviciute/dev/pmi/EDocumentWorkspace
GMatuleviciute Dec 12, 2024
67671f4
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
GMatuleviciute Feb 10, 2025
9a3c7f0
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Feb 11, 2025
498825b
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
GMatuleviciute Feb 13, 2025
5254d23
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Feb 13, 2025
5df55fc
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Feb 13, 2025
d8c4999
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
GMatuleviciute Feb 14, 2025
c4fcc52
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Feb 17, 2025
6acfc41
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Mar 19, 2025
1f8a734
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
GMatuleviciute Mar 24, 2025
e9f888d
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
GMatuleviciute Mar 26, 2025
2695882
export reminders/fin charge memos as peppol
AdeleStankeviciute Mar 31, 2025
3b4bcd0
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Apr 3, 2025
189f45a
Merge branch 'microsoft:main' into main
petemchlk Apr 7, 2025
c009127
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Apr 7, 2025
b2c0a05
fixes
AdeleStankeviciute Apr 14, 2025
579bc39
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Apr 17, 2025
88e3368
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Apr 25, 2025
dce554d
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
May 5, 2025
fcf687a
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
May 9, 2025
722739e
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
May 13, 2025
5e1523e
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
May 23, 2025
e3d3b76
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Jun 27, 2025
b707bc1
Merge branch 'main' into dev/asm/export_reminders_finchargememos
Jun 27, 2025
fec1c79
fix test
Jun 27, 2025
f49eead
Merge branch 'main' of https://github.com/GMatuleviciute/ALAppExtensions
Jul 2, 2025
49fcc7b
Merge branch 'main' into dev/asm/export_reminders_finchargememos
Jul 2, 2025
de8636f
Get it to build
Jul 4, 2025
b56e796
Merge branch 'main' into dev/asm/export_reminders_finchargememos
GMatuleviciute Jul 14, 2025
a5debe0
Automated tests fixes
GMatuleviciute Jul 15, 2025
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 @@ -87,6 +87,7 @@ permissionset 6100 "E-Doc. Core - Objects"
codeunit "E-Doc. PO Copilot Matching" = X,
codeunit "E-Doc. Attachment Processor" = X,
codeunit "Service Participant" = X,
codeunit "EDoc PEPPOL Validation" = X,
page "E-Doc. Changes Part" = X,
page "E-Doc. Changes Preview" = X,
page "E-Document Activities" = X,
Expand All @@ -110,6 +111,7 @@ permissionset 6100 "E-Doc. Core - Objects"
page "E-Doc. PO Match Prop. Sub" = X,
page "E-Doc. Order Match Act." = X,
page "Service Participants" = X,
xmlport "Fin. Results - PEPPOL BIS 3.0" = X,
page "E-Doc. Create Purch Order Line" = X,
page "E-Doc. Purchase Draft Subform" = X,
page "E-Doc. Read. Purch. Lines" = X,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ using Microsoft.eServices.EDocument;

pageextension 6140 "E-Doc. Fin. Charge Memo" extends "Finance Charge Memo"
{
layout
{
addlast(General)
{
field("Your Reference"; Rec."Your Reference")
{
ApplicationArea = All;
Caption = 'Your Reference';
ToolTip = 'Specifies the customer''s reference. The contents will be printed on e-document.';
}
}
}

actions
{
addafter("&Issuing")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ using Microsoft.eServices.EDocument;

pageextension 6149 "E-Doc. Issued Fin. Charge Memo" extends "Issued Finance Charge Memo"
{
layout
{
addlast(General)
{
field("Your Reference"; Rec."Your Reference")
{
ApplicationArea = All;
Caption = 'Your Reference';
ToolTip = 'Specifies the customer''s reference. The contents will be printed on e-document.';
}
}
}

actions
{
addafter("&Memo")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ using Microsoft.eServices.EDocument;

pageextension 6148 "E-Doc. Issued Reminder" extends "Issued Reminder"
{
layout
{
addlast(General)
{
field("Your Reference"; Rec."Your Reference")
{
ApplicationArea = All;
Caption = 'Your Reference';
ToolTip = 'Specifies the customer''s reference. The contents will be printed on e-document.';
}
}
}

actions
{
addafter("&Reminder")
Expand Down
13 changes: 13 additions & 0 deletions Apps/W1/EDocument/app/src/Extensions/EDocReminder.PageExt.al
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ using Microsoft.eServices.EDocument;

pageextension 6141 "E-Doc. Reminder" extends Reminder
{
layout
{
addlast(General)
{
field("Your Reference"; Rec."Your Reference")
{
ApplicationArea = All;
Caption = 'Your Reference';
ToolTip = 'Specifies the customer''s reference. The contents will be printed on e-document.';
}
}
}

actions
{
addafter("&Issuing")
Expand Down
26 changes: 26 additions & 0 deletions Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ using Microsoft.Sales.Peppol;
using Microsoft.Purchases.Document;
using Microsoft.Service.History;
using Microsoft.Sales.Document;
using Microsoft.Sales.FinanceCharge;
using Microsoft.Sales.History;
using Microsoft.Sales.Reminder;

codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
{
Expand All @@ -17,8 +19,11 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
SalesCrMemoHeader: Record "Sales Cr.Memo Header";
ServiceInvoiceHeader: Record "Service Invoice Header";
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";
EDocPEPPOLValidation: Codeunit "EDoc PEPPOL Validation";
begin
case SourceDocumentHeader.Number of
Database::"Sales Header":
Expand Down Expand Up @@ -46,6 +51,16 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
SourceDocumentHeader.SetTable(ServiceCrMemoHeader);
PEPPOLServiceValidation.CheckServiceCreditMemo(ServiceCrMemoHeader);
end;
Database::"Reminder Header":
begin
SourceDocumentHeader.SetTable(ReminderHeader);
EDocPEPPOLValidation.CheckReminder(ReminderHeader);
end;
Database::"Finance Charge Memo Header":
begin
SourceDocumentHeader.SetTable(FinChargeMemoHeader);
EDocPEPPOLValidation.CheckFinChargeMemo(FinChargeMemoHeader);
end;
end;
end;

Expand All @@ -60,6 +75,8 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
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"::"Issued Reminder", EDocument."Document Type"::"Issued Finance Charge Memo":
GenerateFinancialResultsXMLFile(SourceDocumentHeader, DocOutStream);
else
EDocErrorHelper.LogSimpleErrorMessage(EDocument, StrSubstNo(DocumentTypeNotSupportedErr, EDocument.FieldCaption("Document Type"), EDocument."Document Type"));
end;
Expand Down Expand Up @@ -109,6 +126,15 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
SalesCrMemoPEPPOLBIS30.Export();
end;

local procedure GenerateFinancialResultsXMLFile(VariantRec: Variant; var OutStr: OutStream)
var
FinResultsPEPPOLBIS30: XMLport "Fin. Results - PEPPOL BIS 3.0";
begin
FinResultsPEPPOLBIS30.Initialize(VariantRec);
FinResultsPEPPOLBIS30.SetDestination(OutStr);
FinResultsPEPPOLBIS30.Export();
end;

[EventSubscriber(ObjectType::Table, Database::"E-Document Service", 'OnAfterValidateEvent', 'Document Format', false, false)]
local procedure OnAfterValidateDocumentFormat(var Rec: Record "E-Document Service"; var xRec: Record "E-Document Service"; CurrFieldNo: Integer)
var
Expand Down
210 changes: 210 additions & 0 deletions Apps/W1/EDocument/app/src/Format/EDocPEPPOLValidation.Codeunit.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.eServices.EDocument.IO.Peppol;

using Microsoft.Finance.Currency;
using Microsoft.Sales.FinanceCharge;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.Address;
using Microsoft.Foundation.Company;
using Microsoft.Sales.Customer;
using Microsoft.Sales.Reminder;

codeunit 6172 "EDoc PEPPOL Validation"
{
/// <summary>
/// Validates if a reminder meets PEPPOL requirements.
/// </summary>
/// <param name="ReminderHeader">Record "Reminder Header" that contains the reminder document to validate.</param>
/// <remarks>
/// Checks both header and line information for PEPPOL compliance including:
/// - Required fields
/// - Currency codes
/// - Country codes
/// - Company/Customer identification
/// - Banking information
/// </remarks>
internal procedure CheckReminder(ReminderHeader: Record "Reminder Header")
var
ReminderLine: Record "Reminder Line";
begin
this.CheckReminderHeader(ReminderHeader);
ReminderLine.SetRange("Reminder No.", ReminderHeader."No.");
if ReminderLine.FindSet() then
repeat
this.CheckReminderLine(ReminderLine);
until ReminderLine.Next() = 0;
end;

/// <summary>
/// Validates if a finance charge memo meets PEPPOL requirements.
/// </summary>
/// <param name="FinChargeMemoHeader">Record "Finance Charge Memo Header" that contains the finance charge memo to validate.</param>
/// <remarks>
/// Checks both header and line information for PEPPOL compliance including:
/// - Required fields
/// - Currency codes
/// - Country codes
/// - Company/Customer identification
/// - Banking information
/// </remarks>
internal procedure CheckFinChargeMemo(FinChargeMemoHeader: Record "Finance Charge Memo Header");
var
FinChargeMemoLine: Record "Finance Charge Memo Line";
begin
this.CheckFinChargeMemoHeader(FinChargeMemoHeader);
FinChargeMemoLine.SetRange("Finance Charge Memo No.", FinChargeMemoHeader."No.");
if FinChargeMemoLine.FindSet() then
repeat
this.CheckFinChargeMemoLine(FinChargeMemoLine);
until FinChargeMemoLine.Next() = 0;
end;

local procedure CheckReminderHeader(ReminderHeader: Record "Reminder Header")
var
CompanyInfo: Record "Company Information";
GLSetup: Record "General Ledger Setup";
Customer: Record Customer;
begin
CompanyInfo.Get();
GLSetup.Get();

this.CheckCurrencyCode(ReminderHeader."Currency Code");

CompanyInfo.TestField(Name);
CompanyInfo.TestField(Address);
CompanyInfo.TestField(City);
CompanyInfo.TestField("Post Code");

CompanyInfo.TestField("Country/Region Code");
this.CheckCountryRegionCode(CompanyInfo."Country/Region Code");

if CompanyInfo.GLN + CompanyInfo."VAT Registration No." = '' then
Error(this.MissingCompInfGLNOrVATRegNoErr, CompanyInfo.TableCaption());
ReminderHeader.TestField(Name);
ReminderHeader.TestField(Address);
ReminderHeader.TestField(City);
ReminderHeader.TestField("Post Code");
ReminderHeader.TestField("Country/Region Code");
this.CheckCountryRegionCode(ReminderHeader."Country/Region Code");

if Customer.Get(ReminderHeader."Customer No.")
then
if (Customer.GLN + Customer."VAT Registration No.") = '' then
Error(MissingCustGLNOrVATRegNoErr, Customer."No.");

ReminderHeader.TestField("Your Reference");
ReminderHeader.TestField("Due Date");

if CompanyInfo.IBAN = '' then
CompanyInfo.TestField("Bank Account No.");
CompanyInfo.TestField("Bank Branch No.");
CompanyInfo.TestField("SWIFT Code");
end;

local procedure CheckReminderLine(ReminderLine: Record "Reminder Line")
begin
if (ReminderLine.Type <> ReminderLine.Type::" ") and (ReminderLine.Description = '') then
Error(this.MissingDescriptionErr);
end;

local procedure CheckFinChargeMemoHeader(FinChargeMemoHeader: Record "Finance Charge Memo Header")
var
CompanyInfo: Record "Company Information";
GLSetup: Record "General Ledger Setup";
Customer: Record Customer;
begin
CompanyInfo.Get();
GLSetup.Get();

this.CheckCurrencyCode(FinChargeMemoHeader."Currency Code");

CompanyInfo.TestField(Name);
CompanyInfo.TestField(Address);
CompanyInfo.TestField(City);
CompanyInfo.TestField("Post Code");

CompanyInfo.TestField("Country/Region Code");
this.CheckCountryRegionCode(CompanyInfo."Country/Region Code");

if CompanyInfo.GLN + CompanyInfo."VAT Registration No." = '' then
Error(this.MissingCompInfGLNOrVATRegNoErr, CompanyInfo.TableCaption());
FinChargeMemoHeader.TestField(Name);
FinChargeMemoHeader.TestField(Address);
FinChargeMemoHeader.TestField(City);
FinChargeMemoHeader.TestField("Post Code");
FinChargeMemoHeader.TestField("Country/Region Code");
this.CheckCountryRegionCode(FinChargeMemoHeader."Country/Region Code");

if Customer.Get(FinChargeMemoHeader."Customer No.")
then
if (Customer.GLN + Customer."VAT Registration No.") = '' then
Error(this.MissingCustGLNOrVATRegNoErr, Customer."No.");

FinChargeMemoHeader.TestField("Your Reference");
FinChargeMemoHeader.TestField("Due Date");

if CompanyInfo.IBAN = '' then
CompanyInfo.TestField("Bank Account No.");
CompanyInfo.TestField("Bank Branch No.");
CompanyInfo.TestField("SWIFT Code");
end;

local procedure CheckFinChargeMemoLine(FinChargeMemoLine: Record "Finance Charge Memo Line")
begin
if (FinChargeMemoLine.Type <> FinChargeMemoLine.Type::" ") and (FinChargeMemoLine.Description = '') then
Error(this.MissingDescriptionErr);
end;

local procedure CheckCurrencyCode(CurrencyCode: Code[10])
var
GLSetup: Record "General Ledger Setup";
Currency: Record Currency;
MaxCurrencyCodeLength: Integer;
begin
MaxCurrencyCodeLength := 3;

if CurrencyCode = '' then begin
GLSetup.Get();
GLSetup.TestField("LCY Code");
CurrencyCode := GLSetup."LCY Code";
end;

if not Currency.Get(CurrencyCode) then begin
if StrLen(CurrencyCode) <> MaxCurrencyCodeLength then
GLSetup.FieldError("LCY Code", StrSubstNo(WrongLengthErr, MaxCurrencyCodeLength));
exit;
end;

if StrLen(Currency.Code) <> MaxCurrencyCodeLength then
Currency.FieldError(Code, StrSubstNo(WrongLengthErr, MaxCurrencyCodeLength));
end;

local procedure CheckCountryRegionCode(CountryRegionCode: Code[10])
var
CountryRegion: Record "Country/Region";
CompanyInfo: Record "Company Information";
MaxCountryCodeLength: Integer;
begin
MaxCountryCodeLength := 2;

if CountryRegionCode = '' then begin
CompanyInfo.Get();
CompanyInfo.TestField("Country/Region Code");
CountryRegionCode := CompanyInfo."Country/Region Code";
end;

CountryRegion.Get(CountryRegionCode);
CountryRegion.TestField("ISO Code");
if StrLen(CountryRegion."ISO Code") <> MaxCountryCodeLength then
CountryRegion.FieldError("ISO Code", StrSubstNo(WrongLengthErr, MaxCountryCodeLength));
end;

var
WrongLengthErr: Label 'should be %1 characters long', Comment = '%1 - number of characters';
MissingDescriptionErr: Label 'Description field is empty. This field must be filled if you want to send the posted document as an electronic document.';
MissingCustGLNOrVATRegNoErr: Label 'You must specify either GLN or VAT Registration No. for Customer %1.', Comment = '%1 - Customer No.';
MissingCompInfGLNOrVATRegNoErr: Label 'You must specify either GLN or VAT Registration No. in %1.', Comment = '%1 - Company Information';
}
Loading
Loading