Codeunit 70 Purch.-Calc.Discount, source in 29
Source29
src/Layers/W1/BaseApp/Purchases/Document/PurchCalcDiscount.Codeunit.al324 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Purchases.Document;
using Microsoft.Finance.Currency;
using Microsoft.Finance.VAT.Calculation;
using Microsoft.Purchases.Setup;
using Microsoft.Purchases.Vendor;
using Microsoft.Utilities;
codeunit 70 "Purch.-Calc.Discount"
{
Permissions = tabledata "Purchase Header" = rm,
tabledata "Purchase Line" = rm;
TableNo = "Purchase Line";
trigger OnRun()
var
TempPurchHeader: Record "Purchase Header";
TempPurchLine: Record "Purchase Line";
begin
PurchLine.Copy(Rec);
TempPurchHeader.Get(Rec."Document Type", Rec."Document No.");
OnOnRunOnBeforeUpdateHeader(TempPurchHeader, Rec);
UpdateHeader := true;
CalculateInvoiceDiscount(TempPurchHeader, TempPurchLine);
if Rec.Get(PurchLine."Document Type", PurchLine."Document No.", PurchLine."Line No.") then;
end;
var
#pragma warning disable AA0074
Text000: Label 'Service Charge';
#pragma warning restore AA0074
PurchLine: Record "Purchase Line";
VendInvDisc: Record "Vendor Invoice Disc.";
VendPostingGr: Record "Vendor Posting Group";
Currency: Record Currency;
InvDiscBase: Decimal;
ChargeBase: Decimal;
CurrencyDate: Date;
UpdateHeader: Boolean;
procedure CalculateInvoiceDiscount(var PurchHeader: Record "Purchase Header"; var PurchLine2: Record "Purchase Line")
var
TempVATAmountLine: Record "VAT Amount Line" temporary;
PurchSetup: Record "Purchases & Payables Setup";
TempServiceChargeLine: Record "Purchase Line" temporary;
PurchCalcDiscByType: Codeunit "Purch - Calc Disc. By Type";
DiscountNotificationMgt: Codeunit "Discount Notification Mgt.";
IsHandled: Boolean;
begin
PurchSetup.Get();
IsHandled := false;
OnBeforeCalcPurchaseDiscount(PurchHeader, IsHandled, PurchLine2, UpdateHeader, PurchLine);
if IsHandled then
exit;
PurchLine.LockTable();
PurchHeader.TestField("Vendor Posting Group");
VendPostingGr.Get(PurchHeader."Vendor Posting Group");
PurchLine2.Reset();
PurchLine2.SetRange("Document Type", PurchLine."Document Type");
PurchLine2.SetRange("Document No.", PurchLine."Document No.");
PurchLine2.SetFilter(Type, '<>0');
PurchLine2.SetRange("System-Created Entry", true);
PurchLine2.SetRange(Type, PurchLine2.Type::"G/L Account");
PurchLine2.SetRange("No.", VendPostingGr."Service Charge Acc.");
PurchLine2.SetLoadFields("Unit Cost", "Receipt No.", "Qty. Rcd. Not Invoiced (Base)");
if PurchLine2.FindSet(true) then
repeat
PurchLine2."Direct Unit Cost" := 0;
PurchLine2.Modify();
TempServiceChargeLine := PurchLine2;
TempServiceChargeLine.Insert();
until PurchLine2.Next() = 0;
PurchLine2.Reset();
PurchLine2.SetLoadFields();
PurchLine2.SetRange("Document Type", PurchLine."Document Type");
PurchLine2.SetRange("Document No.", PurchLine."Document No.");
PurchLine2.SetFilter(Type, '<>0');
OnCalculateInvoiceDiscountOnBeforeFindForCalcVATAmountLines(PurchHeader, PurchLine2, UpdateHeader);
if PurchLine2.FindFirst() then;
PurchLine2.CalcVATAmountLines(0, PurchHeader, PurchLine2, TempVATAmountLine);
InvDiscBase :=
TempVATAmountLine.GetTotalInvDiscBaseAmount(
PurchHeader."Prices Including VAT", PurchHeader."Currency Code");
ChargeBase :=
TempVATAmountLine.GetTotalLineAmount(
PurchHeader."Prices Including VAT", PurchHeader."Currency Code");
if UpdateHeader then
PurchHeader.Modify();
if PurchHeader."Posting Date" = 0D then
CurrencyDate := WorkDate()
else
CurrencyDate := PurchHeader."Posting Date";
GetVendInvDisc(PurchHeader, ChargeBase);
OnCalculateInvoiceDiscountOnBeforeCheckVendInvDiscServiceCharge(VendInvDisc, PurchHeader, CurrencyDate, ChargeBase);
if VendInvDisc."Service Charge" <> 0 then begin
OnCalculateInvoiceDiscountOnBeforeCurrencyInitialize(VendPostingGr);
Currency.Initialize(PurchHeader."Currency Code");
if not UpdateHeader then
PurchLine2.SetPurchHeader(PurchHeader);
if not TempServiceChargeLine.IsEmpty() then begin
TempServiceChargeLine.FindLast();
PurchLine2.Get(PurchLine."Document Type", PurchLine."Document No.", TempServiceChargeLine."Line No.");
if PurchHeader."Prices Including VAT" then
PurchLine2.Validate(
"Direct Unit Cost",
Round(
(1 + PurchLine2."VAT %" / 100) * VendInvDisc."Service Charge",
Currency."Unit-Amount Rounding Precision"))
else
PurchLine2.Validate("Direct Unit Cost", VendInvDisc."Service Charge");
PurchLine2.Modify();
end else begin
PurchLine2.Reset();
PurchLine2.SetRange("Document Type", PurchLine."Document Type");
PurchLine2.SetRange("Document No.", PurchLine."Document No.");
PurchLine2.FindLast();
PurchLine2.Init();
if not UpdateHeader then
PurchLine2.SetPurchHeader(PurchHeader);
PurchLine2."Line No." := PurchLine2."Line No." + 10000;
PurchLine2.Type := PurchLine2.Type::"G/L Account";
PurchLine2.Validate("No.", VendPostingGr.GetServiceChargeAccount());
PurchLine2.Description := Text000;
PurchLine2.Validate(Quantity, 1);
OnCalculateInvoiceDiscountOnAfterPurchLine2ValidateQuantity(PurchHeader, PurchLine2, VendInvDisc);
if PurchLine2."Document Type" in
[PurchLine2."Document Type"::"Return Order", PurchLine2."Document Type"::"Credit Memo"]
then
PurchLine2.Validate("Return Qty. to Ship", PurchLine2.Quantity)
else
PurchLine2.Validate("Qty. to Receive", PurchLine2.Quantity);
if PurchHeader."Prices Including VAT" then
PurchLine2.Validate(
"Direct Unit Cost",
Round(
(1 + PurchLine2."VAT %" / 100) * VendInvDisc."Service Charge",
Currency."Unit-Amount Rounding Precision"))
else
PurchLine2.Validate("Direct Unit Cost", VendInvDisc."Service Charge");
PurchLine2."System-Created Entry" := true;
OnCalculateInvoiceDiscountOnbeforePurchLineInsert(PurchLine2, PurchHeader);
PurchLine2.Insert();
end;
PurchLine2.CalcVATAmountLines(0, PurchHeader, PurchLine2, TempVATAmountLine);
end else
if TempServiceChargeLine.FindSet(false) then
repeat
if (TempServiceChargeLine."Receipt No." = '') and (TempServiceChargeLine."Qty. Rcd. Not Invoiced (Base)" = 0) then begin
PurchLine2 := TempServiceChargeLine;
IsHandled := false;
OnCalculateInvoiceDiscountOnBeforeDeletePurchaseLine(UpdateHeader, PurchLine2, IsHandled);
if not IsHandled then
PurchLine2.Delete(true);
end;
until TempServiceChargeLine.Next() = 0;
if VendInvDiscRecExists(PurchHeader."Invoice Disc. Code") then begin
if InvDiscBase <> ChargeBase then
GetVendInvDisc(PurchHeader, InvDiscBase);
DiscountNotificationMgt.NotifyAboutMissingSetup(
PurchSetup.RecordId, PurchHeader."Gen. Bus. Posting Group", PurchLine2."Gen. Prod. Posting Group",
PurchSetup."Discount Posting", PurchSetup."Discount Posting"::"Line Discounts");
PurchHeader."Invoice Discount Calculation" := PurchHeader."Invoice Discount Calculation"::"%";
PurchHeader."Invoice Discount Value" := VendInvDisc."Discount %";
if UpdateHeader then
PurchHeader.Modify();
TempVATAmountLine.SetInvoiceDiscountPercent(
VendInvDisc."Discount %", PurchHeader."Currency Code",
PurchHeader."Prices Including VAT", PurchSetup."Calc. Inv. Disc. per VAT ID",
PurchHeader."VAT Base Discount %");
PurchLine2.UpdateVATOnLines(0, PurchHeader, PurchLine2, TempVATAmountLine);
UpdatePrepmtLineAmount(PurchHeader);
end;
PurchCalcDiscByType.ResetRecalculateInvoiceDisc(PurchHeader);
OnAfterCalcPurchaseDiscount(PurchHeader);
end;
local procedure GetVendInvDisc(var PurchHeader: Record "Purchase Header"; BaseAmount: Decimal)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetVendInvDisc(PurchHeader, CurrencyDate, ChargeBase, InvDiscBase, BaseAmount, IsHandled, VendInvDisc);
if IsHandled then
exit;
VendInvDisc.GetRec(PurchHeader."Invoice Disc. Code", PurchHeader."Currency Code", CurrencyDate, BaseAmount);
end;
local procedure VendInvDiscRecExists(InvDiscCode: Code[20]): Boolean
var
VendInvDisc: Record "Vendor Invoice Disc.";
begin
VendInvDisc.SetRange(Code, InvDiscCode);
exit(VendInvDisc.FindFirst());
end;
procedure CalculateIncDiscForHeader(var PurchHeader: Record "Purchase Header")
var
PurchSetup: Record "Purchases & Payables Setup";
IsHandled: Boolean;
begin
PurchSetup.Get();
if not PurchSetup."Calc. Inv. Discount" then
exit;
PurchLine."Document Type" := PurchHeader."Document Type";
PurchLine."Document No." := PurchHeader."No.";
UpdateHeader := true;
IsHandled := false;
OnCalculateIncDiscForHeaderOnBeforeCalculateInvoiceDiscount(PurchHeader, PurchLine, UpdateHeader, IsHandled);
if not IsHandled then
CalculateInvoiceDiscount(PurchHeader, PurchLine);
end;
procedure CalculateInvoiceDiscountOnLine(var PurchLineToUpdate: Record "Purchase Line")
var
PurchHeaderTemp: Record "Purchase Header";
begin
PurchLine.Copy(PurchLineToUpdate);
PurchHeaderTemp.Get(PurchLine."Document Type", PurchLine."Document No.");
UpdateHeader := false;
CalculateInvoiceDiscount(PurchHeaderTemp, PurchLine);
if PurchLineToUpdate.Get(PurchLineToUpdate."Document Type", PurchLineToUpdate."Document No.", PurchLineToUpdate."Line No.") then;
end;
local procedure UpdatePrepmtLineAmount(PurchaseHeader: Record "Purchase Header")
var
PurchaseLine: Record "Purchase Line";
begin
if (PurchaseHeader."Invoice Discount Calculation" = PurchaseHeader."Invoice Discount Calculation"::"%") and
(PurchaseHeader."Prepayment %" > 0) and (PurchaseHeader."Invoice Discount Value" > 0) and
(PurchaseHeader."Invoice Discount Value" + PurchaseHeader."Prepayment %" >= 100)
then begin
PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
PurchaseLine.SetLoadFields(Type, Quantity, "Direct Unit Cost", "Qty. to Invoice", "Prepayment %", "Prepmt. Line Amount", Amount);
if PurchaseLine.FindSet(true) then
repeat
if not PurchaseLine.ZeroAmountLine(0) and (PurchaseLine."Prepayment %" = PurchaseHeader."Prepayment %") then begin
PurchaseLine."Prepmt. Line Amount" := PurchaseLine.Amount;
PurchaseLine.Modify();
end;
until PurchaseLine.Next() = 0;
end;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcPurchaseDiscount(var PurchaseHeader: Record "Purchase Header"; var IsHandled: Boolean; var PurchaseLine: Record "Purchase Line"; UpdateHeader: Boolean; var GlobalPurchaseLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalcPurchaseDiscount(var PurchaseHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetVendInvDisc(var PurchaseHeader: Record "Purchase Header"; CurrencyDate: Date; ChargeBase: Decimal; InvDiscBase: Decimal; BaseAmount: Decimal; var IsHandled: Boolean; var VendInvDisc: Record "Vendor Invoice Disc.")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnAfterPurchLine2ValidateQuantity(var PurchHeader: Record "Purchase Header"; var PurchLine2: Record "Purchase Line"; var VendInvDisc: Record "Vendor Invoice Disc.")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnBeforeCurrencyInitialize(var VendorPostingGroup: record "Vendor Posting Group")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnBeforeCheckVendInvDiscServiceCharge(var VendorInvoiceDisc: Record "Vendor Invoice Disc."; var PurchaseHeader: Record "Purchase Header"; CurrencyDate: Date; ChargeBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnbeforePurchLineInsert(var PurchaseLine: Record "Purchase Line"; PurchHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateIncDiscForHeaderOnBeforeCalculateInvoiceDiscount(var PurchHeader: Record "Purchase Header"; var PurchLine: Record "Purchase Line"; UpdateHeader: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnBeforeFindForCalcVATAmountLines(var PurchHeader: Record "Purchase Header"; var PurchLine2: Record "Purchase Line"; UpdateHeader: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateInvoiceDiscountOnBeforeDeletePurchaseLine(UpdateHeader: Boolean; var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnOnRunOnBeforeUpdateHeader(var PurchaseHeader: Record "Purchase Header"; var PurchaseLine: Record "Purchase Line")
begin
end;
}