Codeunit 841 Cash Flow Management
- App
- Base Application
- Namespace
- Microsoft.CashFlow.Forecast
- Versions
- 17-28
Procedures, 21Events, 11Obsolete, 1
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/CashFlow/Forecast/CashFlowManagement.Codeunit.al843 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.CashFlow.Forecast;
using Microsoft.CashFlow.Account;
using Microsoft.CashFlow.Comment;
using Microsoft.CashFlow.Setup;
using Microsoft.CashFlow.Worksheet;
using Microsoft.Finance.Analysis;
using Microsoft.Finance.GeneralLedger.Account;
using Microsoft.Finance.GeneralLedger.Budget;
using Microsoft.Finance.VAT.Ledger;
using Microsoft.FixedAssets.FixedAsset;
using Microsoft.Foundation.NoSeries;
using Microsoft.Projects.Project.Planning;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.Payables;
using Microsoft.Purchases.Posting;
using Microsoft.Sales.Document;
using Microsoft.Sales.Posting;
using Microsoft.Sales.Receivables;
using System.Security.AccessControl;
using System.Threading;
codeunit 841 "Cash Flow Management"
{
trigger OnRun()
begin
end;
var
#pragma warning disable AA0470
SourceDataDoesNotExistErr: Label 'Source data does not exist for %1: %2.', Comment = 'Source data doesn''t exist for G/L Account: 8210.';
SourceDataDoesNotExistInfoErr: Label 'Source data does not exist in %1 for %2: %3.', Comment = 'Source data doesn''t exist in Vendor Ledger Entry for Document No.: PO000123.';
#pragma warning restore AA0470
SourceTypeNotSupportedErr: Label 'Source type is not supported.';
DefaultTxt: Label 'Default';
DummyDate: Date;
CashFlowTxt: Label 'CashFlow';
CashFlowForecastTxt: Label 'Cash Flow Forecast';
CashFlowAbbreviationTxt: Label 'CF', Comment = 'Abbreviation of Cash Flow';
UpdatingMsg: Label 'Updating Cash Flow Forecast...';
JobQueueEntryDescTxt: Label 'Auto-created for updating of cash flow figures. Can be deleted if not used. Will be recreated when the feature is activated.';
[Scope('OnPrem')]
procedure ShowSourceDocument(CFVariant: Variant)
var
CFRecordRef: RecordRef;
Handled: Boolean;
begin
OnBeforeShowSourceDocument(CFVariant, Handled);
if Handled then
exit;
CFRecordRef.GetTable(CFVariant);
case CFRecordRef.Number of
DATABASE::"Cash Flow Worksheet Line":
ShowSourceLocalCFWorkSheetLine(true, CFVariant);
DATABASE::"Cash Flow Forecast Entry":
ShowSourceLocalCFEntry(true, CFVariant);
end;
end;
[Scope('OnPrem')]
procedure ShowSource(CFVariant: Variant)
var
CFRecordRef: RecordRef;
Handled: Boolean;
begin
OnBeforeShowSource(CFVariant, Handled);
if Handled then
exit;
CFRecordRef.GetTable(CFVariant);
case CFRecordRef.Number of
DATABASE::"Cash Flow Worksheet Line":
ShowSourceLocalCFWorkSheetLine(false, CFVariant);
DATABASE::"Cash Flow Forecast Entry":
ShowSourceLocalCFEntry(false, CFVariant);
end;
end;
local procedure ShowSourceLocalCFWorkSheetLine(ShowDocument: Boolean; CFVariant: Variant)
var
CashFlowWorksheetLine: Record "Cash Flow Worksheet Line";
begin
CashFlowWorksheetLine := CFVariant;
CashFlowWorksheetLine.TestField("Source Type");
if CashFlowWorksheetLine."Source Type" <> CashFlowWorksheetLine."Source Type"::Tax then
CashFlowWorksheetLine.TestField("Source No.");
if CashFlowWorksheetLine."Source Type" = CashFlowWorksheetLine."Source Type"::"G/L Budget" then
CashFlowWorksheetLine.TestField("G/L Budget Name");
ShowSourceLocal(ShowDocument,
CashFlowWorksheetLine."Source Type",
CashFlowWorksheetLine."Source No.",
CashFlowWorksheetLine."G/L Budget Name",
CashFlowWorksheetLine."Document Date",
CashFlowWorksheetLine."Document No.");
end;
local procedure ShowSourceLocalCFEntry(ShowDocument: Boolean; CFVariant: Variant)
var
CashFlowForecastEntry: Record "Cash Flow Forecast Entry";
begin
CashFlowForecastEntry := CFVariant;
CashFlowForecastEntry.TestField("Source Type");
if CashFlowForecastEntry."Source Type" <> CashFlowForecastEntry."Source Type"::Tax then
CashFlowForecastEntry.TestField("Source No.");
if CashFlowForecastEntry."Source Type" = CashFlowForecastEntry."Source Type"::"G/L Budget" then
CashFlowForecastEntry.TestField("G/L Budget Name");
ShowSourceLocal(ShowDocument,
CashFlowForecastEntry."Source Type",
CashFlowForecastEntry."Source No.",
CashFlowForecastEntry."G/L Budget Name",
CashFlowForecastEntry."Document Date",
CashFlowForecastEntry."Document No.");
end;
local procedure ShowSourceLocal(ShowDocument: Boolean; SourceType: Enum "Cash Flow Source Type"; SourceNo: Code[20]; BudgetName: Code[10]; DocumentDate: Date; DocumentNo: Code[20])
var
CFWorksheetLine: Record "Cash Flow Worksheet Line";
IsHandled: Boolean;
begin
case SourceType of
CFWorksheetLine."Source Type"::"Liquid Funds":
ShowLiquidFunds(SourceNo, ShowDocument);
CFWorksheetLine."Source Type"::Receivables:
ShowCustomer(SourceNo, ShowDocument);
CFWorksheetLine."Source Type"::Payables:
ShowVendor(SourceNo, ShowDocument);
CFWorksheetLine."Source Type"::"Sales Orders":
ShowSalesOrder(SourceNo);
CFWorksheetLine."Source Type"::"Purchase Orders":
ShowPurchaseOrder(SourceNo);
CFWorksheetLine."Source Type"::"Cash Flow Manual Revenue":
ShowManualRevenue(SourceNo);
CFWorksheetLine."Source Type"::"Cash Flow Manual Expense":
ShowManualExpense(SourceNo);
CFWorksheetLine."Source Type"::"Fixed Assets Budget",
CFWorksheetLine."Source Type"::"Fixed Assets Disposal":
ShowFixedAsset(SourceNo);
CFWorksheetLine."Source Type"::"G/L Budget":
ShowGLBudget(BudgetName, SourceNo);
CFWorksheetLine."Source Type"::Job:
ShowJob(SourceNo, DocumentDate, DocumentNo);
CFWorksheetLine."Source Type"::Tax:
ShowTax(SourceNo, DocumentDate);
CFWorksheetLine."Source Type"::"Azure AI":
ShowAzureAIForecast();
else begin
IsHandled := false;
OnShowSourceLocalSourceTypeCase(SourceType, SourceNo, ShowDocument, DocumentNo, DocumentDate, BudgetName, IsHandled);
if not IsHandled then
Error(SourceTypeNotSupportedErr);
end;
end;
end;
local procedure ShowLiquidFunds(SourceNo: Code[20]; ShowDocument: Boolean)
var
GLAccount: Record "G/L Account";
begin
GLAccount.SetRange("No.", SourceNo);
if not GLAccount.FindFirst() then
Error(SourceDataDoesNotExistErr, GLAccount.TableCaption(), SourceNo);
if ShowDocument then
PAGE.Run(PAGE::"G/L Account Card", GLAccount)
else
PAGE.Run(PAGE::"Chart of Accounts", GLAccount);
end;
local procedure ShowCustomer(SourceNo: Code[20]; ShowDocument: Boolean)
var
CustLedgEntry: Record "Cust. Ledger Entry";
begin
CustLedgEntry.SetRange("Document No.", SourceNo);
if not CustLedgEntry.FindFirst() then
Error(SourceDataDoesNotExistInfoErr, CustLedgEntry.TableCaption(), CustLedgEntry.FieldCaption("Document No."), SourceNo);
if ShowDocument then
CustLedgEntry.ShowDoc()
else
PAGE.Run(0, CustLedgEntry);
end;
local procedure ShowVendor(SourceNo: Code[20]; ShowDocument: Boolean)
var
VendLedgEntry: Record "Vendor Ledger Entry";
begin
VendLedgEntry.SetRange("Document No.", SourceNo);
if not VendLedgEntry.FindFirst() then
Error(SourceDataDoesNotExistInfoErr, VendLedgEntry.TableCaption(), VendLedgEntry.FieldCaption("Document No."), SourceNo);
if ShowDocument then
VendLedgEntry.ShowDoc()
else
PAGE.Run(0, VendLedgEntry);
end;
local procedure ShowSalesOrder(SourceNo: Code[20])
var
SalesHeader: Record "Sales Header";
SalesOrder: Page "Sales Order";
SourceType: Enum "Cash Flow Source Type";
begin
SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order);
SalesHeader.SetRange("No.", SourceNo);
if not SalesHeader.FindFirst() then
Error(SourceDataDoesNotExistErr, SourceType::"Sales Orders", SourceNo);
SalesOrder.SetTableView(SalesHeader);
SalesOrder.Run();
end;
local procedure ShowPurchaseOrder(SourceNo: Code[20])
var
PurchaseHeader: Record "Purchase Header";
PurchaseOrder: Page "Purchase Order";
SourceType: Enum "Cash Flow Source Type";
begin
PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order);
PurchaseHeader.SetRange("No.", SourceNo);
if not PurchaseHeader.FindFirst() then
Error(SourceDataDoesNotExistErr, SourceType::"Purchase Orders", SourceNo);
PurchaseOrder.SetTableView(PurchaseHeader);
PurchaseOrder.Run();
end;
local procedure ShowManualRevenue(SourceNo: Code[20])
var
CFManualRevenue: Record "Cash Flow Manual Revenue";
CFManualRevenues: Page "Cash Flow Manual Revenues";
begin
CFManualRevenue.SetRange(Code, SourceNo);
if not CFManualRevenue.FindFirst() then
Error(SourceDataDoesNotExistErr, CFManualRevenues.Caption, SourceNo);
CFManualRevenues.SetTableView(CFManualRevenue);
CFManualRevenues.Run();
end;
local procedure ShowManualExpense(SourceNo: Code[20])
var
CFManualExpense: Record "Cash Flow Manual Expense";
CFManualExpenses: Page "Cash Flow Manual Expenses";
begin
CFManualExpense.SetRange(Code, SourceNo);
if not CFManualExpense.FindFirst() then
Error(SourceDataDoesNotExistErr, CFManualExpenses.Caption, SourceNo);
CFManualExpenses.SetTableView(CFManualExpense);
CFManualExpenses.Run();
end;
local procedure ShowFixedAsset(SourceNo: Code[20])
var
FixedAsset: Record "Fixed Asset";
begin
FixedAsset.SetRange("No.", SourceNo);
if not FixedAsset.FindFirst() then
Error(SourceDataDoesNotExistInfoErr, FixedAsset.TableCaption(), FixedAsset.FieldCaption("No."), SourceNo);
PAGE.Run(PAGE::"Fixed Asset Card", FixedAsset);
end;
local procedure ShowGLBudget(BudgetName: Code[10]; SourceNo: Code[20])
var
GLBudgetName: Record "G/L Budget Name";
GLAccount: Record "G/L Account";
Budget: Page Budget;
begin
if not GLAccount.Get(SourceNo) then
Error(SourceDataDoesNotExistErr, GLAccount.TableCaption(), SourceNo);
if not GLBudgetName.Get(BudgetName) then
Error(SourceDataDoesNotExistErr, GLBudgetName.TableCaption(), BudgetName);
Budget.SetBudgetName(BudgetName);
Budget.SetGLAccountFilter(SourceNo);
Budget.Run();
end;
local procedure ShowAzureAIForecast()
begin
end;
procedure CashFlowNameFullLength(CashFlowNo: Code[20]): Text[100]
var
CashFlowForecast: Record "Cash Flow Forecast";
begin
if CashFlowForecast.Get(CashFlowNo) then
exit(CashFlowForecast.Description);
exit('')
end;
procedure CashFlowAccountName(CashFlowAccountNo: Code[20]): Text[100]
var
CashFlowAccount: Record "Cash Flow Account";
begin
if CashFlowAccount.Get(CashFlowAccountNo) then
exit(CashFlowAccount.Name);
exit('')
end;
local procedure ShowJob(SourceNo: Code[20]; DocumentDate: Date; DocumentNo: Code[20])
var
JobPlanningLine: Record "Job Planning Line";
JobPlanningLines: Page "Job Planning Lines";
begin
JobPlanningLine.SetRange("Job No.", SourceNo);
JobPlanningLine.SetRange("Document Date", DocumentDate);
JobPlanningLine.SetRange("Document No.", DocumentNo);
JobPlanningLine.SetFilter("Line Type",
StrSubstNo('%1|%2',
JobPlanningLine."Line Type"::Billable,
JobPlanningLine."Line Type"::"Both Budget and Billable"));
if not JobPlanningLine.FindFirst() then
Error(SourceDataDoesNotExistErr, JobPlanningLines.Caption, SourceNo);
JobPlanningLines.SetTableView(JobPlanningLine);
JobPlanningLines.Run();
end;
local procedure ShowTax(SourceNo: Code[20]; TaxPayableDate: Date)
var
PurchaseHeader: Record "Purchase Header";
SalesHeader: Record "Sales Header";
VATEntry: Record "VAT Entry";
SalesOrderList: Page "Sales Order List";
PurchaseOrderList: Page "Purchase Order List";
SourceNum: Integer;
begin
Evaluate(SourceNum, SourceNo);
case SourceNum of
DATABASE::"Purchase Header":
begin
SetViewOnPurchaseHeaderForTaxCalc(PurchaseHeader, TaxPayableDate);
PurchaseOrderList.SkipShowingLinesWithoutVAT();
PurchaseOrderList.SetTableView(PurchaseHeader);
PurchaseOrderList.Run();
end;
DATABASE::"Sales Header":
begin
SetViewOnSalesHeaderForTaxCalc(SalesHeader, TaxPayableDate);
SalesOrderList.SkipShowingLinesWithoutVAT();
SalesOrderList.SetTableView(SalesHeader);
SalesOrderList.Run();
end;
DATABASE::"VAT Entry":
begin
SetViewOnVATEntryForTaxCalc(VATEntry, TaxPayableDate);
PAGE.Run(PAGE::"VAT Entries", VATEntry);
end;
end;
end;
procedure RecurrenceToRecurringFrequency(Recurrence: Option " ",Daily,Weekly,Monthly,Quarterly,Yearly) RecurringFrequency: Text
begin
case Recurrence of
Recurrence::Daily:
RecurringFrequency := '<1D>';
Recurrence::Weekly:
RecurringFrequency := '<1W>';
Recurrence::Monthly:
RecurringFrequency := '<1M>';
Recurrence::Quarterly:
RecurringFrequency := '<1Q>';
Recurrence::Yearly:
RecurringFrequency := '<1Y>';
else
RecurringFrequency := '';
end;
end;
procedure RecurringFrequencyToRecurrence(RecurringFrequency: DateFormula; var RecurrenceOut: Option " ",Daily,Weekly,Monthly,Quarterly,Yearly)
var
Daily: DateFormula;
Weekly: DateFormula;
Monthly: DateFormula;
Quarterly: DateFormula;
Yearly: DateFormula;
begin
Evaluate(Daily, '<1D>');
Evaluate(Weekly, '<1W>');
Evaluate(Monthly, '<1M>');
Evaluate(Quarterly, '<1Q>');
Evaluate(Yearly, '<1Y>');
case RecurringFrequency of
Daily:
RecurrenceOut := RecurrenceOut::Daily;
Weekly:
RecurrenceOut := RecurrenceOut::Weekly;
Monthly:
RecurrenceOut := RecurrenceOut::Monthly;
Quarterly:
RecurrenceOut := RecurrenceOut::Quarterly;
Yearly:
RecurrenceOut := RecurrenceOut::Yearly;
else
RecurrenceOut := RecurrenceOut::" ";
end;
end;
procedure CreateAndStartJobQueueEntry(UpdateFrequency: Option Never,Daily,Weekly)
var
JobQueueEntry: Record "Job Queue Entry";
JobQueueManagement: Codeunit "Job Queue Management";
begin
// Create a new job queue entry for Cash Flow Forecast
JobQueueEntry."No. of Minutes between Runs" := UpdateFrequencyToNoOfMinutes(UpdateFrequency);
JobQueueEntry."Object Type to Run" := JobQueueEntry."Object Type to Run"::Codeunit;
JobQueueEntry."Object ID to Run" := CODEUNIT::"Cash Flow Forecast Update";
JobQueueEntry.Description := CopyStr(JobQueueEntryDescTxt, 1, MaxStrLen(JobQueueEntry.Description));
JobQueueManagement.CreateJobQueueEntry(JobQueueEntry);
// Start it
CODEUNIT.Run(CODEUNIT::"Job Queue - Enqueue", JobQueueEntry);
end;
procedure DeleteJobQueueEntries()
var
JobQueueEntry: Record "Job Queue Entry";
JobQueueManagement: Codeunit "Job Queue Management";
begin
JobQueueManagement.DeleteJobQueueEntries(JobQueueEntry."Object Type to Run"::Codeunit, CODEUNIT::"Cash Flow Forecast Update");
end;
procedure GetCashAccountFilter() CashAccountFilter: Text
var
GLAccountCategory: Record "G/L Account Category";
begin
GLAccountCategory.SetRange("Additional Report Definition", GLAccountCategory."Additional Report Definition"::"Cash Accounts");
if not GLAccountCategory.FindSet() then
exit;
CashAccountFilter := GLAccountCategory.GetTotaling();
while GLAccountCategory.Next() <> 0 do
CashAccountFilter += '|' + GLAccountCategory.GetTotaling();
CashAccountFilter := CashAccountFilter.TrimStart('|').TrimEnd('|');
end;
procedure SetupCashFlow(LiquidFundsGLAccountFilter: Code[250])
var
CashFlowNoSeriesCode: Code[20];
begin
DeleteExistingSetup();
CreateCashFlowAccounts(LiquidFundsGLAccountFilter);
CashFlowNoSeriesCode := CreateCashFlowNoSeries();
CreateCashFlowSetup(CashFlowNoSeriesCode);
CreateCashFlowForecast();
CreateCashFlowChartSetup();
CreateCashFlowReportSelection();
end;
local procedure DeleteExistingSetup()
var
CashFlowForecast: Record "Cash Flow Forecast";
CashFlowAccount: Record "Cash Flow Account";
CashFlowAccountComment: Record "Cash Flow Account Comment";
CashFlowSetup: Record "Cash Flow Setup";
CashFlowWorksheetLine: Record "Cash Flow Worksheet Line";
CashFlowForecastEntry: Record "Cash Flow Forecast Entry";
CashFlowManualRevenue: Record "Cash Flow Manual Revenue";
CashFlowManualExpense: Record "Cash Flow Manual Expense";
CashFlowReportSelection: Record "Cash Flow Report Selection";
CashFlowChartSetup: Record "Cash Flow Chart Setup";
JobQueueEntry: Record "Job Queue Entry";
JobQueueManagement: Codeunit "Job Queue Management";
begin
CashFlowForecast.DeleteAll();
CashFlowAccount.DeleteAll();
CashFlowAccountComment.DeleteAll();
CashFlowSetup.DeleteAll();
CashFlowWorksheetLine.DeleteAll();
CashFlowForecastEntry.DeleteAll();
CashFlowManualRevenue.DeleteAll();
CashFlowManualExpense.DeleteAll();
CashFlowReportSelection.DeleteAll();
CashFlowChartSetup.DeleteAll();
JobQueueManagement.DeleteJobQueueEntries(JobQueueEntry."Object Type to Run"::Codeunit, CODEUNIT::"Cash Flow Forecast Update");
end;
local procedure CreateCashFlowAccounts(LiquidFundsGLAccountFilter: Code[250])
var
CashFlowAccount: Record "Cash Flow Account";
begin
CreateCashFlowAccount(CashFlowAccount."Source Type"::Receivables, '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::Payables, '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Sales Orders", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Purchase Orders", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Fixed Assets Budget", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Fixed Assets Disposal", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Liquid Funds", LiquidFundsGLAccountFilter);
CreateCashFlowAccount(CashFlowAccount."Source Type"::Job, '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Cash Flow Manual Expense", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::"Cash Flow Manual Revenue", '');
CreateCashFlowAccount(CashFlowAccount."Source Type"::Tax, '');
OnAfterCreateCashFlowAccounts(LiquidFundsGLAccountFilter);
end;
procedure CreateCashFlowAccount(SourceType: Enum "Cash Flow Source Type"; LiquidFundsGLAccountFilter: Code[250])
var
CashFlowAccount: Record "Cash Flow Account";
begin
InitCashFlowAccount(CashFlowAccount, SourceType);
if SourceType = CashFlowAccount."Source Type"::"Liquid Funds" then begin
CashFlowAccount."G/L Integration" := CashFlowAccount."G/L Integration"::Balance;
CashFlowAccount."G/L Account Filter" := LiquidFundsGLAccountFilter;
end;
CashFlowAccount.Insert();
end;
procedure GetNoFromSourceType(SourceType: Option): Text
var
CashFlowAccount: Record "Cash Flow Account";
begin
CashFlowAccount."Source Type" := "Cash Flow Source Type".FromInteger(SourceType);
exit(CopyStr(StrSubstNo('%1-%2', SourceType, Format(CashFlowAccount."Source Type")), 1, MaxStrLen(CashFlowAccount."No.")));
end;
local procedure InitCashFlowAccount(var CashFlowAccount: Record "Cash Flow Account"; SourceType: Enum "Cash Flow Source Type")
begin
CashFlowAccount.Init();
CashFlowAccount.Validate("Source Type", SourceType);
CashFlowAccount.Validate("No.", GetNoFromSourceType(SourceType.AsInteger()));
CashFlowAccount.Validate(Name, Format(CashFlowAccount."Source Type", MaxStrLen(CashFlowAccount.Name)));
end;
local procedure CreateCashFlowForecast()
var
CashFlowForecast: Record "Cash Flow Forecast";
begin
CashFlowForecast.Init();
CashFlowForecast.Validate("No.", DefaultTxt);
CashFlowForecast.Validate(Description, DefaultTxt);
CashFlowForecast.ValidateShowInChart(true);
CashFlowForecast."Overdue CF Dates to Work Date" := true;
CashFlowForecast.Insert();
end;
local procedure CreateCashFlowNoSeries(): Code[20]
var
NoSeries: Record "No. Series";
NoSeriesLine: Record "No. Series Line";
begin
if NoSeries.Get(CashFlowTxt) then
exit(NoSeries.Code);
NoSeries.Init();
NoSeries.Code := CashFlowTxt;
NoSeries.Description := CashFlowForecastTxt;
NoSeries."Default Nos." := true;
NoSeries."Manual Nos." := true;
NoSeries.Insert();
NoSeriesLine.Init();
NoSeriesLine."Series Code" := NoSeries.Code;
NoSeriesLine."Line No." := 10000;
NoSeriesLine.Validate("Starting No.", CashFlowAbbreviationTxt + '000001');
NoSeriesLine.Insert(true);
exit(NoSeries.Code);
end;
local procedure CreateCashFlowSetup(CashFlowNoSeriesCode: Code[20])
var
CashFlowSetup: Record "Cash Flow Setup";
CashFlowAccount: Record "Cash Flow Account";
begin
CashFlowSetup.Init();
CashFlowSetup.Validate("Cash Flow Forecast No. Series", CashFlowNoSeriesCode);
CashFlowSetup.Validate("Receivables CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::Receivables.AsInteger()));
CashFlowSetup.Validate("Payables CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::Payables.AsInteger()));
CashFlowSetup.Validate("Sales Order CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::"Sales Orders".AsInteger()));
CashFlowSetup.Validate("Purch. Order CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::"Purchase Orders".AsInteger()));
CashFlowSetup.Validate("FA Budget CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::"Fixed Assets Budget".AsInteger()));
CashFlowSetup.Validate(
"FA Disposal CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::"Fixed Assets Disposal".AsInteger()));
CashFlowSetup.Validate("Job CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::Job.AsInteger()));
CashFlowSetup.Validate("Tax CF Account No.", GetNoFromSourceType(CashFlowAccount."Source Type"::Tax.AsInteger()));
OnBeforeInsertOnCreateCashFlowSetup(CashFlowSetup, CashFlowNoSeriesCode);
CashFlowSetup.Insert();
end;
local procedure CreateCashFlowChartSetup()
var
User: Record User;
begin
if not User.FindSet() then
CreateCashFlowChartSetupForUser(UserId)
else
repeat
CreateCashFlowChartSetupForUser(User."User Name");
until User.Next() = 0;
end;
local procedure CreateCashFlowChartSetupForUser(UserName: Code[50])
var
CashFlowChartSetup: Record "Cash Flow Chart Setup";
begin
CashFlowChartSetup.Init();
CashFlowChartSetup."User ID" := UserName;
CashFlowChartSetup.Show := CashFlowChartSetup.Show::Combined;
CashFlowChartSetup."Start Date" := CashFlowChartSetup."Start Date"::"Working Date";
CashFlowChartSetup."Period Length" := CashFlowChartSetup."Period Length"::Month;
CashFlowChartSetup."Group By" := CashFlowChartSetup."Group By"::"Source Type";
CashFlowChartSetup.Insert();
end;
local procedure CreateCashFlowReportSelection()
var
CashFlowReportSelection: Record "Cash Flow Report Selection";
begin
CashFlowReportSelection.NewRecord();
CashFlowReportSelection.Validate("Report ID", 846);
CashFlowReportSelection.Insert();
end;
procedure UpdateCashFlowForecast(AzureAIEnabled: Boolean)
var
CashFlowForecast: Record "Cash Flow Forecast";
CashFlowSetup: Record "Cash Flow Setup";
SuggestWorksheetLines: Report "Suggest Worksheet Lines";
Window: Dialog;
Sources: array[16] of Boolean;
Index: Integer;
SourceType: Enum "Cash Flow Source Type";
Handled: Boolean;
begin
OnBeforeUpdateCashFlowForecast(AzureAIEnabled, Handled);
if Handled then
exit;
Window.Open(UpdatingMsg);
if not CashFlowSetup.Get() then
exit;
if not CashFlowForecast.Get(CashFlowSetup."CF No. on Chart in Role Center") then
exit;
UpdateCashFlowForecastManualPaymentHorizon(CashFlowForecast);
for Index := 1 to ArrayLen(Sources) do
Sources[Index] := true;
Sources[SourceType::"Azure AI".AsInteger()] := AzureAIEnabled;
SuggestWorksheetLines.InitializeRequest(
Sources, CashFlowSetup."CF No. on Chart in Role Center", CashFlowForecast."Default G/L Budget Name", true);
SuggestWorksheetLines.UseRequestPage := false;
OnBeforeRunSuggestWorksheetLinesOnUpdateCashFlowForecast(SuggestWorksheetLines);
SuggestWorksheetLines.Run();
CODEUNIT.Run(CODEUNIT::"Cash Flow Wksh.-Register Batch");
Window.Close();
end;
local procedure UpdateCashFlowForecastManualPaymentHorizon(var CashFlowForecast: Record "Cash Flow Forecast")
begin
CashFlowForecast.Validate("Manual Payments From", WorkDate());
CashFlowForecast.Validate("Manual Payments To", CalcDate('<+1Y>', WorkDate()));
CashFlowForecast.Modify();
end;
local procedure UpdateFrequencyToNoOfMinutes(UpdateFrequency: Option Never,Daily,Weekly): Integer
begin
case UpdateFrequency of
UpdateFrequency::Never:
exit(0);
UpdateFrequency::Daily:
exit(60 * 24);
UpdateFrequency::Weekly:
exit(60 * 24 * 7);
end;
end;
procedure SetViewOnPurchaseHeaderForTaxCalc(var PurchaseHeader: Record "Purchase Header"; TaxPaymentDueDate: Date)
var
CashFlowSetup: Record "Cash Flow Setup";
StartDate: Date;
EndDate: Date;
begin
DummyDate := 0D;
PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order);
PurchaseHeader.SetFilter("Document Date", '<>%1', DummyDate);
if TaxPaymentDueDate <> DummyDate then begin
CashFlowSetup.GetTaxPeriodStartEndDates(TaxPaymentDueDate, StartDate, EndDate);
PurchaseHeader.SetFilter("Document Date", StrSubstNo('%1..%2', StartDate, EndDate));
end;
PurchaseHeader.SetCurrentKey("Document Date");
PurchaseHeader.SetAscending("Document Date", true);
end;
procedure SetViewOnSalesHeaderForTaxCalc(var SalesHeader: Record "Sales Header"; TaxPaymentDueDate: Date)
var
CashFlowSetup: Record "Cash Flow Setup";
StartDate: Date;
EndDate: Date;
begin
SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order);
SalesHeader.SetFilter("Document Date", '<>%1', DummyDate);
if TaxPaymentDueDate <> DummyDate then begin
CashFlowSetup.GetTaxPeriodStartEndDates(TaxPaymentDueDate, StartDate, EndDate);
SalesHeader.SetFilter("Document Date", StrSubstNo('%1..%2', StartDate, EndDate));
end;
SalesHeader.SetCurrentKey("Document Date");
SalesHeader.SetAscending("Document Date", true);
end;
procedure SetViewOnVATEntryForTaxCalc(var VATEntry: Record "VAT Entry"; TaxPaymentDueDate: Date)
var
CashFlowSetup: Record "Cash Flow Setup";
StartDate: Date;
EndDate: Date;
begin
VATEntry.SetFilter(Type, StrSubstNo('%1|%2', VATEntry.Type::Purchase, VATEntry.Type::Sale));
VATEntry.SetFilter("VAT Calculation Type", StrSubstNo('<>%1', VATEntry."VAT Calculation Type"::"Reverse Charge VAT"));
VATEntry.SetRange(Closed, false);
VATEntry.SetFilter(Amount, '<>%1', 0);
VATEntry.SetFilter("Document Date", '<>%1', DummyDate);
if TaxPaymentDueDate <> DummyDate then begin
CashFlowSetup.GetTaxPeriodStartEndDates(TaxPaymentDueDate, StartDate, EndDate);
VATEntry.SetFilter("Document Date", StrSubstNo('%1..%2', StartDate, EndDate));
end;
VATEntry.SetCurrentKey("Document Date");
VATEntry.SetAscending("Document Date", true);
OnAfterSetViewOnVATEntryForTaxCalc(VATEntry, TaxPaymentDueDate, DummyDate);
end;
procedure GetTaxAmountFromSalesOrder(SalesHeader: Record "Sales Header"): Decimal
var
NewSalesLine: Record "Sales Line";
NewSalesLineLCY: Record "Sales Line";
SalesPost: Codeunit "Sales-Post";
QtyType: Option General,Invoicing,Shipping;
VATAmount: Decimal;
VATAmountText: Text[30];
ProfitLCY: Decimal;
ProfitPct: Decimal;
TotalAdjCostLCY: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetTaxAmountFromSalesOrder(SalesHeader, VATAmount, IsHandled);
if IsHandled then
exit(VATAmount);
SalesPost.SumSalesLines(
SalesHeader, QtyType::Invoicing, NewSalesLine, NewSalesLineLCY,
VATAmount, VATAmountText, ProfitLCY, ProfitPct, TotalAdjCostLCY);
exit(-1 * VATAmount);
end;
procedure GetTaxAmountFromPurchaseOrder(PurchaseHeader: Record "Purchase Header"): Decimal
var
NewPurchLine: Record "Purchase Line";
NewPurchLineLCY: Record "Purchase Line";
PurchPost: Codeunit "Purch.-Post";
QtyType: Option General,Invoicing,Shipping;
VATAmount: Decimal;
VATAmountText: Text[30];
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetTaxAmountFromPurchaseOrder(PurchaseHeader, VATAmount, IsHandled);
if IsHandled then
exit(VATAmount);
PurchPost.SumPurchLines(
PurchaseHeader, QtyType::Invoicing, NewPurchLine, NewPurchLineLCY, VATAmount, VATAmountText);
exit(VATAmount);
end;
procedure GetTotalAmountFromSalesOrder(SalesHeader: Record "Sales Header") Result: Decimal
begin
SalesHeader.CalcFields("Amount Including VAT");
Result := SalesHeader."Amount Including VAT";
OnAfterGetTotalAmountFromSalesOrder(SalesHeader, Result);
end;
procedure GetTotalAmountFromPurchaseOrder(PurchaseHeader: Record "Purchase Header"): Decimal
begin
PurchaseHeader.CalcFields("Amount Including VAT");
exit(PurchaseHeader."Amount Including VAT");
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetTaxAmountFromPurchaseOrder(PurchaseHeader: Record "Purchase Header"; var VATAmount: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetTaxAmountFromSalesOrder(SalesHeader: Record "Sales Header"; var VATAmount: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeShowSource(CFVariant: Variant; var Handled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeShowSourceDocument(CFVariant: Variant; var Handled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateCashFlowForecast(AzureAIEnabled: Boolean; var Handled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnShowSourceLocalSourceTypeCase(SourceType: Enum "Cash Flow Source Type"; SourceNo: Code[20]; ShowDocument: Boolean; DocumentNo: Code[20]; DocumentDate: Date; BudgetName: Code[10]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetViewOnVATEntryForTaxCalc(var VATEntry: Record "VAT Entry"; TaxPaymentDueDate: Date; DummyDate: Date)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCreateCashFlowAccounts(LiquidFundsGLAccountFilter: Code[250])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetTotalAmountFromSalesOrder(SalesHeader: Record "Sales Header"; var Result: Decimal)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeInsertOnCreateCashFlowSetup(var CashFlowSetup: Record "Cash Flow Setup"; CashFlowNoSeriesCode: Code[20])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRunSuggestWorksheetLinesOnUpdateCashFlowForecast(var SuggestWorksheetLines: Report "Suggest Worksheet Lines")
begin
end;
}