Codeunit 5510 Production Journal Mgt, source in 29
Source29
src/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournalMgt.Codeunit.al825 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.Manufacturing.Journal;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Tracking;
using Microsoft.Manufacturing.Document;
using Microsoft.Manufacturing.MachineCenter;
using Microsoft.Manufacturing.Setup;
using Microsoft.Manufacturing.WorkCenter;
codeunit 5510 "Production Journal Mgt"
{
trigger OnRun()
begin
end;
var
MfgSetup: Record "Manufacturing Setup";
ItemJnlLine: Record "Item Journal Line";
ItemJnlTemplate: Record "Item Journal Template";
ItemJnlBatch: Record "Item Journal Batch";
UOMMgt: Codeunit "Unit of Measure Management";
PostingDate: Date;
CalcBasedOn: Option "Actual Output","Expected Output";
PresetOutputQuantity: Option "Expected Quantity","Zero on All Operations","Zero on Last Operation";
ToTemplateName: Code[10];
ToBatchName: Code[10];
NextLineNo: Integer;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text000: Label '%1 journal';
#pragma warning restore AA0470
Text001: Label 'Do you want to leave the Production Journal?';
#pragma warning restore AA0074
BlockedMsg: Label '%2 %1 is blocked and therefore, no journal line is created for this %2.', Comment = '%1 - Entity No, %2 - Table caption';
#pragma warning disable AA0074
Text003: Label 'DEFAULT';
Text004: Label 'Production Journal';
#pragma warning disable AA0470
Text005: Label '%1 %2 for operation %3 is blocked and therefore, no journal line is created for this operation.';
#pragma warning restore AA0470
#pragma warning restore AA0074
GeneratingJnlLinesMsg: Label 'Generating journal lines.';
procedure Handling(ProdOrder: Record "Production Order"; ActualLineNo: Integer)
var
ProductionJnl: Page "Production Journal";
ProgressBar: Dialog;
LeaveForm: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeHandling(ProdOrder, ActualLineNo, IsHandled);
if not IsHandled then begin
MfgSetup.Get();
SetTemplateAndBatchName();
InitSetupValues();
ProgressBar.Open(GeneratingJnlLinesMsg);
DeleteJnlLines(ToTemplateName, ToBatchName, ProdOrder."No.", ActualLineNo);
CreateJnlLines(ProdOrder, ActualLineNo);
ProgressBar.Close();
IsHandled := false;
OnBeforeRunProductionJnl(ToTemplateName, ToBatchName, ProdOrder, ActualLineNo, PostingDate, IsHandled);
if not IsHandled then begin
repeat
// Commit before running Production Journal page
Commit();
LeaveForm := true;
Clear(ProductionJnl);
ProductionJnl.Setup(ToTemplateName, ToBatchName, ProdOrder, ActualLineNo, PostingDate);
ProductionJnl.RunModal();
if DataHasChanged(ToTemplateName, ToBatchName, ProdOrder."No.", ActualLineNo) then
LeaveForm := Confirm(Text001, true);
until LeaveForm;
DeleteJnlLines(ToTemplateName, ToBatchName, ProdOrder."No.", ActualLineNo);
end;
end;
end;
procedure CreateJnlLines(ProdOrder: Record "Production Order"; ProdOrderLineNo: Integer)
var
ItemJnlLine: Record "Item Journal Line";
ProdOrderLine: Record "Prod. Order Line";
ProdOrderRtngLine: Record "Prod. Order Routing Line";
ProdOrderComp: Record "Prod. Order Component";
IsHandled: Boolean;
begin
SetNextLineNo(ItemJnlLine);
ProdOrderLine.Reset();
ProdOrderLine.SetRange(Status, ProdOrder.Status);
ProdOrderLine.SetRange("Prod. Order No.", ProdOrder."No.");
if ProdOrderLineNo <> 0 then
ProdOrderLine.SetRange("Line No.", ProdOrderLineNo);
OnCreateJnlLinesOnAfterSetProdOrderLineFilters(ProdOrderLine);
if ProdOrderLine.Find('-') then
repeat
OnCreateJnlLinesOnBeforeCheckProdOrderLine(ProdOrderLine);
ProdOrderRtngLine.Reset();
ProdOrderRtngLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRtngLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
ProdOrderRtngLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRtngLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
OnCreateJnlLinesOnAfterProdOrderRtngLineSetFilters(ProdOrderRtngLine);
if ProdOrderRtngLine.Find('-') then begin
IsHandled := false;
OnCreateJnlLinesOnBeforeInsertComponents(ProdOrderRtngLine, ProdOrder, ProdOrderLine, IsHandled);
if not IsHandled then
InsertComponents(ProdOrderLine, true, 0); // With no Routing Link or illegal Routing Link
repeat
IsHandled := false;
OnCreateJnlLinesOnAfterFindProdOrderRtngLine(ProdOrderRtngLine, IsHandled, ItemJnlLine, NextLineNo);
if not IsHandled then begin
InsertOutputItemJnlLine(ProdOrderRtngLine, ProdOrderLine);
if ProdOrderRtngLine."Routing Link Code" <> '' then begin
ProdOrderComp.Reset();
ProdOrderComp.SetCurrentKey(Status, "Prod. Order No.", "Routing Link Code");
ProdOrderComp.SetRange(Status, ProdOrder.Status);
ProdOrderComp.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderComp.SetRange("Routing Link Code", ProdOrderRtngLine."Routing Link Code");
ProdOrderComp.SetRange("Prod. Order Line No.", ProdOrderLine."Line No.");
ProdOrderComp.SetFilter("Item No.", '<>%1', '');
if ProdOrderComp.FindSet() then
repeat
InsertConsumptionItemJnlLine(ProdOrderComp, ProdOrderLine, 1);
until ProdOrderComp.Next() = 0;
end;
end;
until ProdOrderRtngLine.Next() = 0;
end else begin
// Insert All Components - No Routing Link Check
InsertComponents(ProdOrderLine, false, 0);
// Create line for Output Qty
Clear(ProdOrderRtngLine);
InsertOutputItemJnlLine(ProdOrderRtngLine, ProdOrderLine);
end;
until ProdOrderLine.Next() = 0;
end;
procedure InsertComponents(ProdOrderLine: Record "Prod. Order Line"; CheckRoutingLink: Boolean; Level: Integer)
var
ProdOrderComp: Record "Prod. Order Component";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInsertComponents(ProdOrderLine, CheckRoutingLink, Level, IsHandled);
if IsHandled then
exit;
// Components with no Routing Link or illegal Routing Link
ProdOrderComp.Reset();
ProdOrderComp.SetRange(Status, ProdOrderLine.Status);
ProdOrderComp.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderComp.SetRange("Prod. Order Line No.", ProdOrderLine."Line No.");
ProdOrderComp.SetFilter("Item No.", '<>%1', '');
OnInsertComponentsOnAfterProdOrderCompSetFilters(ProdOrderComp);
if ProdOrderComp.Find('-') then
repeat
if not CheckRoutingLink then
InsertConsumptionItemJnlLine(ProdOrderComp, ProdOrderLine, Level)
else
if not RoutingLinkValid(ProdOrderComp, ProdOrderLine) then
InsertConsumptionItemJnlLine(ProdOrderComp, ProdOrderLine, Level);
until ProdOrderComp.Next() = 0;
end;
procedure RoutingLinkValid(ProdOrderComp: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"): Boolean
var
ProdOrderRtngLine: Record "Prod. Order Routing Line";
IsHandled: Boolean;
Result: Boolean;
begin
IsHandled := false;
OnBeforeRoutingLinkValid(ProdOrderComp, ProdOrderLine, Result, IsHandled);
if IsHandled then
exit(Result);
if ProdOrderComp."Routing Link Code" = '' then
exit(false);
ProdOrderRtngLine.Reset();
ProdOrderRtngLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRtngLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRtngLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
ProdOrderRtngLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
ProdOrderRtngLine.SetRange("Routing Link Code", ProdOrderComp."Routing Link Code");
exit(not ProdOrderRtngLine.IsEmpty());
end;
procedure InsertConsumptionItemJnlLine(ProdOrderComp: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"; Level: Integer)
var
Item: Record Item;
ItemVariant: Record "Item Variant";
Location: Record Location;
ItemTrackingMgt: Codeunit "Item Tracking Management";
NeededQty: Decimal;
OriginalNeededQty: Decimal;
IsHandled: Boolean;
ShouldAdjustQty: Boolean;
ItemItemVariantLbl: Label '%1 %2', Comment = '%1 - Item No., %2 - Variant Code';
begin
Item.Get(ProdOrderComp."Item No.");
if Item.Blocked then begin
Message(BlockedMsg, ProdOrderComp."Item No.", Item.TableCaption());
exit;
end;
if ProdOrderComp."Variant Code" <> '' then begin
ItemVariant.SetLoadFields(Blocked);
ItemVariant.Get(ProdOrderComp."Item No.", ProdOrderComp."Variant Code");
if ItemVariant.Blocked then begin
Message(BlockedMsg, StrSubstNo(ItemItemVariantLbl, ProdOrderComp."Item No.", ProdOrderComp."Variant Code"), ItemVariant.TableCaption());
exit;
end;
end;
IsHandled := false;
OnInsertConsumptionJnlLineOnBeforeCheck(ProdOrderComp, ProdOrderLine, Item, IsHandled);
if IsHandled then
exit;
if not (ProdOrderComp."Flushing Method" in [ProdOrderComp."Flushing Method"::Manual, ProdOrderComp."Flushing Method"::"Pick + Manual"]) then
NeededQty := 0
else
NeededQty := ProdOrderComp.GetNeededQty(CalcBasedOn, true);
OriginalNeededQty := NeededQty;
ShouldAdjustQty := ProdOrderComp."Flushing Method" = ProdOrderComp."Flushing Method"::"Pick + Manual";
if ShouldAdjustQty then begin
if ProdOrderComp."Location Code" <> Location.Code then
if not Location.GetLocationSetup(ProdOrderComp."Location Code", Location) then
Clear(Location);
ShouldAdjustQty := Location."Prod. Consump. Whse. Handling" = Location."Prod. Consump. Whse. Handling"::"Warehouse Pick (mandatory)";
OnInsertConsumptionItemJnlLineOnAfterCalcShouldAdjustQty(ProdOrderComp, Location, NeededQty, ShouldAdjustQty);
if ShouldAdjustQty then
ProdOrderComp.AdjustQtyToQtyPicked(NeededQty);
end;
ItemJnlLine.Init();
OnInsertConsumptionJnlLineOnAfterItemJnlLineInit(ItemJnlLine, ItemJnlTemplate, ItemJnlBatch);
ItemJnlLine."Journal Template Name" := ToTemplateName;
ItemJnlLine."Journal Batch Name" := ToBatchName;
ItemJnlLine."Line No." := NextLineNo;
ItemJnlLine.Validate("Posting Date", PostingDate);
ItemJnlLine.Validate("Entry Type", ItemJnlLine."Entry Type"::Consumption);
ItemJnlLine.Validate("Order Type", ItemJnlLine."Order Type"::Production);
ItemJnlLine.Validate("Order No.", ProdOrderComp."Prod. Order No.");
ItemJnlLine.Validate("Source No.", ProdOrderLine."Item No.");
ItemJnlLine.Validate("Item No.", ProdOrderComp."Item No.");
ItemJnlLine.Validate("Unit of Measure Code", ProdOrderComp."Unit of Measure Code");
ItemJnlLine.Description := ProdOrderComp.Description;
ConsumptionItemJnlLineValidateQuantity(ProdOrderComp, NeededQty, Item, NeededQty < OriginalNeededQty);
ItemJnlLine.Validate("Location Code", ProdOrderComp."Location Code");
ItemJnlLine.Validate("Dimension Set ID", ProdOrderComp."Dimension Set ID");
if ProdOrderComp."Bin Code" <> '' then
ItemJnlLine."Bin Code" := ProdOrderComp."Bin Code";
ItemJnlLine."Variant Code" := ProdOrderComp."Variant Code";
ItemJnlLine.Validate("Order Line No.", ProdOrderComp."Prod. Order Line No.");
ItemJnlLine.Validate("Prod. Order Comp. Line No.", ProdOrderComp."Line No.");
ItemJnlLine.Level := Level;
ItemJnlLine."Flushing Method" := ProdOrderComp."Flushing Method";
ItemJnlLine."Source Code" := ItemJnlTemplate."Source Code";
ItemJnlLine."Reason Code" := ItemJnlBatch."Reason Code";
ItemJnlLine."Posting No. Series" := ItemJnlBatch."Posting No. Series";
OnBeforeInsertConsumptionJnlLine(ItemJnlLine, ProdOrderComp, ProdOrderLine, Level);
ItemJnlLine.Insert();
OnAfterInsertConsumptionJnlLine(ItemJnlLine);
if Item."Item Tracking Code" <> '' then
ItemTrackingMgt.CopyItemTracking(ProdOrderComp.RowID1(), ItemJnlLine.RowID1(), false);
OnInsertConsumptionItemJnlLineOnAfterCopyItemTracking(ItemJnlLine, Item."Item Tracking Code", NextLineNo);
NextLineNo += 10000;
OnAfterInsertConsumptionJnlLine(ItemJnlLine);
end;
local procedure ConsumptionItemJnlLineValidateQuantity(ProdOrderComp: Record "Prod. Order Component"; NeededQty: Decimal; Item: Record Item; IgnoreRoundingPrecision: Boolean)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnInsertConsumptionItemJnlLineOnBeforeValidateQuantity(ItemJnlLine, ProdOrderComp, NeededQty, IsHandled);
if IsHandled then
exit;
if NeededQty <> 0 then
if (Item."Rounding Precision" > 0) and not IgnoreRoundingPrecision then
ItemJnlLine.Validate(Quantity, UOMMgt.RoundToItemRndPrecision(NeededQty, Item."Rounding Precision"))
else
ItemJnlLine.Validate(Quantity, Round(NeededQty, UOMMgt.QtyRndPrecision()));
end;
procedure InsertOutputItemJnlLine(ProdOrderRtngLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line")
var
WorkCenter: Record "Work Center";
MachineCenter: Record "Machine Center";
ItemTrackingMgt: Codeunit "Item Tracking Management";
QtyToPost: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInsertOutputItemJnlLine(ProdOrderRtngLine, ProdOrderLine, IsHandled);
if IsHandled then
exit;
if ProdOrderRtngLine."Prod. Order No." <> '' then
// Operation exist
case ProdOrderRtngLine.Type of
ProdOrderRtngLine.Type::"Work Center":
begin
WorkCenter.Get(ProdOrderRtngLine."No.");
if WorkCenter.Blocked then begin
Message(Text005, WorkCenter.TableCaption(), WorkCenter."No.", ProdOrderRtngLine."Operation No.");
exit;
end;
end;
ProdOrderRtngLine.Type::"Machine Center":
begin
MachineCenter.Get(ProdOrderRtngLine."No.");
if MachineCenter.Blocked then begin
Message(Text005, MachineCenter.TableCaption(), MachineCenter."No.", ProdOrderRtngLine."Operation No.");
exit;
end;
WorkCenter.Get(ProdOrderRtngLine."Work Center No.");
if WorkCenter.Blocked then begin
Message(Text005, WorkCenter.TableCaption(), WorkCenter."No.", ProdOrderRtngLine."Operation No.");
exit;
end;
end;
end;
if (ProdOrderRtngLine."Flushing Method" <> ProdOrderRtngLine."Flushing Method"::Manual) or
(PresetOutputQuantity = PresetOutputQuantity::"Zero on All Operations") or
((PresetOutputQuantity = PresetOutputQuantity::"Zero on Last Operation") and
IsLastOperation(ProdOrderRtngLine)) or
((ProdOrderRtngLine."Prod. Order No." = '') and
(PresetOutputQuantity <> PresetOutputQuantity::"Expected Quantity")) or
(ProdOrderRtngLine."Routing Status" = ProdOrderRtngLine."Routing Status"::Finished)
then
QtyToPost := 0
else
if ProdOrderRtngLine."Prod. Order No." <> '' then
CalculateQtyToPostForProdOrder(ProdOrderLine, ProdOrderRtngLine, QtyToPost)
else
// No Routing Line
QtyToPost := ProdOrderLine."Remaining Quantity";
if QtyToPost < 0 then
QtyToPost := 0;
ItemJnlLine.Init();
OnInsertOutputItemJnlLineOnAfterItemJnlLineInit(ItemJnlLine, ProdOrderLine, ItemJnlTemplate, ItemJnlBatch);
ItemJnlLine."Journal Template Name" := ToTemplateName;
ItemJnlLine."Journal Batch Name" := ToBatchName;
ItemJnlLine."Line No." := NextLineNo;
ItemJnlLine.Validate("Posting Date", PostingDate);
ItemJnlLine.Validate("Entry Type", ItemJnlLine."Entry Type"::Output);
ItemJnlLine.Validate("Order Type", ItemJnlLine."Order Type"::Production);
ItemJnlLine.Validate("Order No.", ProdOrderLine."Prod. Order No.");
ItemJnlLine.Validate("Order Line No.", ProdOrderLine."Line No.");
ItemJnlLine.Validate("Item No.", ProdOrderLine."Item No.");
ItemJnlLine.Validate("Variant Code", ProdOrderLine."Variant Code");
ItemJnlLine.Validate("Location Code", ProdOrderLine."Location Code");
ItemJnlLine.Validate("Dimension Set ID", ProdOrderLine."Dimension Set ID");
if ProdOrderLine."Bin Code" <> '' then
ItemJnlLine.Validate("Bin Code", ProdOrderLine."Bin Code");
ItemJnlLine.Validate("Routing No.", ProdOrderLine."Routing No.");
ItemJnlLine.Validate("Routing Reference No.", ProdOrderLine."Routing Reference No.");
if ProdOrderRtngLine."Prod. Order No." <> '' then
ItemJnlLine.Validate("Operation No.", ProdOrderRtngLine."Operation No.");
ItemJnlLine.Validate("Unit of Measure Code", ProdOrderLine."Unit of Measure Code");
ItemJnlLine.Validate("Setup Time", 0);
ItemJnlLine.Validate("Run Time", 0);
OnInsertOutputItemJnlLineOnAfterAssignTimes(ItemJnlLine, ProdOrderLine, ProdOrderRtngLine, QtyToPost);
if (ProdOrderLine."Location Code" <> '') and IsLastOperation(ProdOrderRtngLine) then
ItemJnlLine.CheckWhse(ProdOrderLine."Location Code", QtyToPost);
OnInsertOutputItemJnlLineOnBeforeSubcontractingWorkCenterUsed(ItemJnlLine, ProdOrderLine);
if ItemJnlLine.SubcontractingWorkCenterUsed() then
ItemJnlLine.Validate("Output Quantity", 0)
else begin
if not IsLastOperation(ProdOrderRtngLine) then begin
ItemJnlLine."Qty. Rounding Precision" := 0;
ItemJnlLine."Qty. Rounding Precision (Base)" := 0;
end;
QtyToPost := UOMMgt.RoundQty(QtyToPost, ItemJnlLine."Qty. Rounding Precision (Base)");
ItemJnlLine.Validate("Output Quantity", QtyToPost);
end;
if ProdOrderRtngLine."Routing Status" = ProdOrderRtngLine."Routing Status"::Finished then
ItemJnlLine.Finished := true;
ItemJnlLine."Flushing Method" := ProdOrderRtngLine."Flushing Method";
ItemJnlLine."Source Code" := ItemJnlTemplate."Source Code";
ItemJnlLine."Reason Code" := ItemJnlBatch."Reason Code";
ItemJnlLine."Posting No. Series" := ItemJnlBatch."Posting No. Series";
OnBeforeInsertOutputJnlLine(ItemJnlLine, ProdOrderRtngLine, ProdOrderLine);
ItemJnlLine.Insert();
OnAfterInsertOutputJnlLine(ItemJnlLine);
if IsLastOperation(ProdOrderRtngLine) then
ItemTrackingMgt.CopyItemTracking(ProdOrderLine.RowID1(), ItemJnlLine.RowID1(), false);
OnInsertOutputItemJnlLineOnAfterCopyItemTracking(ItemJnlLine, ProdOrderRtngLine, NextLineNo);
NextLineNo += 10000;
RecursiveInsertOutputJnlLine(ProdOrderRtngLine, ProdOrderLine);
end;
local procedure CalculateQtyToPostForProdOrder(ProdOrderLine: Record "Prod. Order Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var QtyToPost: Decimal)
var
MfgCostCalcMgt: Codeunit "Mfg. Cost Calculation Mgt.";
begin
QtyToPost :=
MfgCostCalcMgt.CalcQtyAdjdForRoutingScrap(
ProdOrderLine."Quantity (Base)",
ProdOrderRoutingLine."Scrap Factor % (Accumulated)",
ProdOrderRoutingLine."Fixed Scrap Qty. (Accum.)") -
MfgCostCalcMgt.CalcActOutputQtyBase(ProdOrderLine, ProdOrderRoutingLine);
QtyToPost := QtyToPost / ProdOrderLine."Qty. per Unit of Measure";
OnAfterCalculateQtyToPostForProdOrder(ProdOrderLine, ProdOrderRoutingLine, QtyToPost);
end;
local procedure RecursiveInsertOutputJnlLine(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line")
var
AdditionalProdOrderLine: Record "Prod. Order Line";
DoRecursion: Boolean;
begin
DoRecursion := false;
OnBeforeRecursiveInsertOutputJnlLine(ProdOrderRoutingLine, ProdOrderLine, DoRecursion, AdditionalProdOrderLine);
if DoRecursion and AdditionalProdOrderLine.HasFilter then
if AdditionalProdOrderLine.FindSet() then
repeat
InsertOutputItemJnlLine(ProdOrderRoutingLine, AdditionalProdOrderLine);
until AdditionalProdOrderLine.Next() = 0;
end;
procedure InitSetupValues()
begin
MfgSetup.Get();
PostingDate := WorkDate();
CalcBasedOn := MfgSetup."Default Consum. Calc. Based on";
PresetOutputQuantity := MfgSetup."Preset Output Quantity";
OnAfterInitSetupValues(PostingDate, CalcBasedOn)
end;
local procedure IsLastOperation(ProdOrderRoutingLine: Record "Prod. Order Routing Line") Result: Boolean
begin
Result := ProdOrderRoutingLine."Next Operation No." = '';
OnAfterIsLastOperation(ProdOrderRoutingLine, Result);
end;
procedure SetTemplateAndBatchName()
var
PageTemplate: Option Item,Transfer,"Phys. Inventory",Revaluation,Consumption,Output,Capacity,"Prod. Order";
User: Text;
IsHandled: Boolean;
PageID: Integer;
begin
PageID := Page::"Production Journal";
PageTemplate := PageTemplate::"Prod. Order";
IsHandled := false;
OnBeforeSetTemplateAndBatchName(ToTemplateName, ToBatchName, IsHandled, PageID, PageTemplate);
if IsHandled then
exit;
ItemJnlTemplate.Reset();
ItemJnlTemplate.SetRange("Page ID", PageID);
ItemJnlTemplate.SetRange(Recurring, false);
ItemJnlTemplate.SetRange(Type, PageTemplate);
if not ItemJnlTemplate.FindFirst() then begin
ItemJnlTemplate.Init();
ItemJnlTemplate.Recurring := false;
ItemJnlTemplate.Validate(Type, PageTemplate);
ItemJnlTemplate.Validate("Page ID");
ItemJnlTemplate.Name := Format(ItemJnlTemplate.Type, MaxStrLen(ItemJnlTemplate.Name));
ItemJnlTemplate.Description := StrSubstNo(Text000, ItemJnlTemplate.Type);
ItemJnlTemplate.Insert();
end;
ToTemplateName := ItemJnlTemplate.Name;
ToBatchName := '';
User := UpperCase(UserId); // Uppercase in case of Windows Login
OnAfterSetTemplateAndBatchName(ItemJnlTemplate, User);
if User <> '' then
if (StrLen(User) < MaxStrLen(ItemJnlLine."Journal Batch Name")) and (ItemJnlLine."Journal Batch Name" <> '') then
ToBatchName := CopyStr(ItemJnlLine."Journal Batch Name", 1, MaxStrLen(ItemJnlLine."Journal Batch Name") - 1) + 'A'
else
ToBatchName := DelChr(CopyStr(User, 1, MaxStrLen(ItemJnlLine."Journal Batch Name")), '>', '0123456789');
if ToBatchName = '' then
ToBatchName := Text003;
if not ItemJnlBatch.Get(ToTemplateName, ToBatchName) then begin
ItemJnlBatch.Init();
ItemJnlBatch."Journal Template Name" := ItemJnlTemplate.Name;
ItemJnlBatch.SetupNewBatch();
ItemJnlBatch.Name := ToBatchName;
ItemJnlBatch.Description := Text004;
ItemJnlBatch.Insert(true);
end;
end;
procedure SetJnlTemplateAndBatchName(TemplateName: Code[10]; BatchName: Code[10])
begin
ToTemplateName := TemplateName;
ToBatchName := BatchName;
end;
procedure DeleteJnlLines(TemplateName: Code[10]; BatchName: Code[10]; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer)
var
ItemJnlLine2: Record "Item Journal Line";
ReservEntry: Record "Reservation Entry";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteJnlLines(TemplateName, BatchName, ProdOrderNo, ProdOrderLineNo, IsHandled);
if IsHandled then
exit;
ItemJnlLine2.Reset();
ItemJnlLine2.SetRange("Journal Template Name", TemplateName);
ItemJnlLine2.SetRange("Journal Batch Name", BatchName);
ItemJnlLine2.SetRange("Order Type", ItemJnlLine2."Order Type"::Production);
ItemJnlLine2.SetRange("Order No.", ProdOrderNo);
if ProdOrderLineNo <> 0 then
ItemJnlLine2.SetRange("Order Line No.", ProdOrderLineNo);
OnDeleteJnlLinesOnAfterSetFilters(ItemJnlLine2);
if ItemJnlLine2.Find('-') then begin
repeat
if ReservEntryExist(ItemJnlLine2, ReservEntry) then
ReservEntry.DeleteAll(true);
until ItemJnlLine2.Next() = 0;
OnBeforeDeleteAllItemJnlLine(ItemJnlLine2);
ItemJnlLine2.DeleteAll(true);
end;
// Delete reservation entries whose item journal lines are missing
ReservEntry.SetCurrentKey("Source ID", "Source Ref. No.", "Source Type", "Source Subtype", "Source Batch Name", "Source Prod. Order Line");
ReservEntry.SetRange("Source Type", Database::"Item Journal Line");
ReservEntry.SetRange("Source ID", TemplateName);
ReservEntry.SetRange("Source Batch Name", BatchName);
if ReservEntry.Findset() then
repeat
if not ItemJnlLine2.Get(TemplateName, BatchName, ReservEntry."Source Ref. No.") then
ReservEntry.Delete(true);
until ReservEntry.Next() = 0;
end;
local procedure DataHasChanged(TemplateName: Code[10]; BatchName: Code[10]; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer): Boolean
var
ItemJnlLine2: Record "Item Journal Line";
ReservEntry: Record "Reservation Entry";
HasChanged: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDataHasChanged(TemplateName, BatchName, ProdOrderNo, ProdOrderLineNo, HasChanged, IsHandled);
if IsHandled then
exit(HasChanged);
ItemJnlLine2.Reset();
ItemJnlLine2.SetRange("Journal Template Name", TemplateName);
ItemJnlLine2.SetRange("Journal Batch Name", BatchName);
ItemJnlLine2.SetRange("Order Type", ItemJnlLine2."Order Type"::Production);
ItemJnlLine2.SetRange("Order No.", ProdOrderNo);
if ProdOrderLineNo <> 0 then
ItemJnlLine2.SetRange("Order Line No.", ProdOrderLineNo);
if ItemJnlLine2.Find('-') then
repeat
if ItemJnlLine2."Changed by User" then
exit(true);
if ReservEntryExist(ItemJnlLine2, ReservEntry) then
exit(true);
until ItemJnlLine2.Next() = 0;
HasChanged := false;
OnAfterDataHasChanged(ItemJnlLine2, ProdOrderLineNo, HasChanged);
exit(HasChanged);
end;
procedure ReservEntryExist(ItemJnlLine2: Record "Item Journal Line"; var ReservEntry: Record "Reservation Entry"): Boolean
begin
ReservEntry.Reset();
ReservEntry.SetCurrentKey(
"Source ID", "Source Ref. No.", "Source Type", "Source Subtype", "Source Batch Name", "Source Prod. Order Line");
ReservEntry.SetRange("Source ID", ItemJnlLine2."Journal Template Name");
ReservEntry.SetRange("Source Ref. No.", ItemJnlLine2."Line No.");
ReservEntry.SetRange("Source Type", DATABASE::"Item Journal Line");
ReservEntry.SetRange("Source Subtype", ItemJnlLine2."Entry Type");
ReservEntry.SetRange("Source Batch Name", ItemJnlLine2."Journal Batch Name");
ReservEntry.SetRange("Source Prod. Order Line", 0);
if not ReservEntry.IsEmpty() then
exit(true);
exit(false);
end;
procedure SetNextLineNo(var ItemJournalLine: Record "Item Journal Line")
begin
ItemJournalLine.LockTable();
ItemJournalLine.Reset();
ItemJournalLine.SetRange("Journal Template Name", ToTemplateName);
ItemJournalLine.SetRange("Journal Batch Name", ToBatchName);
if ItemJournalLine.FindLast() then
NextLineNo := ItemJournalLine."Line No." + 10000
else
NextLineNo := 10000;
end;
procedure GetJnlTemplateAndBatchName(var TemplateName: Code[10]; var BatchName: Code[10])
begin
TemplateName := ToTemplateName;
BatchName := ToBatchName;
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalculateQtyToPostForProdOrder(ProdOrderLine: Record "Prod. Order Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var QtyToPost: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterDataHasChanged(var ItemJournalLine: Record "Item Journal Line"; ProdOrderLineNo: Integer; var HasChanged: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitSetupValues(var PostingDate: Date; var CalcBasedOn: Option "Actual Output","Expected Output")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInsertConsumptionJnlLine(var ItemJournalLine: Record "Item Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInsertOutputJnlLine(var ItemJournalLine: Record "Item Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterIsLastOperation(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var IsLastOperation: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetTemplateAndBatchName(var ItemJournalTemplate: Record "Item Journal Template"; var User: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertConsumptionJnlLine(var ItemJournalLine: Record "Item Journal Line"; ProdOrderComp: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"; Level: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertOutputJnlLine(var ItemJournalLine: Record "Item Journal Line"; ProdOrderRtngLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteAllItemJnlLine(var ItemJournalLine: Record "Item Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeHandling(ProdOrder: Record "Production Order"; ActualLineNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRecursiveInsertOutputJnlLine(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; var DoRecursion: Boolean; var AdditionalProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRunProductionJnl(ToTemplateName: Code[10]; ToBatchName: Code[10]; ProdOrder: Record "Production Order"; ActualLineNo: Integer; var PostingDate: Date; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateJnlLinesOnAfterFindProdOrderRtngLine(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var IsHandled: Boolean; var ItemJnlLine: Record "Item Journal Line"; var NextLineNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateJnlLinesOnBeforeCheckProdOrderLine(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateJnlLinesOnAfterProdOrderRtngLineSetFilters(var ProdOrderRtngLine: Record "Prod. Order Routing Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertConsumptionJnlLineOnBeforeCheck(ProdOrderComponent: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"; Item: Record Item; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertConsumptionItemJnlLineOnAfterCalcShouldAdjustQty(ProdOrderComp: Record "Prod. Order Component"; Location: Record Location; var NeededQty: Decimal; var ShouldAdjustQty: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertConsumptionJnlLineOnAfterItemJnlLineInit(var ItemJournalLine: Record "Item Journal Line"; ItemJournalTemplate: Record "Item Journal Template"; ItemJournalBatch: Record "Item Journal Batch")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertConsumptionItemJnlLineOnAfterCopyItemTracking(var ItemJournalLine: Record "Item Journal Line"; ItemTrackingCode: Code[10]; var NextLineNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertOutputItemJnlLine(ProdOrderRtngLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteJnlLines(TemplateName: Code[10]; BatchName: Code[10]; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSetTemplateAndBatchName(var ToTemplateName: Code[10]; var ToBatchName: Code[10]; var IsHandled: Boolean; var PageID: Integer; var PageTemplate: Option Item,Transfer,"Phys. Inventory",Revaluation,Consumption,Output,Capacity,"Prod. Order")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertConsumptionItemJnlLineOnBeforeValidateQuantity(var ItemJnlLine: Record "Item Journal Line"; ProdOrderComp: Record "Prod. Order Component"; NeededQty: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertOutputItemJnlLineOnBeforeSubcontractingWorkCenterUsed(var ItemJnlLine: Record "Item Journal Line"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertOutputItemJnlLineOnAfterCopyItemTracking(var ItemJnlLine: Record "Item Journal Line"; ProdOrderRtngLine: Record "Prod. Order Routing Line"; var NextLineNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertOutputItemJnlLineOnAfterItemJnlLineInit(var ItemJnlLine: Record "Item Journal Line"; ProdOrderLine: Record "Prod. Order Line"; ItemJournalTemplate: Record "Item Journal Template"; ItemJournalBatch: Record "Item Journal Batch")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateJnlLinesOnBeforeInsertComponents(var ProdOrderRtngLine: Record "Prod. Order Routing Line"; ProdOrder: Record "Production Order"; ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertComponentsOnAfterProdOrderCompSetFilters(var ProdOrderComp: Record "Prod. Order Component")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRoutingLinkValid(ProdOrderComponent: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertOutputItemJnlLineOnAfterAssignTimes(var ItemJournalLine: Record "Item Journal Line"; ProdOrderLine: Record "Prod. Order Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var QtyToPost: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertComponents(ProdOrderLine: Record "Prod. Order Line"; CheckRoutingLink: Boolean; Level: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateJnlLinesOnAfterSetProdOrderLineFilters(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteJnlLinesOnAfterSetFilters(var ItemJournalLine: Record "Item Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDataHasChanged(TemplateName: Code[10]; BatchName: Code[10]; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; var HasChanged: Boolean; var IsHandled: Boolean)
begin
end;
}