Skip to content
Closed
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
31 changes: 31 additions & 0 deletions src/Layers/BE/BaseApp/Utilities/DocumentTotals.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.Utilities;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.SalesTax;
using Microsoft.Finance.VAT.Calculation;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Purchases.Posting;
Expand Down Expand Up @@ -671,6 +672,8 @@ codeunit 57 "Document Totals"
TotalPurchaseLine2: Record "Purchase Line";
PurchaseLineWithReverseChargeVAT: Record "Purchase Line";
VATAmountOfLinesWithRevChargeVAT: Decimal;
NonDeductibleVATAmount: Decimal;
GroupedVATAmount: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
Expand Down Expand Up @@ -747,14 +750,42 @@ codeunit 57 "Document Totals"
repeat
TotalPurchaseLine2.Amount += PurchaseLine2.GetNonDeductibleVATAmount();
VATAmount -= PurchaseLine2.GetNonDeductibleVATAmount();
NonDeductibleVATAmount += PurchaseLine2.GetNonDeductibleVATAmount();
until PurchaseLine2.Next() = 0;

if (VATAmountOfLinesWithRevChargeVAT = 0) and (NonDeductibleVATAmount = 0) then
if GetGroupedVATAmount(TotalPurchaseHeader, GroupedVATAmount) and (GroupedVATAmount <> VATAmount) then begin
VATAmount := GroupedVATAmount;
TotalPurchaseLine2."Amount Including VAT" := TotalPurchaseLine2.Amount + VATAmount;
TotalPurchaseLine."Amount Including VAT" := TotalPurchaseLine2."Amount Including VAT";
end;

OnAfterCalculatePurchaseSubPageTotals(
TotalPurchaseHeader, TotalPurchaseLine, VATAmount, InvoiceDiscountAmount, InvoiceDiscountPct, TotalPurchaseLine2);

TotalPurchaseLine := TotalPurchaseLine2;
end;

local procedure GetGroupedVATAmount(var PurchHeader: Record "Purchase Header"; var GroupedVATAmount: Decimal): Boolean
var
PurchLine: Record "Purchase Line";
TempVATAmountLine: Record "VAT Amount Line" temporary;
begin
if PurchHeader."No." = '' then
exit(false);

PurchasesPayablesSetup.Get();
if not PurchasesPayablesSetup."Allow VAT Difference" then
exit(false);

if PurchHeader."Tax Liable" then
exit(false);

PurchLine.CalcVATAmountLines(0, PurchHeader, PurchLine, TempVATAmountLine);
GroupedVATAmount := TempVATAmountLine.GetTotalVATAmount();
exit(true);
end;

procedure CalculatePostedPurchInvoiceTotals(var PurchInvHeader: Record "Purch. Inv. Header"; var VATAmount: Decimal; PurchInvLine: Record "Purch. Inv. Line")
var
CurrPurchInvLine: Record "Purch. Inv. Line";
Expand Down
30 changes: 29 additions & 1 deletion src/Layers/NA/BaseApp/Utilities/DocumentTotals.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.Utilities;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.SalesTax;
using Microsoft.Finance.VAT.Calculation;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Purchases.Posting;
Expand Down Expand Up @@ -666,6 +667,7 @@ codeunit 57 "Document Totals"
PurchaseHeader: Record "Purchase Header";
PurchaseLine2: Record "Purchase Line";
TotalPurchaseLine2: Record "Purchase Line";
GroupedVATAmount: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
Expand Down Expand Up @@ -723,12 +725,38 @@ codeunit 57 "Document Totals"
end;
end;

if GetGroupedVATAmount(TotalPurchaseHeader, GroupedVATAmount) and (GroupedVATAmount <> VATAmount) then begin
VATAmount := GroupedVATAmount;
TotalPurchaseLine2."Amount Including VAT" := TotalPurchaseLine2.Amount + VATAmount;
TotalPurchaseLine."Amount Including VAT" := TotalPurchaseLine2."Amount Including VAT";
end;

