Report 5810 Costing Errors Detection
- App
- Base Application
- Namespace
- Microsoft.Inventory.Costing
- Versions
- 24-28
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Inventory/Costing/CostingErrorsDetection.Report.al915 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.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Ledger;
using System.Utilities;
report 5810 "Costing Errors Detection"
{
Caption = 'Costing Errors Detection';
ToolTip = 'Run the diagnostic report to detect issues in item related data that may cause costing calculation errors.';
PreviewMode = PrintLayout;
ApplicationArea = Basic, Suite;
DefaultRenderingLayout = RDLCLayout;
dataset
{
dataitem(ErrorGroup; "Integer")
{
DataItemTableView = sorting(Number);
column(CompanyName; CompanyName())
{
}
column(Today; Format(Today(), 0, 4))
{
}
column(UserID; UserId())
{
}
column(ShowCaption; ShowCaption())
{
}
column(Number_ErrorGroup; Number)
{
}
dataitem(Item; Item)
{
PrintOnlyIfDetail = true;
RequestFilterFields = "No.";
column(No_Item; "No.")
{
}
column(Description_Item; Description)
{
IncludeCaption = true;
}
dataitem(ItemCheck; Item)
{
DataItemLink = "No." = field("No.");
DataItemTableView = sorting("No.");
dataitem(ItemErrors; "Integer")
{
DataItemTableView = sorting(Number);
column(ErrorText_ItemErrors; ErrorText[Number])
{
}
column(Number_ItemErrors; Number)
{
}
trigger OnPreDataItem()
begin
SetRange(Number, 1, CompressArray(ErrorText));
end;
}
trigger OnAfterGetRecord()
begin
ClearErrorText();
case ErrorGroupIndex of
0:
CheckItem("No.");
end;
if CompressArray(ErrorText) = 0 then
CurrReport.Skip();
end;
}
dataitem("Item Ledger Entry"; "Item Ledger Entry")
{
DataItemLink = "Item No." = field("No.");
DataItemTableView = sorting("Item No.");
column(EntryNo_ItemLedgerEntry; "Entry No.")
{
IncludeCaption = true;
}
column(EntryType_ItemLedgerEntry; "Entry Type")
{
IncludeCaption = true;
}
column(EntryTypeFormat_ItemLedgerEntry; Format("Entry Type"))
{
}
column(ItemNo_ItemLedgerEntry; "Item No.")
{
IncludeCaption = true;
}
column(Quantity_ItemLedgerEntry; Quantity)
{
IncludeCaption = true;
}
column(RemainingQuantity_ItemLedgerEntry; "Remaining Quantity")
{
IncludeCaption = true;
}
column(Positive_ItemLedgerEntry; Positive)
{
IncludeCaption = true;
}
column(Open_ItemLedgerEntry; Open)
{
IncludeCaption = true;
}
column(PostingDate_ItemLedgerEntry; "Posting Date")
{
IncludeCaption = true;
}
dataitem(Errors; "Integer")
{
DataItemTableView = sorting(Number);
column(ErrorText_Errors; ErrorText[Number])
{
}
column(Number_Errors; Number)
{
}
trigger OnPreDataItem()
begin
SetRange(Number, 1, CompressArray(ErrorText))
end;
}
trigger OnAfterGetRecord()
begin
Window.Update(3, "Entry No.");
ClearErrorText();
case ErrorGroupIndex of
0:
CheckBasicData();
1:
CheckItemLedgEntryQty();
2:
CheckApplicationQty();
4:
CheckValuedByAverageCost();
5:
CheckValuationDate();
6:
CheckRemainingExpectedAmount();
7:
CheckOutputCompletelyInvdDate();
end;
if CompressArray(ErrorText) = 0 then
CurrReport.Skip();
end;
trigger OnPreDataItem()
begin
case ErrorGroupIndex of
0: // Basic Data Test
;
1: // Qty. Check Item Entry <--> Item Appl. Entry
begin
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Item Ledger Entry No.");
end;
2: // Application Qty. Check
begin
SetRange(Positive, true);
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Inbound Item Entry No.");
end;
3: // Check Related Inb. - Outb. Value Entry
begin
SetRange(Positive, true);
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Item Ledger Entry No.");
end;
4: // Check Valued By Average Cost
begin
SetRange(Positive, false);
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Item Ledger Entry No.");
end;
5: // Check Valuation Date
begin
SetRange(Positive, true);
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Inbound Item Entry No.");
end;
6: // Check remaining expected cost on closed item ledger entry
begin
ItemApplEntry.Reset();
ItemApplEntry.SetCurrentKey("Outbound Item Entry No.", "Item Ledger Entry No.");
end;
7: // Check Output Completely Invd. Date' in Table 339
;
end;
end;
}
dataitem("Value Entry"; "Value Entry")
{
DataItemLink = "Item No." = field("No.");
DataItemTableView = sorting("Item No.", "Posting Date", "Item Ledger Entry Type", "Entry Type", "Variance Type", "Item Charge No.", "Location Code", "Variant Code");
column(EntryNo_ValueEntry; "Entry No.")
{
}
column(ItemNo_ValueEntry; "Item No.")
{
}
column(ItemLedgerEntryType_ValueEntry; "Item Ledger Entry Type")
{
}
column(PostingDate_ValueEntry; "Posting Date")
{
}
column(ItemLedgerEntryQuantity_ValueEntry; "Item Ledger Entry Quantity")
{
}
trigger OnAfterGetRecord()
var
ItemLedgEntry: Record "Item Ledger Entry";
begin
if ItemLedgEntry.Get("Item Ledger Entry No.") then
CurrReport.Skip();
if Item2.Get("Item No.") then begin
TempItem := Item2;
if TempItem.Insert() then;
end;
end;
trigger OnPreDataItem()
begin
if (ErrorGroupIndex <> 8) or (Item."No." = '') then
CurrReport.Break();
if not CheckItemLedgEntryExists then
CurrReport.Break();
end;
}
trigger OnAfterGetRecord()
begin
if Type <> Type::Inventory then
CurrReport.Skip();
Window.Update(2, "No.");
end;
trigger OnPreDataItem()
begin
if ErrorGroupIndex in [3, 4] then begin
if CostingMethodFiltered then
CurrReport.Break()
else
SetRange("Costing Method", "Costing Method"::Average);
end else
SetRange("Costing Method");
end;
}
trigger OnAfterGetRecord()
begin
ErrorGroupIndex := Number;
case ErrorGroupIndex of
0:
if not BasicDataTest then
CurrReport.Skip()
else
Window.Update(1, BasicDataTestLbl);
1:
if not QtyCheckItemLedgEntry then
CurrReport.Skip()
else
Window.Update(1, ItemLedgEntryItemApplEntryCheckLbl);
2:
if not ApplicationQtyCheck then
CurrReport.Skip()
else
Window.Update(1, ApplicationQtyCheckLbl);
4:
if not ValuedByAverageCheck then
CurrReport.Skip()
else
Window.Update(1, CheckValuedByAverageCostLbl);
5:
if not ValuationDateCheck then
CurrReport.Skip()
else
Window.Update(1, CheckValuationDateLbl);
6:
if not RemExpectedOnClosedEntry then
CurrReport.Skip()
else
Window.Update(1, CheckExpectedCostOnClosedEntryLbl);
7:
if not OutputCompletelyInvd then
CurrReport.Skip()
else
Window.Update(1, CheckOutputCompletelyInvdDateLbl);
8:
if not CheckItemLedgEntryExists then
CurrReport.Skip()
else
Window.Update(1, ValueEntriesWithMissingILELbl);
end;
end;
trigger OnPreDataItem()
begin
SetRange(Number, 0, 8);
end;
}
dataitem(Summary; "Integer")
{
DataItemTableView = sorting(Number);
column(ItemSummaryCaption; ItemSummaryLbl)
{
}
column(No_Summary; TempItem."No.")
{
}
column(Description_Summary; TempItem.Description)
{
}
column(Number_Summary; Number)
{
}
trigger OnAfterGetRecord()
begin
if Number = 1 then
TempItem.FindFirst()
else
TempItem.Next();
end;
trigger OnPreDataItem()
begin
SetRange(Number, 1, TempItem.Count());
end;
}
}
requestpage
{
SaveValues = true;
layout
{
area(content)
{
field("Basic Item Test"; BasicDataTest)
{
Caption = 'Check basic data';
ToolTip = 'Specifies if you want to check the correctness of the item ledger entries and the value entries.';
}
field("Qty. Check Item Ledger Entry"; QtyCheckItemLedgEntry)
{
Caption = 'Check Item Ledger Entry vs Item Application Entry';
ToolTip = 'Specifies if you want to check the correctness of the item application entries.';
}
field("Application Qty. Check"; ApplicationQtyCheck)
{
Caption = 'Check Item Application quantity';
ToolTip = 'Specifies if you want to check the correctness of the quantity between the item ledger entries and the item application entries.';
}
field("Valued by Average Check"; ValuedByAverageCheck)
{
Caption = 'Check Valued By Average Cost';
ToolTip = 'Specifies if you want to check the correctness of the valued by average cost field in the value entries.';
}
field("Valuation Date Check"; ValuationDateCheck)
{
Caption = 'Check Valuation Date';
ToolTip = 'Specifies if you want to check the correctness of the valuation date in the value entries.';
}
field("Rem. Expected On Closed Entry"; RemExpectedOnClosedEntry)
{
Caption = 'Check Expected Cost on completely invoiced entries';
ToolTip = 'Specifies if you want to check the correctness of the expected cost.';
}
field("Check Item Ledg. Entry Exists"; CheckItemLedgEntryExists)
{
Caption = 'Check Value Entries with missing Item Ledger Entry';
ToolTip = 'Specifies if you want to check if the item ledger entries exist for the value entries.';
}
}
}
}
rendering
{
layout(RDLCLayout)
{
Type = RDLC;
LayoutFile = './Inventory/Costing/CostingErrorsDetection.rdlc';
Summary = 'Report layout made in the legacy RDLC format. Use an RDLC editor to modify the layout.';
}
}
labels
{
ReportName = 'Costing_Errors_Detection';
PageNoCaption = 'Page';
}
trigger OnPostReport()
begin
Window.Close();
end;
trigger OnPreReport()
var
DummyItem: Record Item;
begin
if not (BasicDataTest or QtyCheckItemLedgEntry or ApplicationQtyCheck or
ValuedByAverageCheck or ValuationDateCheck or RemExpectedOnClosedEntry or
OutputCompletelyInvd or CheckItemLedgEntryExists)
then
Error(NoChecksSelectedErr);
if not "Item Ledger Entry".FindSet() then
Error(NoItemLedgerEntriesToCheckErr);
Window.Open(ProgressWindow1Lbl + ProgressWindow2Lbl + ProgressWindow3Lbl);
DummyItem.SetRange("Costing Method", DummyItem."Costing Method"::Average);
if Item.GetFilter("Costing Method") <> '' then
if Item.GetFilter("Costing Method") <> DummyItem.GetFilter("Costing Method") then
CostingMethodFiltered := true;
end;
var
ItemApplEntry: Record "Item Application Entry";
Item2: Record Item;
TempItem: Record Item temporary;
ErrorText: array[20] of Text;
ErrorGroupIndex: Integer;
ErrorIndex: Integer;
BasicDataTest: Boolean;
QtyCheckItemLedgEntry: Boolean;
ApplicationQtyCheck: Boolean;
ValuedByAverageCheck: Boolean;
ValuationDateCheck: Boolean;
RemExpectedOnClosedEntry: Boolean;
OutputCompletelyInvd: Boolean;
CheckItemLedgEntryExists: Boolean;
CostingMethodFiltered: Boolean;
Window: Dialog;
ProgressWindow1Lbl: Label 'Function #1##########################\', Comment = '%1: Function name';
ProgressWindow2Lbl: Label 'Item #2##########################\', Comment = '%1: Item No.';
ProgressWindow3Lbl: Label 'Item Ledger Entry #3##########################', Comment = '%1: Entry No.';
ItemSummaryLbl: Label 'Item Summary';
BasicDataTestLbl: Label 'Check basic data';
ItemLedgEntryItemApplEntryCheckLbl: Label 'Check Item Ledger Entry vs Item Application Entry';
ApplicationQtyCheckLbl: Label 'Check Item Application quantity';
CheckValuationDateLbl: Label 'Check Valuation Date';
CheckValuedByAverageCostLbl: Label 'Check Valued By Average Cost';
ValueEntriesWithMissingILELbl: Label 'Check Value Entries with missing Item Ledger Entry';
CheckExpectedCostForInvoicedLbl: Label 'Check Expected Cost on completely invoiced entries';
CheckCompletelyInvoicedDateLbl: Label 'Check Completely Invoiced date';
CheckExpectedCostOnClosedEntryLbl: Label 'Check Expected Cost on a closed entry';
CheckOutputCompletelyInvdDateLbl: Label 'Check output Completely Invoiced date';
NoChecksSelectedErr: Label 'You must select one or more of the data checks.';
NoItemLedgerEntriesToCheckErr: Label 'There are no Item Ledger Entries to check.';
WrongValueEntryFieldValueErr: Label 'The value of the Valued by Average Cost field in the corresponding Value Entries is not correct.';
ItemLedgerEntryQtyZeroErr: Label 'The quantity must not be 0 on Item Ledger Entry.';
ItemLedgerEntryFieldValueErr: Label '%1 must be %2.', Comment = '%1, %2: Field values in Item Ledger Entry table';
ValueEntryFieldValueErr: Label 'The linked Value Entries do not all have the same value of %1.', Comment = '%1: Field value in Value Entry table';
NoValueEntryForILEErr: Label 'There are no Value Entries for this Item Ledger Entry.';
NoItemApplEntryForILEErr: Label 'There are no Item Application Entries for this Item Ledger Entry.';
BlankLastInvoicedDateErr: Label 'Blank Last Invoice Date on an Item Ledger Entry which has been invoiced.';
ItemApplEntryExistsForNotAppliedILEErr: Label 'An Item Application Entry exists even though the Quantity and Remaining Quantity are the same in this negative Item Ledger Entry.';
DuplicatedItemApplEntryErr: Label 'There is more than one Item Application Entry with the same combination of Item Ledger Entry No., Inbound Item Entry No., and Outbound Item Entry No.';
RemQtyGreaterThanQtyErr: Label 'The Remaining Quantity is greater than the Quantity.';
ItemApplEntryQtyNotMatchQtyMinusRemQtyErr: Label 'The summed Quantity of the linked Item Application Entries is not the same as the difference between Quantity and Remaining Quantity on Item Ledger Entry.';
ItemApplEntryQtyNotMatchQtyErr: Label 'The summed Quantity of the linked Item Application Entries is not the same as the Quantity on Item Ledger Entry.';
ItemApplEntryWrongSignErr: Label 'The sign of the Quantity in one or more of the linked Item Application Entries must be the opposite (positive must be negative or negative must be positive).';
ItemApplEntryQtyNotMatchRemQtyErr: Label 'The summed Quantity of the linked Item Application Entries is different than the Remaining Quantity of the Item Ledger Entry.';
EarlierValuationDateErr: Label 'The Valuation Date in Value Entries applied to this Item Ledger Entry is earlier than the Valuation Date in the Valuation Date for this Item Ledger Entry.';
CostApplicationFieldValueErr: Label 'The value of the Cost Application field in the corresponding Item Application Entries is not correct.';
WrongValuationDateForConsumptionErr: Label 'A linked Value Entry should not have the Valuation Date %1 for a positive entry with Entry Type = Consumption.', Comment = '%1: Valuation Date';
ValuedByAvgCostForNonAvgEntryErr: Label 'Valued by Average Cost of Value Entries must not be Yes for any Costing Method other than Average.';
PostingDateAndOutputComplInvdDateNotMatchErr: Label 'Posting Date is different to Output Completely Invd. Date on a linked Item Application Entry.';
OutputCompletelyInvdDateMustBeBlankErr: Label 'Output Completely Invd. Date is specified on a linked Item Application Entry but the Item Ledger Entry is not completely invoiced.';
OutputCompletelyInvdDateNotEqualToLastInvDateErr: Label 'Output Completely Invd. Date is not equal to Last Invoice Date on a linked Item Application Entry.';
InvoicedQuantityDoNotMatchErr: Label 'The summed Invoiced Quantity of the linked Value Entries is not the same as the Invoiced Quantity on the Item Ledger Entry.';
ExpectedCostPostedToGLNotZeroErr: Label 'Expected Cost Posted to G/L is not 0 on a linked Value Entry. However this could be because the report ''Post Inventory Cost to G/L'' has not been run yet.';
InvoicedQuantityMustBeZeroErr: Label 'Invoiced Quantity must be 0 when Adjustment is true on Value Entry.';
CostAmountExpectedNotZeroErr: Label 'Cost Amount (Expected) is not 0 on a completely invoiced Item Ledger Entry.';
InvoicedQtyMustBeEqualToQtyForComplInvdErr: Label 'Invoiced Quantity must be equal to Quantity when Completely Invoiced is true.';
QuantityMustBeZeroWhenAdjmtTrueErr: Label 'Quantity must be 0 on Item Ledger Entry %1 when Adjustment is true on a Value Entry.', Comment = '%1: Entry No.';
ValuedByAverageCostMustBeFalseErr: Label 'Valued by Average Cost must be false when Valued Quantity > 0 and Costing Method is %1 on Value Entry %2.', Comment = '%1: Costing Method on Item, %2: Entry No. on Value Entry';
ItemLedgerEntryTypeNotMatchEntryTypeErr: Label 'Item Ledger Entry Type on a Value Entry is not equal to Entry Type on Item Ledger Entry %1.', Comment = '%1: Entry No. on Item Ledger Entry';
NegativeEntryNoOnILEErr: Label 'Entry No. on Item Ledger Entry must not be less or equal than zero.';
ItemNoBlankErr: Label 'Item No. must not be blank.';
local procedure ShowCaption(): Text
begin
case ErrorGroupIndex of
0:
exit(BasicDataTestLbl);
1:
exit(ItemLedgEntryItemApplEntryCheckLbl);
2:
exit(ApplicationQtyCheckLbl);
4:
exit(CheckValuedByAverageCostLbl);
5:
exit(CheckValuationDateLbl);
6:
exit(CheckExpectedCostForInvoicedLbl);
7:
exit(CheckCompletelyInvoicedDateLbl);
8:
exit(ValueEntriesWithMissingILELbl);
end;
end;
local procedure ClearErrorText()
begin
if CompressArray(ErrorText) <> 0 then
for ErrorIndex := 1 to CompressArray(ErrorText) do
ErrorText[ErrorIndex] := '';
ErrorIndex := 1;
end;
local procedure CheckBasicData()
begin
BasicCheckItemLedgEntry();
BasicCheckValueEntry();
end;
local procedure BasicCheckItemLedgEntry()
var
ValueEntry: Record "Value Entry";
begin
if "Item Ledger Entry"."Entry No." <= 0 then
AddError(NegativeEntryNoOnILEErr, "Item Ledger Entry"."Item No.");
if "Item Ledger Entry".Quantity = 0 then
AddError(ItemLedgerEntryQtyZeroErr, "Item Ledger Entry"."Item No.");
if ("Item Ledger Entry".Quantity * "Item Ledger Entry"."Remaining Quantity") < 0 then
AddError(RemQtyGreaterThanQtyErr, "Item Ledger Entry"."Item No.");
if Abs("Item Ledger Entry"."Remaining Quantity") > Abs("Item Ledger Entry".Quantity) then
AddError(RemQtyGreaterThanQtyErr, "Item Ledger Entry"."Item No.");
if ("Item Ledger Entry".Quantity > 0) <> "Item Ledger Entry".Positive then
AddError(StrSubstNo(ItemLedgerEntryFieldValueErr, "Item Ledger Entry".FieldCaption(Positive), not "Item Ledger Entry".Positive), "Item Ledger Entry"."Item No.");
if ("Item Ledger Entry"."Remaining Quantity" = 0) = "Item Ledger Entry".Open then
AddError(StrSubstNo(ItemLedgerEntryFieldValueErr, "Item Ledger Entry".FieldCaption(Open), not "Item Ledger Entry".Open), "Item Ledger Entry"."Item No.");
if "Item Ledger Entry"."Completely Invoiced" then begin
if "Item Ledger Entry"."Invoiced Quantity" <> "Item Ledger Entry".Quantity then
AddError(InvoicedQtyMustBeEqualToQtyForComplInvdErr, "Item Ledger Entry"."Item No.");
ValueEntry.SetCurrentKey("Item Ledger Entry No.");
ValueEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
ValueEntry.CalcSums("Invoiced Quantity");
if "Item Ledger Entry"."Invoiced Quantity" <> ValueEntry."Invoiced Quantity" then
AddError(InvoicedQuantityDoNotMatchErr, "Item Ledger Entry"."Item No.");
end;
end;
local procedure BasicCheckValueEntry()
var
ValueEntry: Record "Value Entry";
ValuationDate: Date;
ConsumptionDate: Date;
ValuedByAverageCost: Boolean;
Continue: Boolean;
Compare: Boolean;
begin
ValueEntry.SetCurrentKey("Item Ledger Entry No.");
ValueEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
ValueEntry.SetRange(Inventoriable, true);
if not ValueEntry.FindSet() then
AddError(NoValueEntryForILEErr, "Item Ledger Entry"."Item No.")
else begin
ValuedByAverageCost := ValueEntry."Valued By Average Cost";
repeat
if ValueEntry.Adjustment then begin
if ValueEntry."Invoiced Quantity" <> 0 then begin
AddError(InvoicedQuantityMustBeZeroErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
if ValueEntry."Item Ledger Entry Quantity" <> 0 then
AddError(StrSubstNo(QuantityMustBeZeroWhenAdjmtTrueErr, "Item Ledger Entry"."Entry No."), "Item Ledger Entry"."Item No.");
end;
if ("Item Ledger Entry"."Entry Type" = "Item Ledger Entry"."Entry Type"::Consumption) and "Item Ledger Entry".Positive and
(ValueEntry."Valuation Date" = DMY2Date(31, 12, 9999))
then begin
ConsumptionDate := DMY2Date(31, 12, 9999);
AddError(StrSubstNo(WrongValuationDateForConsumptionErr, ConsumptionDate), "Item Ledger Entry"."Item No.");
Continue := true;
end else begin
if (not Compare) and (ValueEntry."Valuation Date" <> 0D) and
not (ValueEntry."Entry Type" in [ValueEntry."Entry Type"::Rounding, ValueEntry."Entry Type"::Revaluation])
then begin
ValuationDate := ValueEntry."Valuation Date";
Compare := true;
end;
if Compare then
if (ValueEntry."Valuation Date" <> ValuationDate) and (ValueEntry."Valuation Date" <> 0D) and
not (ValueEntry."Entry Type" in [ValueEntry."Entry Type"::Rounding, ValueEntry."Entry Type"::Revaluation])
then begin
AddError(StrSubstNo(ValueEntryFieldValueErr, ValueEntry.FieldCaption("Valuation Date")), "Item Ledger Entry"."Item No.");
Continue := true;
end;
end;
if (ValueEntry."Valued By Average Cost") and
(Item."Costing Method" <> Item."Costing Method"::Average)
then begin
AddError(ValuedByAvgCostForNonAvgEntryErr, "Item Ledger Entry"."Item No.");
Continue := true;
end else
if ValueEntry."Valued By Average Cost" <> ValuedByAverageCost then begin
AddError(StrSubstNo(ValueEntryFieldValueErr, ValueEntry.FieldCaption("Valued By Average Cost")), "Item Ledger Entry"."Item No.");
Continue := true;
end;
if (ValueEntry."Valued By Average Cost") and
(Item."Costing Method" = Item."Costing Method"::Average) and
(not "Item Ledger Entry".Correction)
then
if ValueEntry."Valued Quantity" > 0 then
AddError(StrSubstNo(ValuedByAverageCostMustBeFalseErr, Format(Item."Costing Method"), ValueEntry."Entry No."), "Item Ledger Entry"."Item No.");
if ValueEntry."Item Charge No." = '' then
if ValueEntry."Item Ledger Entry Type" <> "Item Ledger Entry"."Entry Type" then
AddError(StrSubstNo(ItemLedgerEntryTypeNotMatchEntryTypeErr, "Item Ledger Entry"."Entry No."), "Item Ledger Entry"."Item No.");
until (ValueEntry.Next() = 0) or Continue;
end;
end;
local procedure CheckItemLedgEntryQty()
begin
if (not "Item Ledger Entry".Positive) and "Item Ledger Entry".Open then
CheckNegOpenILEQty()
else
CheckILEQty();
SearchInbOutbCombination();
end;
local procedure CheckNegOpenILEQty()
var
ApplQty: Decimal;
begin
if "Item Ledger Entry".Quantity = "Item Ledger Entry"."Remaining Quantity" then begin
ItemApplEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
if not ItemApplEntry.IsEmpty() then
AddError(ItemApplEntryExistsForNotAppliedILEErr, "Item Ledger Entry"."Item No.");
end else begin
ItemApplEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
if not ItemApplEntry.IsEmpty() then begin
ItemApplEntry.CalcSums(Quantity);
ApplQty := ItemApplEntry.Quantity;
if ApplQty <> ("Item Ledger Entry".Quantity - "Item Ledger Entry"."Remaining Quantity") then
AddError(ItemApplEntryQtyNotMatchQtyMinusRemQtyErr, "Item Ledger Entry"."Item No.");
end;
end;
end;
local procedure CheckILEQty()
var
ApplQty: Decimal;
begin
ItemApplEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
if not ItemApplEntry.IsEmpty() then begin
ItemApplEntry.CalcSums(Quantity);
ApplQty := ItemApplEntry.Quantity;
if ApplQty <> "Item Ledger Entry".Quantity then
AddError(ItemApplEntryQtyNotMatchQtyErr, "Item Ledger Entry"."Item No.");
end else
AddError(NoItemApplEntryForILEErr, "Item Ledger Entry"."Item No.");
end;
local procedure SearchInbOutbCombination()
var
ItemApplEntry2: Record "Item Application Entry";
Continue: Boolean;
begin
if ItemApplEntry.FindSet() then
repeat
ItemApplEntry2.SetCurrentKey(
"Item Ledger Entry No.", "Inbound Item Entry No.", "Outbound Item Entry No.");
ItemApplEntry2.SetRange("Item Ledger Entry No.", ItemApplEntry."Item Ledger Entry No.");
ItemApplEntry2.SetRange("Inbound Item Entry No.", ItemApplEntry."Inbound Item Entry No.");
ItemApplEntry2.SetRange("Outbound Item Entry No.", ItemApplEntry."Outbound Item Entry No.");
ItemApplEntry2.SetFilter("Entry No.", '<>%1', ItemApplEntry."Entry No.");
if not ItemApplEntry2.IsEmpty() then begin
AddError(DuplicatedItemApplEntryErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
until (ItemApplEntry.Next() = 0) or Continue;
end;
local procedure CheckApplicationQty()
var
ApplQty: Decimal;
Continue: Boolean;
begin
ItemApplEntry.SetRange("Inbound Item Entry No.", "Item Ledger Entry"."Entry No.");
if ItemApplEntry.FindSet() then begin
repeat
if ((ItemApplEntry."Item Ledger Entry No." = ItemApplEntry."Inbound Item Entry No.") and
(ItemApplEntry.Quantity < 0)) or
((ItemApplEntry."Item Ledger Entry No." <> ItemApplEntry."Inbound Item Entry No.") and
(ItemApplEntry.Quantity > 0)) or
((ItemApplEntry."Item Ledger Entry No." <> ItemApplEntry."Outbound Item Entry No.") and
(ItemApplEntry.Quantity < 0))
then begin
AddError(ItemApplEntryWrongSignErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
until Continue or (ItemApplEntry.Next() = 0);
ItemApplEntry.CalcSums(Quantity);
ApplQty := ItemApplEntry.Quantity;
if ApplQty <> "Item Ledger Entry"."Remaining Quantity" then
AddError(ItemApplEntryQtyNotMatchRemQtyErr, "Item Ledger Entry"."Item No.");
end;
end;
local procedure CheckValuedByAverageCost()
begin
CheckVEValuedBySetting();
CheckItemApplCostApplSetting();
end;
local procedure CheckVEValuedBySetting()
var
ValueEntry: Record "Value Entry";
ValueEntry2: Record "Value Entry";
Continue: Boolean;
begin
ValueEntry2.SetCurrentKey("Item Ledger Entry No.");
ValueEntry2.SetRange(Inventoriable, true);
ValueEntry.SetCurrentKey("Item Ledger Entry No.");
ValueEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
ValueEntry.SetRange(Inventoriable, true);
ValueEntry.SetFilter("Item Ledger Entry Type", '<>%1', ValueEntry."Item Ledger Entry Type"::Output);
if ValueEntry.FindSet() then
repeat
if "Item Ledger Entry"."Applies-to Entry" <> 0 then begin
ValueEntry2.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Applies-to Entry");
if ValueEntry2.FindFirst() then
if ValueEntry."Valued By Average Cost" <> ValueEntry2."Valued By Average Cost" then begin
AddError(WrongValueEntryFieldValueErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
end else
if (not ValueEntry."Valued By Average Cost") and
(ValueEntry."Valuation Date" <> 0D) and
("Item Ledger Entry"."Entry Type" <> "Item Ledger Entry"."Entry Type"::Transfer) and
("Item Ledger Entry".Quantity < 0)
then begin
AddError(WrongValueEntryFieldValueErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
until (ValueEntry.Next() = 0) or Continue;
end;
local procedure CheckItemApplCostApplSetting()
var
Continue: Boolean;
begin
ItemApplEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
if ItemApplEntry.FindSet() then
repeat
if ItemApplEntry.Quantity > 0 then begin
if not ItemApplEntry."Cost Application" then begin
AddError(CostApplicationFieldValueErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
end else
if "Item Ledger Entry"."Applies-to Entry" <> 0 then begin
if not ItemApplEntry."Cost Application" then begin
AddError(CostApplicationFieldValueErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
end else
if ItemApplEntry."Cost Application" and ("Item Ledger Entry"."Entry Type" <> "Item Ledger Entry"."Entry Type"::Transfer) then begin
AddError(CostApplicationFieldValueErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
until (ItemApplEntry.Next() = 0) or Continue;
end;
local procedure CheckValuationDate()
var
ValueEntry: Record "Value Entry";
ValuationDate: Date;
Continue: Boolean;
begin
ValueEntry.SetCurrentKey("Item Ledger Entry No.");
ValueEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
ValueEntry.SetRange(Inventoriable, true);
ValueEntry.SetRange("Partial Revaluation", false);
if ValueEntry.FindFirst() then begin
ValuationDate := ValueEntry."Valuation Date";
ItemApplEntry.SetRange("Inbound Item Entry No.", "Item Ledger Entry"."Entry No.");
if ItemApplEntry.FindSet() then
repeat
if ItemApplEntry.Quantity < 0 then begin
ValueEntry.SetRange("Item Ledger Entry No.", ItemApplEntry."Item Ledger Entry No.");
ValueEntry.SetFilter("Valuation Date", '<%1', ValuationDate);
if not ValueEntry.IsEmpty() then begin
AddError(EarlierValuationDateErr, "Item Ledger Entry"."Item No.");
Continue := true;
end;
end;
until (ItemApplEntry.Next() = 0) or Continue;
end;
end;
local procedure CheckRemainingExpectedAmount()
var
ValueEntry: Record "Value Entry";
begin
if not "Item Ledger Entry"."Completely Invoiced" then
exit;
ValueEntry.SetCurrentKey("Item Ledger Entry No.");
ValueEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
"Item Ledger Entry".CalcFields("Cost Amount (Expected)", "Cost Amount (Expected) (ACY)");
if ("Item Ledger Entry"."Cost Amount (Expected)" = 0) and
("Item Ledger Entry"."Cost Amount (Expected) (ACY)" = 0)
then begin
ValueEntry.CalcSums("Expected Cost Posted to G/L", "Exp. Cost Posted to G/L (ACY)");
if (ValueEntry."Expected Cost Posted to G/L" = 0) and (ValueEntry."Exp. Cost Posted to G/L (ACY)" = 0) then
exit;
end;
if ValueEntry.FindSet() then
repeat
if (ValueEntry."Expected Cost Posted to G/L" <> 0) or (ValueEntry."Exp. Cost Posted to G/L (ACY)" <> 0) then
AddError(ExpectedCostPostedToGLNotZeroErr, ValueEntry."Item No.");
until ValueEntry.Next() = 0;
if ErrorIndex > 0 then
AddError(CostAmountExpectedNotZeroErr, "Item Ledger Entry"."Item No.");
end;
local procedure CheckOutputCompletelyInvdDate()
var
ItemApplicationEntry: Record "Item Application Entry";
ZeroDateFound: Boolean;
begin
if "Item Ledger Entry"."Invoiced Quantity" <> 0 then
if "Item Ledger Entry"."Last Invoice Date" = 0D then
AddError(BlankLastInvoicedDateErr, "Item Ledger Entry"."Item No.");
ItemApplicationEntry.SetCurrentKey("Item Ledger Entry No.", "Output Completely Invd. Date");
ItemApplicationEntry.SetRange("Item Ledger Entry No.", "Item Ledger Entry"."Entry No.");
if ItemApplicationEntry.FindSet() then
repeat
if ItemApplicationEntry.Quantity > 0 then begin
if ItemApplicationEntry."Output Completely Invd. Date" <> ItemApplicationEntry."Posting Date" then begin
ZeroDateFound := true;
AddError(PostingDateAndOutputComplInvdDateNotMatchErr, "Item Ledger Entry"."Item No.");
end;
end else
if "Item Ledger Entry".Quantity = "Item Ledger Entry"."Invoiced Quantity" then begin
if ItemApplicationEntry."Output Completely Invd. Date" <> "Item Ledger Entry"."Last Invoice Date" then begin
ZeroDateFound := true;
AddError(OutputCompletelyInvdDateNotEqualToLastInvDateErr, "Item Ledger Entry"."Item No.");
end;
end else
if ItemApplicationEntry."Output Completely Invd. Date" <> 0D then begin
ZeroDateFound := true;
AddError(OutputCompletelyInvdDateMustBeBlankErr, "Item Ledger Entry"."Item No.");
end;
until ZeroDateFound or (ItemApplicationEntry.Next() = 0);
end;
local procedure CheckItem(ItemNo: Code[20])
begin
if ItemNo = '' then
AddError(ItemNoBlankErr, ItemNo);
end;
local procedure AddError(ErrorMessage: Text; ItemNo: Code[20])
begin
ErrorText[ErrorIndex] := ErrorMessage;
ErrorIndex := ErrorIndex + 1;
if Item2.Get(ItemNo) then begin
TempItem := Item2;
if TempItem.Insert() then;
end;
end;
}