From 7f9db318d8bb176ee9e42c42f01350e6febcb2b9 Mon Sep 17 00:00:00 2001 From: v-sanjmaurya Date: Sat, 31 Oct 2026 11:56:02 +0530 Subject: [PATCH 1/2] Initial commit --- .../VAT/Calculation/NonDedVATImpl.Codeunit.al | 4 +- .../W1/Tests/VAT/NonDeductibleUT.Codeunit.al | 27 +++++ .../NonDeductibleVATStatistics.Codeunit.al | 110 ++++++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/src/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/src/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al index 08f79563ba7..41ea23be099 100644 --- a/src/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al +++ b/src/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al @@ -1007,7 +1007,9 @@ codeunit 6201 "Non-Ded. VAT Impl." GeneralLedgerSetup.GetRecordOnce(); UpdateNonDeductibleAmounts(GenJournalLine."Non-Deductible VAT Base ACY", GenJournalLine."Non-Deductible VAT Amount ACY", BaseAmountACY, VATAmountACY, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup."Amount Rounding Precision"); AdjustVATAmounts(VATAmountACY, BaseAmountACY, GenJournalLine."Non-Deductible VAT Amount ACY", GenJournalLine."Non-Deductible VAT Base ACY"); - if IsNormalVATInvoiceForVendor(GenJournalLine) then + if (GenJournalLine."VAT Posting" = GenJournalLine."VAT Posting"::"Automatic VAT Entry") and + IsNormalVATInvoiceForVendor(GenJournalLine) + then UpdateNonDeductibleAmounts(GenJournalLine."Non-Deductible VAT Base LCY", GenJournalLine."Non-Deductible VAT Amount LCY", BaseAmount, VATAmount, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup."Amount Rounding Precision"); AdjustVATAmounts(VATAmount, BaseAmount, GenJournalLine."Non-Deductible VAT Amount LCY", GenJournalLine."Non-Deductible VAT Base LCY"); end; diff --git a/src/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al b/src/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al index 918c76da689..530722c13b6 100644 --- a/src/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al +++ b/src/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al @@ -469,6 +469,33 @@ codeunit 134282 "Non-Deductible UT" Assert.ExpectedError(StrSubstNo(DifferentNonDedVATRatesSameVATIdentifierErr, VATPostingSetup."VAT Bus. Posting Group", VATPostingSetup."VAT Prod. Posting Group")); end; + [Test] + procedure AutomaticVATEntryStillCalculatesNonDeductibleVAT() + var + GenJournalLine: Record "Gen. Journal Line"; + NonDeductibleVAT: Codeunit "Non-Deductible VAT"; + VATAmount: Decimal; + VATBase: Decimal; + VATAmountACY: Decimal; + VATBaseACY: Decimal; + begin + // [SCENARIO 657371] Automatic journal VAT entries still calculate non-deductible VAT. + Initialize(); + GenJournalLine."Document Type" := GenJournalLine."Document Type"::Invoice; + GenJournalLine."VAT Calculation Type" := GenJournalLine."VAT Calculation Type"::"Normal VAT"; + GenJournalLine."VAT Posting" := GenJournalLine."VAT Posting"::"Automatic VAT Entry"; + GenJournalLine."Non-Deductible VAT %" := 50; + VATAmount := 0.03; + VATBase := 0.13; + + NonDeductibleVAT.AdjustVATAmountsFromGenJnlLine(VATAmount, VATBase, VATAmountACY, VATBaseACY, GenJournalLine); + + GenJournalLine.TestField("Non-Deductible VAT Amount LCY", 0.02); + GenJournalLine.TestField("Non-Deductible VAT Base LCY", 0.07); + Assert.AreEqual(0.01, VATAmount, AmountErrorLbl); + Assert.AreEqual(0.06, VATBase, AmountErrorLbl); + end; + local procedure Initialize() begin LibraryTestInitialize.OnTestInitialize(Codeunit::"Non-Deductible UT"); diff --git a/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al b/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al index 13be7d00ab4..6af6505ee7c 100644 --- a/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al @@ -714,6 +714,108 @@ codeunit 134287 "Non-Deductible VAT Statistics" Assert.RecordIsNotEmpty(PurchCrMemoHdr); end; + [Test] + [HandlerFunctions('PurchaseStatisticsVerifyAllocatedNonDedVATPageHandler')] + procedure PurchaseInvoiceStatisticsMatchSplitVATEntries() + var + PurchaseDocumentType: Enum "Purchase Document Type"; + begin + // [SCENARIO 657371] Splitting invoice posting lines does not change the non-deductible VAT total. + VerifySplitNonDeductibleVATPosting(PurchaseDocumentType::Invoice, false); + end; + + [Test] + [HandlerFunctions('PurchaseStatisticsVerifyAllocatedNonDedVATPageHandler')] + procedure PurchaseInvoiceInclVATStatisticsMatchSplitVATEntries() + var + PurchaseDocumentType: Enum "Purchase Document Type"; + begin + // [SCENARIO 657371] An invoice with prices including VAT retains its allocated non-deductible VAT. + VerifySplitNonDeductibleVATPosting(PurchaseDocumentType::Invoice, true); + end; + + [Test] + [HandlerFunctions('PurchaseStatisticsVerifyAllocatedNonDedVATPageHandler')] + procedure PurchaseCreditMemoStatisticsMatchSplitVATEntries() + var + PurchaseDocumentType: Enum "Purchase Document Type"; + begin + // [SCENARIO 657371] Credit memo posting continues to retain the allocated non-deductible VAT. + VerifySplitNonDeductibleVATPosting(PurchaseDocumentType::"Credit Memo", false); + end; + + local procedure VerifySplitNonDeductibleVATPosting(DocumentType: Enum "Purchase Document Type"; PricesIncludingVAT: Boolean) + var + VATPostingSetup: Record "VAT Posting Setup"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + GeneralPostingSetup: Record "General Posting Setup"; + GLAccount: Record "G/L Account"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + VATEntry: Record "VAT Entry"; + PurchaseInvoicePage: TestPage "Purchase Invoice"; + PurchaseCreditMemoPage: TestPage "Purchase Credit Memo"; + GLAccountNo: Code[20]; + PostedDocumentNo: Code[20]; + ExpectedSign: Integer; + LineIndex: Integer; + begin + Initialize(); + + // [GIVEN] 23% VAT, 50% non-deductible VAT, and separate posting entries for each G/L line. + LibraryNonDeductibleVAT.CreateVATPostingSetupWithNonDeductibleDetail(VATPostingSetup, 23, 50); + VATPostingSetup.Validate("Non-Ded. Purchase VAT Account", LibraryERM.CreateGLAccountNo()); + VATPostingSetup.Modify(true); + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Copy Line Descr. to G/L Entry", true); + PurchasesPayablesSetup.Validate("Discount Posting", PurchasesPayablesSetup."Discount Posting"::"No Discounts"); + PurchasesPayablesSetup.Modify(true); + + GLAccountNo := LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, GLAccount."Gen. Posting Type"::Purchase); + GLAccount.Get(GLAccountNo); + LibraryERM.FindGeneralPostingSetup(GeneralPostingSetup); + LibraryPurchase.CreatePurchHeader( + PurchaseHeader, DocumentType, + LibraryPurchase.CreateVendorWithBusPostingGroups(GeneralPostingSetup."Gen. Bus. Posting Group", VATPostingSetup."VAT Bus. Posting Group")); + PurchaseHeader.Validate("Prices Including VAT", PricesIncludingVAT); + PurchaseHeader.Modify(true); + for LineIndex := 1 to 2 do begin + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::"G/L Account", GLAccountNo, 1); + if PricesIncludingVAT then + PurchaseLine.Validate("Direct Unit Cost", 0.16) + else + PurchaseLine.Validate("Direct Unit Cost", 0.13); + PurchaseLine.Modify(true); + end; + + // [GIVEN] Statistics show VAT of 0.06, of which 0.03 is non-deductible. + if DocumentType = DocumentType::Invoice then begin + PurchaseInvoicePage.OpenEdit(); + PurchaseInvoicePage.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseInvoicePage.PurchaseStatistics.Invoke(); + PurchaseInvoicePage.Close(); + ExpectedSign := 1; + end else begin + PurchaseCreditMemoPage.OpenEdit(); + PurchaseCreditMemoPage.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseCreditMemoPage.PurchaseStatistics.Invoke(); + PurchaseCreditMemoPage.Close(); + ExpectedSign := -1; + end; + + // [WHEN] Post two VAT amounts of 0.03 with allocated non-deductible amounts of 0.02 and 0.01. + PostedDocumentNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] VAT and G/L totals match statistics, rather than rounding each half of 0.03 to 0.02. + FindVATEntry(VATEntry, PostedDocumentNo); + Assert.RecordCount(VATEntry, 2); + VATEntry.CalcSums(Amount, "Non-Deductible VAT Amount"); + VATEntry.TestField("Non-Deductible VAT Amount", ExpectedSign * 0.03); + VATEntry.TestField(Amount, ExpectedSign * 0.03); + VerifyGLEntry(PostedDocumentNo, VATPostingSetup."Non-Ded. Purchase VAT Account", 2, ExpectedSign * 0.03); + VerifyGLEntryByDocumentNo(PostedDocumentNo, 0); + end; + local procedure Initialize() var LibraryERMCountryData: Codeunit "Library - ERM Country Data"; @@ -933,6 +1035,14 @@ codeunit 134287 "Non-Deductible VAT Statistics" Assert.AreEqual(ExpectedAmount, GLEntry.Amount, GLEntryConsistentErr); end; + [PageHandler] + procedure PurchaseStatisticsVerifyAllocatedNonDedVATPageHandler(var PurchaseStatisticsPage: TestPage "Purchase Statistics") + begin + PurchaseStatisticsPage.SubForm."VAT Amount".AssertEquals(0.06); + PurchaseStatisticsPage.SubForm.NonDeductibleAmount.AssertEquals(0.03); + PurchaseStatisticsPage.SubForm.DeductibleAmount.AssertEquals(0.03); + end; + [PageHandler] procedure PurchaseStatisticsChangeVATAmountPageHandler(var PurchaseStatisticsPage: TestPage "Purchase Statistics") var From b8ea0dad6c6744230046f0d33b9a50aa270ebb12 Mon Sep 17 00:00:00 2001 From: v-sanjmaurya Date: Mon, 2 Nov 2026 12:32:33 +0530 Subject: [PATCH 2/2] Fix the BB Issue --- .../NonDeductibleVATStatistics.Codeunit.al | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al b/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al index 6af6505ee7c..552ec8f2f53 100644 --- a/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al @@ -757,6 +757,7 @@ codeunit 134287 "Non-Deductible VAT Statistics" PurchaseCreditMemoPage: TestPage "Purchase Credit Memo"; GLAccountNo: Code[20]; PostedDocumentNo: Code[20]; + ExpectedNonDeductibleVATAmount: Decimal; ExpectedSign: Integer; LineIndex: Integer; begin @@ -788,7 +789,7 @@ codeunit 134287 "Non-Deductible VAT Statistics" PurchaseLine.Modify(true); end; - // [GIVEN] Statistics show VAT of 0.06, of which 0.03 is non-deductible. + // [GIVEN] Statistics show VAT of 0.06 with non-deductible VAT calculated by the localization. if DocumentType = DocumentType::Invoice then begin PurchaseInvoicePage.OpenEdit(); PurchaseInvoicePage.Filter.SetFilter("No.", PurchaseHeader."No."); @@ -802,17 +803,21 @@ codeunit 134287 "Non-Deductible VAT Statistics" PurchaseCreditMemoPage.Close(); ExpectedSign := -1; end; + ExpectedNonDeductibleVATAmount := LibraryVariableStorage.DequeueDecimal(); + if not PricesIncludingVAT then + Assert.AreEqual(0.03, ExpectedNonDeductibleVATAmount, 'Statistics must allocate half of the total VAT.'); + LibraryVariableStorage.AssertEmpty(); - // [WHEN] Post two VAT amounts of 0.03 with allocated non-deductible amounts of 0.02 and 0.01. + // [WHEN] Post two VAT amounts of 0.03 with the non-deductible amounts allocated by Statistics. PostedDocumentNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); - // [THEN] VAT and G/L totals match statistics, rather than rounding each half of 0.03 to 0.02. + // [THEN] VAT and G/L totals match Statistics, including localization-specific rounding. FindVATEntry(VATEntry, PostedDocumentNo); Assert.RecordCount(VATEntry, 2); VATEntry.CalcSums(Amount, "Non-Deductible VAT Amount"); - VATEntry.TestField("Non-Deductible VAT Amount", ExpectedSign * 0.03); - VATEntry.TestField(Amount, ExpectedSign * 0.03); - VerifyGLEntry(PostedDocumentNo, VATPostingSetup."Non-Ded. Purchase VAT Account", 2, ExpectedSign * 0.03); + VATEntry.TestField("Non-Deductible VAT Amount", ExpectedSign * ExpectedNonDeductibleVATAmount); + VATEntry.TestField(Amount, ExpectedSign * (0.06 - ExpectedNonDeductibleVATAmount)); + VerifyGLEntry(PostedDocumentNo, VATPostingSetup."Non-Ded. Purchase VAT Account", 2, ExpectedSign * ExpectedNonDeductibleVATAmount); VerifyGLEntryByDocumentNo(PostedDocumentNo, 0); end; @@ -1037,10 +1042,13 @@ codeunit 134287 "Non-Deductible VAT Statistics" [PageHandler] procedure PurchaseStatisticsVerifyAllocatedNonDedVATPageHandler(var PurchaseStatisticsPage: TestPage "Purchase Statistics") + var + NonDeductibleVATAmount: Decimal; begin PurchaseStatisticsPage.SubForm."VAT Amount".AssertEquals(0.06); - PurchaseStatisticsPage.SubForm.NonDeductibleAmount.AssertEquals(0.03); - PurchaseStatisticsPage.SubForm.DeductibleAmount.AssertEquals(0.03); + NonDeductibleVATAmount := PurchaseStatisticsPage.SubForm.NonDeductibleAmount.AsDecimal(); + PurchaseStatisticsPage.SubForm.DeductibleAmount.AssertEquals(0.06 - NonDeductibleVATAmount); + LibraryVariableStorage.Enqueue(NonDeductibleVATAmount); end; [PageHandler]