OnAfterCalculatePurchaseSubPageTotals(
TotalPurchaseHeader, TotalPurchaseLine, VATAmount, InvoiceDiscountAmount, InvoiceDiscountPct, TotalPurchaseLine2);

TotalPurchaseLine := TotalPurchaseLine2;
end;

local procedure GetGroupedVATAmount(var PurchHeader: Record "Purchase Header"; var GroupedVATAmount: Decimal): Boolean
var
PurchLine: Record "Purchase Line";
TempVATAmountLine: Record "VAT Amount Line" temporary;
begin
if PurchHeader."No." = '' then
exit(false);

PurchasesPayablesSetup.Get();
if not PurchasesPayablesSetup."Allow VAT Difference" then
exit(false);

if PurchHeader."Tax Liable" then
exit(false);

PurchLine.CalcVATAmountLines(0, PurchHeader, PurchLine, TempVATAmountLine);
GroupedVATAmount := TempVATAmountLine.GetTotalVATAmount();
exit(true);
end;

procedure CalculatePostedPurchInvoiceTotals(var PurchInvHeader: Record "Purch. Inv. Header"; var VATAmount: Decimal; PurchInvLine: Record "Purch. Inv. Line")
var
IsHandled: Boolean;
Expand Down Expand Up @@ -963,7 +991,7 @@ codeunit 57 "Document Totals"
procedure PurchaseCalculateTotalsNoRounding(var TempCurrentPurchaseLine: Record "Purchase Line"; var VATAmount: Decimal; var TempTotalPurchaseLine: Record "Purchase Line"; var TaxAreaCode: Code[20])
var
PurchaseLine: Record "Purchase Line";
IsHandled: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforePurchaseCalculateTotalsNoRounding(TempCurrentPurchaseLine, VATAmount, TempTotalPurchaseLine, TaxAreaCode, IsHandled);
Expand Down
28 changes: 28 additions & 0 deletions src/Layers/W1/BaseApp/Utilities/DocumentTotals.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.Utilities;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.SalesTax;
using Microsoft.Finance.VAT.Calculation;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Purchases.Posting;
Expand Down Expand Up @@ -651,6 +652,7 @@ codeunit 57 "Document Totals"
PurchaseHeader: Record "Purchase Header";
PurchaseLine2: Record "Purchase Line";
TotalPurchaseLine2: Record "Purchase Line";
GroupedVATAmount: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
Expand Down Expand Up @@ -708,12 +710,38 @@ codeunit 57 "Document Totals"
end;
end;

if GetGroupedVATAmount(TotalPurchaseHeader, GroupedVATAmount) and (GroupedVATAmount <> VATAmount) then begin
VATAmount := GroupedVATAmount;
TotalPurchaseLine2."Amount Including VAT" := TotalPurchaseLine2.Amount + VATAmount;
TotalPurchaseLine."Amount Including VAT" := TotalPurchaseLine2."Amount Including VAT";
end;

OnAfterCalculatePurchaseSubPageTotals(
TotalPurchaseHeader, TotalPurchaseLine, VATAmount, InvoiceDiscountAmount, InvoiceDiscountPct, TotalPurchaseLine2);

TotalPurchaseLine := TotalPurchaseLine2;
end;

local procedure GetGroupedVATAmount(var PurchHeader: Record "Purchase Header"; var GroupedVATAmount: Decimal): Boolean
var
PurchLine: Record "Purchase Line";
TempVATAmountLine: Record "VAT Amount Line" temporary;
begin
if PurchHeader."No." = '' then
exit(false);

PurchasesPayablesSetup.Get();
if not PurchasesPayablesSetup."Allow VAT Difference" then
exit(false);

if PurchHeader."Tax Liable" then
exit(false);

PurchLine.CalcVATAmountLines(0, PurchHeader, PurchLine, TempVATAmountLine);
GroupedVATAmount := TempVATAmountLine.GetTotalVATAmount();
exit(true);
end;

