Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ page 99001561 "Subc. WIP Adjustment"
StyleExpr = QuantityStyle;
ToolTip = 'Specifies the quantity that will be adjusted (New Quantity (Base) minus Current Quantity (Base)).';
}
field("Unit of Measure Code"; Rec."Unit of Measure Code")
Comment thread
ChethanT marked this conversation as resolved.
field("Base Unit of Measure"; Rec."Base Unit of Measure")
{
Editable = false;
Caption = 'Base Unit of Measure';
Expand Down Expand Up @@ -218,7 +218,7 @@ page 99001561 "Subc. WIP Adjustment"
StyleExpr = QuantityStyle;
ToolTip = 'Specifies the quantity that will be adjusted (New Quantity minus Current Quantity).';
}
field("Unit of Measure Code Line"; Rec."Unit of Measure Code")
field("Base Unit of Measure Line"; Rec."Base Unit of Measure")
{
Caption = 'Base Unit of Measure';
Editable = false;
Expand Down Expand Up @@ -303,7 +303,7 @@ page 99001561 "Subc. WIP Adjustment"
Rec."Document Line No." := 0;
Rec."In Transit" := WIPLedgerEntry."In Transit";
Rec."Quantity (Base)" := WIPLedgerEntry."Quantity (Base)";
Rec."Unit of Measure Code" := GetItemBaseUnitOfMeasure(WIPLedgerEntry."Item No.");
Rec."Base Unit of Measure" := GetItemBaseUnitOfMeasure(WIPLedgerEntry."Item No.");
Rec.Insert();
NewQuantities.Add(Rec."Entry No.", Rec."Quantity (Base)");
EntrySeq += 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ page 99001560 "Subc. WIP Ledger Entries"
field("Quantity (Base)"; Rec."Quantity (Base)")
{
}
field("Unit of Measure Code"; Rec."Unit of Measure Code")
field("Base Unit of Measure"; Rec."Base Unit of Measure")
{
}
field("Prod. Order Status"; Rec."Prod. Order Status")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ table 99001560 "Subcontractor WIP Ledger Entry"
DecimalPlaces = 0 : 5;
ToolTip = 'Specifies the WIP quantity in base unit of measure';
}
field(8; "Unit of Measure Code"; Code[10])
Comment thread
ChethanT marked this conversation as resolved.
field(8; "Base Unit of Measure"; Code[10])
{
Caption = 'Unit of Measure Code';
Caption = 'Base Unit of Measure';
DataClassification = CustomerContent;
TableRelation = "Item Unit of Measure".Code where("Item No." = field("Item No."));
ToolTip = 'Specifies the unit of measure code.';
ToolTip = 'Specifies the base unit of measure of the item.';
}
field(9; "Document Type"; Enum "WIP Document Type")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ codeunit 139983 "Subc. Management Library"
end;

procedure CreateWIPLedgerEntry(var WIPLedgerEntry: Record "Subcontractor WIP Ledger Entry"; ItemNo: Code[20]; LocationCode: Code[10]; ProductionOrder: Record "Production Order"; ProdOrderLine: Record "Prod. Order Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; WorkCenterNo: Code[20]; QuantityBase: Decimal; InTransit: Boolean)
var
Item: Record Item;
begin
if WIPLedgerEntry.FindLast() then;
WIPLedgerEntry.Init();
Expand All @@ -253,7 +255,9 @@ codeunit 139983 "Subc. Management Library"
WIPLedgerEntry."Work Center No." := WorkCenterNo;
WIPLedgerEntry."Quantity (Base)" := QuantityBase;
WIPLedgerEntry."In Transit" := InTransit;
WIPLedgerEntry."Unit of Measure Code" := ProdOrderLine."Unit of Measure Code";
Item.SetLoadFields("Base Unit of Measure");
if Item.Get(ItemNo) then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ Performance} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Incomplete WIP entry when Item.Get fails in library

The same silent-skip pattern used in production code is repeated in CreateWIPLedgerEntry: if Item.Get(ItemNo) fails, WIPLedgerEntry."Base Unit of Measure" is never set and the entry is inserted with a blank value. This can cause tests to pass even when the UOM field is empty, giving false confidence.

Recommendation:

  • Either assert that the item must exist (using Item.Get(ItemNo) with a direct error on failure) or use TestField after the insert to verify the field was populated, ensuring the test library catches missing items early.
Suggested change
if Item.Get(ItemNo) then
Item.SetLoadFields("Base Unit of Measure");
Item.Get(ItemNo);
WIPLedgerEntry."Base Unit of Measure" := Item."Base Unit of Measure";
WIPLedgerEntry.Insert();

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

