Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 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
715cedd
add checks for zero Vat and standard vat peppol codes
Feb 18, 2025
be5bde5
create test codeunit
Feb 24, 2025
e577a16
create category zero tests
Feb 24, 2025
202095c
add outside tax scope test
Feb 25, 2025
0e99028
add standard (S) Peppol tax category tests
Feb 25, 2025
2728b77
add subscriber to handle zero amoutn and vat amount sales documents i…
Mar 5, 2025
1e9af36
fix subscriber name
Mar 5, 2025
9330755
Update Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest…
GMatuleviciute Mar 6, 2025
562511f
git meMerge branch 'main' into dev/asm/ExportRemindersFinChargeMemos
GMatuleviciute Jul 21, 2025
bdde554
Delete Apps/W1/EDocument/edocument_workspace.code-workspace
GMatuleviciute Jul 21, 2025
84f3894
Merge branch 'main' of https://github.com/microsoft/ALAppExtensions i…
Aug 11, 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
10 changes: 10 additions & 0 deletions Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ using Microsoft.Sales.FinanceCharge;
using Microsoft.Sales.Reminder;
using Microsoft.EServices.EDocument.Format;
using Microsoft.Inventory.Transfer;
using Microsoft.Finance.VAT.Calculation;

codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
{
Expand Down Expand Up @@ -197,6 +198,15 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document"
begin
end;

[EventSubscriber(ObjectType::Table, Database::"VAT Amount Line", OnInsertLine, '', false, false)]
local procedure SetInsertNotToSkipZeroVatAmounts(var VATAmountLine: Record "VAT Amount Line"; var SkipZeroVatAmounts: Boolean)
var
PEPPOLManagement: Codeunit "PEPPOL Management";
begin
if PEPPOLManagement.IsZeroVatCategory(VATAmountLine."Tax Category") then
SkipZeroVatAmounts := false;
end;

var
ImportPeppol: Codeunit "EDoc Import PEPPOL BIS 3.0";
DocumentTypeNotSupportedErr: Label '%1 %2 is not supported by PEPPOL BIS30 Format', Comment = '%1 - Document Type caption, %2 - Document Type';
Expand Down
37 changes: 25 additions & 12 deletions Apps/W1/EDocument/test/src/LibraryEDocument.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ codeunit 139629 "Library - E-Document"

procedure SetupStandardSalesScenario(var Customer: Record Customer; var EDocService: Record "E-Document Service")
var
CountryRegion: Record "Country/Region";
DocumentSendingProfile: Record "Document Sending Profile";
SalesSetup: Record "Sales & Receivables Setup";
WorkflowSetup: Codeunit "Workflow Setup";
Expand All @@ -71,17 +70,7 @@ codeunit 139629 "Library - E-Document"
DocumentSendingProfile.Modify();

// Create Customer for sales scenario
LibrarySales.CreateCustomer(Customer);
LibraryERM.FindCountryRegion(CountryRegion);
Customer.Validate(Address, LibraryUtility.GenerateRandomCode(Customer.FieldNo(Address), DATABASE::Customer));
Customer.Validate("Country/Region Code", CountryRegion.Code);
Customer.Validate(City, LibraryUtility.GenerateRandomCode(Customer.FieldNo(City), DATABASE::Customer));
Customer.Validate("Post Code", LibraryUtility.GenerateRandomCode(Customer.FieldNo("Post Code"), DATABASE::Customer));
Customer.Validate("VAT Bus. Posting Group", VATPostingSetup."VAT Bus. Posting Group");
Customer."VAT Registration No." := LibraryERM.GenerateVATRegistrationNo(CountryRegion.Code);
Customer.Validate(GLN, '1234567890128');
Customer."Document Sending Profile" := DocumentSendingProfile.Code;
Customer.Modify(true);
CreateCustomerForSalesScenario(Customer, DocumentSendingProfile.Code);

// Create Item
if StandardItem."No." = '' then begin
Expand All @@ -103,6 +92,13 @@ codeunit 139629 "Library - E-Document"
Item.Get(StandardItem."No.");
end;

procedure GetVatPostingSetup(): Record "VAT Posting Setup"
begin
if VATPostingSetup."VAT Bus. Posting Group" = '' then
SetupStandardVAT();
exit(VATPostingSetup);
end;

#if not CLEAN26
#pragma warning disable AL0432
[Obsolete('Use SetupStandardPurchaseScenario(var Vendor: Record Vendor; var EDocService: Record "E-Document Service"; EDocDocumentFormat: Enum "E-Document Format"; EDocIntegration: Enum "Service Integration") instead', '26.0')]
Expand Down Expand Up @@ -738,6 +734,23 @@ codeunit 139629 "Library - E-Document"
exit(EntityName);
end;

procedure CreateCustomerForSalesScenario(var Customer: Record Customer; DocumentSendingProfileCode: Code[20])
var
CountryRegion: Record "Country/Region";
begin
LibrarySales.CreateCustomer(Customer);
LibraryERM.FindCountryRegion(CountryRegion);
Customer.Validate(Address, LibraryUtility.GenerateRandomCode(Customer.FieldNo(Address), DATABASE::Customer));
Customer.Validate("Country/Region Code", CountryRegion.Code);
Customer.Validate(City, LibraryUtility.GenerateRandomCode(Customer.FieldNo(City), DATABASE::Customer));
Customer.Validate("Post Code", LibraryUtility.GenerateRandomCode(Customer.FieldNo("Post Code"), DATABASE::Customer));
Customer.Validate("VAT Bus. Posting Group", VATPostingSetup."VAT Bus. Posting Group");
Customer."VAT Registration No." := LibraryERM.GenerateVATRegistrationNo(CountryRegion.Code);
Customer.Validate(GLN, '1234567890128');
Customer."Document Sending Profile" := DocumentSendingProfileCode;
Customer.Modify(true);
end;

#if not CLEAN26
#pragma warning disable AL0432
[Obsolete('Use CreateService(EDocDocumentFormat: Enum "E-Document Format"; EDocIntegration: Enum "Service Integration") instead', '26.0')]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
codeunit 139502 "E-Doc. PEPPOL Validation Test"
{
Subtype = Test;

var
Customer: Record Customer;
EDocumentService: Record "E-Document Service";
VATPostingSetup: Record "VAT Posting Setup";
Assert: Codeunit Assert;
LibraryVariableStorage: Codeunit "Library - Variable Storage";
LibraryEDoc: Codeunit "Library - E-Document";
LibrarySales: Codeunit "Library - Sales";
EDocImplState: Codeunit "E-Doc. Impl. State";
LibraryLowerPermission: Codeunit "Library - Lower Permissions";
Any: Codeunit Any;
IsInitialized: Boolean;

[Test]
procedure PostInvoiceWithZeroVatAmountCategoryAndNonZeroVat()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Post invoice with zero VAT amount category and non-zero VAT %
Initialize();

// [GIVEN] VAT Posting Setup with zero VAT amount category and non-zero VAT %
SetVatPostingSetupTaxCategory('Z', 10);

// [WHEN] Posting invoice
asserterror SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer);

// [THEN] Error is raised
Assert.ExpectedError('VAT % must be 0 for tax category code Z');
end;

[Test]
procedure PostInvoiceWithZeroVatAmountCategoryAndZeroVat()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
EDocument: Record "E-Document";
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Post invoice with zero VAT amount category and zero VAT %
Initialize();

// [GIVEN] VAT Posting Setup with zero VAT amount category and zero VAT %
SetVatPostingSetupTaxCategory('Z', 0);

// [WHEN] Posting invoice
SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer);

