diff --git a/dataset/bcbench.jsonl b/dataset/bcbench.jsonl index 64e974d72..cbe3de460 100644 --- a/dataset/bcbench.jsonl +++ b/dataset/bcbench.jsonl @@ -53,3 +53,4 @@ {"metadata": {"area": "manufacturing", "image_count": 11}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-212355", "base_commit": "a7de1e6b1a271e60b86657a69a98e863b2b85d33", "created_at": "2025-04-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137154, "functionName": ["InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\nindex 972aa5e52834..c2e1e71567ec 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n@@ -64,6 +64,8 @@ codeunit 137154 \"SCM Warehouse Management II\"\n ReceiptLinesNotCreatedErr: Label 'There are no warehouse receipt lines created.';\n ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Assign Multiple Lot No.\",\"Assign Serial No.\",\"Assign Lot And Serial\",\"Select Entries\",\"Blank Quantity Base\",\"Assign Lot No. & Expiration Date\",\"Assign Manual Lot Nos\",\"Show Entries\";\n DescriptionMustBeSame: Label 'Description must be same.';\n+ InputQtyErr: Label 'Input Quantity Must be %1 in %2', Comment = '1% = Remaining Quanity value, %2 = Prod. Order Routing Line';\n+ StartingDateTimeErr: Label 'Starting Date-Time must not be %1 in %2', Comment = '%1 = StartingDateTime value, %2 = Prod. Order Routing Line.';\n \n [Test]\n [HandlerFunctions('ReservationPageHandler')]\n@@ -3447,6 +3449,97 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryWarehouse.PostWhseShipment(WarehouseShipmentHeader, false);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ProductionJournalPageHandler,ConfirmHandlerYes,MessageHandlerNotext')]\n+ procedure InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ RoutingHeader: Record \"Routing Header\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProdOrderRoutingLine: Record \"Prod. Order Routing Line\";\n+ WorkCenter: Record \"Work Center\";\n+ Direction: Option Forward,Backward;\n+ CalcMethod: Option \"No Levels\",\"One level\",\"All levels\";\n+ StartingDateTime: DateTime;\n+ begin\n+ // [SCENARIO 565975] \"Input Quantity\" and \"Starting Date-Time\" in Prod. Order Routing Line is \n+ // recalculated when Production Journal is posted and Stan runs Replan Production Order Report.\n+ Initialize();\n+\n+ // [GIVEN] Create a Component Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\" and \"Flushing Method\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Manufacturing Policy\", CompItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::\"Pick + Manual\");\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create a Work Center.\n+ CreateWorkCenter(WorkCenter);\n+\n+ // [GIVEN] Create and Certify Routing.\n+ CreateAndCertifyRouting(RoutingHeader, WorkCenter);\n+\n+ // [GIVEN] Create and Certify Production BOM.\n+ CreateAndCertifyProductionBOM(ProductionBOMLine, CompItem, LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [GIVEN] Create a Production Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\", \"Routing No.\" and \"Production BOM No.\".\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMLine.\"Production BOM No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Set Item Inventory.\n+ SetItemInventory(CompItem, LibraryRandom.RandIntInRange(500, 500));\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProductionOrder(ProductionOrder, ProdItem.\"No.\", LibraryRandom.RandIntInRange(50, 50));\n+\n+ // [GIVEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [GIVEN] Generate and save Starting Date-Time in a Variable.\n+ StartingDateTime := ProdOrderRoutingLine.\"Starting Date-Time\";\n+\n+ // [GIVEN] Open Production Journal.\n+ OpenProductionJournal(ProductionOrder.\"No.\");\n+\n+ // [GIVEN] Run Replan Production Order Report.\n+ LibraryManufacturing.RunReplanProductionOrder(ProductionOrder, Direction::Backward, CalcMethod::\"No Levels\");\n+\n+ // [GIVEN] Find Prod. Order Line.\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrder.\"No.\");\n+ ProdOrderLine.FindFirst();\n+\n+ // [WHEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [THEN] \"Input Quantity\" in Prod. Order Routing Line is equal to \"Remaining Quantity\" of Prod. Order Line.\n+ Assert.AreEqual(\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.\"Input Quantity\",\n+ StrSubstNo(\n+ InputQtyErr,\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.TableCaption()));\n+\n+ // [THEN] \"Starting Date-Time\" in Prod. Order Routing Line is equal to StartingDateTime.\n+ Assert.AreNotEqual(\n+ StartingDateTime,\n+ ProdOrderRoutingLine.\"Starting Date-Time\",\n+ StrSubstNo(\n+ StartingDateTimeErr,\n+ StartingDateTime,\n+ ProdOrderRoutingLine.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5174,6 +5267,71 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n end;\n \n+ local procedure CreateAndRefreshProductionOrder(var ProductionOrder: Record \"Production Order\"; ItemNo: Code[20]; Quantity: Decimal)\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder, ProductionOrder.Status::Released, ProductionOrder.\"Source Type\"::Item, ItemNo, Quantity);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n+\n+ local procedure SetItemInventory(Item: Record Item; Quantity: Decimal)\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ ItemJnlBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ Item.TestField(\"No.\");\n+\n+ LibraryInventory.CreateItemJournalTemplate(ItemJnlTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJnlBatch, ItemJnlTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJnlTemplate.Name, ItemJnlBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Quantity);\n+\n+ LibraryInventory.PostItemJournalLine(ItemJnlTemplate.Name, ItemJnlBatch.Name);\n+ end;\n+\n+ local procedure OpenProductionJournal(No: Code[20])\n+ var\n+ ReleasedProductionOrder: TestPage \"Released Production Order\";\n+ begin\n+ ReleasedProductionOrder.OpenEdit();\n+ ReleasedProductionOrder.FILTER.SetFilter(\"No.\", No);\n+ ReleasedProductionOrder.ProdOrderLines.ProductionJournal.Invoke();\n+ end;\n+\n+ local procedure CreateWorkCenter(var WorkCenter: Record \"Work Center\")\n+ begin\n+ LibraryManufacturing.CreateWorkCenterWithCalendar(WorkCenter);\n+ WorkCenter.Validate(\"Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ WorkCenter.Validate(Capacity, LibraryRandom.RandIntInRange(3, 3));\n+ WorkCenter.Validate(Efficiency, LibraryRandom.RandIntInRange(100, 100));\n+ WorkCenter.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyRouting(var RoutingHeader: Record \"Routing Header\"; WorkCenter: Record \"Work Center\")\n+ var\n+ RoutingLine: Record \"Routing Line\";\n+ begin\n+ LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial);\n+ LibraryManufacturing.CreateRoutingLine(RoutingHeader, RoutingLine, '', Format(LibraryRandom.RandIntInRange(10, 10)), RoutingLine.Type::\"Work Center\", WorkCenter.\"No.\");\n+ RoutingLine.Validate(\"Setup Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Validate(\"Run Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Modify(true);\n+\n+ RoutingHeader.Validate(Status, RoutingHeader.Status::Certified);\n+ RoutingHeader.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyProductionBOM(var ProductionBOMLine: Record \"Production BOM Line\"; Item: Record Item; Qty: Decimal)\n+ var\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ begin\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, Item.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, Item.\"No.\", Qty);\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify(true);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure EnterQuantityToCreatePageHandler(var EnterQuantityToCreate: TestPage \"Enter Quantity to Create\")\n@@ -5347,6 +5505,19 @@ codeunit 137154 \"SCM Warehouse Management II\"\n SourceDocumentFilterCard.Run.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n+ begin\n+ ProductionJournal.First();\n+ ProductionJournal.Quantity.SetValue(LibraryRandom.RandIntInRange(200, 200));\n+ ProductionJournal.Next();\n+ ProductionJournal.\"Setup Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Run Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Output Quantity\".SetValue(LibraryRandom.RandIntInRange(20, 20));\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n [Scope('OnPrem')]\n procedure GLPostingPreviewPageHandler(var ShowAllEntries: TestPage \"G/L Posting Preview\")\n@@ -5372,6 +5543,11 @@ codeunit 137154 \"SCM Warehouse Management II\"\n Assert.IsTrue(StrPos(Message, LocalMessage) > 0, Message);\n end;\n \n+ [MessageHandler]\n+ procedure MessageHandlerNotext(Message: Text[1024])\n+ begin\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(ConfirmMessage: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\nindex 33305adaa10c..25cb5cb00d64 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n@@ -65,7 +65,7 @@ report 99001026 \"Replan Production Order\"\n \"Ending Time\" := \"Prod. Order Line\".\"Ending Time\";\n Modify();\n end;\n- CalcProdOrderRtngLine.CalculateRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n+ CalcProdOrderRtngLine.ReplanRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n end;\n Modify();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\nindex c46c8c20688a..1481dab83903 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n@@ -1261,6 +1261,7 @@ codeunit 99000774 \"Calculate Routing Line\"\n OnCalculateRoutingLineOnBeforeProdOrderCapNeedReset(ProdOrderRoutingLine, ProdOrderRoutingLine2);\n \n ProdOrderCapNeed.Reset();\n+ ProdOrderCapNeed.SetLoadFields(Status, \"Prod. Order No.\", \"Requested Only\", \"Routing No.\", \"Routing Reference No.\", \"Operation No.\");\n ProdOrderCapNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n ProdOrderCapNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n ProdOrderCapNeed.SetRange(\"Requested Only\", false);\n@@ -2114,6 +2115,118 @@ codeunit 99000774 \"Calculate Routing Line\"\n CalendarEntry.SetRange(\"Ending Date-Time\", 0DT, CreateDateTime(DateValue + 1, TimeValue));\n end;\n \n+ procedure ReplanRoutingLine(var ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\"; Direction: Option Forward,Backward; CalcStartEndDate: Boolean)\n+ var\n+ ProdOrderCapacityNeed: Record \"Prod. Order Capacity Need\";\n+ MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n+ ExpectedOperOutput: Decimal;\n+ ActualOperOutput: Decimal;\n+ TotalQtyPerOperation: Decimal;\n+ TotalCapacityPerOperation: Decimal;\n+ begin\n+ MfgSetup.Get();\n+\n+ ProdOrderRoutingLine := ProdOrderRoutingLine2;\n+\n+ WaitTimeOnly :=\n+ (ProdOrderRoutingLine.\"Setup Time\" = 0) and (ProdOrderRoutingLine.\"Run Time\" = 0) and\n+ (ProdOrderRoutingLine.\"Move Time\" = 0);\n+\n+ if ProdOrderRoutingLine.\"Ending Time\" = 0T then\n+ ProdOrderRoutingLine.\"Ending Time\" := 000000T;\n+\n+ if ProdOrderRoutingLine.\"Starting Time\" = 0T then\n+ ProdOrderRoutingLine.\"Starting Time\" := 000000T;\n+\n+ ProdOrderRoutingLine.\"Expected Operation Cost Amt.\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Ovhd. Cost\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Need\" := 0;\n+\n+ ProdOrderCapacityNeed.Reset();\n+ ProdOrderCapacityNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderCapacityNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Requested Only\", false);\n+ ProdOrderCapacityNeed.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Operation No.\", ProdOrderRoutingLine.\"Operation No.\");\n+ ProdOrderCapacityNeed.DeleteAll();\n+\n+ NextCapNeedLineNo := 1;\n+\n+ ProdOrderRoutingLine.TestField(\"Work Center No.\");\n+\n+ CurrentWorkCenterNo := '';\n+ Workcenter.Get(ProdOrderRoutingLine.\"Work Center No.\");\n+ if ProdOrderRoutingLine.Type = ProdOrderRoutingLine.Type::\"Machine Center\" then begin\n+ MachineCenter.Get(ProdOrderRoutingLine.\"No.\");\n+ Workcenter.\"Queue Time\" := MachineCenter.\"Queue Time\";\n+ Workcenter.\"Queue Time Unit of Meas. Code\" := MachineCenter.\"Queue Time Unit of Meas. Code\";\n+ end;\n+ if not CalcStartEndDate then\n+ Clear(Workcenter.\"Queue Time\");\n+ ProdOrder.Get(ProdOrderRoutingLine.Status, ProdOrderRoutingLine.\"Prod. Order No.\");\n+\n+ ProdOrderQty := 0;\n+ TotalScrap := 0;\n+ TotalLotSize := 0;\n+ ProdOrderLine.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderLine.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderLine.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderLine.SetLoadFields(\"Quantity (Base)\", \"Scrap %\", \"Prod. Order No.\", \"Line No.\", Status, \"Routing No.\", \"Routing Version Code\", \"Ending Date\", \"Ending Time\");\n+ if ProdOrderLine.Find('-') then begin\n+ ExpectedOperOutput := 0;\n+ repeat\n+ ExpectedOperOutput := ExpectedOperOutput + ProdOrderLine.\"Quantity (Base)\";\n+ TotalScrap := TotalScrap + ProdOrderLine.\"Scrap %\";\n+ until ProdOrderLine.Next() = 0;\n+ ActualOperOutput := MfgCostCalcMgt.CalcActOutputQtyBase(ProdOrderLine, ProdOrderRoutingLine);\n+ ProdOrderQty := ExpectedOperOutput - ActualOperOutput;\n+ if ProdOrderQty < 0 then\n+ ProdOrderQty := 0;\n+ end;\n+\n+ MaxLotSize :=\n+ ProdOrderQty *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\";\n+\n+ ProdOrderRoutingLine.\"Input Quantity\" := MaxLotSize;\n+\n+ if ActualOperOutput > 0 then\n+ TotalQtyPerOperation :=\n+ ExpectedOperOutput *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\"\n+ else\n+ TotalQtyPerOperation := MaxLotSize;\n+\n+ TotalCapacityPerOperation :=\n+ Round(\n+ TotalQtyPerOperation *\n+ ProdOrderRoutingLine.RunTimePer() *\n+ CalendarMgt.QtyperTimeUnitofMeasure(\n+ ProdOrderRoutingLine.\"Work Center No.\", ProdOrderRoutingLine.\"Run Time Unit of Meas. Code\"),\n+ UOMMgt.QtyRndPrecision());\n+\n+ if MfgSetup.\"Cost Incl. Setup\" then\n+ CalcCostInclSetup(ProdOrderRoutingLine, TotalCapacityPerOperation);\n+\n+ CalcExpectedCost(ProdOrderRoutingLine, TotalQtyPerOperation, TotalCapacityPerOperation);\n+\n+ if ProdOrderRoutingLine.\"Schedule Manually\" then\n+ CalculateRoutingLineFixed()\n+ else\n+ if Direction = Direction::Backward then\n+ CalcRoutingLineBack(CalcStartEndDate)\n+ else\n+ CalcRoutingLineForward(CalcStartEndDate);\n+\n+ ProdOrderRoutingLine2 := ProdOrderRoutingLine;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCalcCostInclSetup(ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; var TotalCapacityPerOperation: Decimal)\n begin\n"} {"metadata": {"area": "project", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214825", "base_commit": "9a03d309156dd751b1a508767c678093c9516506", "created_at": "2025-05-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136350, "functionName": ["CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\nindex bb7f40e246dc..8aac1963c2d5 100644\n--- a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n@@ -2248,6 +2248,36 @@ codeunit 136350 \"UT T Job\"\n Assert.IsFalse(PurchaseLine.IsEmpty, 'Purchase Line not created for Job Task' + JobTask.\"Job Task No.\");\n end;\n \n+ [Test]\n+ [HandlerFunctions('CheckPurchOrderFromJobModalPageHandlerHaveLines')]\n+ procedure CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne()\n+ var\n+ Item, Item2 : Record Item;\n+ JobPlanningLines: TestPage \"Job Planning Lines\";\n+ begin\n+ // [SCENARIO 574938] Create Purchase Order from Project not working as expected if we add Project Planning Lines before the previous ones.\n+ Initialize();\n+\n+ // [GIVEN] Create 2 New Item.\n+ LibraryInventory.CreateItem(Item);\n+ LibraryInventory.CreateItem(Item2);\n+\n+ // [GIVEN] Create Job X with Job Task and 2 Job Planning Lines.\n+ CreateJobAndJobTask();\n+ CreateJobPlanningLineWithItem(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item.\"No.\", LibraryRandom.RandInt(100));\n+ CreateJobPlanningLineBeforePreviousLine(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item2.\"No.\", LibraryRandom.RandInt(100));\n+\n+ // [WHEN] Open Job Planning Lines.\n+ JobPlanningLines.OpenEdit();\n+ JobPlanningLines.GoToRecord(JobPlanningLine);\n+ LibraryVariableStorage.Clear();\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+\n+ // [WHEN] Create Purchase Order from Job Planning Lines.\n+ JobPlanningLines.CreatePurchaseOrder.Invoke();//assert check\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2617,6 +2647,30 @@ codeunit 136350 \"UT T Job\"\n until DefaultDimension.Next() = 0;\n end;\n \n+ local procedure CreateJobPlanningLineBeforePreviousLine(LineType: Enum \"Job Planning Line Line Type\"; ItemNo: Code[20]; Quantity: Decimal)\n+ var\n+ JobPlanLine: Record \"Job Planning Line\";\n+ LineNo: Integer;\n+ begin\n+ JobPlanLine.SetRange(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ if JobPlanLine.FindFirst() then;\n+ LineNo := JobPlanLine.\"Line No.\" / 2;\n+ JobPlanningLine.Init();\n+ JobPlanningLine.Validate(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanningLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ JobPlanningLine.Validate(\"Line No.\", LineNo);\n+ JobPlanningLine.Insert(true);\n+\n+ JobPlanningLine.Validate(\"Planning Date\", WorkDate());\n+ JobPlanningLine.Validate(\"Line Type\", LineType);\n+ JobPlanningLine.Validate(Type, JobPlanningLine.Type::Item);\n+ JobPlanningLine.Validate(Description, LibraryUtility.GenerateGUID());\n+ JobPlanningLine.Validate(\"No.\", ItemNo);\n+ JobPlanningLine.Validate(Quantity, Quantity);\n+ JobPlanningLine.Modify(true);\n+ end;\n+\n [EventSubscriber(ObjectType::Table, Database::\"Job\", 'OnAfterModifyEvent', '', false, false)]\n local procedure InsertNameValueBufferOnJobModify(var Rec: Record Job; var xRec: Record Job; RunTrigger: Boolean)\n var\n@@ -2730,6 +2784,13 @@ codeunit 136350 \"UT T Job\"\n PurchOrderFromSalesOrder.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ procedure CheckPurchOrderFromJobModalPageHandlerHaveLines(var PurchOrderFromSalesOrder: TestPage \"Purch. Order From Sales Order\")\n+ begin\n+ //[THEN] Check Purch. Order From Sales Order Page have Record.\n+ PurchOrderFromSalesOrder.\"No.\".AssertEquals(LibraryVariableStorage.DequeueText());\n+ end;\n+\n [MessageHandler]\n procedure MessageHandler(Message: Text[1024])\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\nindex 604bb9158a26..2da4897165fb 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n@@ -78,6 +78,7 @@ codeunit 1018 \"Purchase Doc. From Job\"\n JobPlanningLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n if JobPlanningLine.IsEmpty() then\n exit;\n+ JobPlanningLine.SetCurrentKey(\"Job Contract Entry No.\");\n JobPlanningLine.FindSet();\n RecRef.GetTable(JobPlanningLine);\n ContractEntryNoFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, JobPlanningLine.FieldNo(\"Job Contract Entry No.\"));\n"} {"metadata": {"area": "subscription billing", "image_count": 0}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4766", "base_commit": "700d04453d3f0851ce7b7e34eb50b283f7c10e52", "created_at": "2025-09-15T15:39:32Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Subscription Billing\\App", "src\\Apps\\W1\\Subscription Billing\\Test"], "FAIL_TO_PASS": [{"codeunitID": 148155, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}, {"codeunitID": 148154, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\nindex 7e485c8c43..e945075fa8 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n@@ -613,23 +613,62 @@ codeunit 148155 \"Contracts Test\"\n CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n ServiceCommitment: Record \"Subscription Line\";\n ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n EntryNo: Integer;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n \n+ // [GIVEN] A customer contract with a connected Subscription Line\n SetupNewContract(false, ServiceObject, CustomerContract);\n \n- CustomerContractLine.Reset();\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n CustomerContractLine.FindFirst();\n EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n CustomerContractLine.Validate(\"Contract Line Type\", CustomerContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ CustomerContract: Record \"Customer Subscription Contract\";\n+ CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n+ ServiceCommitment: Record \"Subscription Line\";\n+ ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ EntryNo: Integer;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A customer contract with a connected Subscription Line\n+ SetupNewContract(false, ServiceObject, CustomerContract);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n+ CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ CustomerContractLine.FindFirst();\n+ EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ CustomerContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\ndiff --git a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\nindex c47f577102..b827f99217 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n@@ -338,11 +338,15 @@ codeunit 148154 \"Vendor Contracts Test\"\n procedure ContractLineDisconnectServiceOnTypeChange()\n var\n EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n SetupNewContract(false);\n \n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n VendorContractLine.Reset();\n VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n@@ -350,9 +354,43 @@ codeunit 148154 \"Vendor Contracts Test\"\n VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n VendorContractLine.FindFirst();\n EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n VendorContractLine.Validate(\"Contract Line Type\", VendorContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n+ SetupNewContract(false);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ VendorContractLine.Reset();\n+ VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n+ VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ VendorContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ VendorContractLine.FindFirst();\n+ EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ VendorContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\n", "patch": "diff --git a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\nindex 91f83b18b3..a092d10f19 100644\n--- a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n@@ -49,23 +49,25 @@ table 8062 \"Cust. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempCustomerContractLine: Record \"Cust. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempCustomerContractLine := Rec;\n Init();\n SystemId := TempCustomerContractLine.SystemId;\n@@ -170,6 +172,8 @@ table 8062 \"Cust. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n CustomerContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.UpdateCustomerDataFromCustomerContract(CustomerContract);\ndiff --git a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\nindex 533581b5a2..38ecf0e9c3 100644\n--- a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n@@ -46,23 +46,25 @@ table 8065 \"Vend. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempVendorContractLine: Record \"Vend. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempVendorContractLine := Rec;\n Init();\n SystemId := TempVendorContractLine.SystemId;\n@@ -161,6 +163,8 @@ table 8065 \"Vend. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n VendorContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.\"Created in Contract line\" := true;\n"} +{"metadata": {"area": null, "image_count": null}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-3135", "base_commit": "21116ec278483dc1c79b0d157195721c3deea1df", "created_at": "2025-03-03T10:11:22Z", "environment_setup_version": "26.0", "project_paths": ["src\\System Application\\App", "src\\System Application\\Test"], "FAIL_TO_PASS": [{"codeunitID": 130443, "functionName": ["AddUnrelatedTableCreatesRecord", "AddUnrelatedTableReturnsTrueIfCreated", "AddUnrelatedTableReturnsFalseIfNotCreated"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/System Application/Test/Word Templates/app.json b/src/System Application/Test/Word Templates/app.json\nindex 5037543de7..d25c6edb7c 100644\n--- a/src/System Application/Test/Word Templates/app.json\n+++ b/src/System Application/Test/Word Templates/app.json\n@@ -23,6 +23,12 @@\n \"publisher\": \"Microsoft\",\n \"version\": \"27.0.0.0\"\n },\n+ {\n+ \"id\": \"e7320ebb-08b3-4406-b1ec-b4927d3e280b\",\n+ \"name\": \"Any\",\n+ \"publisher\": \"Microsoft\",\n+ \"version\": \"27.0.0.0\"\n+ },\n {\n \"id\": \"e31ad830-3d46-472e-afeb-1d3d35247943\",\n \"name\": \"BLOB Storage\",\ndiff --git a/src/System Application/Test/Word Templates/src/WordTemplatesTest.Codeunit.al b/src/System Application/Test/Word Templates/src/WordTemplatesTest.Codeunit.al\nindex c316fe4391..a80375e467 100644\n--- a/src/System Application/Test/Word Templates/src/WordTemplatesTest.Codeunit.al\n+++ b/src/System Application/Test/Word Templates/src/WordTemplatesTest.Codeunit.al\n@@ -23,6 +23,101 @@ codeunit 130443 \"Word Templates Test\"\n PermissionsMock: Codeunit \"Permissions Mock\";\n Assert: Codeunit \"Library Assert\";\n \n+ [Test]\n+ [TransactionModel(TransactionModel::AutoRollback)]\n+ procedure AddUnrelatedTableCreatesRecord()\n+ var\n+ WordTemplatesRelatedTable: Record \"Word Templates Related Table\";\n+ Any: Codeunit Any;\n+ WordTemplate: Codeunit \"Word Template\";\n+ PrefixCode: Code[5];\n+ TemplateCode: Code[30];\n+ RelatedTableSystemId: Guid;\n+ begin\n+ // [SCENARIO 3105] Calling AddUnrelatedTable creates a related table record correctly\n+\n+ // [GIVEN] A Word Template Code\n+ TemplateCode := CopyStr(Any.AlphabeticText(10), 1, MaxStrLen(TemplateCode));\n+\n+ // [GIVEN] A prefix code for the unrelated table\n+ PrefixCode := CopyStr(Any.AlphabeticText(5), 1, MaxStrLen(PrefixCode));\n+\n+ // [GIVEN] A SystemId for the unrelated table record\n+ RelatedTableSystemId := CreateGuid();\n+\n+ // [WHEN] AddUnrelatedTable is called for a specific table and record\n+ WordTemplate.AddUnrelatedTable(TemplateCode, PrefixCode, Database::\"Word Templates Table\", RelatedTableSystemId);\n+\n+ // [THEN] The related table record is created\n+ WordTemplatesRelatedTable.Get(TemplateCode, Database::\"Word Templates Table\");\n+\n+ // [THEN] The values match the provided parameters\n+ Assert.AreEqual(PrefixCode, WordTemplatesRelatedTable.\"Related Table Code\", WordTemplatesRelatedTable.FieldName(\"Related Table Code\"));\n+ Assert.AreEqual(RelatedTableSystemId, WordTemplatesRelatedTable.\"Source Record ID\", WordTemplatesRelatedTable.FieldName(\"Source Record ID\"));\n+ end;\n+\n+ [Test]\n+ [TransactionModel(TransactionModel::AutoRollback)]\n+ procedure AddUnrelatedTableReturnsTrueIfCreated()\n+ var\n+ WordTemplatesRelatedTable: Record \"Word Templates Related Table\";\n+ Any: Codeunit Any;\n+ WordTemplate: Codeunit \"Word Template\";\n+ Result: Boolean;\n+ PrefixCode: Code[5];\n+ TemplateCode: Code[30];\n+ begin\n+ // [SCENARIO 3105] Calling AddUnrelatedTable returns true if the record is created\n+\n+ // [GIVEN] No related table records exist\n+ if not WordTemplatesRelatedTable.IsEmpty() then\n+ WordTemplatesRelatedTable.DeleteAll(false);\n+\n+ // [WHEN] AddUnrelatedTable is called with arbitrary table and record id\n+ TemplateCode := CopyStr(Any.AlphabeticText(10), 1, MaxStrLen(TemplateCode));\n+ PrefixCode := CopyStr(Any.AlphabeticText(5), 1, MaxStrLen(PrefixCode));\n+ Result := WordTemplate.AddUnrelatedTable(TemplateCode, PrefixCode, Any.IntegerInRange(1, 100), CreateGuid());\n+\n+ // [THEN] The method result is true\n+ Assert.IsTrue(Result, 'Unexpected method return value.');\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ [TransactionModel(TransactionModel::AutoRollback)]\n+ procedure AddUnrelatedTableReturnsFalseIfNotCreated()\n+ var\n+ Any: Codeunit Any;\n+ WordTemplate: Codeunit \"Word Template\";\n+ Result: Boolean;\n+ PrefixCode: Code[5];\n+ TemplateCode: Code[30];\n+ RelatedTableSystemId: Guid;\n+ begin\n+ // [SCENARIO 3105] Calling AddUnrelatedTable returns false if related table already exists\n+\n+ // [GIVEN] A Word Template Code\n+ TemplateCode := CopyStr(Any.AlphabeticText(10), 1, MaxStrLen(TemplateCode));\n+\n+ // [GIVEN] A prefix code for the unrelated table\n+ PrefixCode := CopyStr(Any.AlphabeticText(5), 1, MaxStrLen(PrefixCode));\n+\n+ // [GIVEN] A SystemId for the unrelated table record\n+ RelatedTableSystemId := CreateGuid();\n+\n+ // [GIVEN] The related table already exists\n+ WordTemplate.AddUnrelatedTable(TemplateCode, PrefixCode, Database::\"Word Templates Table\", RelatedTableSystemId);\n+\n+ // [WHEN] AddUnrelatedTable is called for the same table and record\n+ Result := WordTemplate.AddUnrelatedTable(TemplateCode, PrefixCode, Database::\"Word Templates Table\", RelatedTableSystemId);\n+\n+ // [THEN] The user is informed that the (un)related table already exists\n+ // Verified by MessageHandler\n+\n+ // [THEN] The method result is false\n+ Assert.IsFalse(Result, 'Unexpected method return value.');\n+ end;\n+\n [Test]\n procedure TestCreateDocument()\n var\n@@ -253,4 +348,9 @@ codeunit 130443 \"Word Templates Test\"\n begin\n Reply := false;\n end;\n+\n+ [MessageHandler]\n+ procedure MessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n\\ No newline at end of file\n", "patch": "diff --git a/src/System Application/App/Word Templates/src/WordTemplate.Codeunit.al b/src/System Application/App/Word Templates/src/WordTemplate.Codeunit.al\nindex 363eb0728f..83123ab770 100644\n--- a/src/System Application/App/Word Templates/src/WordTemplate.Codeunit.al\n+++ b/src/System Application/App/Word Templates/src/WordTemplate.Codeunit.al\n@@ -297,16 +297,16 @@ codeunit 9987 \"Word Template\"\n end;\n \n /// \n- /// Add unrelated table.\n+ /// Adds an unrelated table entry for the specified .\n /// \n /// The code of an existing parent Word template.\n /// The code of the unrelated table to add.\n /// The ID of the unrelated table to add.\n /// The system id of the record to add.\n- /// True if the unrelated table was added, false otherwise.\n+ /// True if the unrelated table was added; otherwise, false.\n procedure AddUnrelatedTable(WordTemplateCode: Code[30]; PrefixCode: Code[5]; UnrelatedTableId: Integer; RecordSystemId: Guid): Boolean\n begin\n- WordTemplateImpl.AddUnrelatedTable(WordTemplateCode, PrefixCode, UnrelatedTableId, RecordSystemId);\n+ exit(WordTemplateImpl.AddUnrelatedTable(WordTemplateCode, PrefixCode, UnrelatedTableId, RecordSystemId));\n end;\n \n /// \ndiff --git a/src/System Application/App/Word Templates/src/WordTemplateImpl.Codeunit.al b/src/System Application/App/Word Templates/src/WordTemplateImpl.Codeunit.al\nindex 57409281b6..9c02ce2d37 100644\n--- a/src/System Application/App/Word Templates/src/WordTemplateImpl.Codeunit.al\n+++ b/src/System Application/App/Word Templates/src/WordTemplateImpl.Codeunit.al\n@@ -912,7 +912,9 @@ codeunit 9988 \"Word Template Impl.\"\n WordTemplatesRelatedTable.SetRange(\"Related Table Code\", TableCode);\n \n if not WordTemplatesRelatedTable.IsEmpty() then begin\n- Message(RelatedTableCodeAlreadyUsedMsg);\n+ if GuiAllowed() then\n+ Message(RelatedTableCodeAlreadyUsedMsg);\n+\n exit(false);\n end;\n \n@@ -921,9 +923,12 @@ codeunit 9988 \"Word Template Impl.\"\n WordTemplatesRelatedTable.SetRange(\"Related Table ID\", TableId);\n \n if not WordTemplatesRelatedTable.IsEmpty() then begin\n- Message(RelatedTableIdAlreadyUsedMsg);\n+ if GuiAllowed() then\n+ Message(RelatedTableIdAlreadyUsedMsg);\n+\n exit(false);\n end;\n+\n exit(true);\n end;\n \n@@ -937,6 +942,7 @@ codeunit 9988 \"Word Template Impl.\"\n exit(false);\n \n WordTemplatesRelatedTable.Init();\n+ WordTemplatesRelatedTable.Code := WordTemplateCode;\n WordTemplatesRelatedTable.\"Source Record ID\" := RecordSystemId;\n WordTemplatesRelatedTable.\"Related Table ID\" := UnrelatedTableId;\n WordTemplatesRelatedTable.\"Related Table Code\" := PrefixCode;\n"} diff --git a/dataset/problemstatement/microsoft__BCApps-3135/README.md b/dataset/problemstatement/microsoft__BCApps-3135/README.md new file mode 100644 index 000000000..9fac04b3b --- /dev/null +++ b/dataset/problemstatement/microsoft__BCApps-3135/README.md @@ -0,0 +1,19 @@ +# [Word Template] Fix unexpected behavior of AddUnrelatedTable + + +#### Summary +This change addresses two issues that were present in the AddUnrelatedTable method. + 1. The result of the implementation method call is returned so that callers know if the record was successfully added. + 2. The "Word Templates Related Table" record that is created has the word template code assigned to it that was provided by the caller. + +#### Work Item(s) +Fixes #3105 + + +Fixes [AB#567861](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/567861) + + + +