WIPLedgerEntry."Base Unit of Measure" := Item."Base Unit of Measure";
WIPLedgerEntry.Insert();
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ using Microsoft.Inventory.Location;
using Microsoft.Inventory.Requisition;
using Microsoft.Inventory.Tracking;
using Microsoft.Inventory.Transfer;
using Microsoft.Manufacturing.Document;
using Microsoft.Manufacturing.MachineCenter;
using Microsoft.Manufacturing.Routing;
using Microsoft.Manufacturing.Setup;
using Microsoft.Manufacturing.Subcontracting;
using Microsoft.Manufacturing.WorkCenter;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Customer;
using Microsoft.Sales.Document;
using Microsoft.Warehouse.Activity;
Expand Down Expand Up @@ -600,6 +608,91 @@ codeunit 149910 "Subc. WIP Transfer Post Test"
Assert.RecordIsEmpty(RequisitionLine);
end;

[Test]
[HandlerFunctions('DoNotConfirmShowCreatedPurchOrderForSubcontracting,HandleTransferOrder')]
procedure PostWIPTransfer_WhenTransferLineHasAlternativeUOM_WIPLedgerEntryHasBaseUOM()
var
Item: Record Item;
ItemUOM: Record "Item Unit of Measure";
MachineCenter: array[2] of Record "Machine Center";
ProductionOrder: Record "Production Order";
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
TransferHeader: Record "Transfer Header";
TransferLine: Record "Transfer Line";
Vendor: Record Vendor;
WIPLedgerEntry: Record "Subcontractor WIP Ledger Entry";
WorkCenter: array[2] of Record "Work Center";
PurchaseHeaderPage: TestPage "Purchase Order";
begin
// [SCENARIO] WIP Ledger Entries use the item's base unit of measure even when the
// subcontracting purchase order line carries a different (alternative) unit of measure.
Initialize();

// [GIVEN] Work centers, machine centers, item with subcontracting routing and Transfer WIP Item flag
SubcWarehouseLibrary.CreateAndCalculateNeededWorkAndMachineCenter(WorkCenter, MachineCenter, true);
SubcWarehouseLibrary.CreateItemForProductionIncludeRoutingAndProdBOM(Item, WorkCenter, MachineCenter);
SetTransferWIPItemOnRoutingLine(Item."Routing No.", WorkCenter[2]."No.", true);
SubcontractingMgmtLibrary.UpdateVendorWithSubcontractingLocationCode(WorkCenter[2]);

// [GIVEN] Item has an additional alternative UOM (6 base units each) — different from the base UOM
LibraryInventory.CreateItemUnitOfMeasureCode(ItemUOM, Item."No.", 6);

// [GIVEN] Released Production Order refreshed at the manufacturing components location
LibraryManufacturing.CreateProductionOrder(
ProductionOrder, "Production Order Status"::Released,
ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5);
SetProdOrderLocationToCompSetupLocationAndRefresh(ProductionOrder);

// [GIVEN] Subcontracting Purchase Order created via the Prod. Order Routing page
SubcontractingMgmtLibrary.CreateSubcontractingOrderFromProdOrderRtngPage(Item."Routing No.", WorkCenter[2]."No.");

// [GIVEN] Change the purchase line UOM to the alternative UOM to simulate a non-base-UOM document
PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No.");
PurchaseLine.FindFirst();
PurchaseLine.Validate("Unit of Measure Code", ItemUOM.Code);
PurchaseLine.Modify(true);
PurchaseHeader.Get(PurchaseLine."Document Type", PurchaseLine."Document No.");

// [GIVEN] Create Transfer Route from production order location to subcontractor location
Vendor.Get(WorkCenter[2]."Subcontractor No.");
CreateAndUpdateTransferRoute(ProductionOrder."Location Code", Vendor."Subc. Location Code");

// [WHEN] Create WIP Transfer Order to Subcontractor and post the shipment
PurchaseHeaderPage.OpenView();
PurchaseHeaderPage.GoToRecord(PurchaseHeader);
PurchaseHeaderPage.CreateTransfOrdToSubcontractor.Invoke();

TransferLine.SetRange("Subc. Prod. Order No.", ProductionOrder."No.");
#pragma warning disable AA0210
TransferLine.SetRange("Transfer WIP Item", true);
#pragma warning restore AA0210
TransferLine.FindFirst();
TransferHeader.Get(TransferLine."Document No.");
LibraryWarehouse.PostTransferOrder(TransferHeader, true, false);