// [THEN] Invoice is posted successfully
Assert.RecordIsNotEmpty(SalesInvoiceHeader);
// [THEN] E-Document is created
EDocument.SetRange("Document Record ID", SalesInvoiceHeader.RecordId());
Assert.IsFalse(EDocument.IsEmpty(), 'No E-Document created');
end;

[Test]
procedure PostInvoiceWithStandardVatAmountCategoryAndNonZeroVat()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
EDocument: Record "E-Document";
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Post invoice with standard VAT amount category and non-zero VAT %
Initialize();

// [GIVEN] VAT Posting Setup with standard VAT amount category and non-zero VAT %
SetVatPostingSetupTaxCategory('S', 25);

// [WHEN] Posting invoice
SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer);

// [THEN] Invoice is posted successfully
Assert.RecordIsNotEmpty(SalesInvoiceHeader);
// [THEN] E-Document is created
EDocument.SetRange("Document Record ID", SalesInvoiceHeader.RecordId());
Assert.IsFalse(EDocument.IsEmpty(), 'No E-Document created');
end;

[Test]
procedure TestPostInvoiceWithStandardVatAmountCategoryAndZeroVat()
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Attempt to post invoice with standard VAT category and 0% VAT should fail
Initialize();

// [GIVEN] VAT Posting Setup with standard VAT amount category and zero VAT %
SetVatPostingSetupTaxCategory('S', 0);

// [WHEN] Posting invoice
asserterror LibraryEDoc.PostInvoice(Customer);

