From 120b0dbd825cb46f3ce66fafe3cdb27bcb67328a Mon Sep 17 00:00:00 2001 From: Sebastian Pinkow Date: Tue, 23 Jun 2026 16:11:57 +0200 Subject: [PATCH 1/2] Disable "WIP Item Transfer" for Machine Center --- .../Manufacturing/SubcRoutingLine.TableExt.al | 1 + .../Manufacturing/SubcRoutingLines.PageExt.al | 2 +- .../SubcRoutingVersionLines.PageExt.al | 2 +- .../SubcLibraryMfgManagement.Codeunit.al | 8 +- .../SubcSubcontractingUITest.Codeunit.al | 225 ++++++++++++++++++ 5 files changed, 235 insertions(+), 3 deletions(-) diff --git a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLine.TableExt.al b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLine.TableExt.al index 0f79bb81f6..27b9133751 100644 --- a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLine.TableExt.al +++ b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLine.TableExt.al @@ -99,6 +99,7 @@ tableextension 99001560 "Subc. Routing Line" extends "Routing Line" if "Transfer WIP Item" then begin CalcFields(Subcontracting); TestField(Subcontracting, true); + TestField(Type, Type::"Work Center"); end; end; } diff --git a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLines.PageExt.al b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLines.PageExt.al index 62da5b63a9..ad67527337 100644 --- a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLines.PageExt.al +++ b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingLines.PageExt.al @@ -112,7 +112,7 @@ pageextension 99001508 "Subc. Routing Lines" extends "Routing Lines" local procedure UpdateWIPEnabled() begin Rec.Calcfields(Subcontracting); - TransferWIPItemEnabled := Rec.Subcontracting; + TransferWIPItemEnabled := Rec.Subcontracting and (Rec.Type = Rec.Type::"Work Center"); end; procedure ShowRelatedSubcontractorPrices() diff --git a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingVersionLines.PageExt.al b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingVersionLines.PageExt.al index 88ed221f0f..0e5cc67c4f 100644 --- a/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingVersionLines.PageExt.al +++ b/src/Apps/W1/Subcontracting/App/src/Manufacturing/SubcRoutingVersionLines.PageExt.al @@ -106,7 +106,7 @@ pageextension 99001509 "Subc. Routing Version Lines" extends "Routing Version Li local procedure UpdateWIPEnabled() begin Rec.Calcfields(Subcontracting); - TransferWIPItemEnabled := Rec.Subcontracting; + TransferWIPItemEnabled := Rec.Subcontracting and (Rec.Type = Rec.Type::"Work Center"); end; procedure ShowRelatedSubcontractorPrices() diff --git a/src/Apps/W1/Subcontracting/Test/Libraries/SubcLibraryMfgManagement.Codeunit.al b/src/Apps/W1/Subcontracting/Test/Libraries/SubcLibraryMfgManagement.Codeunit.al index 9afed09fa2..87686b69dc 100644 --- a/src/Apps/W1/Subcontracting/Test/Libraries/SubcLibraryMfgManagement.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/Libraries/SubcLibraryMfgManagement.Codeunit.al @@ -124,6 +124,12 @@ codeunit 139984 "Subc. Library Mfg. Management" MachineCenterNo := MachineCenter."No."; end; + procedure CreateRoutingLineForMachineCenter(var RoutingLine: Record "Routing Line"; RoutingHeader: Record "Routing Header"; MachineCenterNo: Code[20]) + begin + RoutingLine.Type := RoutingLine.Type::"Machine Center"; + CreateRoutingLine(RoutingLine, RoutingHeader, MachineCenterNo); + end; + procedure CreateRouting(var RoutingNo: Code[20]; MachineCenterNo: Code[20]; MachineCenterNo2: Code[20]; WorkCenterNo: Code[20]; WorkCenterNo2: Code[20]) var RoutingHeader: Record "Routing Header"; @@ -143,7 +149,7 @@ codeunit 139984 "Subc. Library Mfg. Management" RoutingNo := RoutingHeader."No."; end; - local procedure CreateRoutingLine(var RoutingLine: Record "Routing Line"; RoutingHeader: Record "Routing Header"; CenterNo: Code[20]) + procedure CreateRoutingLine(var RoutingLine: Record "Routing Line"; RoutingHeader: Record "Routing Header"; CenterNo: Code[20]) var CapacityUnitOfMeasure: Record "Capacity Unit of Measure"; OperationNo: Code[10]; diff --git a/src/Apps/W1/Subcontracting/Test/Tests/SubcSubcontractingUITest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/Tests/SubcSubcontractingUITest.Codeunit.al index 09674db98a..de486a1a52 100644 --- a/src/Apps/W1/Subcontracting/Test/Tests/SubcSubcontractingUITest.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/Tests/SubcSubcontractingUITest.Codeunit.al @@ -620,6 +620,228 @@ codeunit 139990 "Subc. Subcontracting UI Test" ItemLedgerEntry.Delete(); end; + [Test] + procedure RoutingLinesTransferWIPItemDisabledForMachineCenterLine() + var + WorkCenter: Record "Work Center"; + RoutingHeader: Record "Routing Header"; + RoutingLine: Record "Routing Line"; + RoutingLines: TestPage "Routing Lines"; + MachineCenterNo: Code[20]; + begin + // [SCENARIO] Transfer WIP Item field is disabled on Routing Lines page for a Machine Center routing line, + // even when the parent Work Center has a Subcontractor No. + Initialize(); + + // [GIVEN] A Work Center with a Subcontractor No. + LibraryMfgManagement.CreateWorkCenterWithCalendar(WorkCenter, 0); + WorkCenter.Validate("Subcontractor No.", LibraryMfgManagement.CreateSubcontractorWithCurrency('')); + WorkCenter.Modify(true); + + // [GIVEN] A Machine Center belonging to that Work Center + LibraryMfgManagement.CreateMachineCenter(MachineCenterNo, WorkCenter."No.", 0); + + // [GIVEN] A Routing with a Machine Center routing line + LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); + LibraryMfgManagement.CreateRoutingLineForMachineCenter(RoutingLine, RoutingHeader, MachineCenterNo); + + // [WHEN] The Routing Lines page is opened for that line + RoutingLines.OpenEdit(); + RoutingLines.GoToRecord(RoutingLine); + + // [THEN] Transfer WIP Item is not enabled (Machine Center type is not eligible for Transfer WIP Item) + Assert.IsFalse(RoutingLines."Transfer WIP Item".Enabled(), RoutingLineTransferWIPEnabledErr); + RoutingLines.Close(); + end; + + [Test] + procedure RoutingLinesTransferWIPItemEnabledForSubcontractingWorkCenterLine() + var + WorkCenter: Record "Work Center"; + RoutingHeader: Record "Routing Header"; + RoutingLine: Record "Routing Line"; + RoutingLines: TestPage "Routing Lines"; + begin + // [SCENARIO] Transfer WIP Item field is enabled on Routing Lines page for a Work Center routing line + // when the Work Center has a Subcontractor No. + Initialize(); + + // [GIVEN] A Work Center with a Subcontractor No. + LibraryMfgManagement.CreateWorkCenterWithCalendar(WorkCenter, 0); + WorkCenter.Validate("Subcontractor No.", LibraryMfgManagement.CreateSubcontractorWithCurrency('')); + WorkCenter.Modify(true); + + // [GIVEN] A Routing with a Work Center routing line + LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); + LibraryMfgManagement.CreateRoutingLine(RoutingLine, RoutingHeader, WorkCenter."No."); + + // [WHEN] The Routing Lines page is opened for that line + RoutingLines.OpenEdit(); + RoutingLines.GoToRecord(RoutingLine); + + // [THEN] Transfer WIP Item is enabled (subcontracting Work Center type) + Assert.IsTrue(RoutingLines."Transfer WIP Item".Enabled(), RoutingLineTransferWIPNotEnabledErr); + RoutingLines.Close(); + end; + + [Test] + procedure RoutingVersionLinesTransferWIPItemDisabledForMachineCenterLine() + var + WorkCenter: Record "Work Center"; + RoutingHeader: Record "Routing Header"; + RoutingLine: Record "Routing Line"; + RoutingVersionLines: TestPage "Routing Version Lines"; + MachineCenterNo: Code[20]; + VersionCode: Code[20]; + begin + // [SCENARIO] Transfer WIP Item field is disabled on Routing Version Lines page for a Machine Center + // routing line, even when the parent Work Center has a Subcontractor No. + Initialize(); + + // [GIVEN] A Work Center with a Subcontractor No. + LibraryMfgManagement.CreateWorkCenterWithCalendar(WorkCenter, 0); + WorkCenter.Validate("Subcontractor No.", LibraryMfgManagement.CreateSubcontractorWithCurrency('')); + WorkCenter.Modify(true); + + // [GIVEN] A Machine Center belonging to that Work Center + LibraryMfgManagement.CreateMachineCenter(MachineCenterNo, WorkCenter."No.", 0); + + // [GIVEN] A Routing Version with a Machine Center routing line + LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); + VersionCode := '1'; + CreateRoutingVersionAndMachineCenterLine(RoutingHeader."No.", VersionCode, MachineCenterNo, RoutingLine); + + // [WHEN] The Routing Version Lines page is opened for that line + RoutingVersionLines.OpenEdit(); + RoutingVersionLines.Filter.SetFilter("Routing No.", RoutingHeader."No."); + RoutingVersionLines.Filter.SetFilter("Version Code", VersionCode); + RoutingVersionLines.GoToRecord(RoutingLine); + + // [THEN] Transfer WIP Item is not enabled (Machine Center type is not eligible for Transfer WIP Item) + Assert.IsFalse(RoutingVersionLines."Transfer WIP Item".Enabled(), RoutingLineTransferWIPEnabledErr); + RoutingVersionLines.Close(); + end; + + [Test] + procedure RoutingVersionLinesTransferWIPItemEnabledForSubcontractingWorkCenterLine() + var + WorkCenter: Record "Work Center"; + RoutingHeader: Record "Routing Header"; + RoutingLine: Record "Routing Line"; + RoutingVersionLines: TestPage "Routing Version Lines"; + VersionCode: Code[20]; + begin + // [SCENARIO] Transfer WIP Item field is enabled on Routing Version Lines page for a Work Center routing line + // when the Work Center has a Subcontractor No. + Initialize(); + + // [GIVEN] A Work Center with a Subcontractor No. + LibraryMfgManagement.CreateWorkCenterWithCalendar(WorkCenter, 0); + WorkCenter.Validate("Subcontractor No.", LibraryMfgManagement.CreateSubcontractorWithCurrency('')); + WorkCenter.Modify(true); + + // [GIVEN] A Routing Version with a Work Center routing line + LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); + VersionCode := '1'; + CreateRoutingVersionAndWorkCenterLine(RoutingHeader."No.", VersionCode, WorkCenter."No.", RoutingLine); + + // [WHEN] The Routing Version Lines page is opened for that line + RoutingVersionLines.OpenEdit(); + RoutingVersionLines.Filter.SetFilter("Routing No.", RoutingHeader."No."); + RoutingVersionLines.Filter.SetFilter("Version Code", VersionCode); + RoutingVersionLines.GoToRecord(RoutingLine); + + // [THEN] Transfer WIP Item is enabled (subcontracting Work Center type) + Assert.IsTrue(RoutingVersionLines."Transfer WIP Item".Enabled(), RoutingLineTransferWIPNotEnabledErr); + RoutingVersionLines.Close(); + end; + + [Test] + procedure RoutingLineTransferWIPItemValidationFailsForMachineCenterType() + var + WorkCenter: Record "Work Center"; + RoutingHeader: Record "Routing Header"; + RoutingLine: Record "Routing Line"; + MachineCenterNo: Code[20]; + begin + // [SCENARIO] Validating Transfer WIP Item = true on a Machine Center routing line fails + // with an error because the Type must be Work Center. + Initialize(); + + // [GIVEN] A Work Center with a Subcontractor No. + LibraryMfgManagement.CreateWorkCenterWithCalendar(WorkCenter, 0); + WorkCenter.Validate("Subcontractor No.", LibraryMfgManagement.CreateSubcontractorWithCurrency('')); + WorkCenter.Modify(true); + + // [GIVEN] A Machine Center belonging to that Work Center + LibraryMfgManagement.CreateMachineCenter(MachineCenterNo, WorkCenter."No.", 0); + + // [GIVEN] A Routing with a Machine Center routing line + LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); + LibraryMfgManagement.CreateRoutingLineForMachineCenter(RoutingLine, RoutingHeader, MachineCenterNo); + + // [WHEN] Transfer WIP Item is set to true on the Machine Center routing line + // [THEN] An error is raised because the line type must be Work Center + asserterror RoutingLine.Validate("Transfer WIP Item", true); + Assert.ExpectedTestFieldError(RoutingLine.FieldCaption(Type), Format(RoutingLine.Type::"Work Center")); + end; + + local procedure CreateRoutingVersionAndWorkCenterLine(RoutingNo: Code[20]; VersionCode: Code[20]; WorkCenterNo: Code[20]; var RoutingLine: Record "Routing Line") + var + RoutingVersion: Record "Routing Version"; + CapacityUoM: Record "Capacity Unit of Measure"; + begin + RoutingVersion.Init(); + RoutingVersion.Validate("Routing No.", RoutingNo); + RoutingVersion."Version Code" := VersionCode; + RoutingVersion.Insert(true); + +#pragma warning disable AA0210 + CapacityUoM.SetRange(Type, CapacityUoM.Type::Minutes); +#pragma warning restore AA0210 + CapacityUoM.FindFirst(); + + RoutingLine.Init(); + RoutingLine.Validate("Routing No.", RoutingNo); + RoutingLine.Validate("Version Code", VersionCode); + RoutingLine.Validate("Operation No.", '10'); + RoutingLine.Validate(Type, RoutingLine.Type::"Work Center"); + RoutingLine.Validate("No.", WorkCenterNo); + RoutingLine.Validate("Setup Time", 1); + RoutingLine.Validate("Run Time", 1); + RoutingLine.Validate("Run Time Unit of Meas. Code", CapacityUoM.Code); + RoutingLine.Validate("Setup Time Unit of Meas. Code", CapacityUoM.Code); + RoutingLine.Insert(true); + end; + + local procedure CreateRoutingVersionAndMachineCenterLine(RoutingNo: Code[20]; VersionCode: Code[20]; MachineCenterNo: Code[20]; var RoutingLine: Record "Routing Line") + var + RoutingVersion: Record "Routing Version"; + CapacityUoM: Record "Capacity Unit of Measure"; + begin + RoutingVersion.Init(); + RoutingVersion.Validate("Routing No.", RoutingNo); + RoutingVersion."Version Code" := VersionCode; + RoutingVersion.Insert(true); + +#pragma warning disable AA0210 + CapacityUoM.SetRange(Type, CapacityUoM.Type::Minutes); +#pragma warning restore AA0210 + CapacityUoM.FindFirst(); + + RoutingLine.Init(); + RoutingLine.Validate("Routing No.", RoutingNo); + RoutingLine.Validate("Version Code", VersionCode); + RoutingLine.Validate("Operation No.", '10'); + RoutingLine.Validate(Type, RoutingLine.Type::"Machine Center"); + RoutingLine.Validate("No.", MachineCenterNo); + RoutingLine.Validate("Setup Time", 1); + RoutingLine.Validate("Run Time", 1); + RoutingLine.Validate("Run Time Unit of Meas. Code", CapacityUoM.Code); + RoutingLine.Validate("Setup Time Unit of Meas. Code", CapacityUoM.Code); + RoutingLine.Insert(true); + end; + local procedure GetNextItemLedgerEntryNo(): Integer var ItemLedgerEntry: Record "Item Ledger Entry"; @@ -634,6 +856,7 @@ codeunit 139990 "Subc. Subcontracting UI Test" LibraryERMCountryData: Codeunit "Library - ERM Country Data"; LibrarySetupStorage: Codeunit "Library - Setup Storage"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; + LibraryManufacturing: Codeunit "Library - Manufacturing"; LibraryMfgManagement: Codeunit "Subc. Library Mfg. Management"; SubcontractingMgmtLibrary: Codeunit "Subc. Management Library"; SubSetupLibrary: Codeunit "Subc. Setup Library"; @@ -647,4 +870,6 @@ codeunit 139990 "Subc. Subcontracting UI Test" ILEProdActionsNotEnabledErr: Label 'Production actions should be enabled for a subcontracting Item Ledger Entry.'; ILEPurchActionsEnabledErr: Label 'Purchase Order action should not be enabled for a non-subcontracting Item Ledger Entry.'; ILEPurchActionsNotEnabledErr: Label 'Purchase Order action should be enabled for a subcontracting Item Ledger Entry.'; + RoutingLineTransferWIPEnabledErr: Label 'Transfer WIP Item should not be enabled for a Machine Center routing line.'; + RoutingLineTransferWIPNotEnabledErr: Label 'Transfer WIP Item should be enabled for a subcontracting Work Center routing line.'; } \ No newline at end of file From 228315dd81224f2ccd282782a52ba30b44f6075c Mon Sep 17 00:00:00 2001 From: Sebastian Pinkow Date: Tue, 23 Jun 2026 16:14:26 +0200 Subject: [PATCH 2/2] Set "Transfer WIP Item" field to non-editable in Subc. PO Subform --- .../W1/Subcontracting/App/src/Purchase/SubcPOSubform.PageExt.al | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Apps/W1/Subcontracting/App/src/Purchase/SubcPOSubform.PageExt.al b/src/Apps/W1/Subcontracting/App/src/Purchase/SubcPOSubform.PageExt.al index 039907685a..2ada2bac07 100644 --- a/src/Apps/W1/Subcontracting/App/src/Purchase/SubcPOSubform.PageExt.al +++ b/src/Apps/W1/Subcontracting/App/src/Purchase/SubcPOSubform.PageExt.al @@ -16,6 +16,7 @@ pageextension 99001524 "Subc. PO Subform" extends "Purchase Order Subform" { ApplicationArea = Subcontracting; Visible = false; + Editable = false; } } }