Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -1897,6 +1897,69 @@ codeunit 148321 "ERM Withholding Tax Tests I"
UnapplyVendorLedgerEntryAmount(''); // Currency as blank.
end;

[Test]
[HandlerFunctions('ConfirmHandler')]
procedure VendorLiabilityReducedByCumulativeWHTWhenMultipleWHTRatesOnInvoice()
var
GeneralPostingSetup: Record "General Posting Setup";
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
VATPostingSetup: Record "VAT Posting Setup";
VendorLedgerEntry: Record "Vendor Ledger Entry";
WHTPostingSetup1: Record "Withholding Tax Posting Setup";
WHTPostingSetup2: Record "Withholding Tax Posting Setup";
DocumentNo: Code[20];
VendorNo: Code[20];
ExpectedWHTAmount: Decimal;
LineAmount1: Decimal;
LineAmount2: Decimal;
begin
// [SCENARIO 646139] Vendor liability is reduced by the cumulative Withholding Tax of all invoice lines when the lines use different Withholding Tax Product Posting Groups.
Initialize();

// [GIVEN] Withholding Tax enabled and two WHT Posting Setups sharing the WHT Bus. Posting Group but with different WHT Prod. Posting Groups and percentages.
UpdateGeneralLedgerSetup(true, false); // Round Amount for WHT Calc and True as Enable WHT.
LibraryERM.FindZeroVATPostingSetup(VATPostingSetup, VATPostingSetup."VAT Calculation Type"::"Normal VAT");
CreateWHTPostingSetup(WHTPostingSetup1, LibraryRandom.RandIntInRange(10, 15));
CreateSecondWHTPostingSetupForSameBusGroup(WHTPostingSetup2, WHTPostingSetup1, LibraryRandom.RandIntInRange(20, 25));

// [GIVEN] Vendor liable for WHT with the shared WHT Bus. Posting Group.
VendorNo := CreateVendorWithPostingGroup(VATPostingSetup."VAT Bus. Posting Group", WHTPostingSetup1."Wthldg. Tax Bus. Post. Group");

// [GIVEN] Purchase Invoice with one line per WHT Prod. Posting Group.
CreatePurchaseHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, VendorNo, ''); // Blank Currency Code.
LineAmount1 := CreatePurchaseLineWithFixedAmount(
PurchaseLine, PurchaseHeader, WHTPostingSetup1,
CreateGLAccount(VATPostingSetup."VAT Prod. Posting Group", WHTPostingSetup1."Wthldg. Tax Prod. Post. Group"));
LineAmount2 := CreatePurchaseLineWithFixedAmount(
PurchaseLine, PurchaseHeader, WHTPostingSetup2,
CreateGLAccount(VATPostingSetup."VAT Prod. Posting Group", WHTPostingSetup2."Wthldg. Tax Prod. Post. Group"));

ExpectedWHTAmount :=
Round(LineAmount1 * WHTPostingSetup1."Withholding Tax %" / 100) +
Round(LineAmount2 * WHTPostingSetup2."Withholding Tax %" / 100);
Comment on lines +1938 to +1940

// [GIVEN] Unblock the General Posting Setup for the combination of Gen. Bus. Posting Group and Gen. Prod. Posting Group used by the Purchase Lines.
GeneralPostingSetup.Get(PurchaseLine."Gen. Bus. Posting Group", PurchaseLine."Gen. Prod. Posting Group");
if GeneralPostingSetup.Blocked then begin
GeneralPostingSetup.Blocked := false;
GeneralPostingSetup.Modify(true);
end;

// [WHEN] Post the Purchase Invoice.
DocumentNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true);

// [THEN] The posting balances and the Vendor Ledger Entry is reduced by the cumulative WHT of both lines.
VendorLedgerEntry.SetRange("Document No.", DocumentNo);
VendorLedgerEntry.SetRange("Vendor No.", VendorNo);
VendorLedgerEntry.FindFirst();
VendorLedgerEntry.CalcFields(Amount);
Assert.AreEqual(
-(LineAmount1 + LineAmount2 - ExpectedWHTAmount), VendorLedgerEntry.Amount,
StrSubstNo(
AmountErr, VendorLedgerEntry.FieldCaption(Amount), -(LineAmount1 + LineAmount2 - ExpectedWHTAmount)));
end;

local procedure Initialize()
var
LibraryERMCountryData: Codeunit "Library - ERM Country Data";
Expand Down Expand Up @@ -2832,6 +2895,34 @@ codeunit 148321 "ERM Withholding Tax Tests I"
exit(Vendor."No.");
end;

