From 3e81f6a4a07661656640280db87833876e3fc627 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Wed, 11 Dec 2024 15:16:15 +0100 Subject: [PATCH 01/11] add EDocument app workspace --- .../EDocument/edocument_workspace.code-workspace | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Apps/W1/EDocument/edocument_workspace.code-workspace diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace new file mode 100644 index 0000000000..f10f2a03cc --- /dev/null +++ b/Apps/W1/EDocument/edocument_workspace.code-workspace @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "name": "app", + "path": "app" + }, + { + "name": "test", + "path": "test" + }, + { + "name": "demo data", + "path": "demo data" + } + ] +} \ No newline at end of file From f4c11e284549a39e0b356ae69c618198edd0bdc0 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Thu, 12 Dec 2024 11:10:12 +0100 Subject: [PATCH 02/11] add code analyzers settings to code workspace --- Apps/W1/EDocument/edocument_workspace.code-workspace | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace index f10f2a03cc..35fb4f1ea3 100644 --- a/Apps/W1/EDocument/edocument_workspace.code-workspace +++ b/Apps/W1/EDocument/edocument_workspace.code-workspace @@ -1,4 +1,12 @@ { + "settings": { + "al.enableCodeAnalysis": true, + "al.codeAnalyzers": [ + "${CodeCop}", + "${UICop}", + "${AppSourceCop}" + ] + }, "folders": [ { "name": "app", From 715ceddab2cd7aca270e8928b3f913d07e19697d Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 18 Feb 2025 17:40:49 +0100 Subject: [PATCH 03/11] add checks for zero Vat and standard vat peppol codes --- .../EDocumentVATPostingSetup.TableExt.al | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al new file mode 100644 index 0000000000..2ad499f883 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al @@ -0,0 +1,57 @@ +namespace Microsoft.eServices.EDocument; + +using Microsoft.Finance.VAT.Setup; + +tableextension 6103 "E-Document VAT Posting Setup" extends "VAT Posting Setup" +{ + fields + { + modify("Tax Category") + { + trigger OnAfterValidate() + begin + this.CheckStandardPeppolVATCategory(); + this.CheckNullPeppolVATCategory(); + end; + } + } + + var + NullPeppolVatCategoryNoApplErr: Label 'Tax Category %1 cannot have 0 VAT.', Comment = '%1 = Tax Category Code'; + + local procedure HasNullPeppolVATCategory(): Boolean + begin + exit(Rec."Tax Category" in [ + 'Z', // Zero rated goods + 'E', // Exempt from tax + 'AE', // VAT reverse charge + 'K', // VAT exempt for EEA intra-community supply of goods and services + 'G' // Free export item, tax not charged + ]); + end; + + local procedure HasStandardPeppolVATCategory(): Boolean + begin + exit(Rec."Tax Category" = 'S'); + end; + + local procedure CheckNullPeppolVATCategory() + var + NullPeppolCateforyApplicableNotification: Notification; + begin + if this.HasNullPeppolVATCategory() and (Rec."VAT %" > 0) then + Error(NullPeppolVatCategoryNoApplErr, Rec."Tax Category") + else + if not this.HasNullPeppolVATCategory() then begin + NullPeppolCateforyApplicableNotification.Message := 'For 0 VAT, use one of the the standard PEPPOL VAT category codes. Z, E, AE, K or G'; + NullPeppolCateforyApplicableNotification.Scope := NotificationScope::LocalScope; + NullPeppolCateforyApplicableNotification.Send(); + end + end; + + local procedure CheckStandardPeppolVATCategory() + begin + if this.HasStandardPeppolVATCategory() and (Rec."VAT %" = 0) then + Error(NullPeppolVatCategoryNoApplErr, Rec."Tax Category"); + end; +} From be5bde5ce7ec2ba6c2ddc8ee2b77da618ddd399c Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 24 Feb 2025 16:52:38 +0100 Subject: [PATCH 04/11] create test codeunit --- .../test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al diff --git a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al new file mode 100644 index 0000000000..1d36a27ba4 --- /dev/null +++ b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al @@ -0,0 +1,5 @@ +codeunit 139502 "E-Doc. PEPPOL Validation Test" +{ + Subtype = Test; + +} From e577a16bfbaaf592cfe2fad0a57ddb69afb46708 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 24 Feb 2025 19:14:37 +0100 Subject: [PATCH 05/11] create category zero tests --- .../test/src/LibraryEDocument.Codeunit.al | 37 +++++--- .../EDocPEPPOLValidationTest.Codeunit.al | 89 +++++++++++++++++++ 2 files changed, 114 insertions(+), 12 deletions(-) diff --git a/Apps/W1/EDocument/test/src/LibraryEDocument.Codeunit.al b/Apps/W1/EDocument/test/src/LibraryEDocument.Codeunit.al index dfd6015163..37e689a78e 100644 --- a/Apps/W1/EDocument/test/src/LibraryEDocument.Codeunit.al +++ b/Apps/W1/EDocument/test/src/LibraryEDocument.Codeunit.al @@ -50,7 +50,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"; @@ -66,17 +65,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 @@ -98,6 +87,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 [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')] procedure SetupStandardPurchaseScenario(var Vendor: Record Vendor; var EDocService: Record "E-Document Service"; EDocDocumentFormat: Enum "E-Document Format"; EDocIntegration: Enum "E-Document Integration") @@ -550,6 +546,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 [Obsolete('Use CreateService(EDocDocumentFormat: Enum "E-Document Format"; EDocIntegration: Enum "Service Integration") instead', '26.0')] procedure CreateService(Integration: Enum "E-Document Integration"): Code[20] diff --git a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al index 1d36a27ba4..6828fcd61c 100644 --- a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al @@ -2,4 +2,93 @@ 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"; + EDocImplState: Codeunit "E-Doc. Impl. State"; + LibraryLowerPermission: Codeunit "Library - Lower Permissions"; + 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 % + VATPostingSetup."Tax Category" := 'Z'; + VATPostingSetup."VAT %" := 10; + VATPostingSetup.Modify(false); + + // [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 % + VATPostingSetup."Tax Category" := 'Z'; + VATPostingSetup."VAT %" := 0; + VATPostingSetup.Modify(false); + + // [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; + + + + 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; + } From 202095c898d08284d0cf3469ad2eefc158c6c6d1 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 25 Feb 2025 14:37:11 +0100 Subject: [PATCH 06/11] add outside tax scope test --- .../EDocumentVATPostingSetup.TableExt.al | 57 ------------- .../EDocPEPPOLValidationTest.Codeunit.al | 84 +++++++++++++++++-- 2 files changed, 78 insertions(+), 63 deletions(-) delete mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al deleted file mode 100644 index 2ad499f883..0000000000 --- a/Apps/W1/EDocument/app/src/Extensions/EDocumentVATPostingSetup.TableExt.al +++ /dev/null @@ -1,57 +0,0 @@ -namespace Microsoft.eServices.EDocument; - -using Microsoft.Finance.VAT.Setup; - -tableextension 6103 "E-Document VAT Posting Setup" extends "VAT Posting Setup" -{ - fields - { - modify("Tax Category") - { - trigger OnAfterValidate() - begin - this.CheckStandardPeppolVATCategory(); - this.CheckNullPeppolVATCategory(); - end; - } - } - - var - NullPeppolVatCategoryNoApplErr: Label 'Tax Category %1 cannot have 0 VAT.', Comment = '%1 = Tax Category Code'; - - local procedure HasNullPeppolVATCategory(): Boolean - begin - exit(Rec."Tax Category" in [ - 'Z', // Zero rated goods - 'E', // Exempt from tax - 'AE', // VAT reverse charge - 'K', // VAT exempt for EEA intra-community supply of goods and services - 'G' // Free export item, tax not charged - ]); - end; - - local procedure HasStandardPeppolVATCategory(): Boolean - begin - exit(Rec."Tax Category" = 'S'); - end; - - local procedure CheckNullPeppolVATCategory() - var - NullPeppolCateforyApplicableNotification: Notification; - begin - if this.HasNullPeppolVATCategory() and (Rec."VAT %" > 0) then - Error(NullPeppolVatCategoryNoApplErr, Rec."Tax Category") - else - if not this.HasNullPeppolVATCategory() then begin - NullPeppolCateforyApplicableNotification.Message := 'For 0 VAT, use one of the the standard PEPPOL VAT category codes. Z, E, AE, K or G'; - NullPeppolCateforyApplicableNotification.Scope := NotificationScope::LocalScope; - NullPeppolCateforyApplicableNotification.Send(); - end - end; - - local procedure CheckStandardPeppolVATCategory() - begin - if this.HasStandardPeppolVATCategory() and (Rec."VAT %" = 0) then - Error(NullPeppolVatCategoryNoApplErr, Rec."Tax Category"); - end; -} diff --git a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al index 6828fcd61c..4d57e6f157 100644 --- a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al @@ -9,8 +9,10 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" 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; @@ -24,9 +26,7 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" Initialize(); // [GIVEN] VAT Posting Setup with zero VAT amount category and non-zero VAT % - VATPostingSetup."Tax Category" := 'Z'; - VATPostingSetup."VAT %" := 10; - VATPostingSetup.Modify(false); + SetVatPostingSetupTaxCategory('Z', 10); // [WHEN] Posting invoice asserterror SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer); @@ -46,9 +46,7 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" Initialize(); // [GIVEN] VAT Posting Setup with zero VAT amount category and zero VAT % - VATPostingSetup."Tax Category" := 'Z'; - VATPostingSetup."VAT %" := 0; - VATPostingSetup.Modify(false); + SetVatPostingSetupTaxCategory('Z', 0); // [WHEN] Posting invoice SalesInvoiceHeader := LibraryEDoc.PostInvoice(Customer); @@ -60,7 +58,67 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" Assert.IsFalse(EDocument.IsEmpty(), 'No E-Document created'); 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 @@ -91,4 +149,18 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" 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; } From 0e990283a03faca25131bea57c53bd92eed9b3ad Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 25 Feb 2025 16:26:10 +0100 Subject: [PATCH 07/11] add standard (S) Peppol tax category tests --- .../EDocPEPPOLValidationTest.Codeunit.al | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al index 4d57e6f157..bd55a35be8 100644 --- a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al @@ -58,6 +58,46 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" 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 From 2728b77d494357b0db032353023c1d72e5be9886 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Wed, 5 Mar 2025 14:02:24 +0100 Subject: [PATCH 08/11] add subscriber to handle zero amoutn and vat amount sales documents in PEPPOL --- .../app/src/Format/EDocPEPPOLBIS30.Codeunit.al | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al b/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al index 42e8832cac..96a3d7dcf5 100644 --- a/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al @@ -7,6 +7,7 @@ using Microsoft.Purchases.Document; using Microsoft.Service.History; using Microsoft.Sales.Document; using Microsoft.Sales.History; +using Microsoft.Finance.VAT.Calculation; codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" { @@ -137,6 +138,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 Set(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'; From 1e9af364004b25d62c103442bffe6b4cb0018e91 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Wed, 5 Mar 2025 14:05:45 +0100 Subject: [PATCH 09/11] fix subscriber name --- Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al b/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al index 96a3d7dcf5..e064e5338a 100644 --- a/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Format/EDocPEPPOLBIS30.Codeunit.al @@ -139,7 +139,7 @@ codeunit 6165 "EDoc PEPPOL BIS 3.0" implements "E-Document" end; [EventSubscriber(ObjectType::Table, Database::"VAT Amount Line", OnInsertLine, '', false, false)] - local procedure Set(var VATAmountLine: Record "VAT Amount Line"; var SkipZeroVatAmounts: Boolean) + local procedure SetInsertNotToSkipZeroVatAmounts(var VATAmountLine: Record "VAT Amount Line"; var SkipZeroVatAmounts: Boolean) var PEPPOLManagement: Codeunit "PEPPOL Management"; begin From 9330755ada859a7d1a0a4e14e10b0b2cb3dd103f Mon Sep 17 00:00:00 2001 From: Grasiele Matuleviciute <131970463+GMatuleviciute@users.noreply.github.com> Date: Thu, 6 Mar 2025 10:09:31 +0200 Subject: [PATCH 10/11] Update Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al --- .../test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al | 1 - 1 file changed, 1 deletion(-) diff --git a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al index bd55a35be8..99966636f1 100644 --- a/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Processing/EDocPEPPOLValidationTest.Codeunit.al @@ -15,7 +15,6 @@ codeunit 139502 "E-Doc. PEPPOL Validation Test" Any: Codeunit Any; IsInitialized: Boolean; - [Test] procedure PostInvoiceWithZeroVatAmountCategoryAndNonZeroVat() var From bdde5540f0ec6c08f59c6efdcd33819730b83151 Mon Sep 17 00:00:00 2001 From: Grasiele Matuleviciute <131970463+GMatuleviciute@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:11:05 +0300 Subject: [PATCH 11/11] Delete Apps/W1/EDocument/edocument_workspace.code-workspace --- .../edocument_workspace.code-workspace | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 Apps/W1/EDocument/edocument_workspace.code-workspace diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace deleted file mode 100644 index 35fb4f1ea3..0000000000 --- a/Apps/W1/EDocument/edocument_workspace.code-workspace +++ /dev/null @@ -1,24 +0,0 @@ -{ - "settings": { - "al.enableCodeAnalysis": true, - "al.codeAnalyzers": [ - "${CodeCop}", - "${UICop}", - "${AppSourceCop}" - ] - }, - "folders": [ - { - "name": "app", - "path": "app" - }, - { - "name": "test", - "path": "test" - }, - { - "name": "demo data", - "path": "demo data" - } - ] -} \ No newline at end of file