Table 904 Assemble-to-Order Link
- App
- Base Application
- Namespace
- Microsoft.Assembly.Document
- Versions
- 17-28
Fields, 9Keys, 3Procedures, 42Events, 48
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Assembly/Document/AssembletoOrderLink.Table.al2112 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.Assembly.Document;
using Microsoft.Assembly.Comment;
using Microsoft.Assembly.History;
using Microsoft.Finance.Currency;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Availability;
using Microsoft.Inventory.BOM;
using Microsoft.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Tracking;
using Microsoft.Pricing.Calculation;
using Microsoft.Pricing.PriceList;
using Microsoft.Projects.Project.Job;
using Microsoft.Projects.Project.Planning;
using Microsoft.Projects.Resources.Resource;
using Microsoft.Sales.Document;
using Microsoft.Sales.Setup;
using Microsoft.Warehouse.Activity;
using Microsoft.Warehouse.Document;
using Microsoft.Warehouse.Journal;
using System.Utilities;
table 904 "Assemble-to-Order Link"
{
Caption = 'Assemble-to-Order Link';
DataClassification = CustomerContent;
Permissions = TableData "Assembly Header" = rimd,
TableData "Assemble-to-Order Link" = rimd;
fields
{
#pragma warning disable AS0004 // required fix
field(1; "Assembly Document Type"; Enum "Assembly Document Type")
{
Caption = 'Assembly Document Type';
}
#pragma warning restore AS0004
field(2; "Assembly Document No."; Code[20])
{
Caption = 'Assembly Document No.';
TableRelation = "Assembly Header" where("Document Type" = field("Assembly Document Type"),
"No." = field("Assembly Document No."));
ValidateTableRelation = false;
}
field(11; Type; Enum "Assemble-to-Order Link Type")
{
Caption = 'Type';
}
field(12; "Document Type"; Enum "Sales Document Type")
{
Caption = 'Document Type';
}
field(13; "Document No."; Code[20])
{
Caption = 'Document No.';
TableRelation = if (Type = const(Sale)) "Sales Line"."Document No." where("Document Type" = field("Document Type"),
"Document No." = field("Document No."),
"Line No." = field("Document Line No."))
else
if (Type = const(Job)) "Job Planning Line"."Document No." where("Job No." = field("Job No."),
"Job Task No." = field("Job Task No."),
"Line No." = field("Document Line No."));
}
field(14; "Document Line No."; Integer)
{
Caption = 'Document Line No.';
}
field(20; "Assembled Quantity"; Decimal)
{
Caption = 'Assembled Quantity';
DecimalPlaces = 0 : 5;
AutoFormatType = 0;
}
field(40; "Job No."; Code[20])
{
Caption = 'Project No.';
TableRelation = Job;
}
field(41; "Job Task No."; Code[20])
{
Caption = 'Project Task No.';
TableRelation = "Job Task"."Job Task No." where("Job No." = field("Job No."));
}
}
keys
{
key(Key1; "Assembly Document Type", "Assembly Document No.")
{
Clustered = true;
}
key(Key2; Type, "Document Type", "Document No.", "Document Line No.")
{
}
key(Key3; Type, "Job No.", "Job Task No.", "Document Line No.")
{
}
}
fieldgroups
{
}
var
AsmHeader: Record "Assembly Header";
UOMMgt: Codeunit "Unit of Measure Management";
HideConfirm: Boolean;
#pragma warning disable AA0074
Text000: Label 'Synchronizing...\ from: %1 with %2\ to: %3 with %4.', Comment = '%1 = Table caption of SalesLine or WhseShptLine or InvtPickLine, %2 = Key text of SalesLine or WhseShptLine or InvtPickLine, %3 = Table caption of Assembly header, %4 = Key text of assembly header';
Text001: Label 'Do you want to roll up the price from the assembly components?';
Text002: Label 'Do you want to roll up the cost from the assembly components?';
#pragma warning disable AA0470
Text003: Label 'The item tracking defined on Assembly Header with Document Type %1, No. %2 exceeds %3 on Sales Line with Document Type %4, Document No. %5, Line No. %6.\\ You must adjust the existing item tracking before you can reenter the new quantity.', Comment = '%1 = Document Type, %2 = No.';
Text004: Label '%1 cannot be lower than %2 or higher than %3.\These limits may be defined by constraints calculated from the %4 field on the related %5. Refer to the field help for more information.';
Text005: Label 'One or more %1 lines exist for the %2.';
Text006: Label 'The status of the linked assembly order will be changed to %1. Do you want to continue?';
Text007: Label 'A %1 exists for the %2. \\If you want to record and post a different %3, then you must do this in the %4 field on the related %1.';
#pragma warning restore AA0470
Text008: Label '%1 %2', Comment = 'Key Value, say: %1=Line No. %2=10000';
#pragma warning restore AA0074
ItemTrackingQtyDiffErr: Label 'The item tracking defined on Assembly Header with Document Type %1, No. %2 exceeds %3 on Project Planning Line with Job No. %4, Job Task No. %5, Line No. %6.\\ You must adjust the existing item tracking before you can reenter the new quantity.', Comment = '%1 = Document Type, %2 = No., %3 = Qty. to Assemble (Base), %4 = Job No., %5 = Job Task No., %6 = Line No.';
CreateAsmForJobErr: Label 'It is not possible to create an assembly order for a job task that is completed.';
AssebmlyOrderExistsForJobErr: Label 'One or more assembly orders exists for the project %1.\\You must delete the assembly order before you can change the job status.', Comment = '%1 = Job No.';
procedure UpdateAsmFromSalesLine(var NewSalesLine: Record "Sales Line")
begin
UpdateAsm(NewSalesLine, AsmExistsForSalesLine(NewSalesLine));
end;
procedure UpdateAsmFromSalesLineATOExist(var NewSalesLine: Record "Sales Line")
begin
UpdateAsm(NewSalesLine, true);
end;
local procedure UpdateAsm(var NewSalesLine: Record "Sales Line"; AsmExists: Boolean)
var
SalesLine2: Record "Sales Line";
InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
PostedATOLink: Record "Posted Assemble-to-Order Link";
IsHandled: Boolean;
ShouldDeleteAsm: Boolean;
begin
IsHandled := false;
OnBeforeUpdateAsm(NewSalesLine, AsmExists, IsHandled);
if not IsHandled then begin
if AsmExists then begin
if not NewSalesLine.IsAsmToOrderAllowed() then begin
DeleteAsmFromSalesLine(NewSalesLine);
exit;
end;
ShouldDeleteAsm := NewSalesLine."Qty. to Assemble to Order" = 0;
OnUpdateAsmOnAfterCalcShouldDeleteAsm(NewSalesLine, ShouldDeleteAsm);
if ShouldDeleteAsm then begin
DeleteAsmFromSalesLine(NewSalesLine);
if "Assembly Document Type" = "Assembly Document Type"::Order then begin
InvtAdjmtEntryOrder.SetLoadFields("Order Type", "Order No.");
InvtAdjmtEntryOrder.SetRange("Order Type", InvtAdjmtEntryOrder."Order Type"::Assembly);
InvtAdjmtEntryOrder.SetRange("Order No.", "Assembly Document No.");
if not InvtAdjmtEntryOrder.IsEmpty() then begin
PostedATOLink.SetRange("Assembly Order No.", "Assembly Document No.");
if PostedATOLink.IsEmpty() then
Insert();
end;
end;
exit;
end;
if not GetAsmHeader() then begin
Delete();
InsertAsmHeader(AsmHeader, "Assembly Document Type", "Assembly Document No.");
end else begin
if not NeedsSynchronization(NewSalesLine) then
exit;
OnUpdateAsmOnBeforeAsmReOpenIfReleased(Rec, AsmHeader);
AsmReopenIfReleased();
Delete();
end;
end else begin
if NewSalesLine."Qty. to Assemble to Order" = 0 then
exit;
if not SalesLine2.Get(NewSalesLine."Document Type", NewSalesLine."Document No.", NewSalesLine."Line No.") then
exit;
InsertAsmHeader(AsmHeader, NewSalesLine."Document Type", '');
"Assembly Document Type" := AsmHeader."Document Type";
"Assembly Document No." := AsmHeader."No.";
Type := Type::Sale;
"Document Type" := NewSalesLine."Document Type";
"Document No." := NewSalesLine."Document No.";
"Document Line No." := NewSalesLine."Line No.";
end;
OnUpdateAsmOnBeforeSynchronizeAsmFromSalesLine(Rec, AsmHeader, NewSalesLine);
SynchronizeAsmFromSalesLine(NewSalesLine);
Insert();
AsmHeader."Shortcut Dimension 1 Code" := NewSalesLine."Shortcut Dimension 1 Code";
AsmHeader."Shortcut Dimension 2 Code" := NewSalesLine."Shortcut Dimension 2 Code";
AsmHeader.Modify(true);
end;
OnAfterUpdateAsm(AsmHeader, Rec, NewSalesLine, AsmExists);
end;
procedure UpdateAsmFromJobPlanningLine(var NewJobPlanningLine: Record "Job Planning Line")
begin
UpdateAsmFromJobPlanningLine(NewJobPlanningLine, AsmExistsForJobPlanningLine(NewJobPlanningLine));
end;
local procedure UpdateAsmFromJobPlanningLine(var NewJobPlanningLine: Record "Job Planning Line"; AsmExists: Boolean)
var
Job: Record Job;
begin
if AsmExists then begin
if not NewJobPlanningLine.IsAsmToOrderAllowed() then begin
DeleteAsmFromJobPlanningLine(NewJobPlanningLine);
exit;
end;
if NewJobPlanningLine."Qty. to Assemble" = 0 then begin
DeleteAsmFromJobPlanningLine(NewJobPlanningLine);
NewJobPlanningLine."Assemble to Order" := false;
InsertAssembeToOrderLinkIfInvtAdjmtEntryOrderExist();
exit;
end;
if not DeleteAssembleToOrderLink(NewJobPlanningLine) then
exit;
end else begin
if JobPlanningLineIsNotCorrect(NewJobPlanningLine) then
exit;
if not NewJobPlanningLine.IsAsmToOrderAllowed() then begin
NewJobPlanningLine."Qty. to Assemble" := 0;
NewJobPlanningLine."Qty. to Assemble (Base)" := 0;
exit;
end;
Job.Get(NewJobPlanningLine."Job No.");
CheckJobStatus(Job);
AssignAssembleToOrderData(NewJobPlanningLine, Job);
NewJobPlanningLine."Assemble to Order" := true;
end;
SynchronizeAsmFromJobPlanningLine(NewJobPlanningLine, "Document Type" = "Document Type"::Order);
Insert();
AssignGlobalDimensionsFromJobTask(NewJobPlanningLine);
end;
procedure UpdateAsmDimFromSalesLine(SalesLine: Record "Sales Line")
begin
UpdateAsmDimFromSalesLine(SalesLine, false);
end;
procedure UpdateAsmDimFromSalesLine(SalesLine: Record "Sales Line"; HideValidationDialog: Boolean)
var
Window: Dialog;
begin
if AsmExistsForSalesLine(SalesLine) then
if GetAsmHeader() then begin
AsmHeader.SetHideValidationDialog(HideValidationDialog);
Window.Open(GetWindowOpenTextSale(SalesLine));
if ChangeDim(SalesLine."Dimension Set ID") then begin
AsmHeader."Shortcut Dimension 1 Code" := SalesLine."Shortcut Dimension 1 Code";
AsmHeader."Shortcut Dimension 2 Code" := SalesLine."Shortcut Dimension 2 Code";
AsmHeader.Modify(true);
end;
Window.Close();
end;
end;
procedure UpdateQtyToAsmFromSalesLine(SalesLine: Record "Sales Line")
var
Window: Dialog;
ShowWindow: Boolean;
begin
if AsmExistsForSalesLine(SalesLine) then
if GetAsmHeader() then begin
ShowWindow := GuiAllowed();
OnUpdateQtyToAsmFromSalesLineOnBeforeUpdateQtyToAsm(SalesLine, ShowWindow);
if ShowWindow then
Window.Open(GetWindowOpenTextSale(SalesLine));
UpdateQtyToAsm(MaxQtyToAsm(SalesLine, AsmHeader));
if ShowWindow then
Window.Close();
end;
end;
procedure UpdateQtyToAsmFromWhseShptLine(WhseShptLine: Record "Warehouse Shipment Line")
var
Window: Dialog;
IsHandled: Boolean;
ShowWindow: Boolean;
begin
IsHandled := false;
ShowWindow := GuiAllowed();
OnBeforeUpdateQtyToAsmFromWhseShptLine(WhseShptLine, IsHandled, ShowWindow);
if IsHandled then
exit;
if AsmExistsForWhseShptLine(WhseShptLine) then
if GetAsmHeader() then begin
if ShowWindow then
Window.Open(GetWindowOpenTextWhseShpt(WhseShptLine));
UpdateQtyToAsm(WhseShptLine."Qty. to Ship");
if ShowWindow then
Window.Close();
end;
end;
procedure UpdateQtyToAsmFromInvtPickLine(InvtPickWhseActivityLine: Record "Warehouse Activity Line")
var
WhseActivityLine: Record "Warehouse Activity Line";
Window: Dialog;
TotalQtyToAsm: Decimal;
begin
WhseActivityLine.SetRange("Activity Type", InvtPickWhseActivityLine."Activity Type");
WhseActivityLine.SetRange("Source Type", InvtPickWhseActivityLine."Source Type");
WhseActivityLine.SetRange("Source Subtype", InvtPickWhseActivityLine."Source Subtype");
WhseActivityLine.SetRange("Source No.", InvtPickWhseActivityLine."Source No.");
WhseActivityLine.SetRange("Source Line No.", InvtPickWhseActivityLine."Source Line No.");
WhseActivityLine.SetRange("Assemble to Order", true);
if WhseActivityLine.FindSet() then
repeat
TotalQtyToAsm += WhseActivityLine."Qty. to Handle";
until WhseActivityLine.Next() = 0;
if AsmExistsForInvtPickLine(InvtPickWhseActivityLine) then
if GetAsmHeader() then begin
Window.Open(GetWindowOpenTextInvtPick(InvtPickWhseActivityLine));
UpdateQtyToAsm(TotalQtyToAsm);
Window.Close();
end;
end;
local procedure UpdateQtyToAsm(NewQtyToAsm: Decimal)
begin
Delete();
if ChangeQtyToAsm(NewQtyToAsm) then
AsmHeader.Modify(true);
Insert();
end;
procedure UpdateAsmBinCodeFromSalesLine(SalesLine: Record "Sales Line")
var
Window: Dialog;
begin
if AsmExistsForSalesLine(SalesLine) then
if GetAsmHeader() then begin
Window.Open(GetWindowOpenTextSale(SalesLine));
UpdateAsmBinCode(SalesLine."Bin Code");
Window.Close();
end;
end;
procedure UpdateAsmBinCodeFromWhseShptLine(WhseShptLine: Record "Warehouse Shipment Line")
var
Window: Dialog;
begin
if AsmExistsForWhseShptLine(WhseShptLine) then
if GetAsmHeader() then begin
Window.Open(GetWindowOpenTextWhseShpt(WhseShptLine));
UpdateAsmBinCode(WhseShptLine."Bin Code");
Window.Close();
end;
end;
procedure UpdateAsmBinCodeFromInvtPickLine(InvtPickWhseActivityLine: Record "Warehouse Activity Line")
var
Window: Dialog;
begin
if AsmExistsForInvtPickLine(InvtPickWhseActivityLine) then
if GetAsmHeader() then begin
Window.Open(GetWindowOpenTextInvtPick(InvtPickWhseActivityLine));
UpdateAsmBinCode(InvtPickWhseActivityLine."Bin Code");
Window.Close();
end;
end;
internal procedure UpdateAsmBinCodeFromJobPlanningLine(JobPlanningLine: Record "Job Planning Line")
var
Window: Dialog;
begin
if AsmExistsForJobPlanningLine(JobPlanningLine) then
if GetAsmHeader() and GuiAllowed() then begin
Window.Open(GetWindowOpenTextJob(JobPlanningLine));
UpdateAsmBinCode(JobPlanningLine."Bin Code");
Window.Close();
end;
end;
local procedure UpdateAsmBinCode(NewBinCode: Code[20])
begin
AsmHeader.SuspendStatusCheck(true);
if ChangeBinCode(NewBinCode) then
AsmHeader.Modify(true);
AsmHeader.SuspendStatusCheck(false);
end;
procedure DeleteAsmFromSalesLine(SalesLine: Record "Sales Line")
begin
if AsmExistsForSalesLine(SalesLine) then begin
Delete();
if "Document Type" = "Document Type"::Order then
UnreserveAsm();
if GetAsmHeader() then begin
AsmHeader.Delete(true);
AsmHeader.Init();
end;
end;
end;
procedure DeleteAsmFromJobPlanningLine(JobPlanningLine: Record "Job Planning Line")
begin
if AsmExistsForJobPlanningLine(JobPlanningLine) then begin
Delete();
if "Document Type" = "Document Type"::Order then
UnreserveAsm();
if GetAsmHeader() then begin
AsmHeader.Delete(true);
AsmHeader.Init();
end;
end;
end;
procedure InsertAsmHeader(var AsmHeader: Record "Assembly Header"; NewDocType: Enum "Assembly Document Type"; NewDocNo: Code[20])
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInsertAsmHeader(AsmHeader, NewDocType.AsInteger(), NewDocNo, IsHandled);
if IsHandled then
exit;
AsmHeader.Init();
AsmHeader.Validate("Document Type", NewDocType);
AsmHeader."No." := NewDocNo;
OnBeforeAsmHeaderInsert(AsmHeader);
AsmHeader.Insert(true);
end;
local procedure SynchronizeAsmFromSalesLine(var NewSalesLine: Record "Sales Line")
var
TempTrackingSpecification: Record "Tracking Specification" temporary;
SalesHeader: Record "Sales Header";
Window: Dialog;
QtyTracked: Decimal;
QtyTrackedBase: Decimal;
ShowWindow: Boolean;
begin
GetAsmHeader();
ShowWindow := GuiAllowed();
OnSynchronizeAsmFromSalesLineOnAfterGetAsmHeader(NewSalesLine, AsmHeader, ShowWindow);
if ShowWindow then
Window.Open(GetWindowOpenTextSale(NewSalesLine));
CaptureItemTracking(TempTrackingSpecification, QtyTracked, QtyTrackedBase);
if NewSalesLine."Qty. to Asm. to Order (Base)" < QtyTrackedBase then
Error(Text003,
AsmHeader."Document Type",
AsmHeader."No.",
NewSalesLine.FieldCaption("Qty. to Assemble to Order"),
NewSalesLine."Document Type",
NewSalesLine."Document No.",
NewSalesLine."Line No.");
UnreserveAsm();
SalesHeader.Get(NewSalesLine."Document Type", NewSalesLine."Document No.");
AsmHeader.SetWarningsOff();
ChangeItem(NewSalesLine."No.");
ChangeLocation(NewSalesLine."Location Code");
ChangeVariant(NewSalesLine."Variant Code");
ChangeBinCode(NewSalesLine."Bin Code");
ChangeUOM(NewSalesLine."Unit of Measure Code");
ChangeDate(NewSalesLine."Shipment Date");
ChangePostingDate(SalesHeader."Posting Date");
ChangeDim(NewSalesLine."Dimension Set ID");
ChangePlanningFlexibility();
OnSynchronizeAsmFromSalesLineOnBeforeChangeQty(AsmHeader, NewSalesLine);
ChangeQty(NewSalesLine."Qty. to Assemble to Order");
if NewSalesLine."Document Type" <> NewSalesLine."Document Type"::Quote then
ChangeQtyToAsm(MaxQtyToAsm(NewSalesLine, AsmHeader));
OnBeforeAsmHeaderModify(AsmHeader, NewSalesLine);
AsmHeader.Modify(true);
ReserveAsmToSale(NewSalesLine,
AsmHeader."Remaining Quantity" - QtyTracked,
AsmHeader."Remaining Quantity (Base)" - QtyTrackedBase);
RestoreItemTracking(TempTrackingSpecification, NewSalesLine);
NewSalesLine.CheckAsmToOrder(AsmHeader);
if ShowWindow then
Window.Close();
AsmHeader.SetWarningsOn();
AsmHeader.ShowDueDateBeforeWorkDateMsg();
end;
local procedure SynchronizeAsmFromJobPlanningLine(var NewJobPlanningLine: Record "Job Planning Line"; ReserveLine: Boolean)
var
TempTrackingSpecification: Record "Tracking Specification" temporary;
Window: Dialog;
QtyTracked: Decimal;
QtyTrackedBase: Decimal;
begin
GetAsmHeader();
Window.Open(GetWindowOpenTextJob(NewJobPlanningLine));
CaptureItemTracking(TempTrackingSpecification, QtyTracked, QtyTrackedBase);
if NewJobPlanningLine."Qty. to Assemble (Base)" < QtyTrackedBase then
Error(ItemTrackingQtyDiffErr,
AsmHeader."Document Type",
AsmHeader."No.",
NewJobPlanningLine.FieldCaption("Qty. to Assemble"),
NewJobPlanningLine."Job No.",
NewJobPlanningLine."Job Task No.",
NewJobPlanningLine."Line No.");
UnreserveAsm();
ChangeAsmHeaderFromJobPLanningLine(NewJobPlanningLine);
if ReserveLine then
ReserveAsmToJob(NewJobPlanningLine,
AsmHeader."Remaining Quantity" - QtyTracked,
AsmHeader."Remaining Quantity (Base)" - QtyTrackedBase);
RestoreItemTracking(TempTrackingSpecification, NewJobPlanningLine);
NewJobPlanningLine.CheckAsmToOrder(AsmHeader);
Window.Close();
AsmHeader.SetWarningsOn();
AsmHeader.ShowDueDateBeforeWorkDateMsg();
end;
local procedure ChangeAsmHeaderFromJobPLanningLine(var NewJobPlanningLine: Record "Job Planning Line")
begin
AsmHeader.SetWarningsOff();
ChangeItem(NewJobPlanningLine."No.");
ChangeLocation(NewJobPlanningLine."Location Code");
ChangeVariant(NewJobPlanningLine."Variant Code");
ChangeBinCode(NewJobPlanningLine."Bin Code");
ChangeUOM(NewJobPlanningLine."Unit of Measure Code");
ChangePostingDate(NewJobPlanningLine."Planning Date");
ChangePlanningFlexibility();
ChangeQty(NewJobPlanningLine."Qty. to Assemble");
AsmHeader.Modify(true);
end;
procedure MakeAsmOrderLinkedToSalesOrderLine(FromSalesLine: Record "Sales Line"; ToSalesOrderLine: Record "Sales Line")
var
ToAsmOrderHeader: Record "Assembly Header";
begin
if AsmExistsForSalesLine(FromSalesLine) then begin
ToSalesOrderLine.TestField(Type, ToSalesOrderLine.Type::Item);
ToSalesOrderLine.TestField("No.", FromSalesLine."No.");
if GetAsmHeader() then begin
ToAsmOrderHeader.Init();
CopyAsmToNewAsmOrder(AsmHeader, ToAsmOrderHeader, true);
Init();
"Assembly Document Type" := ToAsmOrderHeader."Document Type";
"Assembly Document No." := ToAsmOrderHeader."No.";
Type := Type::Sale;
"Document Type" := ToSalesOrderLine."Document Type";
"Document No." := ToSalesOrderLine."Document No.";
"Document Line No." := ToSalesOrderLine."Line No.";
SynchronizeAsmFromSalesLine(ToSalesOrderLine);
RecalcAutoReserve(ToAsmOrderHeader);
Insert();
end;
OnMakeAsmOrderLinkedToSalesOrderLineOnBeforeCheckDocumentType(Rec, ToAsmOrderHeader, AsmHeader, ToSalesOrderLine, FromSalesLine);
if FromSalesLine."Document Type" = FromSalesLine."Document Type"::Quote then
DeleteAsmFromSalesLine(FromSalesLine);
end;
end;
procedure CheckIfAssembleToOrderLinkExist(Job: Record Job)
begin
if Job.Status in [Job.Status::Completed, Job.Status::Open] then
exit;
SetRange(Type, Type::Job);
SetRange("Job No.", Job."No.");
SetRange("Document Type", "Document Type"::Order);
if not IsEmpty() then
Error(AssebmlyOrderExistsForJobErr, Job."No.");
end;
procedure MakeAsmOrderLinkedToJobPlanningOrderLine(var JobPlanningLine: Record "Job Planning Line")
var
ToAsmOrderHeader: Record "Assembly Header";
begin
if not JobPlanningLine."Assemble to Order" then
exit;
if JobPlanningLine.Status = JobPlanningLine.Status::Order then
exit;
if JobPlanningLine."Line Type" = JobPlanningLine."Line Type"::Billable then
exit;
if not AsmExistsForJobPlanningLine(JobPlanningLine) then
exit;
JobPlanningLine.TestField(Type, JobPlanningLine.Type::Item);
if GetAsmHeader() then begin
ToAsmOrderHeader.Init();
CopyAsmToNewAsmOrder(AsmHeader, ToAsmOrderHeader, true);
Init();
"Assembly Document Type" := ToAsmOrderHeader."Document Type";
"Assembly Document No." := ToAsmOrderHeader."No.";
Type := Type::Job;
"Document No." := JobPlanningLine."Document No.";
"Document Type" := "Document Type"::Order;
"Document Line No." := JobPlanningLine."Line No.";
"Job No." := JobPlanningLine."Job No.";
"Job Task No." := JobPlanningLine."Job Task No.";
SynchronizeAsmFromJobPlanningLine(JobPlanningLine, true);
RecalcAutoReserve(ToAsmOrderHeader);
Insert();
end;
if JobPlanningLine.Status <> JobPlanningLine.Status::Order then
DeleteAsmFromJobPlanningLine(JobPlanningLine);
end;
local procedure NeedsSynchronization(SalesLine: Record "Sales Line") Result: Boolean
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeNeedsSynchronization(AsmHeader, SalesLine, Result, IsHandled);
if IsHandled then
exit(Result);
GetAsmHeader();
AsmHeader.CalcFields("Reserved Qty. (Base)");
exit(
(SalesLine."No." <> AsmHeader."Item No.") or
(SalesLine."Location Code" <> AsmHeader."Location Code") or
(SalesLine."Shipment Date" <> AsmHeader."Due Date") or
(SalesLine."Variant Code" <> AsmHeader."Variant Code") or
(SalesLine."Bin Code" <> AsmHeader."Bin Code") or
(SalesLine."Dimension Set ID" <> AsmHeader."Dimension Set ID") or
(SalesLine."Qty. to Asm. to Order (Base)" <> AsmHeader."Quantity (Base)") or
(SalesLine."Unit of Measure Code" <> AsmHeader."Unit of Measure Code") or
(AsmHeader."Planning Flexibility" <> AsmHeader."Planning Flexibility"::None) or
((SalesLine."Document Type" = SalesLine."Document Type"::Order) and
(AsmHeader."Remaining Quantity (Base)" <> AsmHeader."Reserved Qty. (Base)")));
end;
local procedure NeedsSynchronization(JobPlanningLine: Record "Job Planning Line") Result: Boolean
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeNeedsSynchronizationForProjectPlanningLine(AsmHeader, JobPlanningLine, Result, IsHandled);
if IsHandled then
exit(Result);
GetAsmHeader();
AsmHeader.CalcFields("Reserved Qty. (Base)");
exit(
(JobPlanningLine."No." <> AsmHeader."Item No.") or
(JobPlanningLine."Location Code" <> AsmHeader."Location Code") or
(JobPlanningLine."Variant Code" <> AsmHeader."Variant Code") or
(JobPlanningLine."Bin Code" <> AsmHeader."Bin Code") or
(JobPlanningLine."Qty. to Assemble (Base)" <> AsmHeader."Quantity (Base)") or
(JobPlanningLine."Unit of Measure Code" <> AsmHeader."Unit of Measure Code") or
(AsmHeader."Planning Flexibility" <> AsmHeader."Planning Flexibility"::None) or
(AsmHeader."Remaining Quantity (Base)" <> AsmHeader."Reserved Qty. (Base)"));
end;
local procedure ChangeItem(NewItemNo: Code[20])
begin
if AsmHeader."Item No." = NewItemNo then
exit;
AsmHeader.Validate("Item No.", NewItemNo);
end;
local procedure ChangeQty(NewQty: Decimal)
begin
if AsmHeader.Quantity = NewQty then
exit;
AsmHeader.Validate(Quantity, NewQty);
end;
local procedure ChangeQtyToAsm(NewQtyToAsm: Decimal): Boolean
begin
if AsmHeader."Quantity to Assemble" = NewQtyToAsm then
exit(false);
AsmHeader.Validate("Quantity to Assemble", NewQtyToAsm);
exit(true)
end;
local procedure ChangeLocation(NewLocation: Code[10])
begin
if AsmHeader."Location Code" = NewLocation then
exit;
AsmHeader.Validate("Location Code", NewLocation);
end;
local procedure ChangeVariant(NewVariant: Code[10])
begin
if AsmHeader."Variant Code" = NewVariant then
exit;
AsmHeader.Validate("Variant Code", NewVariant);
end;
local procedure ChangeUOM(NewUOMCode: Code[10])
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeChangeUOM(AsmHeader, NewUOMCode, IsHandled);
if IsHandled then
exit;
if AsmHeader."Unit of Measure Code" = NewUOMCode then
exit;
AsmHeader.Validate("Unit of Measure Code", NewUOMCode);
end;
local procedure ChangeDate(NewDate: Date)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeChangeDate(AsmHeader, NewDate, IsHandled);
if IsHandled then
exit;
if AsmHeader."Due Date" = NewDate then
exit;
AsmHeader.Validate("Due Date", NewDate);
end;
local procedure ChangePostingDate(NewDate: Date)
begin
if AsmHeader."Posting Date" = NewDate then
exit;
AsmHeader.Validate("Posting Date", NewDate);
end;
local procedure ChangeDim(NewDimSetID: Integer): Boolean
begin
if AsmHeader."Dimension Set ID" = NewDimSetID then
exit(false);
AsmHeader.Validate("Dimension Set ID", NewDimSetID);
exit(true)
end;
local procedure ChangeBinCode(NewBinCode: Code[20]): Boolean
begin
if AsmHeader."Bin Code" = NewBinCode then
exit(false);
AsmHeader.ValidateBinCode(NewBinCode);
exit(true);
end;
local procedure ChangePlanningFlexibility()
begin
if AsmHeader."Planning Flexibility" = AsmHeader."Planning Flexibility"::None then
exit;
AsmHeader.Validate("Planning Flexibility", AsmHeader."Planning Flexibility"::None);
end;
procedure ReserveAsmToSale(var SalesLine: Record "Sales Line"; QtyToReserve: Decimal; QtyToReserveBase: Decimal)
var
ReservEntry: Record "Reservation Entry";
TrackingSpecification: Record "Tracking Specification";
AsmHeaderReserve: Codeunit "Assembly Header-Reserve";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeReserveAsmToSale(SalesLine, QtyToReserve, QtyToReserveBase, IsHandled, Rec);
if IsHandled then
exit;
if SalesLine."Document Type" <> SalesLine."Document Type"::Order then
exit;
if Type = Type::Sale then begin
GetAsmHeader();
AsmHeaderReserve.SetBinding(ReservEntry.Binding::"Order-to-Order");
AsmHeaderReserve.SetDisallowCancellation(true);
TrackingSpecification.InitTrackingSpecification(
DATABASE::"Sales Line", SalesLine."Document Type".AsInteger(), SalesLine."Document No.", '', 0, SalesLine."Line No.",
AsmHeader."Variant Code", AsmHeader."Location Code", AsmHeader."Qty. per Unit of Measure");
AsmHeaderReserve.CreateReservationSetFrom(TrackingSpecification);
AsmHeaderReserve.CreateReservation(AsmHeader, AsmHeader.Description, AsmHeader."Due Date", QtyToReserve, QtyToReserveBase);
if SalesLine.Reserve = SalesLine.Reserve::Never then
SalesLine.Reserve := SalesLine.Reserve::Optional;
OnAfterReserveAsmToSale(Rec, AsmHeader, SalesLine, TrackingSpecification, QtyToReserve, QtyToReserveBase);
end;
end;
procedure ReserveAsmToJob(var JobPlanningLine: Record "Job Planning Line"; QtyToReserve: Decimal; QtyToReserveBase: Decimal)
var
ReservEntry: Record "Reservation Entry";
TrackingSpecification: Record "Tracking Specification";
AsmHeaderReserve: Codeunit "Assembly Header-Reserve";
begin
if Type <> Type::Job then
exit;
GetAsmHeader();
AsmHeaderReserve.SetBinding(ReservEntry.Binding::"Order-to-Order");
AsmHeaderReserve.SetDisallowCancellation(true);
TrackingSpecification.InitTrackingSpecification(
Database::"Job Planning Line", 2, JobPlanningLine."Job No.", '', 0, JobPlanningLine."Job Contract Entry No.",
AsmHeader."Variant Code", AsmHeader."Location Code", AsmHeader."Qty. per Unit of Measure");
AsmHeaderReserve.CreateReservationSetFrom(TrackingSpecification);
AsmHeaderReserve.CreateReservation(AsmHeader, AsmHeader.Description, AsmHeader."Due Date", QtyToReserve, QtyToReserveBase);
if JobPlanningLine.Reserve = JobPlanningLine.Reserve::Never then
JobPlanningLine.Reserve := JobPlanningLine.Reserve::Optional;
end;
local procedure UnreserveAsm()
var
ReservEntry: Record "Reservation Entry";
AsmHeaderReserve: Codeunit "Assembly Header-Reserve";
begin
GetAsmHeader();
AsmHeader.SetReservationFilters(ReservEntry);
AsmHeaderReserve.DeleteLine(AsmHeader);
end;
local procedure CaptureItemTracking(var TrackingSpecification: Record "Tracking Specification"; var QtyTracked: Decimal; var QtyTrackedBase: Decimal)
var
ReservEntry: Record "Reservation Entry";
Item: Record Item;
begin
GetAsmHeader();
TrackingSpecification.Reset();
TrackingSpecification.DeleteAll();
AsmHeader.SetReservationFilters(ReservEntry);
if ReservEntry.Find('-') then begin
Item.Get(AsmHeader."Item No.");
repeat
if ReservEntry.TrackingExists() then begin
TrackingSpecification.TransferFields(ReservEntry);
TrackingSpecification.Insert();
QtyTracked += ReservEntry.Quantity;
QtyTrackedBase += ReservEntry."Quantity (Base)";
RemoveTrackingFromReservation(ReservEntry, Item."Item Tracking Code");
end;
until ReservEntry.Next() = 0;
end;
end;
local procedure RemoveTrackingFromReservation(ReservEntry: Record "Reservation Entry"; ItemTrackingCode: Code[10])
var
ItemTrackingCodeRec: Record "Item Tracking Code";
TrackingSpecification: Record "Tracking Specification";
ReservEngineMgt: Codeunit "Reservation Engine Mgt.";
QtyToAdd: Decimal;
begin
OnBeforeRemoveTrackingFromReservation(ReservEntry, ItemTrackingCode);
ReservEntry.SetPointerFilter();
ReservEntry.SetTrackingFilterFromReservEntry(ReservEntry);
TrackingSpecification.TransferFields(ReservEntry);
TrackingSpecification.SetTrackingBlank();
OnRemoveTrackingFromReservationOnAfterSetTracking(TrackingSpecification);
ItemTrackingCodeRec.Get(ItemTrackingCode);
ReservEngineMgt.AddItemTrackingToTempRecSet(
ReservEntry, TrackingSpecification, TrackingSpecification."Quantity (Base)",
QtyToAdd, ItemTrackingCodeRec);
OnAfterRemoveTrackingFromReservation(ReservEntry, TrackingSpecification, ItemTrackingCodeRec);
end;
local procedure RestoreItemTracking(var TrackingSpecification: Record "Tracking Specification"; SalesLine: Record "Sales Line")
var
ReservEntry: Record "Reservation Entry";
FromTrackingSpecification: Record "Tracking Specification";
CreateReservEntry: Codeunit "Create Reserv. Entry";
SalesLineReserve: Codeunit "Sales Line-Reserve";
begin
GetAsmHeader();
if TrackingSpecification.Find('-') then
repeat
OnRestoreItemTrackingOnBeforeTrackingSpecificationLoop(TrackingSpecification);
CreateReservEntry.SetDates(TrackingSpecification."Warranty Date", TrackingSpecification."Expiration Date");
CreateReservEntry.SetApplyFromEntryNo(TrackingSpecification."Appl.-from Item Entry");
CreateReservEntry.SetDisallowCancellation(true);
CreateReservEntry.SetBinding(ReservEntry.Binding::"Order-to-Order");
CreateReservEntry.SetQtyToHandleAndInvoice(
TrackingSpecification."Qty. to Handle (Base)", TrackingSpecification."Qty. to Invoice (Base)");
ReservEntry.CopyTrackingFromSpec(TrackingSpecification);
CreateReservEntry.CreateReservEntryFor(
DATABASE::"Assembly Header", AsmHeader."Document Type".AsInteger(), AsmHeader."No.", '', 0, 0,
AsmHeader."Qty. per Unit of Measure", 0, TrackingSpecification."Quantity (Base)", ReservEntry);
SalesLineReserve.InitFromSalesLine(FromTrackingSpecification, SalesLine);
FromTrackingSpecification."Qty. per Unit of Measure" := AsmHeader."Qty. per Unit of Measure";
FromTrackingSpecification.CopyTrackingFromTrackingSpec(TrackingSpecification);
CreateReservEntry.CreateReservEntryFrom(FromTrackingSpecification);
OnRestoreItemTrackingOnAfterCreateReservEntryFrom(TrackingSpecification);
CreateReservEntry.CreateEntry(
AsmHeader."Item No.", AsmHeader."Variant Code", AsmHeader."Location Code", AsmHeader.Description,
AsmHeader."Due Date", AsmHeader."Due Date", 0, "Reservation Status"::Reservation);
until TrackingSpecification.Next() = 0;
TrackingSpecification.DeleteAll();
end;
local procedure RestoreItemTracking(var TrackingSpecification: Record "Tracking Specification"; JobPlanningLine: Record "Job Planning Line")
var
ReservEntry: Record "Reservation Entry";
FromTrackingSpecification: Record "Tracking Specification";
CreateReservEntry: Codeunit "Create Reserv. Entry";
JobPlanningLineReserve: Codeunit "Job Planning Line-Reserve";
begin
if not TrackingSpecification.Find('-') then
exit;
GetAsmHeader();
repeat
CreateReservEntry.SetDates(TrackingSpecification."Warranty Date", TrackingSpecification."Expiration Date");
CreateReservEntry.SetApplyFromEntryNo(TrackingSpecification."Appl.-from Item Entry");
CreateReservEntry.SetDisallowCancellation(true);
CreateReservEntry.SetBinding(ReservEntry.Binding::"Order-to-Order");
CreateReservEntry.SetQtyToHandleAndInvoice(
TrackingSpecification."Qty. to Handle (Base)", TrackingSpecification."Qty. to Invoice (Base)");
ReservEntry.CopyTrackingFromSpec(TrackingSpecification);
CreateReservEntry.CreateReservEntryFor(
DATABASE::"Assembly Header", AsmHeader."Document Type".AsInteger(), AsmHeader."No.", '', 0, 0,
AsmHeader."Qty. per Unit of Measure", 0, TrackingSpecification."Quantity (Base)", ReservEntry);
JobPlanningLineReserve.InitFromJobPlanningLine(FromTrackingSpecification, JobPlanningLine);
FromTrackingSpecification."Qty. per Unit of Measure" := AsmHeader."Qty. per Unit of Measure";
FromTrackingSpecification.CopyTrackingFromTrackingSpec(TrackingSpecification);
CreateReservEntry.CreateReservEntryFrom(FromTrackingSpecification);
CreateReservEntry.CreateEntry(
AsmHeader."Item No.", AsmHeader."Variant Code", AsmHeader."Location Code", AsmHeader.Description,
AsmHeader."Due Date", AsmHeader."Due Date", 0, "Reservation Status"::Reservation);
until TrackingSpecification.Next() = 0;
TrackingSpecification.DeleteAll();
end;
local procedure CopyAsmToNewAsmOrder(FromAsmHeader: Record "Assembly Header"; var ToAsmOrderHeader: Record "Assembly Header"; CopyComments: Boolean)
var
FromAsmLine: Record "Assembly Line";
ToAsmOrderLine: Record "Assembly Line";
FromAsmCommentLine: Record "Assembly Comment Line";
ToAsmCommentLine: Record "Assembly Comment Line";
AssemblyLineReserve: Codeunit "Assembly Line-Reserve";
RecordLinkManagement: Codeunit "Record Link Management";
begin
ToAsmOrderHeader := FromAsmHeader;
ToAsmOrderHeader."Document Type" := ToAsmOrderHeader."Document Type"::Order;
ToAsmOrderHeader."No." := '';
ToAsmOrderHeader.Status := ToAsmOrderHeader.Status::Open;
ToAsmOrderHeader."Assembled Quantity" := 0;
ToAsmOrderHeader."Assembled Quantity (Base)" := 0;
ToAsmOrderHeader.Validate(Quantity, FromAsmHeader."Quantity to Assemble");
ToAsmOrderHeader.Insert(true);
RecordLinkManagement.CopyLinks(FromAsmHeader, ToAsmOrderHeader);
FromAsmLine.SetRange("Document Type", FromAsmHeader."Document Type");
FromAsmLine.SetRange("Document No.", FromAsmHeader."No.");
if FromAsmLine.Find('-') then
repeat
ToAsmOrderLine := FromAsmLine;
ToAsmOrderLine."Document Type" := ToAsmOrderLine."Document Type"::Order;
ToAsmOrderLine."Document No." := ToAsmOrderHeader."No.";
ToAsmOrderLine."Consumed Quantity" := 0;
ToAsmOrderLine."Consumed Quantity (Base)" := 0;
ToAsmOrderLine.Validate(Quantity, FromAsmLine."Quantity to Consume");
ToAsmOrderLine.Insert(true);
OnCopyAsmToNewAsmOrderOnToAsmOrderLineInsert(FromAsmLine, ToAsmOrderLine);
AssemblyLineReserve.TransferAsmLineToAsmLine(FromAsmLine, ToAsmOrderLine, ToAsmOrderLine."Quantity (Base)");
AssemblyLineReserve.SetDeleteItemTracking(true);
AssemblyLineReserve.DeleteLine(FromAsmLine);
until FromAsmLine.Next() = 0;
if CopyComments then begin
FromAsmCommentLine.SetRange("Document Type", FromAsmHeader."Document Type");
FromAsmCommentLine.SetRange("Document No.", FromAsmHeader."No.");
if FromAsmCommentLine.Find('-') then
repeat
ToAsmCommentLine := FromAsmCommentLine;
ToAsmCommentLine."Document Type" := ToAsmCommentLine."Document Type"::"Assembly Order";
ToAsmCommentLine."Document No." := ToAsmOrderHeader."No.";
ToAsmCommentLine.Insert(true);
until FromAsmCommentLine.Next() = 0;
end;
end;
procedure RollUpPrice(SalesHeader: Record "Sales Header"; var SalesLine: Record "Sales Line")
var
AssemblyLine: Record "Assembly Line";
CompSalesLine: Record "Sales Line";
CompItem: Record Item;
Resource: Record Resource;
Currency: Record Currency;
PriceCalculationMgt: codeunit "Price Calculation Mgt.";
LineWithPrice: Interface "Line With Price";
PriceCalculation: Interface "Price Calculation";
PriceType: Enum "Price Type";
UnitPrice: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeRollUpPrice(SalesLine, Rec, IsHandled);
if IsHandled then
exit;
SalesLine.TestField(Quantity);
SalesLine.TestField("Qty. to Asm. to Order (Base)");
if not HideConfirm then
if not Confirm(Text001) then
exit;
if not AsmExistsForSalesLine(SalesLine) then
exit;
if not GetAsmHeader() then
exit;
if SalesHeader."Currency Code" = '' then
Currency.InitRoundingPrecision()
else begin
SalesHeader.TestField("Currency Factor");
Currency.Get(SalesHeader."Currency Code");
Currency.TestField("Unit-Amount Rounding Precision");
end;
AssemblyLine.SetRange("Document Type", AsmHeader."Document Type");
AssemblyLine.SetRange("Document No.", AsmHeader."No.");
if AssemblyLine.Find('-') then
repeat
if AssemblyLine.Type in [AssemblyLine.Type::Item, AssemblyLine.Type::Resource] then begin
CompSalesLine := SalesLine;
CompSalesLine."Line No." := 0;
CompSalesLine.Quantity := 0;
CompSalesLine."Quantity (Base)" := 0;
CompSalesLine."No." := AssemblyLine."No.";
CompSalesLine."Variant Code" := AssemblyLine."Variant Code";
CompSalesLine."Qty. per Unit of Measure" := AssemblyLine."Qty. per Unit of Measure";
case AssemblyLine.Type of
AssemblyLine.Type::Item:
begin
CompItem.Get(CompSalesLine."No.");
CompSalesLine.Type := CompSalesLine.Type::Item;
CompSalesLine."Gen. Prod. Posting Group" := CompItem."Gen. Prod. Posting Group";
CompSalesLine."Tax Group Code" := CompItem."Tax Group Code";
CompSalesLine.Validate("VAT Prod. Posting Group", CompItem."VAT Prod. Posting Group");
end;
AssemblyLine.Type::Resource:
begin
Resource.Get(CompSalesLine."No.");
CompSalesLine.Type := CompSalesLine.Type::Resource;
CompSalesLine."Gen. Prod. Posting Group" := Resource."Gen. Prod. Posting Group";
CompSalesLine."Tax Group Code" := Resource."Tax Group Code";
CompSalesLine.Validate("VAT Prod. Posting Group", Resource."VAT Prod. Posting Group");
end;
end;
CompSalesLine.Quantity := AssemblyLine.Quantity;
CompSalesLine."Quantity (Base)" := AssemblyLine."Quantity (Base)";
CompSalesLine."Unit of Measure Code" := AssemblyLine."Unit of Measure Code";
CompSalesLine."Unit Price" := 0;
CompSalesLine."Allow Line Disc." := false;
OnRollUpPriceOnBeforeFindSalesLinePrice(SalesHeader, CompSalesLine, AssemblyLine);
CompSalesLine.GetLineWithPrice(LineWithPrice);
LineWithPrice.SetLine(PriceType::Sale, SalesHeader, CompSalesLine);
PriceCalculationMgt.GetHandler(LineWithPrice, PriceCalculation);
CompSalesLine.ApplyPrice(SalesLine.FieldNo("No."), PriceCalculation);
OnRollUpPriceOnAfterFindSalesLinePrice(SalesHeader, CompSalesLine);
UnitPrice += CompSalesLine."Unit Price" * AssemblyLine.Quantity;
end;
until AssemblyLine.Next() = 0;
UnitPrice := Round(UnitPrice / AsmHeader.Quantity, Currency."Unit-Amount Rounding Precision");
SalesLine.Validate("Unit Price", UnitPrice);
OnRollUpPriceOnBeforeModifySalesline(SalesLine);
SalesLine.Modify(true);
end;
procedure RollUpCost(var SalesLine: Record "Sales Line")
var
AsmLine: Record "Assembly Line";
UnitCost: Decimal;
begin
SalesLine.TestField(Quantity);
SalesLine.TestField("Qty. to Asm. to Order (Base)");
if not HideConfirm then
if not Confirm(Text002) then
exit;
if not AsmExistsForSalesLine(SalesLine) then
exit;
if not GetAsmHeader() then
exit;
AsmLine.SetRange("Document Type", AsmHeader."Document Type");
AsmLine.SetRange("Document No.", AsmHeader."No.");
if AsmLine.Find('-') then
repeat
UnitCost += AsmLine."Cost Amount";
until AsmLine.Next() = 0;
SalesLine.Validate("Unit Cost (LCY)", Round(UnitCost / AsmHeader.Quantity, 0.00001));
OnRollUpCostOnBeforeModifySalesLine(SalesLine);
SalesLine.Modify(true);
end;
procedure ShowAsm(SalesLine: Record "Sales Line")
begin
SalesLine.TestField("Qty. to Asm. to Order (Base)");
if AsmExistsForSalesLine(SalesLine) then begin
GetAsmHeader();
case "Document Type" of
"Document Type"::Quote:
PAGE.RunModal(PAGE::"Assembly Quote", AsmHeader);
"Document Type"::"Blanket Order":
PAGE.RunModal(PAGE::"Blanket Assembly Order", AsmHeader);
"Document Type"::Order:
PAGE.RunModal(PAGE::"Assembly Order", AsmHeader);
end;
end;
end;
local procedure ShowAsm(JobPlanningLine: Record "Job Planning Line")
begin
JobPlanningLine.TestField("Qty. to Assemble (Base)");
if AsmExistsForJobPlanningLine(JobPlanningLine) then begin
GetAsmHeader();
case AsmHeader."Document Type" of
AsmHeader."Document Type"::Quote:
Page.RunModal(Page::"Assembly Quote", AsmHeader);
AsmHeader."Document Type"::Order:
Page.RunModal(Page::"Assembly Order", AsmHeader);
end;
end;
end;
procedure ShowAsmDocument()
var
SalesLine: Record "Sales Line";
JobPlanningLine: Record "Job Planning Line";
begin
case Rec.Type of
Rec.Type::Sale:
begin
SalesLine.Get(Rec."Document Type", Rec."Document No.", Rec."Document Line No.");
ShowAsm(SalesLine);
end;
Rec.Type::Job:
begin
JobPlanningLine.Get(Rec."Job No.", Rec."Job Task No.", Rec."Document Line No.");
ShowAsm(JobPlanningLine);
end;
end;
end;
procedure ShowAsmToOrderLines(SalesLine: Record "Sales Line")
var
AsmLine: Record "Assembly Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeShowAsmToOrderLines(SalesLine, IsHandled);
if IsHandled then
exit;
SalesLine.TestField("Qty. to Asm. to Order (Base)");
if AsmExistsForSalesLine(SalesLine) then begin
AsmLine.FilterGroup := 2;
AsmLine.SetRange("Document Type", "Assembly Document Type");
AsmLine.SetRange("Document No.", "Assembly Document No.");
AsmLine.FilterGroup := 0;
PAGE.RunModal(PAGE::"Assemble-to-Order Lines", AsmLine);
end;
end;
procedure ShowAsmToJobPlanningLines(JobPlanningLine: Record "Job Planning Line")
var
AsmLine: Record "Assembly Line";
begin
JobPlanningLine.TestField("Qty. to Assemble (Base)");
if AsmExistsForJobPlanningLine(JobPlanningLine) then begin
AsmLine.FilterGroup := 2;
AsmLine.SetRange("Document Type", "Assembly Document Type");
AsmLine.SetRange("Document No.", "Assembly Document No.");
AsmLine.FilterGroup := 0;
PAGE.RunModal(PAGE::"Assemble-to-Order Lines", AsmLine);
end;
end;
procedure ShowSales(AssemblyHeader: Record "Assembly Header")
var
SalesHeader: Record "Sales Header";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeShowSales(AssemblyHeader, IsHandled);
if IsHandled then
exit;
if GetATOLink(AssemblyHeader) then begin
SalesHeader.Get(Rec."Document Type", Rec."Document No.");
case "Document Type" of
"Document Type"::Quote:
PAGE.RunModal(PAGE::"Sales Quote", SalesHeader);
"Document Type"::"Blanket Order":
PAGE.RunModal(PAGE::"Blanket Sales Order", SalesHeader);
"Document Type"::Order:
PAGE.RunModal(PAGE::"Sales Order", SalesHeader);
end;
end;
end;
procedure ShowJobPlanningLines()
var
JobPlanningLine: Record "Job Planning Line";
begin
JobPlanningLine.SetRange("Job No.", Rec."Job No.");
JobPlanningLine.SetRange("Job Task No.", Rec."Job Task No.");
JobPlanningLine.SetRange("Line No.", Rec."Document Line No.");
Page.RunModal(Page::"Job Planning Lines", JobPlanningLine);
end;
procedure SalesLineCheckAvailShowWarning(SalesLine: Record "Sales Line"; var TempAsmHeader: Record "Assembly Header" temporary; var TempAsmLine: Record "Assembly Line" temporary): Boolean
var
AsmLine: Record "Assembly Line";
SalesSetup: Record "Sales & Receivables Setup";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeSalesLineCheckAvailShowWarning(SalesLine, IsHandled);
if IsHandled then
exit(false);
if SalesLine."Qty. to Assemble to Order" = 0 then
exit(false);
SalesSetup.Get();
if not SalesSetup."Stockout Warning" then
exit(false);
TempAsmHeader.Init();
TempAsmHeader."Document Type" := SalesLine."Document Type";
if SalesLine.AsmToOrderExists(AsmHeader) then
TempAsmHeader := AsmHeader;
TransAvailSalesLineToAsmHeader(TempAsmHeader, SalesLine);
TempAsmHeader.Insert();
AsmLine.SetRange("Document Type", AsmHeader."Document Type");
AsmLine.SetRange("Document No.", AsmHeader."No.");
if SalesLine.AsmToOrderExists(AsmHeader) and not AsmLine.IsEmpty() then
exit(TransAvailAsmLinesToAsmLines(AsmHeader, TempAsmHeader, TempAsmLine, false));
exit(TransAvailBOMCompToAsmLines(TempAsmHeader, TempAsmLine));
end;
procedure ATOCopyCheckAvailShowWarning(FromAsmHeader: Record "Assembly Header"; SalesLine: Record "Sales Line"; var TempAsmHeader: Record "Assembly Header" temporary; var TempAsmLine: Record "Assembly Line" temporary; Recalculate: Boolean): Boolean
var
SalesSetup: Record "Sales & Receivables Setup";
begin
if SalesLine."Qty. to Assemble to Order" = 0 then
exit(false);
SalesSetup.Get();
if not SalesSetup."Stockout Warning" then
exit(false);
TempAsmHeader.Init();
TempAsmHeader."Document Type" := SalesLine."Document Type";
TransAvailSalesLineToAsmHeader(TempAsmHeader, SalesLine);
TempAsmHeader.Insert();
if not Recalculate then
exit(TransAvailAsmLinesToAsmLines(FromAsmHeader, TempAsmHeader, TempAsmLine, true));
exit(TransAvailBOMCompToAsmLines(TempAsmHeader, TempAsmLine));
end;
procedure PstdATOCopyCheckAvailShowWarn(FromPostedAsmHeader: Record "Posted Assembly Header"; SalesLine: Record "Sales Line"; var TempAsmHeader: Record "Assembly Header" temporary; var TempAsmLine: Record "Assembly Line" temporary; Recalculate: Boolean): Boolean
var
SalesSetup: Record "Sales & Receivables Setup";
begin
if SalesLine."Qty. to Assemble to Order" = 0 then
exit(false);
SalesSetup.Get();
if not SalesSetup."Stockout Warning" then
exit(false);
TempAsmHeader.Init();
TempAsmHeader."Document Type" := SalesLine."Document Type";
TransAvailSalesLineToAsmHeader(TempAsmHeader, SalesLine);
TempAsmHeader.Insert();
if not Recalculate then
exit(TransAvailPstdAsmLnsToAsmLns(FromPostedAsmHeader, TempAsmHeader, TempAsmLine));
exit(TransAvailBOMCompToAsmLines(TempAsmHeader, TempAsmLine));
end;
local procedure TransAvailSalesLineToAsmHeader(var NewAsmHeader: Record "Assembly Header"; SalesLine: Record "Sales Line")
begin
NewAsmHeader."Item No." := SalesLine."No.";
NewAsmHeader."Variant Code" := SalesLine."Variant Code";
NewAsmHeader."Location Code" := SalesLine."Location Code";
NewAsmHeader."Bin Code" := SalesLine."Bin Code";
NewAsmHeader."Due Date" := SalesLine."Shipment Date";
NewAsmHeader.ValidateDates(NewAsmHeader.FieldNo("Due Date"), true);
NewAsmHeader."Unit of Measure Code" := SalesLine."Unit of Measure Code";
NewAsmHeader."Qty. per Unit of Measure" := SalesLine."Qty. per Unit of Measure";
NewAsmHeader.Quantity := SalesLine."Qty. to Assemble to Order" - AsmHeader."Assembled Quantity";
NewAsmHeader."Quantity (Base)" := SalesLine."Qty. to Asm. to Order (Base)" - AsmHeader."Assembled Quantity (Base)";
OnTransAvailSalesLineToAsmHeaderOnBeforeNewAsmHeaderInitRemainingQty(NewAsmHeader, SalesLine, AsmHeader);
NewAsmHeader.InitRemainingQty();
end;
local procedure TransAvailAsmLinesToAsmLines(FromAsmHeader: Record "Assembly Header"; var ToAsmHeader: Record "Assembly Header"; var ToAsmLine: Record "Assembly Line"; InitQtyConsumed: Boolean): Boolean
var
FromAsmLine: Record "Assembly Line";
ShowAsmWarning: Boolean;
begin
FromAsmLine.SetRange("Document Type", FromAsmHeader."Document Type");
FromAsmLine.SetRange("Document No.", FromAsmHeader."No.");
FromAsmLine.SetRange(Type, FromAsmLine.Type::Item);
if FromAsmLine.Find('-') then
repeat
ToAsmLine := FromAsmLine;
if InitQtyConsumed then begin
ToAsmLine."Consumed Quantity" := 0;
ToAsmLine."Consumed Quantity (Base)" := 0;
end;
TransAvailAsmHeaderToAsmLine(ToAsmLine, ToAsmHeader);
UpdateAsmLineQty(ToAsmLine, ToAsmHeader."Qty. per Unit of Measure" * ToAsmHeader."Remaining Quantity");
if ToAsmLine.UpdateAvailWarning() then
ShowAsmWarning := true;
ToAsmLine.Insert();
until FromAsmLine.Next() = 0;
exit(ShowAsmWarning);
end;
procedure TransAvailBOMCompToAsmLines(var ToAsmHeader: Record "Assembly Header"; var ToAsmLine: Record "Assembly Line"): Boolean
var
BOMComponent: Record "BOM Component";
ShowAsmWarning: Boolean;
begin
BOMComponent.SetRange("Parent Item No.", ToAsmHeader."Item No.");
BOMComponent.SetRange(Type, BOMComponent.Type::Item);
if BOMComponent.Find('-') then
repeat
ToAsmLine.Init();
ToAsmLine."Line No." += 10000;
TransAvailAsmHeaderToAsmLine(ToAsmLine, ToAsmHeader);
TransAvailBOMCompToAsmLine(ToAsmLine, BOMComponent);
UpdateAsmLineQty(ToAsmLine, ToAsmHeader."Qty. per Unit of Measure" * ToAsmHeader."Remaining Quantity");
if ToAsmLine.UpdateAvailWarning() then
ShowAsmWarning := true;
ToAsmLine.Insert();
until BOMComponent.Next() = 0;
exit(ShowAsmWarning);
end;
local procedure TransAvailPstdAsmLnsToAsmLns(FromPostedAsmHeader: Record "Posted Assembly Header"; var ToAsmHeader: Record "Assembly Header"; var ToAsmLine: Record "Assembly Line"): Boolean
var
FromPostedAsmLine: Record "Posted Assembly Line";
ShowAsmWarning: Boolean;
begin
FromPostedAsmLine.SetRange("Document No.", FromPostedAsmHeader."No.");
FromPostedAsmLine.SetRange(Type, FromPostedAsmLine.Type::Item);
if FromPostedAsmLine.Find('-') then
repeat
ToAsmLine.TransferFields(FromPostedAsmLine);
TransAvailAsmHeaderToAsmLine(ToAsmLine, ToAsmHeader);
UpdateAsmLineQty(ToAsmLine, ToAsmHeader."Qty. per Unit of Measure" * ToAsmHeader."Remaining Quantity");
if ToAsmLine.UpdateAvailWarning() then
ShowAsmWarning := true;
ToAsmLine.Insert();
until FromPostedAsmLine.Next() = 0;
exit(ShowAsmWarning);
end;
local procedure TransAvailAsmHeaderToAsmLine(var AsmLine: Record "Assembly Line"; var NewAsmHeader: Record "Assembly Header")
begin
AsmLine."Document Type" := NewAsmHeader."Document Type";
AsmLine."Document No." := NewAsmHeader."No.";
if NewAsmHeader."Location Code" <> AsmHeader."Location Code" then begin
AsmLine."Location Code" := NewAsmHeader."Location Code";
if AsmLine.Type = AsmLine.Type::Item then
AsmLine."Bin Code" := AsmLine.FindBin();
end;
if NewAsmHeader."Due Date" <> AsmHeader."Due Date" then
AsmLine."Due Date" := NewAsmHeader."Starting Date";
OnAfterTransAvailAsmHeaderToAsmLine(AsmLine, NewAsmHeader);
end;
local procedure TransAvailBOMCompToAsmLine(var AsmLine: Record "Assembly Line"; BOMComponent: Record "BOM Component")
var
ItemUOM: Record "Item Unit of Measure";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransAvailBOMCompToAsmLine(AsmLine, BOMComponent, IsHandled);
if not IsHandled then begin
AsmLine.Type := AsmLine.Type::Item;
AsmLine."No." := BOMComponent."No.";
AsmLine."Variant Code" := BOMComponent."Variant Code";
AsmLine."Quantity per" := BOMComponent."Quantity per";
AsmLine."Unit of Measure Code" := BOMComponent."Unit of Measure Code";
if not ItemUOM.Get(BOMComponent."No.", BOMComponent."Unit of Measure Code") then
ItemUOM.Init();
AsmLine."Qty. per Unit of Measure" := ItemUOM."Qty. per Unit of Measure";
end;
OnAfterTransAvailBOMCompToAsmLine(AsmLine, BOMComponent);
end;
local procedure UpdateAsmLineQty(var AsmLine: Record "Assembly Line"; QtyFactor: Decimal)
begin
AsmLine.Quantity := AsmLine."Quantity per" * QtyFactor;
AsmHeader.RoundQty(AsmLine.Quantity);
AsmLine."Quantity (Base)" := Round(AsmLine.Quantity * AsmLine."Qty. per Unit of Measure", UOMMgt.QtyRndPrecision());
AsmLine.InitRemainingQty();
end;
procedure AsmExistsForSalesLine(SalesLine: Record "Sales Line"): Boolean
begin
Reset();
SetCurrentKey(Type, "Document Type", "Document No.", "Document Line No.");
SetRange(Type, Type::Sale);
SetRange("Document Type", SalesLine."Document Type");
SetRange("Document No.", SalesLine."Document No.");
SetRange("Document Line No.", SalesLine."Line No.");
exit(FindFirst());
end;
procedure AsmExistsForJobPlanningLine(JobPlanningLine: Record "Job Planning Line"): Boolean
begin
Reset();
SetCurrentKey(Type, "Job No.", "Job Task No.", "Document Line No.");
SetRange(Type, Type::Job);
SetRange("Job No.", JobPlanningLine."Job No.");
SetRange("Job Task No.", JobPlanningLine."Job Task No.");
SetRange("Document Line No.", JobPlanningLine."Line No.");
if JobPlanningLine.Status = JobPlanningLine.Status::Order then
SetRange("Document Type", "Document Type"::Order)
else
SetRange("Document Type", "Document Type"::Quote);
exit(FindFirst());
end;
procedure AsmExistsForWhseShptLine(WhseShptLine: Record "Warehouse Shipment Line"): Boolean
var
SalesLine: Record "Sales Line";
AsmExists, IsHandled : Boolean;
begin
IsHandled := false;
OnBeforeAsmExistsForWhseShptLine(Rec, WhseShptLine, AsmExists, IsHandled);
if IsHandled then
exit(AsmExists);
WhseShptLine.TestField("Assemble to Order", true);
WhseShptLine.TestField("Source Type", DATABASE::"Sales Line");
SalesLine.Get(WhseShptLine."Source Subtype", WhseShptLine."Source No.", WhseShptLine."Source Line No.");
exit(AsmExistsForSalesLine(SalesLine));
end;
local procedure AsmExistsForInvtPickLine(InvtPickWhseActivityLine: Record "Warehouse Activity Line"): Boolean
var
SalesLine: Record "Sales Line";
begin
InvtPickWhseActivityLine.TestField("Assemble to Order", true);
InvtPickWhseActivityLine.TestField("Source Type", DATABASE::"Sales Line");
InvtPickWhseActivityLine.TestField("Activity Type", InvtPickWhseActivityLine."Activity Type"::"Invt. Pick");
SalesLine.Get(
InvtPickWhseActivityLine."Source Subtype", InvtPickWhseActivityLine."Source No.", InvtPickWhseActivityLine."Source Line No.");
exit(AsmExistsForSalesLine(SalesLine));
end;
procedure GetAsmHeader() Result: Boolean
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetAsmHeader(Rec, AsmHeader, Result, IsHandled);
if IsHandled then
exit(Result);
if (AsmHeader."Document Type" = "Assembly Document Type") and
(AsmHeader."No." = "Assembly Document No.")
then
exit(true);
exit(AsmHeader.Get("Assembly Document Type", "Assembly Document No."));
end;
procedure GetATOLink(AssemblyHeader: Record "Assembly Header") LinkFound: Boolean
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetATOLink(Rec, AssemblyHeader, LinkFound, IsHandled);
if IsHandled then
exit(LinkFound);
LinkFound := Get(AssemblyHeader."Document Type", AssemblyHeader."No.") and (Type <> Type::Job);
if LinkFound then
TestField(Type, Type::Sale);
end;
local procedure GetMin(a: Decimal; b: Decimal): Decimal
begin
if a < b then
exit(a);
exit(b);
end;
local procedure GetMax(a: Decimal; b: Decimal): Decimal
begin
if a > b then
exit(a);
exit(b);
end;
local procedure MaxQtyToAsm(SalesLine: Record "Sales Line"; AssemblyHeader: Record "Assembly Header") Result: Decimal
begin
Result := GetMin(SalesLine."Qty. to Ship", AssemblyHeader."Remaining Quantity");
OnAfterMaxQtyToAsm(SalesLine, AssemblyHeader, Result);
end;
local procedure MaxQtyToAsmBase(SalesLine: Record "Sales Line"; AssemblyHeader: Record "Assembly Header") Result: Decimal
begin
Result := GetMin(SalesLine."Qty. to Ship (Base)", AssemblyHeader."Remaining Quantity (Base)");
OnAfterMaxQtyToAsmBase(SalesLine, AssemblyHeader, Result);
end;
local procedure MinQtyToAsm(SalesLine: Record "Sales Line"; AssemblyHeader: Record "Assembly Header"): Decimal
var
UnshippedNonATOQty: Decimal;
begin
UnshippedNonATOQty := SalesLine."Outstanding Quantity" - AssemblyHeader."Remaining Quantity";
exit(GetMax(SalesLine."Qty. to Ship" - UnshippedNonATOQty, 0));
end;
procedure CheckQtyToAsm(AssemblyHeader: Record "Assembly Header")
var
SalesLine: Record "Sales Line";
Location: Record Location;
WhseActivityLine: Record "Warehouse Activity Line";
WhseShptLine: Record "Warehouse Shipment Line";
WMSMgt: Codeunit "WMS Management";
MaxQty: Decimal;
MinQty: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckQtyToAsm(AssemblyHeader, IsHandled);
if IsHandled then
exit;
if GetATOLink(AssemblyHeader) then begin
SalesLine.Get("Document Type", "Document No.", "Document Line No.");
if Location.Get(AssemblyHeader."Location Code") then
if Location."Require Shipment" then begin
AssemblyHeader.CalcFields("Assemble to Order");
if WMSMgt.ATOWhseShptExists(SalesLine) then
Error(
Text007, WhseShptLine.TableCaption(), AssemblyHeader."Document Type", AssemblyHeader.FieldCaption("Quantity to Assemble"),
WhseShptLine.FieldCaption("Qty. to Ship"));
end else
if Location."Require Pick" then
if WMSMgt.ATOInvtPickExists(SalesLine) then
Error(Text005, WhseActivityLine."Activity Type"::"Invt. Pick", AssemblyHeader."Document Type");
MinQty := MinQtyToAsm(SalesLine, AssemblyHeader);
MaxQty := MaxQtyToAsm(SalesLine, AssemblyHeader);
if (AssemblyHeader."Quantity to Assemble" < MinQty) or (AssemblyHeader."Quantity to Assemble" > MaxQty) then
Error(
Text004, AssemblyHeader.FieldCaption("Quantity to Assemble"), MinQty, MaxQty, SalesLine.FieldCaption("Qty. to Ship"),
SalesLine.TableCaption());
end;
end;
procedure InitQtyToAsm(AssemblyHeader: Record "Assembly Header"; var QtyToAsm: Decimal; var QtyToAsmBase: Decimal)
var
SalesLine: Record "Sales Line";
JobPlanningLine: Record "Job Planning Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInitQtyToAsm(AssemblyHeader, QtyToAsm, QtyToAsmBase, IsHandled);
if IsHandled then
exit;
if GetATOLink(AssemblyHeader) then begin
SalesLine.Get("Document Type", "Document No.", "Document Line No.");
QtyToAsm := MaxQtyToAsm(SalesLine, AssemblyHeader);
QtyToAsmBase := MaxQtyToAsmBase(SalesLine, AssemblyHeader);
end else begin
if ("Job No." = '') or ("Job Task No." = '') then
exit;
JobPlanningLine.Get("Job No.", "Job Task No.", "Document Line No.");
QtyToAsm := AssemblyHeader."Remaining Quantity";
QtyToAsmBase := AssemblyHeader."Remaining Quantity (Base)";
end;
end;
local procedure AsmReopenIfReleased()
var
ItemCheckAvail: Codeunit "Item-Check Avail.";
ReleaseAssemblyDoc: Codeunit "Release Assembly Document";
begin
if AsmHeader.Status <> AsmHeader.Status::Released then
exit;
if not HideConfirm then
if not Confirm(Text006, false, AsmHeader.Status::Open) then
ItemCheckAvail.RaiseUpdateInterruptedError();
ReleaseAssemblyDoc.Reopen(AsmHeader);
end;
local procedure GetWindowOpenTextSale(SalesLine: Record "Sales Line"): Text
begin
exit(StrSubstNo(Text000,
SalesLine.TableCaption(),
ConstructKeyTextSalesLine(SalesLine),
AsmHeader.TableCaption(),
ConstructKeyTextAsmHeader()));
end;
local procedure GetWindowOpenTextJob(JobPlanningLine: Record "Job Planning Line"): Text
begin
exit(StrSubstNo(Text000,
JobPlanningLine.TableCaption(),
ConstructKeyTextJobPlanningLine(JobPlanningLine),
AsmHeader.TableCaption(),
ConstructKeyTextAsmHeader()));
end;
local procedure GetWindowOpenTextWhseShpt(WhseShptLine: Record "Warehouse Shipment Line"): Text
begin
exit(StrSubstNo(Text000,
WhseShptLine.TableCaption(),
ConstructKeyTextWhseShptLine(WhseShptLine),
AsmHeader.TableCaption(),
ConstructKeyTextAsmHeader()));
end;
local procedure GetWindowOpenTextInvtPick(InvtPickWhseActivityLine: Record "Warehouse Activity Line"): Text
begin
exit(StrSubstNo(Text000,
InvtPickWhseActivityLine.TableCaption(),
ConstructKeyTextInvtPickLine(InvtPickWhseActivityLine),
AsmHeader.TableCaption(),
ConstructKeyTextAsmHeader()));
end;
local procedure ConstructKeyTextAsmHeader(): Text
var
DocTypeText: Text;
DocNoText: Text;
begin
DocTypeText := StrSubstNo(Text008, AsmHeader.FieldCaption("Document Type"), AsmHeader."Document Type");
DocNoText := StrSubstNo(Text008, AsmHeader.FieldCaption("No."), AsmHeader."No.");
exit(StrSubstNo(Text008, DocTypeText, DocNoText));
end;
local procedure ConstructKeyTextSalesLine(SalesLine: Record "Sales Line"): Text
var
DocTypeText: Text;
DocNoText: Text;
LineNoText: Text;
begin
DocTypeText := StrSubstNo(Text008, SalesLine.FieldCaption("Document Type"), SalesLine."Document Type");
DocNoText := StrSubstNo(Text008, SalesLine.FieldCaption("Document No."), SalesLine."Document No.");
LineNoText := StrSubstNo(Text008, SalesLine.FieldCaption("Line No."), SalesLine."Line No.");
exit(StrSubstNo(Text008, StrSubstNo(Text008, DocTypeText, DocNoText), LineNoText));
end;
local procedure ConstructKeyTextJobPlanningLine(JobPlanningLine: Record "Job Planning Line"): Text
var
JobTaskNoText, JobNoText, LineNoText : Text;
begin
JobNoText := StrSubstNo(Text008, JobPlanningLine.FieldCaption("Job No."), JobPlanningLine."Job No.");
JobTaskNoText := StrSubstNo(Text008, JobPlanningLine.FieldCaption("Job Task No."), JobPlanningLine."Job Task No.");
LineNoText := StrSubstNo(Text008, JobPlanningLine.FieldCaption("Line No."), JobPlanningLine."Line No.");
exit(StrSubstNo(Text008, StrSubstNo(Text008, JobNoText, JobTaskNoText), LineNoText));
end;
local procedure ConstructKeyTextWhseShptLine(WhseShptLine: Record "Warehouse Shipment Line"): Text
var
NoText: Text;
LineNoText: Text;
begin
NoText := StrSubstNo(Text008, WhseShptLine.FieldCaption("No."), WhseShptLine."No.");
LineNoText := StrSubstNo(Text008, WhseShptLine.FieldCaption("Line No."), WhseShptLine."Line No.");
exit(StrSubstNo(Text008, NoText, LineNoText));
end;
local procedure ConstructKeyTextInvtPickLine(InvtPickWhseActivityLine: Record "Warehouse Activity Line"): Text
var
ActTypeText: Text;
NoText: Text;
LineNoText: Text;
begin
ActTypeText :=
StrSubstNo(Text008, InvtPickWhseActivityLine.FieldCaption("Activity Type"), InvtPickWhseActivityLine."Activity Type");
NoText := StrSubstNo(Text008, InvtPickWhseActivityLine.FieldCaption("No."), InvtPickWhseActivityLine."No.");
LineNoText := StrSubstNo(Text008, InvtPickWhseActivityLine.FieldCaption("Line No."), InvtPickWhseActivityLine."Line No.");
exit(StrSubstNo(Text008, StrSubstNo(Text008, ActTypeText, NoText), LineNoText));
end;
procedure ShowAsmOrders(SalesHeader: Record "Sales Header")
var
AssembleToOrderLink: Record "Assemble-to-Order Link";
AssemblyHeader: Record "Assembly Header";
TempAssemblyHeader: Record "Assembly Header" temporary;
begin
TempAssemblyHeader.DeleteAll();
AssembleToOrderLink.SetCurrentKey(Type, "Document Type", "Document No.", "Document Line No.");
AssembleToOrderLink.SetRange(Type, AssembleToOrderLink.Type::Sale);
AssembleToOrderLink.SetRange("Document Type", SalesHeader."Document Type");
AssembleToOrderLink.SetRange("Document No.", SalesHeader."No.");
if AssembleToOrderLink.FindSet() then
repeat
if not TempAssemblyHeader.Get(AssembleToOrderLink."Assembly Document Type", AssembleToOrderLink."Assembly Document No.") then
if AssemblyHeader.Get(AssembleToOrderLink."Assembly Document Type", AssembleToOrderLink."Assembly Document No.") then begin
TempAssemblyHeader := AssemblyHeader;
TempAssemblyHeader.Insert();
end;
until AssembleToOrderLink.Next() = 0;
PAGE.Run(PAGE::"Assembly Orders", TempAssemblyHeader);
end;
procedure ShowAsmOrders(Job: Record Job; JobTaskNo: Code[20])
var
AssembleToOrderLink: Record "Assemble-to-Order Link";
AssemblyHeader: Record "Assembly Header";
TempAssemblyHeader: Record "Assembly Header" temporary;
begin
TempAssemblyHeader.DeleteAll();
AssembleToOrderLink.SetCurrentKey(Type, "Job No.", "Job Task No.", "Document Line No.");
AssembleToOrderLink.SetRange(Type, AssembleToOrderLink.Type::Job);
AssembleToOrderLink.SetRange("Job No.", Job."No.");
if JobTaskNo <> '' then
AssembleToOrderLink.SetRange("Job Task No.", JobTaskNo);
if AssembleToOrderLink.FindSet() then
repeat
if not TempAssemblyHeader.Get(AssembleToOrderLink."Assembly Document Type", AssembleToOrderLink."Assembly Document No.") then
if AssemblyHeader.Get(AssembleToOrderLink."Assembly Document Type", AssembleToOrderLink."Assembly Document No.") then begin
TempAssemblyHeader := AssemblyHeader;
TempAssemblyHeader.Insert();
end;
until AssembleToOrderLink.Next() = 0;
PAGE.Run(PAGE::"Assembly Orders", TempAssemblyHeader);
end;
local procedure RecalcAutoReserve(AsmHeader: Record "Assembly Header")
var
AssemblyLine: Record "Assembly Line";
begin
AssemblyLine.SetRange("Document Type", AsmHeader."Document Type");
AssemblyLine.SetRange("Document No.", AsmHeader."No.");
if AssemblyLine.FindSet() then
repeat
AsmHeader.AutoReserveAsmLine(AssemblyLine);
until AssemblyLine.Next() = 0;
end;
procedure SetHideConfirm(NewHideConfirm: Boolean)
begin
HideConfirm := NewHideConfirm;
end;
local procedure JobPlanningLineIsNotCorrect(var NewJobPlanningLine: Record "Job Planning Line"): Boolean
var
NewJobPlanningLine2: Record "Job Planning Line";
begin
if NewJobPlanningLine."Qty. to Assemble" = 0 then
exit(true);
if not NewJobPlanningLine2.Get(NewJobPlanningLine."Job No.", NewJobPlanningLine."Job Task No.", NewJobPlanningLine."Line No.") then
exit(true);
end;
local procedure CheckJobStatus(Job: Record Job)
begin
if Job.Status = Job.Status::Completed then
Error(CreateAsmForJobErr);
end;
local procedure AssignAssembleToOrderData(var NewJobPlanningLine: Record "Job Planning Line"; Job: Record Job)
begin
if Job.Status = Job.Status::Open then begin
InsertAsmHeader(AsmHeader, "Assembly Document Type"::Order, '');
"Document Type" := "Document Type"::Order;
end else
if Job.Status in [Job.Status::Quote, Job.Status::Planning] then begin
InsertAsmHeader(AsmHeader, "Assembly Document Type"::Quote, '');
"Document Type" := "Document Type"::Quote;
end;
"Assembly Document Type" := AsmHeader."Document Type";
"Assembly Document No." := AsmHeader."No.";
Type := Type::Job;
"Document No." := NewJobPlanningLine."Document No.";
"Job No." := NewJobPlanningLine."Job No.";
"Job Task No." := NewJobPlanningLine."Job Task No.";
"Document Line No." := NewJobPlanningLine."Line No.";
end;
local procedure AssignGlobalDimensionsFromJobTask(var NewJobPlanningLine: Record "Job Planning Line")
var
JobTask: Record "Job Task";
begin
if not JobTask.Get(NewJobPlanningLine."Job No.", NewJobPlanningLine."Job Task No.") then
exit;
AsmHeader."Shortcut Dimension 1 Code" := JobTask."Global Dimension 1 Code";
AsmHeader."Shortcut Dimension 2 Code" := JobTask."Global Dimension 2 Code";
AsmHeader.Modify(true);
end;
local procedure DeleteAssembleToOrderLink(var NewJobPlanningLine: Record "Job Planning Line"): Boolean
begin
if not GetAsmHeader() then begin
Delete();
InsertAsmHeader(AsmHeader, "Assembly Document Type", "Assembly Document No.");
end else begin
if not NeedsSynchronization(NewJobPlanningLine) then
exit(false);
AsmReopenIfReleased();
Delete();
end;
exit(true);
end;
local procedure InsertAssembeToOrderLinkIfInvtAdjmtEntryOrderExist()
var
InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
begin
InvtAdjmtEntryOrder.SetRange("Order Type", InvtAdjmtEntryOrder."Order Type"::Assembly);
InvtAdjmtEntryOrder.SetRange("Order No.", "Assembly Document No.");
if ("Assembly Document Type" = "Assembly Document Type"::Order) and not InvtAdjmtEntryOrder.IsEmpty() then
Insert();
end;
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateAsm(var AsmHeader: Record "Assembly Header"; var AssembleToOrderLink: Record "Assemble-to-Order Link"; var SalesLine: Record "Sales Line"; AsmExists: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterMaxQtyToAsm(SalesLine: Record "Sales Line"; AssemblyHeader: Record "Assembly Header"; var Result: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterMaxQtyToAsmBase(SalesLine: Record "Sales Line"; AssemblyHeader: Record "Assembly Header"; var Result: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterRemoveTrackingFromReservation(var ReservationEntry: Record "Reservation Entry"; var TrackingSpecification: Record "Tracking Specification"; ItemTrackingCode: Record "Item Tracking Code")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransAvailAsmHeaderToAsmLine(var AssemblyLine: Record "Assembly Line"; var NewAssemblyHeader: Record "Assembly Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAsmHeaderInsert(var AssemblyHeader: Record "Assembly Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAsmHeaderModify(var AssemblyHeader: Record "Assembly Header"; var SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeChangeUOM(var AssemblyHeader: Record "Assembly Header"; NewUOMCode: Code[10]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeChangeDate(var AssemblyHeader: Record "Assembly Header"; NewDate: Date; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetATOLink(var AssembleToOrderLink: Record "Assemble-to-Order Link"; var AssemblyHeader: Record "Assembly Header"; var LinkFound: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertAsmHeader(var AssemblyHeader: Record "Assembly Header"; NewDocType: Option; NewDocNo: Code[20]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeNeedsSynchronization(AssemblyHeader: Record "Assembly Header"; SalesLine: Record "Sales Line"; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeNeedsSynchronizationForProjectPlanningLine(AssemblyHeader: Record "Assembly Header"; JobPlanningLine: Record "Job Planning Line"; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRemoveTrackingFromReservation(var ReservEntry: Record "Reservation Entry"; ItemTrackingCode: Code[10])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeReserveAsmToSale(var SalesLine: Record "Sales Line"; QtyToReserve: Decimal; QtyToReserveBase: Decimal; var IsHandled: Boolean; var AssembletoOrderLink: Record "Assemble-to-Order Link")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSalesLineCheckAvailShowWarning(SalesLine: Record "Sales Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeShowAsmToOrderLines(SalesLine: Record "Sales Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransAvailBOMCompToAsmLine(var AssemblyLine: Record "Assembly Line"; BOMComponent: Record "BOM Component"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateAsm(var NewSalesLine: Record "Sales Line"; AsmExists: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCopyAsmToNewAsmOrderOnToAsmOrderLineInsert(FromAssemblyLine: Record "Assembly Line"; var ToAssemblyLineOrder: Record "Assembly Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeAsmOrderLinkedToSalesOrderLineOnBeforeCheckDocumentType(var AssembleToOrderLink: Record "Assemble-to-Order Link"; var ToAssemblyHeader: Record "Assembly Header"; FromAssemblyHeader: Record "Assembly Header"; ToSalesLine: Record "Sales Line"; FromSalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRemoveTrackingFromReservationOnAfterSetTracking(var TrackingSpecification: Record "Tracking Specification")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRestoreItemTrackingOnAfterCreateReservEntryFrom(var TrackingSpecification: Record "Tracking Specification")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRestoreItemTrackingOnBeforeTrackingSpecificationLoop(var TrackingSpecification: Record "Tracking Specification")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRollUpPriceOnAfterFindSalesLinePrice(var SalesHeader: Record "Sales Header"; var CompSalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRollUpPriceOnBeforeFindSalesLinePrice(var SalesHeader: Record "Sales Header"; var CompSalesLine: Record "Sales Line"; AssemblyLine: Record "Assembly Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRollUpPriceOnBeforeModifySalesline(var SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSynchronizeAsmFromSalesLineOnAfterGetAsmHeader(var NewSalesLine: Record "Sales Line"; var AssemblyHeader: Record "Assembly Header"; var ShowWindow: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSynchronizeAsmFromSalesLineOnBeforeChangeQty(var AssemblyHeader: Record "Assembly Header"; var SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateAsmOnBeforeSynchronizeAsmFromSalesLine(var AssembleToOrderLink: Record "Assemble-to-Order Link"; var AssemblyHeader: Record "Assembly Header"; SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateAsmOnAfterCalcShouldDeleteAsm(var NewSalesLine: Record "Sales Line"; var ShouldDeleteAsm: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateAsmOnBeforeAsmReOpenIfReleased(var AssembleToOrderLink: Record "Assemble-to-Order Link"; var AssemblyHeader: Record "Assembly Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransAvailBOMCompToAsmLine(var AsmLine: Record "Assembly Line"; BOMComponent: Record "BOM Component")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransAvailSalesLineToAsmHeaderOnBeforeNewAsmHeaderInitRemainingQty(var NewAsmHeader: Record "Assembly Header"; SalesLine: Record "Sales Line"; AsmHeader: Record "Assembly Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterReserveAsmToSale(var AssembletoOrderLink: Record "Assemble-to-Order Link"; var AsmHeader: Record "Assembly Header"; var SalesLine: Record "Sales Line"; var TrackingSpecification: Record "Tracking Specification"; QtyToReserve: Decimal; QtyToReserveBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRollUpPrice(var SalesLine: Record "Sales Line"; var AssembleToOrderLink: Record "Assemble-to-Order Link"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateQtyToAsmFromWhseShptLine(WarehouseShipmentLine: Record "Warehouse Shipment Line"; var IsHandled: Boolean; var ShowWindow: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAsmExistsForWhseShptLine(var AssembleToOrderLink: Record "Assemble-to-Order Link"; WarehouseShipmentLine: Record "Warehouse Shipment Line"; var AsmExists: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeShowSales(AssemblyHeader: Record "Assembly Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInitQtyToAsm(AssemblyHeader: Record "Assembly Header"; var QtyToAsm: Decimal; var QtyToAsmBase: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckQtyToAsm(AssemblyHeader: Record "Assembly Header"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRollUpCostOnBeforeModifySalesLine(var SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetAsmHeader(AssembleToOrderLink: Record "Assemble-to-Order Link"; var AssemblyHeader: Record "Assembly Header"; var HeaderFound: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateQtyToAsmFromSalesLineOnBeforeUpdateQtyToAsm(var SalesLine: Record "Sales Line"; var ShowWindow: Boolean)
begin
end;
}