// [THEN] WIP Ledger Entries carry the item base unit of measure, not the document UOM
WIPLedgerEntry.SetRange("Item No.", Item."No.");
Assert.IsTrue(WIPLedgerEntry.FindSet(), 'WIP Ledger Entries must be created after posting the WIP transfer shipment.');
repeat
Assert.AreEqual(Item."Base Unit of Measure", WIPLedgerEntry."Base Unit of Measure",
'WIP Ledger Entry Base Unit of Measure must equal the item base UOM, not the document UOM.');
until WIPLedgerEntry.Next() = 0;
end;

[ConfirmHandler]
procedure DoNotConfirmShowCreatedPurchOrderForSubcontracting(Question: Text[1024]; var Reply: Boolean)
begin
Reply := false;
end;

[PageHandler]
procedure HandleTransferOrder(var TransfOrderPage: TestPage "Transfer Order")
begin
TransfOrderPage.OK().Invoke();
end;

[ConfirmHandler]
procedure DeleteWhseReceiptConfimHandler(Question: Text[1024]; var Reply: Boolean)
begin
Expand All @@ -624,6 +717,8 @@ codeunit 149910 "Subc. WIP Transfer Post Test"
LibraryInventory: Codeunit "Library - Inventory";
LibraryItemTracking: Codeunit "Library - Item Tracking";
LibraryMfgManagement: Codeunit "Subc. Library Mfg. Management";
LibraryManufacturing: Codeunit "Library - Manufacturing";
LibraryRandom: Codeunit "Library - Random";
LibrarySetupStorage: Codeunit "Library - Setup Storage";
LibraryTestInitialize: Codeunit "Library - Test Initialize";
LibraryUtility: Codeunit "Library - Utility";
Expand All @@ -650,6 +745,9 @@ codeunit 149910 "Subc. WIP Transfer Post Test"
SubSetupLibrary.InitSetupFields();
LibraryERMCountryData.CreateVATData();
SubSetupLibrary.InitialSetupForGenProdPostingGroup();
SubcontractingMgmtLibrary.UpdateManufacturingSetupWithSubcontractingLocation();
SubcontractingMgmtLibrary.SetupInventorySetup();
SubcWarehouseLibrary.UpdateSubMgmtSetupWithReqWkshTemplate();

IsInitialized := true;
Commit();
Expand All @@ -669,4 +767,44 @@ codeunit 149910 "Subc. WIP Transfer Post Test"
LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo, '', Quantity);
LibraryInventory.PostItemJournalLine(ItemJournalLine."Journal Template Name", ItemJournalLine."Journal Batch Name");
end;

local procedure SetTransferWIPItemOnRoutingLine(RoutingNo: Code[20]; WorkCenterNo: Code[20]; TransferWIPItem: Boolean)
var
RoutingHeader: Record "Routing Header";
RoutingLine: Record "Routing Line";
begin
RoutingHeader.Get(RoutingNo);
RoutingHeader.Validate(Status, RoutingHeader.Status::New);
RoutingHeader.Modify(true);

RoutingLine.SetRange("Routing No.", RoutingHeader."No.");
RoutingLine.SetRange(Type, RoutingLine.Type::"Work Center");
RoutingLine.SetRange("No.", WorkCenterNo);
RoutingLine.FindFirst();
RoutingLine."Transfer WIP Item" := TransferWIPItem;
Comment thread
ChethanT marked this conversation as resolved.
RoutingLine.Modify(true);

RoutingHeader.Validate(Status, RoutingHeader.Status::Certified);
RoutingHeader.Modify(true);
end;

local procedure SetProdOrderLocationToCompSetupLocationAndRefresh(var ProductionOrder: Record "Production Order")
var
ManufacturingSetup: Record "Manufacturing Setup";
begin
ManufacturingSetup.Get();
ProductionOrder.Validate("Location Code", ManufacturingSetup."Components at Location");
ProductionOrder.Modify();
Comment thread
ChethanT marked this conversation as resolved.
LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);
end;

local procedure CreateAndUpdateTransferRoute(FromLocationCode: Code[10]; ToLocationCode: Code[10])
var
Location: Record Location;
TransferRoute: Record "Transfer Route";
begin
LibraryWarehouse.CreateInTransitLocation(Location);
LibraryWarehouse.CreateAndUpdateTransferRoute(
TransferRoute, FromLocationCode, ToLocationCode, Location.Code, '', '');
end;
}
Loading