// [THEN] Error is raised
Assert.ExpectedError('Line should have greater VAT than 0% for tax category S');
end;

[Test]
procedure PostInvoiceWithOutsideVatScopeAndTwoDifferentVatAmountLines()
var
SalesHeader: Record "Sales Header";
SalesLine: Record "Sales Line";
Item: Record Item;
ItemWithTaxGroup: Record Item;
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Post invoice with outside VAT scope and two different VAT amount lines
Initialize();

// [GIVEN] VAT Posting Setup with outside VAT scope
SetVatPostingSetupTaxCategory('O', 0);
// [GIVEN] Item
LibraryEDoc.GetGenericItem(Item);
// [GIVEN] Second item with different Tax Group code than first item
CreateItemWithTaxGroup(ItemWithTaxGroup, Any.AlphanumericText(20));
// [GIVEN] Sales invoice with both items
LibraryEDoc.CreateSalesHeaderWithItem(Customer, SalesHeader, Enum::"Sales Document Type"::Invoice);
LibrarySales.CreateSalesLine(SalesLine, SalesHeader, Enum::"Sales Line Type"::Item, ItemWithTaxGroup."No.", 1);

// [WHEN] Posting invoice
asserterror LibrarySales.PostSalesDocument(SalesHeader, false, true);

// [THEN] Error is raised
Assert.ExpectedError('There can be only one tax subtotal present on invoice used with "Not subject to VAT" (O) tax category.');
end;

[Test]
procedure PostInvoiceWithOutsideVatScopeAndTwoDifferentItemsNoCustomTaxGroup()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
SalesHeader: Record "Sales Header";
SalesLine: Record "Sales Line";
Item: Record Item;
SecondItem: Record Item;
EDocument: Record "E-Document";
begin
// [FEATURE] [E-Document] [Processing]
// [SCENARIO] Post invoice with outside VAT scope and two items without different Tax Group
Initialize();

// [GIVEN] VAT Posting Setup with outside VAT scope
SetVatPostingSetupTaxCategory('O', 0);
// [GIVEN] First item
LibraryEDoc.GetGenericItem(Item);
// [GIVEN] Second item without custom Tax Group
CreateItemWithTaxGroup(SecondItem, Item."Tax Group Code");
// [GIVEN] Sales invoice with both items
LibraryEDoc.CreateSalesHeaderWithItem(Customer, SalesHeader, Enum::"Sales Document Type"::Invoice);
LibrarySales.CreateSalesLine(SalesLine, SalesHeader, Enum::"Sales Line Type"::Item, SecondItem."No.", 1);

// [WHEN] Posting invoice
SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer);

// [THEN] Invoice is posted successfully and E-Document created
Assert.RecordIsNotEmpty(SalesInvoiceHeader);
EDocument.SetRange("Document Record ID", SalesInvoiceHeader.RecordId());
Assert.IsFalse(EDocument.IsEmpty(), 'No E-Document created');
end;

local procedure Initialize()
var
TransformationRule: Record "Transformation Rule";
EDocument: Record "E-Document";
EDocumentServiceStatus: Record "E-Document Service Status";
LibraryWorkflow: Codeunit "Library - Workflow";
begin
LibraryLowerPermission.SetOutsideO365Scope();
LibraryVariableStorage.Clear();
Clear(EDocImplState);

if IsInitialized then
exit;

EDocument.DeleteAll();
EDocumentServiceStatus.DeleteAll();
EDocumentService.DeleteAll();

LibraryEDoc.SetupStandardVAT();
LibraryEDoc.SetupStandardSalesScenario(Customer, EDocumentService, Enum::"E-Document Format"::"PEPPOL BIS 3.0", Enum::"Service Integration"::"No Integration");
VATPostingSetup := LibraryEDoc.GetVatPostingSetup();

TransformationRule.DeleteAll();
TransformationRule.CreateDefaultTransformations();
LibraryWorkflow.SetUpEmailAccount();

IsInitialized := true;
end;

local procedure CreateItemWithTaxGroup(var Item: Record Item; TaxGroupCode: Code[20])
begin
LibraryEDoc.CreateGenericItem(Item);
Item."VAT Prod. Posting Group" := VATPostingSetup."VAT Prod. Posting Group";
Item."Tax Group Code" := TaxGroupCode;
Item.Modify(false);
end;

local procedure SetVatPostingSetupTaxCategory(TaxCategryCode: Code[10]; VATPercent: Decimal)
begin
VATPostingSetup."Tax Category" := TaxCategryCode;
VATPostingSetup."VAT %" := VATPercent;
VATPostingSetup.Modify(false);
end;
}
Loading