procedure CalculatePostedPurchInvoiceTotals(var PurchInvHeader: Record "Purch. Inv. Header"; var VATAmount: Decimal; PurchInvLine: Record "Purch. Inv. Line")
var
IsHandled: Boolean;
Expand Down
98 changes: 98 additions & 0 deletions src/Layers/W1/Tests/ERM/DocumentTotalsPages.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,80 @@ codeunit 134344 "Document Totals Pages"
Assert.AreEqual(NewDescription, SalesOrder.SalesLines.Description.Value(), LineDescriptionRevertedErr);
end;

[Test]
[HandlerFunctions('PurchaseInvoiceStatisticsUpdateVATAmountPageHandler')]
procedure PurchInvTotalInclVATMatchesStatisticsAfterVATAdjMixedVATGroupsSameAccount()
var
GLAccount: Record "G/L Account";
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
VATPostingSetup: array[2] of Record "VAT Posting Setup";
Vendor: Record Vendor;
PurchaseInvoicePage: TestPage "Purchase Invoice";
GLAccountNo: Code[20];
MaxVATDifference: Decimal;
TotalAmountInclVATBefore: Decimal;
TotalVATAmountBefore: Decimal;
VATAdjustment: Decimal;
begin
// [FEATURE] [UI] [VAT] [Purchase] [VAT Difference]
// [SCENARIO 637288] "Total VAT Amount" and "Total Amount Incl. VAT" on Purchase Invoice subform must update
// after VAT adjustment when invoice has mixed VAT groups on the same G/L Account with negative lines.
Initialize();

// [GIVEN] "VAT Difference" is allowed with random Max VAT Difference
MaxVATDifference := LibraryRandom.RandDecInRange(1, 5, 2);
LibraryERM.SetMaxVATDifferenceAllowed(MaxVATDifference);
LibraryPurchase.SetAllowVATDifference(true);

// [GIVEN] Create two VAT Posting Setups with random VAT%, same VAT Bus. Posting Group
CreateVATPostingSetup(VATPostingSetup);

// [GIVEN] Purchase Invoice with mixed VAT lines on the same G/L Account, including negative adjustment lines
GLAccount.Get(LibraryERM.CreateGLAccountWithPurchSetup());
GLAccount.Validate("VAT Prod. Posting Group", VATPostingSetup[1]."VAT Prod. Posting Group");
GLAccount.Modify(true);
Vendor.Get(LibraryPurchase.CreateVendorNo());
Vendor.Validate("VAT Bus. Posting Group", VATPostingSetup[1]."VAT Bus. Posting Group");
Vendor.Modify();
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No.");
CreatePurchLineWithGLAccAndVATSetup(PurchaseLine, PurchaseHeader, VATPostingSetup[1], GLAccount."No.", LibraryRandom.RandDecInRange(1000, 5000, 2));
CreatePurchLineWithGLAccAndVATSetup(PurchaseLine, PurchaseHeader, VATPostingSetup[1], GLAccount."No.", -LibraryRandom.RandDecInRange(100, 500, 2));
CreatePurchLineWithGLAccAndVATSetup(PurchaseLine, PurchaseHeader, VATPostingSetup[2], GLAccount."No.", LibraryRandom.RandDecInRange(1000, 5000, 2));
CreatePurchLineWithGLAccAndVATSetup(PurchaseLine, PurchaseHeader, VATPostingSetup[2], GLAccount."No.", -LibraryRandom.RandDecInRange(100, 900, 2));

// [GIVEN] Open Purchase Invoice page and capture totals before adjustment
PurchaseInvoicePage.OpenEdit();
PurchaseInvoicePage.Filter.SetFilter("No.", PurchaseHeader."No.");
PurchaseInvoicePage.PurchLines.Last();
TotalVATAmountBefore := PurchaseInvoicePage.PurchLines."Total VAT Amount".AsDecimal();
TotalAmountInclVATBefore := PurchaseInvoicePage.PurchLines."Total Amount Incl. VAT".AsDecimal();