local procedure CreatePurchaseLineWithFixedAmount(var PurchaseLine: Record "Purchase Line"; PurchaseHeader: Record "Purchase Header"; WHTPostingSetup: Record "Withholding Tax Posting Setup"; GLAccountNo: Code[20]) LineAmount: Decimal
begin
LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::"G/L Account", GLAccountNo, 1); // Quantity 1.
PurchaseLine.Validate("Direct Unit Cost", LibraryRandom.RandIntInRange(1000, 2000)); // Well above WHT Min. Inv. Amount.
PurchaseLine.Validate("Wthldg. Tax Bus. Post. Group", WHTPostingSetup."Wthldg. Tax Bus. Post. Group");
PurchaseLine.Validate("Wthldg. Tax Prod. Post. Group", WHTPostingSetup."Wthldg. Tax Prod. Post. Group");
PurchaseLine.Modify(true);
LineAmount := PurchaseLine."Line Amount";
end;

local procedure CreateSecondWHTPostingSetupForSameBusGroup(var WHTPostingSetup2: Record "Withholding Tax Posting Setup"; WHTPostingSetup1: Record "Withholding Tax Posting Setup"; WHTPct: Decimal)
var
WHTProductPostingGroup: Record "Wthldg. Tax Prod. Post. Group";
WHTRevenueTypes: Record "Withholding Tax Revenue Types";
begin
LibraryWithholdingTax.CreateWHTProductPostingGroup(WHTProductPostingGroup);
LibraryWithholdingTax.CreateWHTRevenueTypes(WHTRevenueTypes);
CreateWHTPostingSetupWithRealizedWHTType(
WHTPostingSetup2, WHTPostingSetup1."Wthldg. Tax Bus. Post. Group", WHTProductPostingGroup.Code,
WHTPostingSetup2."Realized Withholding Tax Type"::Invoice, WHTPct, WHTRevenueTypes.Code);

// The WHT Min. Inv. Amount must be identical across setups that share a WHT Bus. Posting Group, otherwise posting is blocked.
WHTPostingSetup1."Wthldg. Tax Min. Inv. Amount" := 0;
WHTPostingSetup1.Modify(true);
WHTPostingSetup2."Wthldg. Tax Min. Inv. Amount" := 0;
WHTPostingSetup2.Modify(true);
end;

[ModalPageHandler]
[Scope('OnPrem')]
procedure UnapplyVendorEntriesPageHandler(var UnapplyVendorEntries: TestPage "Unapply Vendor Entries")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ codeunit 6784 "Wthldg Tax Purch. Subscribers"
if TempPurchLineGlobal.Type <> TempPurchLineGlobal.Type::" " then
WithholdingPostingSetup.Get(TempPurchLineGlobal."Wthldg. Tax Bus. Post. Group", TempPurchLineGlobal."Wthldg. Tax Prod. Post. Group");

PurchHeader."Withholding Tax Amount" := 0;

if PurchHeader."Document Type" in [PurchHeader."Document Type"::Order, PurchHeader."Document Type"::Invoice] then begin
PurchInvHeader.Get(GenJnlLineDocNo);

Expand All @@ -438,7 +440,7 @@ codeunit 6784 "Wthldg Tax Purch. Subscribers"
(WithholdingPostingSetup."Realized Withholding Tax Type" <> WithholdingPostingSetup."Realized Withholding Tax Type"::" ")
then
if WithholdingTaxEntry.Amount <> 0 then begin
PurchHeader."Withholding Tax Amount" := WithholdingTaxEntry.Amount;
PurchHeader."Withholding Tax Amount" += WithholdingTaxEntry.Amount;
InsertGenJournalWithholding(PurchHeader, GenJnlLine, WithholdingPostingSetup.GetPayableWithholdingTaxAccount(), SrcCode, GenJnlLineDocType, GenJnlLineDocNo, GenJnlLineExtDocNo, WithholdingTaxEntry.Amount, TotalPurchLineLCY);
GenJnlPostLine.IncreaseTaxEntryNo();
GenJnlPostLine.Run(GenJnlLine);
Expand All @@ -463,7 +465,7 @@ codeunit 6784 "Wthldg Tax Purch. Subscribers"
(WithholdingPostingSetup."Realized Withholding Tax Type" <> WithholdingPostingSetup."Realized Withholding Tax Type"::" ")
then
if WithholdingTaxEntry.Amount <> 0 then begin
PurchHeader."Withholding Tax Amount" := WithholdingTaxEntry.Amount;
PurchHeader."Withholding Tax Amount" += WithholdingTaxEntry.Amount;
InsertGenJournalWithholding(PurchHeader, GenJnlLine, WithholdingPostingSetup.GetPayableWithholdingTaxAccount(), SrcCode, GenJnlLineDocType, GenJnlLineDocNo, GenJnlLineExtDocNo, WithholdingTaxEntry.Amount, TotalPurchLineLCY);
GenJnlPostLine.RunWithCheck(GenJnlLine);
end;
Expand Down
Loading