Table 99000772 Production BOM Line, source in 29
Source29
src/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ProductionBOMLine.Table.al625 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.ProductionBOM;
using Microsoft.Foundation.Enums;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Planning;
using Microsoft.Manufacturing.Routing;
table 99000772 "Production BOM Line"
{
Caption = 'Production BOM Line';
DataClassification = CustomerContent;
fields
{
field(1; "Production BOM No."; Code[20])
{
Caption = 'Production BOM No.';
NotBlank = true;
TableRelation = "Production BOM Header";
}
field(2; "Line No."; Integer)
{
Caption = 'Line No.';
}
field(3; "Version Code"; Code[20])
{
Caption = 'Version Code';
TableRelation = "Production BOM Version"."Version Code" where("Production BOM No." = field("Production BOM No."));
}
field(10; Type; Enum "Production BOM Line Type")
{
Caption = 'Type';
ToolTip = 'Specifies the type of production BOM line.';
trigger OnValidate()
begin
TestStatus();
xRec.Type := Type;
Init();
Type := xRec.Type;
end;
}
field(11; "No."; Code[20])
{
Caption = 'No.';
ToolTip = 'Specifies the number of the involved entry or record, according to the specified number series.';
TableRelation = if (Type = const(Item)) Item where(Type = filter(Inventory | "Non-Inventory"))
else
if (Type = const("Production BOM")) "Production BOM Header";
trigger OnValidate()
var
Item: Record Item;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeValidateNo(Rec, xRec, CurrFieldNo, IsHandled);
if not IsHandled then begin
TestField(Type);
TestStatus();
case Type of
Type::Item:
begin
Item.Get("No.");
Description := Item.Description;
"Description 2" := Item."Description 2";
Item.TestField("Base Unit of Measure");
"Unit of Measure Code" := Item."Base Unit of Measure";
"Scrap %" := Item."Scrap %";
if "No." <> xRec."No." then
"Variant Code" := '';
OnValidateNoOnAfterAssignItemFields(Rec, Item, xRec, CurrFieldNo);
end;
Type::"Production BOM":
begin
ProductionBOMHeader.Get("No.");
ProductionBOMHeader.TestField("Unit of Measure Code");
Description := ProductionBOMHeader.Description;
"Description 2" := ProductionBOMHeader."Description 2";
"Unit of Measure Code" := ProductionBOMHeader."Unit of Measure Code";
OnValidateNoOnAfterAssignProdBOMFields(Rec, ProductionBOMHeader, xRec, CurrFieldNo);
end;
end;
end;
OnAfterValidateNo(Rec);
end;
}
field(12; Description; Text[100])
{
Caption = 'Description';
ToolTip = 'Specifies a description of the production BOM line.';
}
field(13; "Unit of Measure Code"; Code[10])
{
Caption = 'Unit of Measure Code';
ToolTip = 'Specifies how each unit of the item is measured, such as in pieces or tons. By default, the value in the Base Unit of Measure field on the item card is inserted.';
TableRelation = if (Type = const(Item)) "Item Unit of Measure".Code where("Item No." = field("No."))
else
if (Type = const("Production BOM")) "Unit of Measure";
trigger OnValidate()
begin
TestField("No.");
if xRec."Unit of Measure Code" <> "Unit of Measure Code" then
TestField(Type, Type::Item);
end;
}
field(14; Quantity; Decimal)
{
AutoFormatType = 0;
Caption = 'Quantity';
DecimalPlaces = 0 : 5;
Editable = false;
}
field(15; Position; Code[10])
{
Caption = 'Position';
ToolTip = 'Specifies the position of the component on the bill of material.';
}
field(16; "Position 2"; Code[10])
{
Caption = 'Position 2';
ToolTip = 'Specifies more exactly whether the component is to appear at a certain position in the BOM to represent a certain production process.';
}
field(17; "Position 3"; Code[10])
{
Caption = 'Position 3';
ToolTip = 'Specifies the third reference number for the component position on a bill of material, such as the alternate position number of a component on a print card.';
}
field(18; "Lead-Time Offset"; DateFormula)
{
Caption = 'Lead-Time Offset';
ToolTip = 'Specifies the total number of days required to produce this item.';
trigger OnValidate()
begin
TestField("No.");
end;
}
field(19; "Routing Link Code"; Code[10])
{
Caption = 'Routing Link Code';
ToolTip = 'Specifies the routing link code.';
TableRelation = "Routing Link";
trigger OnValidate()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeValidateRoutingLinkCode(Rec, xRec, CurrFieldNo, IsHandled);
if IsHandled then
exit;
if "Routing Link Code" <> '' then begin
TestField(Type, Type::Item);
TestField("No.");
end;
end;
}
field(20; "Scrap %"; Decimal)
{
AutoFormatType = 0;
BlankNumbers = BlankNeg;
Caption = 'Scrap %';
ToolTip = 'Specifies the percentage of the item that you expect to be scrapped in the production process.';
DecimalPlaces = 0 : 5;
MaxValue = 100;
trigger OnValidate()
begin
TestField("No.");
end;
}
field(21; "Variant Code"; Code[10])
{
Caption = 'Variant Code';
ToolTip = 'Specifies the variant of the item on the line.';
TableRelation = if (Type = const(Item)) "Item Variant".Code where("Item No." = field("No."));
trigger OnValidate()
var
ItemVariant: Record "Item Variant";
begin
if Rec."Variant Code" = '' then
exit;
TestField(Type, Type::Item);
TestField("No.");
ItemVariant.SetLoadFields(Description, "Description 2");
ItemVariant.Get("No.", "Variant Code");
Description := ItemVariant.Description;
"Description 2" := ItemVariant."Description 2";
end;
}
field(22; Comment; Boolean)
{
CalcFormula = exist("Production BOM Comment Line" where("Production BOM No." = field("Production BOM No."),
"Version Code" = field("Version Code"),
"BOM Line No." = field("Line No.")));
Caption = 'Comment';
Editable = false;
FieldClass = FlowField;
}
field(23; "Description 2"; Text[50])
{
Caption = 'Description 2';
DataClassification = CustomerContent;
ToolTip = 'Specifies additional description text.';
}
field(28; "Starting Date"; Date)
{
Caption = 'Starting Date';
ToolTip = 'Specifies the date from which this production BOM is valid.';
trigger OnValidate()
begin
TestField("No.");
if "Starting Date" > 0D then
Validate("Ending Date");
end;
}
field(29; "Ending Date"; Date)
{
Caption = 'Ending Date';
ToolTip = 'Specifies the date from which this production BOM is no longer valid.';
trigger OnValidate()
begin
TestField("No.");
if ("Ending Date" > 0D) and
("Starting Date" > 0D) and
("Starting Date" > "Ending Date")
then
Error(
EndingDateBeforeStartingDateErr,
FieldCaption("Ending Date"),
FieldCaption("Starting Date"));
end;
}
field(40; Length; Decimal)
{
AutoFormatType = 0;
Caption = 'Length';
ToolTip = 'Specifies the length of one item unit when measured in the specified unit of measure.';
DecimalPlaces = 0 : 5;
trigger OnValidate()
begin
Validate("Calculation Formula");
end;
}
field(41; Width; Decimal)
{
AutoFormatType = 0;
Caption = 'Width';
ToolTip = 'Specifies the width of one item unit when measured in the specified unit of measure.';
DecimalPlaces = 0 : 5;
trigger OnValidate()
begin
Validate("Calculation Formula");
end;
}
field(42; Weight; Decimal)
{
AutoFormatType = 0;
Caption = 'Weight';
ToolTip = 'Specifies the weight of one item unit when measured in the specified unit of measure.';
DecimalPlaces = 0 : 5;
trigger OnValidate()
begin
Validate("Calculation Formula");
end;
}
field(43; Depth; Decimal)
{
AutoFormatType = 0;
Caption = 'Depth';
ToolTip = 'Specifies the depth of one item unit when measured in the specified unit of measure.';
DecimalPlaces = 0 : 5;
trigger OnValidate()
begin
Validate("Calculation Formula");
end;
}
field(44; "Calculation Formula"; Enum "Quantity Calculation Formula")
{
Caption = 'Calculation Formula';
ToolTip = 'Specifies how to calculate the Quantity field.';
trigger OnValidate()
var
UnitOfMeasureManagement: Codeunit "Unit of Measure Management";
begin
TestField("No.");
case "Calculation Formula" of
"Calculation Formula"::" ":
Quantity := "Quantity per";
"Calculation Formula"::Length:
Quantity := Round(Length * "Quantity per", UnitOfMeasureManagement.QtyRndPrecision());
"Calculation Formula"::"Length * Width":
Quantity := Round(Length * Width * "Quantity per", UnitOfMeasureManagement.QtyRndPrecision());
"Calculation Formula"::"Length * Width * Depth":
Quantity := Round(Length * Width * Depth * "Quantity per", UnitOfMeasureManagement.QtyRndPrecision());
"Calculation Formula"::Weight:
Quantity := Round(Weight * "Quantity per", UnitOfMeasureManagement.QtyRndPrecision());
"Calculation Formula"::"Fixed Quantity":
begin
TestField(Type, Type::Item);
Quantity := "Quantity per";
end;
else
OnValidateCalculationFormulaEnumExtension(Rec);
end;
end;
}
field(45; "Quantity per"; Decimal)
{
AutoFormatType = 0;
Caption = 'Quantity per';
ToolTip = 'Specifies how many units of the component are required to produce the parent item.';
DecimalPlaces = 0 : 5;
trigger OnValidate()
begin
Validate("Calculation Formula");
end;
}
}
keys
{
key(Key1; "Production BOM No.", "Version Code", "Line No.")
{
Clustered = true;
}
key(Key2; Type, "No.")
{
}
}
fieldgroups
{
}
trigger OnDelete()
var
ProdBOMComment: Record "Production BOM Comment Line";
PlanningAssignment: Record "Planning Assignment";
begin
if Type <> Type::" " then begin
TestStatus();
case Type of
Type::Item:
PlanningAssignment.AssignPlannedOrders("No.", false);
Type::"Production BOM":
PlanningAssignment.OldBom("No.");
else
OnDeleteOnCaseTypeElse(Rec);
end;
end;
ProdBOMComment.SetRange("Production BOM No.", "Production BOM No.");
ProdBOMComment.SetRange("BOM Line No.", "Line No.");
ProdBOMComment.SetRange("Version Code", "Version Code");
ProdBOMComment.DeleteAll();
end;
trigger OnInsert()
begin
TestStatus();
end;
trigger OnModify()
begin
if Type <> Type::" " then
TestStatus();
end;
var
BOMVersionUOMErr: Label 'The Unit of Measure Code %1 for Item %2 does not exist. Identification fields and values: Production BOM No. = %3, Version Code = %4.', Comment = '%1=UOM Code;%2=Item No.;%3=Production BOM No.;%4=Version Code';
BOMHeaderUOMErr: Label 'The Unit of Measure Code %1 for Item %2 does not exist. Identification fields and values: Production BOM No. = %3.', Comment = '%1=UOM Code;%2=Item No.;%3=Production BOM No.';
BOMLineUOMErr: Label 'The Unit of Measure Code %1 for Item %2 does not exist. Identification fields and values: Production BOM No. = %3, Version Code = %4, Line No. = %5.', Comment = '%1=UOM Code;%2=Item No.;%3=Production BOM No.;%4=Version Code;%5=Line No.';
EndingDateBeforeStartingDateErr: Label '%1 must be later than %2.', Comment = '%1=Ending Date; %2=Starting Date';
protected var
ProductionBOMHeader: Record "Production BOM Header";
procedure TestStatus()
var
ProdBOMVersion: Record "Production BOM Version";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTestStatus(Rec, IsHandled);
if IsHandled then
exit;
if IsTemporary then
exit;
if "Version Code" = '' then begin
ProductionBOMHeader.Get("Production BOM No.");
if ProductionBOMHeader.Status = ProductionBOMHeader.Status::Certified then
ProductionBOMHeader.FieldError(Status);
end else begin
ProdBOMVersion.Get("Production BOM No.", "Version Code");
if ProdBOMVersion.Status = ProdBOMVersion.Status::Certified then
ProdBOMVersion.FieldError(Status);
end;
OnAfterTestStatus(Rec, ProductionBOMHeader, ProdBOMVersion);
end;
procedure GetQtyPerUnitOfMeasure() Result: Decimal
var
Item: Record Item;
UOMMgt: Codeunit "Unit of Measure Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetQtyPerUnitOfMeasure(Rec, Result, IsHandled);
if IsHandled then
exit;
if Type = Type::Item then begin
Item.Get("No.");
exit(
UOMMgt.GetQtyPerUnitOfMeasure(Item, "Unit of Measure Code"));
end;
exit(1);
end;
procedure GetBOMHeaderQtyPerUOM(Item: Record Item) Result: Decimal
var
ProductionBOMHeader: Record "Production BOM Header";
ProdBOMVersion: Record "Production BOM Version";
ItemUnitOfMeasure: Record "Item Unit of Measure";
UOMMgt: Codeunit "Unit of Measure Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetBOMHeaderQtyPerUOM(Rec, Item, Result, IsHandled);
if IsHandled then
exit(Result);
if "Production BOM No." = '' then
exit(1);
if "Version Code" <> '' then begin
ProdBOMVersion.Get("Production BOM No.", "Version Code");
if not ItemUnitOfMeasure.Get(Item."No.", ProdBOMVersion."Unit of Measure Code") then
Error(BOMVersionUOMErr, ProdBOMVersion."Unit of Measure Code", Item."No.", "Production BOM No.", "Version Code");
exit(UOMMgt.GetQtyPerUnitOfMeasure(Item, ProdBOMVersion."Unit of Measure Code"));
end;
ProductionBOMHeader.Get("Production BOM No.");
if not ItemUnitOfMeasure.Get(Item."No.", ProductionBOMHeader."Unit of Measure Code") then
Error(BOMHeaderUOMErr, ProductionBOMHeader."Unit of Measure Code", Item."No.", "Production BOM No.");
exit(UOMMgt.GetQtyPerUnitOfMeasure(Item, ProductionBOMHeader."Unit of Measure Code"));
end;
procedure GetBOMLineQtyPerUOM(Item: Record Item) Result: Decimal
var
ItemUnitOfMeasure: Record "Item Unit of Measure";
UOMMgt: Codeunit "Unit of Measure Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetBOMLineQtyPerUOM(Rec, Item, Result, IsHandled);
if IsHandled then
exit(Result);
if "No." = '' then
exit(1);
if not ItemUnitOfMeasure.Get(Item."No.", "Unit of Measure Code") then
Error(BOMLineUOMErr, "Unit of Measure Code", Item."No.", "Production BOM No.", "Version Code", "Line No.");
exit(UOMMgt.GetQtyPerUnitOfMeasure(Item, "Unit of Measure Code"));
end;
/// <summary>
/// Opens a page for selecting multiple items to add to the document.
/// Selected items are added to the document.
/// </summary>
procedure SelectMultipleItems()
var
ItemListPage: Page "Item List";
SelectionFilter: Text;
begin
SelectionFilter := ItemListPage.SelectActiveItemsForProductionBOM();
if SelectionFilter <> '' then
AddItems(SelectionFilter);
end;
/// <summary>
/// Adds items to the document based on the provided selection filter.
/// </summary>
/// <param name="SelectionFilter">The filter to use for selecting items.</param>
procedure AddItems(SelectionFilter: Text)
var
Item: Record Item;
ProductionBOMLine: Record "Production BOM Line";
begin
InitNewLine(ProductionBOMLine);
Item.SetLoadFields("No.");
Item.SetFilter("No.", SelectionFilter);
if Item.FindSet() then
repeat
AddItem(ProductionBOMLine, Item."No.");
until Item.Next() = 0;
end;
/// <summary>
/// Adds an item to the document.
/// </summary>
/// <remarks>
/// After the line is added, assembly order is automatically created if required.
/// If the item has extended text, the text is added as a line.
/// </remarks>
/// <param name="ProductionBOMLine">Return value: The added Production BOM Line. Production BOM Line must have the number set.</param>
/// <param name="ItemNo">Return value: The number of the item to add.</param>
procedure AddItem(var ProductionBOMLine: Record "Production BOM Line"; ItemNo: Code[20])
begin
ProductionBOMLine.Init();
ProductionBOMLine."Line No." += 10000;
ProductionBOMLine.Validate(Type, Type::Item);
ProductionBOMLine.Validate("No.", ItemNo);
ProductionBOMLine.Insert(true);
end;
/// <summary>
/// Initializes a new Production BOM Line based on the current Production BOM Line.
/// </summary>
/// <param name="NewProductionBOMLine">Return value: The new Production BOM Line.</param>
procedure InitNewLine(var NewProductionBOMLine: Record "Production BOM Line")
var
ProductionBOMLine: Record "Production BOM Line";
begin
NewProductionBOMLine.Copy(Rec);
ProductionBOMLine.SetLoadFields("Line No.");
ProductionBOMLine.SetRange("Production BOM No.", NewProductionBOMLine."Production BOM No.");
ProductionBOMLine.SetRange("Version Code", NewProductionBOMLine."Version Code");
if ProductionBOMLine.FindLast() then
NewProductionBOMLine."Line No." := ProductionBOMLine."Line No."
else
NewProductionBOMLine."Line No." := 0;
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTestStatus(ProductionBOMLine: Record "Production BOM Line"; ProductionBOMHeader: Record "Production BOM Header"; ProductionBOMVersion: Record "Production BOM Version")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterValidateNo(var ProductionBOMLine: Record "Production BOM Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetBOMHeaderQtyPerUOM(var ProductionBOMLine: Record "Production BOM Line"; Item: Record Item; var Result: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetBOMLineQtyPerUOM(var ProductionBOMLine: Record "Production BOM Line"; Item: Record Item; var Result: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetQtyPerUnitOfMeasure(var ProductionBOMLine: Record "Production BOM Line"; var Result: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateRoutingLinkCode(var ProductionBOMLine: Record "Production BOM Line"; xProductionBOMLine: Record "Production BOM Line"; CallingFieldNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTestStatus(var ProductionBOMLine: Record "Production BOM Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteOnCaseTypeElse(var ProductionBOMLine: Record "Production BOM Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateCalculationFormulaEnumExtension(var ProductionBOMLine: Record "Production BOM Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateNoOnAfterAssignItemFields(var ProductionBOMLine: Record "Production BOM Line"; Item: Record Item; var xProductionBOMLine: Record "Production BOM Line"; CallingFieldNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateNo(var ProductionBOMLine: Record "Production BOM Line"; xProductionBOMLine: Record "Production BOM Line"; CallingFieldNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnValidateNoOnAfterAssignProdBOMFields(var ProductionBOMLine: Record "Production BOM Line"; ProductionBOMHeader: Record "Production BOM Header"; var xProductionBOMLine: Record "Production BOM Line"; CallingFieldNo: Integer)
begin
end;
}