// [WHEN] VAT Amount adjusted on Statistics page (within allowed VAT difference)
VATAdjustment := -LibraryRandom.RandDecInRange(0, MaxVATDifference, 2);
LibraryVariableStorage.Enqueue(VATAdjustment);
PurchaseInvoicePage.PurchaseStatistics.Invoke();
PurchaseInvoicePage.Close();

// [THEN] "Total VAT Amount" on the subform reflects the VAT adjustment
PurchaseInvoicePage.OpenEdit();
PurchaseInvoicePage.Filter.SetFilter("No.", PurchaseHeader."No.");
PurchaseInvoicePage.PurchLines.Last();
Assert.AreEqual(
TotalVATAmountBefore + VATAdjustment,
PurchaseInvoicePage.PurchLines."Total VAT Amount".AsDecimal(),
StrSubstNo(VATAmountErr, PurchaseInvoicePage.PurchLines."Total VAT Amount".Caption, 'expected Total VAT Amount'));

// [THEN] "Total Amount Incl. VAT" on the subform reflects the VAT adjustment
Assert.AreEqual(
TotalAmountInclVATBefore + VATAdjustment,
PurchaseInvoicePage.PurchLines."Total Amount Incl. VAT".AsDecimal(),
StrSubstNo(VATAmountErr, PurchaseInvoicePage.PurchLines."Total Amount Incl. VAT".Caption, 'expected Total Amount Incl. VAT'));

PurchaseInvoicePage.Close();
LibraryVariableStorage.AssertEmpty();
end;

local procedure Initialize()
begin
LibrarySetupStorage.Restore();
Expand Down Expand Up @@ -2461,6 +2535,30 @@ codeunit 134344 "Document Totals Pages"
SalesLine.Modify();
end;

local procedure CreateVATPostingSetup(var VATPostingSetup: array[2] of Record "VAT Posting Setup")
var
VATProductPostingGroup: Record "VAT Product Posting Group";
begin
LibraryERM.CreateVATPostingSetupWithAccounts(
VATPostingSetup[1], VATPostingSetup[1]."VAT Calculation Type"::"Normal VAT", LibraryRandom.RandIntInRange(5, 15));
LibraryERM.CreateVATProductPostingGroup(VATProductPostingGroup);
LibraryERM.CreateVATPostingSetup(VATPostingSetup[2], VATPostingSetup[1]."VAT Bus. Posting Group", VATProductPostingGroup.Code);
VATPostingSetup[2].Validate("VAT Calculation Type", VATPostingSetup[2]."VAT Calculation Type"::"Normal VAT");
VATPostingSetup[2].Validate("VAT %", LibraryRandom.RandIntInRange(16, 25));
VATPostingSetup[2].Validate("VAT Identifier", CopyStr(VATProductPostingGroup.Code, 1, MaxStrLen(VATPostingSetup[2]."VAT Identifier")));
VATPostingSetup[2]."Purchase VAT Account" := LibraryERM.CreateGLAccountNo();
VATPostingSetup[2].Modify(true);
end;

local procedure CreatePurchLineWithGLAccAndVATSetup(var PurchaseLine: Record "Purchase Line"; PurchaseHeader: Record "Purchase Header"; VATPostingSetup: Record "VAT Posting Setup"; GLAccountNo: Code[20]; DirectUnitCost: Decimal)
begin
LibraryPurchase.CreatePurchaseLine(
PurchaseLine, PurchaseHeader, PurchaseLine.Type::"G/L Account", GLAccountNo, 1);
PurchaseLine.Validate("VAT Prod. Posting Group", VATPostingSetup."VAT Prod. Posting Group");
PurchaseLine.Validate("Direct Unit Cost", DirectUnitCost);
PurchaseLine.Modify(true);
end;

[ConfirmHandler]
[Scope('OnPrem')]
procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean)
Expand Down
Loading