diff --git a/dataset/bcbench.jsonl b/dataset/bcbench.jsonl
index 54796b9fb..c568b9299 100644
--- a/dataset/bcbench.jsonl
+++ b/dataset/bcbench.jsonl
@@ -99,3 +99,7 @@
{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-178045", "base_commit": "22d8978231eb8792d03f150d61431d485d3c92a9", "created_at": "2024-03-11", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137404, "functionName": ["ConsumptionIsPostedForMultipleILEsOfSameLotNo"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\nindex 9467380d9f9b..e1036e0420d9 100644\n--- a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n@@ -47,6 +47,7 @@ codeunit 137404 \"SCM Manufacturing\"\n Capacity2: Decimal;\n GLB_ItemTrackingQty: Integer;\n GLB_SerialNo: Code[50];\n+ ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Select Entries\",\"Update Quantity\",\"Manual Lot No.\"; \n DocumentNoDoesNotExistErr: Label 'Document No. %1 does not exist.', Comment = '%1: Document number (Code)';\n ExpectedQuantityErr: Label 'Quantity must be %1.', Comment = '%1: Quantity (decimal value)';\n ModifyRtngErr: Label 'You cannot modify Routing No. %1 because there is at least one %2 associated with it.';\n@@ -80,6 +81,7 @@ codeunit 137404 \"SCM Manufacturing\"\n DidntExpectWhsePickMsg: Label 'Did not expect a Warehouse Pick Request associated with the Production Order Component Line, since the line doesn''t have a postitive remaining quantity';\n ProdOrderNoHandlerErr: Label 'Prod. Order No. must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order No. Value; %2: Actual Prod. Order No. Value.';\n ProdOrderStatusHandlerErr: Label 'Prod. Order Status must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order Status Value; %2: Actual Prod. Order Status Value.';\n+ ItemLedgerEntryMustBeFoundErr: Label 'Item Ledger Entry must be found.';\n \n [Test]\n [HandlerFunctions('ConfirmHandlerTrue,OutputJournalItemtrackingPageHandler,MessageHandler')]\n@@ -4149,6 +4151,104 @@ codeunit 137404 \"SCM Manufacturing\"\n LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ItemTrackingAssignLotNoPageHandler,ProductionJournalPageHandlerOnlyConsumption,ConfirmHandlerTrue,MessageHandler')]\n+ procedure ConsumptionIsPostedForMultipleILEsOfSameLotNo()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ LotNo: Code[10];\n+ Quantity: Decimal;\n+ ReleasedProdOrder: TestPage \"Released Production Order\";\n+ begin\n+ // [SCENARIO 501830] Consumption is posted against multiple Item Ledger Entries of same Lot No. when you post Production Journal from a Released Production Order.\n+ Initialize();\n+\n+ // [GIVEN] Create Item Tracking Code.\n+ LibraryItemTracking.CreateItemTrackingCode(ItemTrackingCode, false, true);\n+\n+ // [GIVEN] Create Unit of Measure.\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+\n+ // [GIVEN] Create Component Item with Unit of Measure.\n+ CreateItemWithUOM(CompItem, UnitOfMeasure, ItemUnitOfMeasure);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(Reserve, CompItem.Reserve::Always);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::Manual);\n+ CompItem.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create Location with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Create Production Item with Unit of Measure.\n+ CreateItemWithUOM(ProdItem, UnitOfMeasure, ItemUnitOfMeasure);\n+\n+ // [GIVEN] Generate and save Lot No. and Quantity in two different Variable.\n+ LotNo := Format(LibraryRandom.RandText(4));\n+ Quantity := LibraryRandom.RandIntInRange(35, 35);\n+\n+ // [GIVEN] Create and Post three Item Journal Lines with same Lot No.\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(5, 5), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(10, 10), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(20, 20), LotNo, '', Location.Code, true);\n+\n+ // [GIVEN] Create a production BOM for the Production Item.\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ItemUnitOfMeasure.Code);\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader,\n+ ProductionBOMLine,\n+ '',\n+ ProductionBOMLine.Type::Item,\n+ CompItem.\"No.\",\n+ LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate Unit of Measure in Production BOM.\n+ ProductionBOMLine.Validate(\"Unit of Measure Code\", ItemUnitOfMeasure.Code);\n+ ProductionBOMLine.Modify(true);\n+\n+ // [GIVEN] Change Status of Production BOM.\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+\n+ // [GIVEN] Validate Replenishment System and Production BOM No. in Production Item.\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProdOrder(\n+ ProductionOrder,\n+ ProductionOrder.Status::Released,\n+ ProdItem.\"No.\",\n+ Quantity,\n+ Location.Code,\n+ '');\n+\n+ // [GIVEN] Open Released Production Order page and run Production Journal action.\n+ ReleasedProdOrder.OpenEdit();\n+ ReleasedProdOrder.GoToRecord(ProductionOrder);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ReleasedProdOrder.ProdOrderLines.ProductionJournal.Invoke();\n+\n+ // [WHEN] Find Item Ledger Entry.\n+ ItemLedgerEntry.SetRange(\"Item No.\", CompItem.\"No.\");\n+ ItemLedgerEntry.SetRange(Quantity, -Quantity);\n+\n+ // [VERIFY] Item Ledger Entry is found.\n+ Assert.IsFalse(ItemLedgerEntry.IsEmpty(), ItemLedgerEntryMustBeFoundErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6772,6 +6872,39 @@ codeunit 137404 \"SCM Manufacturing\"\n ReservationPage.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ItemTrackingAssignLotNoPageHandler(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n+ var\n+ DequeueVariable: Variant;\n+ begin\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingMode := DequeueVariable;\n+ case ItemTrackingMode of\n+ ItemTrackingMode::\"Assign Lot No.\":\n+ begin\n+ ItemTrackingLines.\"Lot No.\".SetValue(LibraryVariableStorage.DequeueText());\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingLines.\"Quantity (Base)\".SetValue(DequeueVariable);\n+ end;\n+ end;\n+ ItemTrackingLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandlerOnlyConsumption(var ProductionJournal: TestPage \"Production Journal\")\n+ var\n+ EntryType: Enum \"Item Ledger Entry Type\";\n+ begin\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Output), '');\n+ ProductionJournal.\"Output Quantity\".SetValue(0);\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Consumption), '');\n+ ProductionJournal.Quantity.SetValue(LibraryVariableStorage.DequeueDecimal());\n+ ProductionJournal.ItemTrackingLines.Invoke();\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n procedure BOMStructurePageHandler(var BOMStructure: TestPage \"BOM Structure\")\n begin\n@@ -6840,5 +6973,74 @@ codeunit 137404 \"SCM Manufacturing\"\n DT2Time(ExpStartDateTime), DT2Time(ProdOrderLine.\"Starting Date-Time\"), StrSubstNo(WrongDateTimeErr, ProdOrderLine.FieldCaption(\"Starting Time\")));\n until ProdOrderLine.Next() = 0;\n end;\n+\n+ local procedure CreateItemWithUOM(\n+ var Item: Record Item;\n+ var UnitOfMeasure: Record \"Unit of Measure\";\n+ var ItemUnitOfMeasure: Record \"Item Unit of Measure\")\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+\n+ LibraryInventory.CreateItemUnitOfMeasure(\n+ ItemUnitOfMeasure,\n+ Item.\"No.\",\n+ UnitOfMeasure.Code,\n+ LibraryRandom.RandInt(0));\n+\n+ Item.Validate(\"Base Unit of Measure\", UnitOfMeasure.Code);\n+ Item.Modify(true);\n+ end;\n+\n+ local procedure CreateAndPostItemJournalLineWithLotNo(\n+ ItemNo: Code[20];\n+ Quantity: Decimal;\n+ LotNo: Code[50];\n+ BinCode: Code[20];\n+ LocationCode: Code[10];\n+ Tracking: Boolean)\n+ var\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ CreateItemJournalLine(ItemJournalLine, ItemNo, Quantity, BinCode, LocationCode);\n+ if Tracking then begin\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ItemJournalLine.OpenItemTrackingLines(false);\n+ end;\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+ end;\n+\n+ local procedure CreateItemJournalLine(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; Quantity: Decimal; BinCode: Code[20]; LocationCode: Code[10])\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ begin\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ LibraryInventory.CreateItemJournalTemplate(ItemJournalTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine,\n+ ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\",\n+ ItemNo,\n+ Quantity);\n+\n+ ItemJournalLine.Validate(\"Unit Cost\", LibraryRandom.RandDec(10, 2));\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure CreateAndRefreshProdOrder(var ProductionOrder: Record \"Production Order\"; Status: Enum \"Production Order Status\"; SourceNo: Code[20]; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20])\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, Status, ProductionOrder.\"Source Type\"::Item, SourceNo, Quantity);\n+ ProductionOrder.Validate(\"Location Code\", LocationCode);\n+ ProductionOrder.Validate(\"Bin Code\", BinCode);\n+ ProductionOrder.Modify(true);\n+\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\nindex 7e739c297201..ffe0b880ce8d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n@@ -1946,8 +1946,11 @@ codeunit 22 \"Item Jnl.-Post Line\"\n Abs(ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\")\n then\n AppliedQty := ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\"\n- else\n+ else begin\n AppliedQty := -(OldItemLedgEntry.\"Remaining Quantity\" - OldItemLedgEntry.\"Reserved Quantity\");\n+ if AppliedQty = 0 then\n+ AppliedQty := UpdateAppliedQtyIfConsumptionEntry(ItemLedgEntry, OldItemLedgEntry);\n+ end;\n \n OnApplyItemLedgEntryOnAfterCalcAppliedQty(OldItemLedgEntry, ItemLedgEntry, AppliedQty);\n \n@@ -5908,6 +5911,17 @@ codeunit 22 \"Item Jnl.-Post Line\"\n (ItemJournalLine.\"Applies-to Entry\" <> 0)));\n end;\n \n+ local procedure UpdateAppliedQtyIfConsumptionEntry(ItemLedgerEntry: Record \"Item Ledger Entry\"; OldItemLedgerEntry: Record \"Item Ledger Entry\"): Decimal\n+ begin\n+ if ItemLedgerEntry.\"Entry Type\" <> ItemLedgerEntry.\"Entry Type\"::Consumption then\n+ exit(0);\n+\n+ if (ItemLedgerEntry.\"Remaining Quantity\" + OldItemLedgerEntry.\"Remaining Quantity\") > 0 then\n+ exit(0);\n+\n+ exit(-Abs(OldItemLedgerEntry.\"Reserved Quantity\"));\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnBeforeAllowProdApplication(OldItemLedgerEntry: Record \"Item Ledger Entry\"; ItemLedgerEntry: Record \"Item Ledger Entry\"; var AllowApplication: Boolean)\n begin\n"}
{"metadata": {"area": "inventory", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176082", "base_commit": "cb30d50fe1ed2c716c6349370fdc31c6bd0ce956", "created_at": "2024-02-23", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex e0b3ba5f0bf7..ffa98cfbb351 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -48,6 +48,7 @@\n UndoneTransLineQtyErr: Label 'Expected Quantity to be 0 after Transfer Shipment was undone';\n DerivedTransLineErr: Label 'Expected no Derived Transfer Line i.e. line with \"Derived From Line No.\" equal to original transfer line.';\n IncorrectSNUndoneErr: Label 'The Serial No. of the item on the transfer shipment line that was undone was different from the SN on the corresponding transfer line.';\n+ ApplToItemEntryErr: Label '%1 must be %2 in %3.', Comment = '%1 is Appl-to Item Entry, %2 is Item Ledger Entry No. and %3 is Transfer Line';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -3655,6 +3656,99 @@\n ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", NewCost);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('PostedPurchaseReceiptsModalPageHandler,PostedPurchRcptLinesModalPageHandler')]\n+ procedure GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines()\n+ var\n+ Item: Record Item;\n+ Vendor: Record Vendor;\n+ Location: Record Location;\n+ Location2: Record Location;\n+ Location3: Record Location;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseHeader2: Record \"Purchase Header\";\n+ PurchaseHeader3: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ PurchaseLine2: Record \"Purchase Line\";\n+ PurchaseLine3: Record \"Purchase Line\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ ItemLedgerEntryNo: Integer;\n+ PurchaseReceiptNo: Code[20];\n+ TransferOrder: TestPage \"Transfer Order\";\n+ begin\n+ // [SCENARIO 500597] Get Receipt Lines action on Transfer Order shows list of Posted Purchase Receipts having Transfer-from Code in Location Code of Purch Rcpt Lines and after selecting it populates Appl-to Item Entry field in Transfer Lines.\n+ Initialize();\n+\n+ // [GIVEN] Create an Item and Validate Costing Method.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Costing Method\", Item.\"Costing Method\"::FIFO);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Create two Locations with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location2);\n+\n+ // [GIVEN] Create another Location with Inventory Posting Setup \n+ // And Validate Use As In-Transit.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location3);\n+ Location3.Validate(\"Use As In-Transit\", true);\n+ Location3.Modify(true);\n+\n+ // [GIVEN] Create a Vendor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Create and Post Purchase Receipt with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader, PurchaseLine, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 2 with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader2, PurchaseLine2, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 3 with Location Code on Line.\n+ PurchaseReceiptNo := CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ PurchaseHeader3,\n+ PurchaseLine3,\n+ Vendor,\n+ Item,\n+ Location);\n+\n+ // [GIVEN] Find and save Item Ledger Entry No. in a Variable.\n+ ItemLedgerEntry.SetRange(\"Document No.\", PurchaseReceiptNo);\n+ ItemLedgerEntry.FindFirst();\n+ ItemLedgerEntryNo := ItemLedgerEntry.\"Entry No.\";\n+\n+ // [GIVEN] Find Purch. Rcpt Line.\n+ FindRandomReceiptLine(PurchaseReceiptNo, PurchRcptLine);\n+\n+ // [GIVEN] Create Transfer Header.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, Location.Code, Location2.Code, Location3.Code);\n+\n+ // [GIVEN] Open Transfer Order page and run Get Receipt Line action.\n+ TransferOrder.OpenEdit();\n+ TransferOrder.GoToRecord(TransferHeader);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchRcptLine.\"No.\");\n+ TransferOrder.GetReceiptLines.Invoke();\n+\n+ // [WHEN] Find Transfer Line.\n+ TransferLine.SetRange(\"Document No.\", TransferHeader.\"No.\");\n+ TransferLine.FindFirst();\n+\n+ // [VERIFY] Appl-to Item Entry and Item Ledger Entry No. are same.\n+ Assert.AreEqual(\n+ ItemLedgerEntryNo,\n+ TransferLine.\"Appl.-to Item Entry\",\n+ StrSubstNo(\n+ ApplToItemEntryErr,\n+ TransferLine.FieldCaption(\"Appl.-to Item Entry\"),\n+ ItemLedgerEntryNo,\n+ TransferLine.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5168,6 +5262,52 @@\n Assert.AreEqual(LineCount, TransferReceiptLine.Count(), '');\n end;\n \n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchHeader(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location)\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ PurchaseHeader.Validate(\"Location Code\", Location.Code);\n+ PurchaseHeader.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+ end;\n+\n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location): Code[20]\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Location Code\", Location.Code);\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ exit(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false));\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n@@ -5394,5 +5534,19 @@\n // 0 = Item.Type::Inventory\n Assert.AreEqual('0', ItemList.Filter.GetFilter(\"Type\"), 'Item List contains non-inventory items.');\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedPurchRcptLinesModalPageHandler(var PostedPurchaseReceiptLines: Page \"Posted Purchase Receipt Lines\"; var Response: Action)\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ begin\n+ PurchRcptLine.SetRange(\"Document No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.SetRange(\"No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.FindFirst();\n+ PostedPurchaseReceiptLines.SetRecord(PurchRcptLine);\n+\n+ Response := ACTION::LookupOK;\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\nindex 5fe44b4568d1..c16ab8669925 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n@@ -1304,7 +1304,7 @@ table 5740 \"Transfer Header\"\n TempPurchRcptHeader: Record \"Purch. Rcpt. Header\" temporary;\n PostedPurchaseReceipts: Page \"Posted Purchase Receipts\";\n begin\n- PurchRcptHeader.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ FindPurchRcptHeader(PurchRcptHeader);\n PostedPurchaseReceipts.SetTableView(PurchRcptHeader);\n PostedPurchaseReceipts.LookupMode := true;\n if PostedPurchaseReceipts.RunModal() = ACTION::LookupOK then begin\n@@ -1376,6 +1376,8 @@ table 5740 \"Transfer Header\"\n PurchRcptLine.FilterPstdDocLnItemLedgEntries(ItemLedgerEntry);\n ItemTrackingDocMgt.CopyItemLedgerEntriesToTemp(TempItemLedgerEntry, ItemLedgerEntry);\n ItemTrackingMgt.CopyItemLedgEntryTrkgToTransferLine(TempItemLedgerEntry, TransferLine);\n+ TransferLine.\"Appl.-to Item Entry\" := ItemLedgerEntry.\"Entry No.\";\n+ TransferLine.Modify(true);\n \n OnAfterAddTransferLineFromReceiptLine(TransferLine, PurchRcptLine, TempItemLedgerEntry, Rec);\n end;\n@@ -1546,6 +1548,31 @@ table 5740 \"Transfer Header\"\n end;\n end;\n \n+ local procedure FindPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\")\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ DocumentNo: Code[20];\n+ begin\n+ PurchRcptLine.SetLoadFields(\"Document No.\", \"Location Code\");\n+ PurchRcptLine.SetCurrentKey(\"Document No.\");\n+ PurchRcptLine.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ if PurchRcptLine.FindSet() then\n+ repeat\n+ GetPurchRcptHeader(PurchRcptHeader, PurchRcptLine, DocumentNo);\n+ until PurchRcptLine.Next() = 0;\n+ PurchRcptHeader.MarkedOnly(true);\n+ end;\n+\n+ local procedure GetPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var DocumentNo: Code[20])\n+ begin\n+ if PurchRcptLine.\"Document No.\" = DocumentNo then\n+ exit;\n+\n+ PurchRcptHeader.Get(PurchRcptLine.\"Document No.\");\n+ PurchRcptHeader.Mark(true);\n+ DocumentNo := PurchRcptLine.\"Document No.\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAddTransferLineFromReceiptLineOnBeforeTransferLineInsert(var TransferLine: Record \"Transfer Line\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var TransferHeader: Record \"Transfer Header\")\n begin\n"}
{"metadata": {"area": "crm", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-174087", "base_commit": "74a0b7c175da3f9a272745bd34453a4712b73e7b", "created_at": "2024-02-02", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136208, "functionName": ["PopulateEvaluationFieldInInteractionLogEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\nindex 4c4c73700d2a..59fff6e2be93 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n@@ -45,6 +45,7 @@ codeunit 136208 \"Marketing Interaction\"\n LoggedSegemntEntriesCreateMsg: Label 'Logged Segment entry was created';\n AttachmentFileShouldNotBeBlankErr: Label 'Attachment File should not be blank.';\n TxtFileExt: Label 'txt';\n+ EvaluationErr: Label '%1 must be %2 in %3', Comment = '%1 = Evaluation, %2 = Positive, %3 = Interaction Log Entry';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2998,6 +2999,50 @@ codeunit 136208 \"Marketing Interaction\"\n VerifyAttachmentFileIsNotBlankOnInteractionLogEntry(Contact.\"No.\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('CreateInteractionFromContactPageHandler')]\n+ procedure PopulateEvaluationFieldInInteractionLogEntry()\n+ var\n+ Contact: Record Contact;\n+ InteractionTemplate: Record \"Interaction Template\";\n+ InteractionLogEntry: Record \"Interaction Log Entry\";\n+ ContactCard: TestPage \"Contact Card\";\n+ InteractionEvaluation: Enum \"Interaction Evaluation\";\n+ begin\n+ // [SCENARIO 498395] When stan creates an Interaction using Create Interaction action from Contact, Evaluation field should be populated in Interaction Log Entry.\n+ Initialize();\n+\n+ // [GIVEN] Create a Contact.\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+\n+ // [GIVEN] Create an Interaction Template and Validate Information Flow.\n+ LibraryMarketing.CreateInteractionTemplate(InteractionTemplate);\n+ InteractionTemplate.Validate(\"Information Flow\", InteractionTemplate.\"Information Flow\"::Outbound);\n+ InteractionTemplate.Modify(true);\n+\n+ // [GIVEN] Open Contact Card and Create Interaction.\n+ ContactCard.OpenEdit();\n+ ContactCard.GoToRecord(Contact);\n+ LibraryVariableStorage.Enqueue(InteractionTemplate.Code);\n+ LibraryVariableStorage.Enqueue(Format(InteractionEvaluation::Positive));\n+ ContactCard.\"Create &Interaction\".Invoke();\n+\n+ // [WHEN] Find Interaction Log Entry.\n+ InteractionLogEntry.SetRange(\"Contact No.\", Contact.\"No.\");\n+ InteractionLogEntry.FindFirst();\n+\n+ // [VERIFY] Interaction Log Entry has Evaluation field populated as Positive.\n+ Assert.AreEqual(\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.Evaluation,\n+ StrSubstNo(\n+ EvaluationErr,\n+ InteractionLogEntry.FieldCaption(Evaluation),\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibrarySales: Codeunit \"Library - Sales\";\n@@ -4309,5 +4354,16 @@ CopyStr(StorageLocation, 1, MaxStrLen(MarketingSetup.\"Attachment Storage Locatio\n CreateInteraction.NextInteraction.Invoke();\n CreateInteraction.Finish.Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure CreateInteractionFromContactPageHandler(var CreateInteraction: TestPage \"Create Interaction\")\n+ begin\n+ CreateInteraction.\"Interaction Template Code\".SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.Evaluation.SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.FinishInteraction.Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\nindex ff43f4ff6a7b..05a21a6196bf 100644\n--- a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n+++ b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n@@ -694,6 +694,7 @@ page 5077 \"Create Interaction\"\n end;\n Step::\"Step 4\":\n begin\n+ InteractionLogEntry.CopyFromSegment(Rec);\n InteractionLogEntry.Modify();\n CurrPage.Close();\n end;\n"}
+{"metadata": {"area": "peppol", "image_count": 1}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-8059", "base_commit": "396e3bb12d0593738c9368371d6273a6d41c6826", "created_at": "2026-05-08T09:31:42Z", "environment_setup_version": "28.1", "project_paths": ["src\\Apps\\W1\\PEPPOL\\App", "src\\Apps\\W1\\PEPPOL\\Test"], "patch": "diff --git a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al\nindex 30f5f792bd..c7981a46fa 100644\n--- a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al\n+++ b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al\n@@ -798,6 +798,8 @@ codeunit 37201 \"PEPPOL30 Impl.\"\n InvoiceLineNote := DelChr(Format(SalesLine.Type), '<>');\n InvoicedQuantity := Format(SalesLine.Quantity, 0, 9);\n SalesLineLineAmount := SalesLine.\"Line Amount\";\n+ if SalesHeader.\"Prices Including VAT\" and (SalesLine.\"VAT %\" <> 0) then\n+ SalesLineLineAmount := Round(SalesLineLineAmount / (1 + SalesLine.\"VAT %\" / 100), 0.01);\n InvoiceLineExtensionAmount := Format(SalesLineLineAmount, 0, 9);\n LineExtensionAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader);\n InvoiceLineAccountingCost := '';\n@@ -869,7 +871,10 @@ codeunit 37201 \"PEPPOL30 Impl.\"\n \n InvLnAllowanceChargeIndicator := 'false';\n InvLnAllowanceChargeReason := LineDisAmtTxt;\n- InvLnAllowanceChargeAmount := Format(SalesLine.\"Line Discount Amount\", 0, 9);\n+ if SalesHeader.\"Prices Including VAT\" and (SalesLine.\"VAT %\" <> 0) then\n+ InvLnAllowanceChargeAmount := Format(Round(SalesLine.\"Line Discount Amount\" / (1 + SalesLine.\"VAT %\" / 100), 0.01), 0, 9)\n+ else\n+ InvLnAllowanceChargeAmount := Format(SalesLine.\"Line Discount Amount\", 0, 9);\n InvLnAllowanceChargeAmtCurrID := GetSalesDocCurrencyCode(SalesHeader);\n end;\n \n", "FAIL_TO_PASS": [{"codeunitID": 139235, "functionName": ["LineAmountsConsistentWhenPricesInclVATNoDiscount"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al b/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al\nindex 36931d56ed..cd237011d5 100644\n--- a/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al\n+++ b/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al\n@@ -3349,6 +3349,68 @@ codeunit 139235 \"PEPPOL30 Management Tests\"\n Assert.AreEqual('', CustTaxSchemeID, 'Tax Scheme ID should be empty for Tax Category O.');\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure LineAmountsConsistentWhenPricesInclVATNoDiscount()\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ SalesInvoiceLine: Record \"Sales Invoice Line\";\n+ PEPPOLLineInfoProvider: Interface \"PEPPOL Line Info Provider\";\n+ InvoiceLineID: Text;\n+ InvoiceLineNote: Text;\n+ InvoicedQuantity: Text;\n+ InvoiceLineExtensionAmount: Text;\n+ LineExtensionAmountCurrencyID: Text;\n+ InvoiceLineAccountingCost: Text;\n+ InvoiceLinePriceAmount: Text;\n+ InvLinePriceAmountCurrencyID: Text;\n+ BaseQuantity: Text;\n+ UnitCode: Text;\n+ PriceAmount: Decimal;\n+ LineExtensionAmt: Decimal;\n+ SalesInvoiceNo: Code[20];\n+ begin\n+ // [FEATURE] [AI test 0.4]\n+ // [SCENARIO 630795] PEPPOL LineExtensionAmount equals PriceAmount times Quantity when Prices Including VAT is used\n+ Initialize();\n+\n+ // [GIVEN] Customer \"C\" with PEPPOL identifier\n+ LibrarySales.CreateCustomer(Customer);\n+ AddCustPEPPOLIdentifier(Customer.\"No.\");\n+\n+ // [GIVEN] Sales Invoice for \"C\" with \"Prices Including VAT\" = TRUE and Quantity = 7\n+ CreateItemWithPrice(Item, 139);\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+ SalesHeader.Validate(\"Prices Including VAT\", true);\n+ SalesHeader.Modify(true);\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", 7);\n+\n+ // [WHEN] Post the Sales Invoice and retrieve PEPPOL line amounts\n+ SalesInvoiceNo := LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+ SalesInvoiceHeader.Get(SalesInvoiceNo);\n+ SalesHeader.TransferFields(SalesInvoiceHeader);\n+ FindSalesInvoiceLine(SalesInvoiceLine, SalesInvoiceNo);\n+ SalesLine.TransferFields(SalesInvoiceLine);\n+\n+ PEPPOLLineInfoProvider := GetFormat();\n+ PEPPOLLineInfoProvider.GetLineGeneralInfo(\n+ SalesLine, SalesHeader, InvoiceLineID, InvoiceLineNote, InvoicedQuantity,\n+ InvoiceLineExtensionAmount, LineExtensionAmountCurrencyID, InvoiceLineAccountingCost);\n+ PEPPOLLineInfoProvider.GetLinePriceInfo(\n+ SalesLine, SalesHeader, InvoiceLinePriceAmount, InvLinePriceAmountCurrencyID,\n+ BaseQuantity, UnitCode);\n+\n+ // [THEN] LineExtensionAmount equals PriceAmount times Quantity per PEPPOL BIS 3.0\n+ Evaluate(PriceAmount, InvoiceLinePriceAmount, 9);\n+ Evaluate(LineExtensionAmt, InvoiceLineExtensionAmount, 9);\n+ Assert.AreEqual(PriceAmount * SalesInvoiceLine.Quantity, LineExtensionAmt,\n+ 'LineExtensionAmount must equal PriceAmount * Quantity per PEPPOL BIS 3.0');\n+ end;\n+\n var\n local procedure Initialize()\n var\n@@ -3993,6 +4055,8 @@ codeunit 139235 \"PEPPOL30 Management Tests\"\n Assert.AreEqual(UnitOfMeasure.\"International Standard Code\", unitCode, '');\n Assert.AreEqual('UNECERec20', unitCodeListID, '');\n SalesInvoiceLineLineAmount := SalesInvoiceLine.\"Line Amount\";\n+ if SalesHeader.\"Prices Including VAT\" and (SalesLine.\"VAT %\" <> 0) then\n+ SalesInvoiceLineLineAmount := Round(SalesInvoiceLineLineAmount / (1 + SalesLine.\"VAT %\" / 100), 0.01);\n Assert.AreEqual(Format(SalesInvoiceLineLineAmount, 0, 9), InvoiceLineExtensionAmount, '');\n Assert.AreEqual(SalesHeader.\"Currency Code\", LineExtensionAmountCurrencyID, '');\n Assert.AreEqual('', InvoiceLineAccountingCost, '');\n"}
+{"metadata": {"area": null, "image_count": null}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-8293", "base_commit": "01e67dc5ff263b26101f7f2db6caa1b346f090a6", "created_at": "2026-05-25T21:31:15Z", "environment_setup_version": "28.1", "project_paths": ["src\\Apps\\W1\\Subcontracting\\App", "src\\Apps\\W1\\Subcontracting\\Test"], "patch": "diff --git a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al\nindex 8d5c75124c..056de67a1c 100644\n--- a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al\n+++ b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al\n@@ -15,12 +15,13 @@ using System.Reflection;\n codeunit 99001559 \"Subc. ProdO. Factbox Mgmt.\"\n {\n /// \n- /// Opens the Released Production Order page for the production order linked to the given variant record.\n+ /// Opens the appropriate Production Order page (Released or Finished) for the production order linked to the given variant record.\n /// \n /// A record variant of a purchase or transfer document line.\n procedure ShowProductionOrder(RecRelatedVariant: Variant)\n var\n ProductionOrder: Record \"Production Order\";\n+ FinishedProductionOrder: Page \"Finished Production Order\";\n ReleasedProductionOrder: Page \"Released Production Order\";\n OperationNo: Code[10];\n ProdOrderNo: Code[20];\n@@ -29,11 +30,26 @@ codeunit 99001559 \"Subc. ProdO. Factbox Mgmt.\"\n begin\n if not SetProdOrderInformationByVariant(RecRelatedVariant, ProdOrderNo, ProdOrderLineNo, RoutingNo, OperationNo) then\n exit;\n- ProductionOrder.SetRange(Status, ProductionOrder.Status::Released);\n+ ProductionOrder.SetFilter(Status, '>=%1', ProductionOrder.Status::Released);\n ProductionOrder.SetRange(\"No.\", ProdOrderNo);\n- ReleasedProductionOrder.SetTableView(ProductionOrder);\n- ReleasedProductionOrder.Editable := false;\n- ReleasedProductionOrder.Run();\n+ if not ProductionOrder.FindFirst() then\n+ exit;\n+ case ProductionOrder.Status of\n+ ProductionOrder.Status::Released:\n+ begin\n+ ProductionOrder.SetRange(Status, ProductionOrder.Status::Released);\n+ ReleasedProductionOrder.SetTableView(ProductionOrder);\n+ ReleasedProductionOrder.Editable := false;\n+ ReleasedProductionOrder.Run();\n+ end;\n+ ProductionOrder.Status::Finished:\n+ begin\n+ ProductionOrder.SetRange(Status, ProductionOrder.Status::Finished);\n+ FinishedProductionOrder.SetTableView(ProductionOrder);\n+ FinishedProductionOrder.Editable := false;\n+ FinishedProductionOrder.Run();\n+ end;\n+ end;\n end;\n \n /// \n@@ -77,9 +93,9 @@ codeunit 99001559 \"Subc. ProdO. Factbox Mgmt.\"\n exit(ProdOrderRoutingLine.Count());\n end;\n \n-local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; RoutingNo: Code[20]; OperationNo: Code[10])\n+ local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; RoutingNo: Code[20]; OperationNo: Code[10])\n begin\n- ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released);\n+ ProdOrderRoutingLine.SetFilter(Status, '>=%1', ProdOrderRoutingLine.Status::Released);\n ProdOrderRoutingLine.SetRange(\"Prod. Order No.\", ProdOrderNo);\n ProdOrderRoutingLine.SetRange(\"Routing Reference No.\", ProdOrderLineNo);\n ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingNo);\n@@ -130,7 +146,7 @@ local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record\n ProdOrderRoutingLine: Record \"Prod. Order Routing Line\";\n begin\n ProdOrderRoutingLine.SetLoadFields(\"Routing Link Code\");\n- ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released);\n+ ProdOrderRoutingLine.SetFilter(Status, '>=%1', ProdOrderRoutingLine.Status::Released);\n ProdOrderRoutingLine.SetRange(\"Prod. Order No.\", ProdOrderNo);\n ProdOrderRoutingLine.SetRange(\"Routing Reference No.\", ProdOrderLineNo);\n ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingNo);\n@@ -138,7 +154,7 @@ local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record\n if ProdOrderRoutingLine.FindFirst() then\n ProdOrderComponent.SetRange(\"Routing Link Code\", ProdOrderRoutingLine.\"Routing Link Code\");\n \n- ProdOrderComponent.SetRange(Status, ProdOrderComponent.Status::Released);\n+ ProdOrderComponent.SetFilter(Status, '>=%1', ProdOrderComponent.Status::Released);\n ProdOrderComponent.SetRange(\"Prod. Order No.\", ProdOrderNo);\n ProdOrderComponent.SetRange(\"Prod. Order Line No.\", ProdOrderLineNo);\n end;\n", "FAIL_TO_PASS": [{"codeunitID": 139989, "functionName": ["ProdOFactboxMgmtShowsDataAfterProdOrderFinished"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\nindex 68c7fff2af..c6c56da2b8 100644\n--- a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\n+++ b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\n@@ -1875,6 +1875,57 @@ codeunit 139989 \"Subc. Subcontracting Test\"\n 'CalcNoOfProductionOrderComponents should return a positive count for an Item Ledger Entry from a subcontracting receipt.');\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmArchiveOrderHandler,HandlePurchaseOrderPage')]\n+ procedure ProdOFactboxMgmtShowsDataAfterProdOrderFinished()\n+ var\n+ Item: Record Item;\n+ ProductionOrder: Record \"Production Order\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ SubcWorkCenter: Record \"Work Center\";\n+ SubcProdOFactboxMgmt: Codeunit \"Subc. ProdO. Factbox Mgmt.\";\n+ begin\n+ // [SCENARIO 634953] Subcontracting factbox drilldowns should work after production order is finished.\n+ Initialize();\n+\n+ // [GIVEN] A released production order with a subcontracting routing operation and a subcontracting purchase order\n+ Subcontracting := true;\n+ UnitCostCalculation := UnitCostCalculation::Units;\n+\n+ CreateItemWithSingleSubcontractingOperation(Item, SubcWorkCenter);\n+ SubcontractingMgmtLibrary.UpdateVendorWithSubcontractingLocationCode(SubcWorkCenter);\n+ SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder(\n+ ProductionOrder, \"Production Order Status\"::Released, ProductionOrder.\"Source Type\"::Item, Item.\"No.\", LibraryRandom.RandInt(10) + 5);\n+ UpdateSubMgmtSetupWithReqWkshTemplate();\n+\n+ SubcontractingMgmtLibrary.CreateSubcontractingOrderFromProdOrderRtngPage(Item.\"Routing No.\", SubcWorkCenter.\"No.\");\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::Order);\n+ PurchaseLine.SetRange(\"Prod. Order No.\", ProductionOrder.\"No.\");\n+#pragma warning disable AA0210\n+ PurchaseLine.SetRange(\"Work Center No.\", SubcWorkCenter.\"No.\");\n+#pragma warning restore AA0210\n+ PurchaseLine.FindFirst();\n+ PurchaseHeader.Get(PurchaseLine.\"Document Type\", PurchaseLine.\"Document No.\");\n+ EnsureGeneralPostingSetupIsValid(PurchaseLine.\"Gen. Bus. Posting Group\", PurchaseLine.\"Gen. Prod. Posting Group\");\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+\n+ // [GIVEN] The production order is changed to Finished status\n+ LibraryManufacturing.ChangeProdOrderStatus(ProductionOrder, \"Production Order Status\"::Finished, WorkDate(), true);\n+\n+ // Re-read purchase line (the order still exists because only receipt was posted)\n+ PurchaseLine.FindFirst();\n+\n+ // [WHEN] CalcNoOfProductionOrderRoutings / CalcNoOfProductionOrderComponents are called with the Purchase Line\n+ // [THEN] Both return a positive count even though the production order is now Finished\n+ Assert.IsTrue(\n+ SubcProdOFactboxMgmt.CalcNoOfProductionOrderRoutings(PurchaseLine) > 0,\n+ 'CalcNoOfProductionOrderRoutings should return a positive count after the production order is finished.');\n+ Assert.IsTrue(\n+ SubcProdOFactboxMgmt.CalcNoOfProductionOrderComponents(PurchaseLine) > 0,\n+ 'CalcNoOfProductionOrderComponents should return a positive count after the production order is finished.');\n+ end;\n+\n [Test]\n [HandlerFunctions('ConfirmHandler')]\n procedure RoutingFactboxMgmtFiltersPurchOrderQtyByRoutingReferenceNo()\n@@ -3430,6 +3481,7 @@ codeunit 139989 \"Subc. Subcontracting Test\"\n \n SubSetupLibrary.InitSetupFields();\n LibraryERMCountryData.CreateVATData();\n+ LibraryERMCountryData.UpdateGeneralPostingSetup();\n SubSetupLibrary.InitialSetupForGenProdPostingGroup();\n \n IsInitialized := true;\n"}
+{"metadata": {"area": null, "image_count": null}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-8287", "base_commit": "ad39c988e2565d1ea1a8cb538a5b9a6ec4107eb4", "created_at": "2026-05-22T17:02:35Z", "environment_setup_version": "28.1", "project_paths": ["src\\Apps\\W1\\Quality Management\\app", "src\\Apps\\W1\\Quality Management\\test"], "patch": "diff --git a/src/Apps/W1/Quality Management/app/src/Configuration/Result/QltyResultEvaluation.Codeunit.al b/src/Apps/W1/Quality Management/app/src/Configuration/Result/QltyResultEvaluation.Codeunit.al\nindex b8a5c1d869..c1b2942c55 100644\n--- a/src/Apps/W1/Quality Management/app/src/Configuration/Result/QltyResultEvaluation.Codeunit.al\n+++ b/src/Apps/W1/Quality Management/app/src/Configuration/Result/QltyResultEvaluation.Codeunit.al\n@@ -22,6 +22,7 @@ codeunit 20410 \"Qlty. Result Evaluation\"\n IsDefaultTextTok: Label '<>''''', Locked = true;\n InvalidDataTypeErr: Label 'The value \"%1\" is not allowed for %2, it is not a %3.', Comment = '%1=the value, %2=field name,%3=field type.';\n NotInAllowableValuesErr: Label 'The value \"%1\" is not allowed for %2, it must be in the range of \"%3\".', Comment = '%1=the value, %2=field name,%3=field type.';\n+ InvalidAllowableValuesFormatErr: Label 'The allowable values \"%1\" are not a valid filter expression for %2 of type %3.', Comment = '%1=the allowable values, %2=field name, %3=field type.';\n \n trigger OnRun()\n var\n@@ -324,6 +325,110 @@ codeunit 20410 \"Qlty. Result Evaluation\"\n ValidateAllowableValuesOnText(TestNameForError, QltyTest.\"Default Value\", QltyTest.\"Allowable Values\", QltyTest.\"Test Value Type\", TempBufferQltyTestLookupValue, QltyCaseSensitivity);\n end;\n \n+ /// \n+ /// Validates that the allowable values expression is a valid filter for the given test value type.\n+ /// \n+ /// The test whose allowable values expression should be validated.\n+ internal procedure ValidateAllowableValuesFormat(var QltyTest: Record \"Qlty. Test\")\n+ var\n+ TestNameForError: Text;\n+ begin\n+ if QltyTest.Description <> '' then\n+ TestNameForError := QltyTest.Description\n+ else\n+ TestNameForError := QltyTest.Code;\n+\n+ ValidateAllowableValuesFormat(TestNameForError, QltyTest.\"Allowable Values\", QltyTest.\"Test Value Type\");\n+ end;\n+\n+ /// \n+ /// Validates that the allowable values expression is a valid filter for the given test value type.\n+ /// \n+ /// Friendly identifier used in error messages.\n+ /// The allowable values filter expression to validate.\n+ /// The test value type that the filter expression must match.\n+ local procedure ValidateAllowableValuesFormat(NumberOrNameOfTestNameForError: Text; AllowableValues: Text; QltyTestValueType: Enum \"Qlty. Test Value Type\")\n+ var\n+ IsValid: Boolean;\n+ begin\n+ if AllowableValues = '' then\n+ exit;\n+\n+ if IsBlankOrEmptyCondition(AllowableValues) then\n+ exit;\n+\n+ if IsAnythingExceptEmptyCondition(AllowableValues) then\n+ exit;\n+\n+ // Allowable values may contain inline expressions like [Field] that are resolved at evaluation time.\n+ // Defer validation until resolution.\n+ if AllowableValues.Contains('[') then\n+ exit;\n+\n+ IsValid := true;\n+ case QltyTestValueType of\n+ QltyTestValueType::\"Value Type Decimal\":\n+ IsValid := TryApplyDecimalFilter(AllowableValues);\n+ QltyTestValueType::\"Value Type Integer\":\n+ IsValid := TryApplyIntegerFilter(AllowableValues);\n+ QltyTestValueType::\"Value Type Boolean\":\n+ IsValid := TryApplyBooleanFilter(AllowableValues);\n+ QltyTestValueType::\"Value Type Date\":\n+ IsValid := TryApplyDateFilter(AllowableValues);\n+ QltyTestValueType::\"Value Type DateTime\":\n+ IsValid := TryApplyDateTimeFilter(AllowableValues);\n+ end;\n+\n+ if not IsValid then\n+ Error(InvalidAllowableValuesFormatErr, AllowableValues, NumberOrNameOfTestNameForError, QltyTestValueType);\n+ end;\n+\n+ [TryFunction]\n+ local procedure TryApplyDecimalFilter(FilterExpression: Text)\n+ var\n+ TempQltyInspectionLine: Record \"Qlty. Inspection Line\" temporary;\n+ begin\n+ TempQltyInspectionLine.SetFilter(\"Derived Numeric Value\", FilterExpression);\n+ if TempQltyInspectionLine.IsEmpty() then;\n+ end;\n+\n+ [TryFunction]\n+ local procedure TryApplyIntegerFilter(FilterExpression: Text)\n+ var\n+ TempInteger: Record \"Integer\" temporary;\n+ begin\n+ TempInteger.SetFilter(Number, FilterExpression);\n+ if TempInteger.IsEmpty() then;\n+ end;\n+\n+ [TryFunction]\n+ local procedure TryApplyBooleanFilter(FilterExpression: Text)\n+ var\n+ QltyBooleanParsing: Codeunit \"Qlty. Boolean Parsing\";\n+ begin\n+ // Valid boolean allowable values are: Yes, No, True, False, 1, 0, On, Off (and variations)\n+ if not QltyBooleanParsing.CanTextBeInterpretedAsBooleanIsh(FilterExpression) then\n+ Error(InvalidAllowableValuesFormatErr, FilterExpression, '', 'Boolean');\n+ end;\n+\n+ [TryFunction]\n+ local procedure TryApplyDateFilter(FilterExpression: Text)\n+ var\n+ TempDateLookupBuffer: Record \"Date Lookup Buffer\" temporary;\n+ begin\n+ TempDateLookupBuffer.SetFilter(\"Period Start\", FilterExpression);\n+ if TempDateLookupBuffer.IsEmpty() then;\n+ end;\n+\n+ [TryFunction]\n+ local procedure TryApplyDateTimeFilter(FilterExpression: Text)\n+ var\n+ TempQltyInspectionHeader: Record \"Qlty. Inspection Header\" temporary;\n+ begin\n+ TempQltyInspectionHeader.SetFilter(\"Finished Date\", FilterExpression);\n+ if TempQltyInspectionHeader.IsEmpty() then;\n+ end;\n+\n local procedure ValidateAllowableValuesOnText(NumberOrNameOfTestNameForError: Text; var TextToValidate: Text[250]; AllowableValues: Text; QltyTestValueType: Enum \"Qlty. Test Value Type\"; var TempBufferQltyTestLookupValue: Record \"Qlty. Test Lookup Value\" temporary; QltyCaseSensitivity: Enum \"Qlty. Case Sensitivity\")\n var\n QltyBooleanParsing: Codeunit \"Qlty. Boolean Parsing\";\n@@ -393,9 +498,8 @@ codeunit 20410 \"Qlty. Result Evaluation\"\n if not (IsBlankOrEmptyCondition(AllowableValues) and (TextToValidate = '')) then\n if not QltyResultEvaluation.CheckIfValueIsString(TextToValidate, ConvertStr(AllowableValues, ',', '|'), QltyCaseSensitivity) then\n Error(NotInAllowableValuesErr, TextToValidate, NumberOrNameOfTestNameForError, AllowableValues);\n-\n QltyTestValueType::\"Value Type Option\",\n- QltyTestValueType::\"Value Type Table Lookup\":\n+ QltyTestValueType::\"Value Type Table Lookup\":\n begin\n TextToValidate := CopyStr(TextToValidate.Trim(), 1, MaxStrLen(TextToValidate));\n \n@@ -419,6 +523,7 @@ codeunit 20410 \"Qlty. Result Evaluation\"\n Error(NotInAllowableValuesErr, TextToValidate, NumberOrNameOfTestNameForError, AllowableValues);\n end;\n end;\n+\n OnAfterValidateAllowableValuesOnText(NumberOrNameOfTestNameForError, TextToValidate, AllowableValues, QltyTestValueType, TempBufferQltyTestLookupValue, QltyCaseSensitivity);\n end;\n \n", "FAIL_TO_PASS": [{"codeunitID": 139963, "functionName": ["ValidateAllowableValuesFormat_Boolean_ValidFormats", "ValidateAllowableValuesFormat_NonValidatedTypes", "ValidateAllowableValuesFormat_Boolean_InvalidFormats", "ValidateAllowableValuesFormat_DateTime_InvalidFormats", "ValidateAllowableValuesFormat_Integer_ValidFormats", "ValidateAllowableValuesFormat_Integer_InvalidFormats", "ValidateAllowableValuesFormat_Date_InvalidFormats", "ValidateAllowableValuesFormat_Decimal_ValidFormats", "ValidateAllowableValuesFormat_Date_ValidFormats", "ValidateAllowableValuesFormat_DateTime_ValidFormats", "ValidateAllowableValuesFormat_Decimal_InvalidFormats"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Quality Management/app/src/Configuration/Template/Test/QltyTest.Table.al b/src/Apps/W1/Quality Management/app/src/Configuration/Template/Test/QltyTest.Table.al\nindex 9f4cbf3006..66e4c203fc 100644\n--- a/src/Apps/W1/Quality Management/app/src/Configuration/Template/Test/QltyTest.Table.al\n+++ b/src/Apps/W1/Quality Management/app/src/Configuration/Template/Test/QltyTest.Table.al\n@@ -54,8 +54,11 @@ table 20401 \"Qlty. Test\"\n {\n Caption = 'Allowable Values';\n ToolTip = 'Specifies an expression for the range of values you can enter or select for the Test. Depending on the Test Value Type, the expression format varies. For example if you want a measurement such as a percentage that collects between 0 and 100 you would enter 0..100. This is not the pass or acceptable condition, these are just the technically possible values that the inspector can enter. You would then enter a passing condition in your result conditions. If you had a result of Pass being 80 to 100, you would then configure 80..100 for that result.';\n+\n trigger OnValidate()\n begin\n+ Rec.ValidateAllowableValuesFormat();\n+\n if Rec.\"Test Value Type\" in [Rec.\"Test Value Type\"::\"Value Type Option\", Rec.\"Test Value Type\"::\"Value Type Table Lookup\"] then\n Rec.\"Allowable Values\" := CopyStr(Rec.\"Allowable Values\".Replace(', ', ','), 1, MaxStrLen(Rec.\"Allowable Values\"));\n end;\n@@ -472,6 +475,16 @@ table 20401 \"Qlty. Test\"\n QltyResultEvaluation.ValidateAllowableValuesOnTest(Rec);\n end;\n \n+ /// \n+ /// Validates that the allowable values expression is a valid filter for the test value type.\n+ /// \n+ procedure ValidateAllowableValuesFormat()\n+ var\n+ QltyResultEvaluation: Codeunit \"Qlty. Result Evaluation\";\n+ begin\n+ QltyResultEvaluation.ValidateAllowableValuesFormat(Rec);\n+ end;\n+\n /// \n /// Code = the unique code\n /// Description = raw description.\ndiff --git a/src/Apps/W1/Quality Management/test/src/QltyTestsResultEval.Codeunit.al b/src/Apps/W1/Quality Management/test/src/QltyTestsResultEval.Codeunit.al\nindex 91159fca6e..05f7d8a17a 100644\n--- a/src/Apps/W1/Quality Management/test/src/QltyTestsResultEval.Codeunit.al\n+++ b/src/Apps/W1/Quality Management/test/src/QltyTestsResultEval.Codeunit.al\n@@ -2071,6 +2071,440 @@ codeunit 139963 \"Qlty. Tests - Result Eval.\"\n LibraryAssert.ExpectedError(StrSubstNo(Expected4Err, OptionListQltyInspectionLine.\"Test Code\"));\n end;\n \n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Decimal_ValidFormats()\n+ var\n+ DecimalQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat accepts valid decimal filter expressions\n+\n+ // [GIVEN] A quality test with decimal type is created\n+ DecimalQltyTest.Init();\n+ DecimalQltyTest.Code := 'TESTDEC';\n+ DecimalQltyTest.Description := 'Test Decimal';\n+ DecimalQltyTest.\"Test Value Type\" := DecimalQltyTest.\"Test Value Type\"::\"Value Type Decimal\";\n+ DecimalQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to range expression \"0..100\"\n+ DecimalQltyTest.\"Allowable Values\" := '0..100';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to greater than expression \">0\"\n+ DecimalQltyTest.\"Allowable Values\" := '>0';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to less than or equal expression \"<=50\"\n+ DecimalQltyTest.\"Allowable Values\" := '<=50';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to exact value \"25.5\"\n+ DecimalQltyTest.\"Allowable Values\" := '25.5';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to list of values \"10|20|30\"\n+ DecimalQltyTest.\"Allowable Values\" := '10|20|30';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are blank\n+ DecimalQltyTest.\"Allowable Values\" := '';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values contain expression with brackets \"[Field]\"\n+ DecimalQltyTest.\"Allowable Values\" := '0..[Field]';\n+ // [THEN] ValidateAllowableValuesFormat is deferred and passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to not empty condition \"<>''\"\n+ DecimalQltyTest.\"Allowable Values\" := '<>''''';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DecimalQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Decimal_InvalidFormats()\n+ var\n+ DecimalQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat rejects invalid decimal filter expressions\n+\n+ // [GIVEN] A quality test with decimal type is created\n+ DecimalQltyTest.Init();\n+ DecimalQltyTest.Code := 'TESTDEC2';\n+ DecimalQltyTest.Description := 'Test Decimal Invalid';\n+ DecimalQltyTest.\"Test Value Type\" := DecimalQltyTest.\"Test Value Type\"::\"Value Type Decimal\";\n+ DecimalQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to invalid text \"not a number\"\n+ DecimalQltyTest.\"Allowable Values\" := 'not a number';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DecimalQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid operator \"==5\"\n+ DecimalQltyTest.\"Allowable Values\" := '==5';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DecimalQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Integer_ValidFormats()\n+ var\n+ IntegerQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat accepts valid integer filter expressions\n+\n+ // [GIVEN] A quality test with integer type is created\n+ IntegerQltyTest.Init();\n+ IntegerQltyTest.Code := 'TESTINT';\n+ IntegerQltyTest.Description := 'Test Integer';\n+ IntegerQltyTest.\"Test Value Type\" := IntegerQltyTest.\"Test Value Type\"::\"Value Type Integer\";\n+ IntegerQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to range expression \"0..100\"\n+ IntegerQltyTest.\"Allowable Values\" := '0..100';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to greater than expression \">0\"\n+ IntegerQltyTest.\"Allowable Values\" := '>0';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to less than or equal expression \"<=50\"\n+ IntegerQltyTest.\"Allowable Values\" := '<=50';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to exact value \"25\"\n+ IntegerQltyTest.\"Allowable Values\" := '25';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to list of values \"1|2|3|4|5\"\n+ IntegerQltyTest.\"Allowable Values\" := '1|2|3|4|5';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are blank\n+ IntegerQltyTest.\"Allowable Values\" := '';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values contain expression with brackets \"[Field]\"\n+ IntegerQltyTest.\"Allowable Values\" := '1..[Field]';\n+ // [THEN] ValidateAllowableValuesFormat is deferred and passes without error\n+ IntegerQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Integer_InvalidFormats()\n+ var\n+ IntegerQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat rejects invalid integer filter expressions\n+\n+ // [GIVEN] A quality test with integer type is created\n+ IntegerQltyTest.Init();\n+ IntegerQltyTest.Code := 'TESTINT2';\n+ IntegerQltyTest.Description := 'Test Integer Invalid';\n+ IntegerQltyTest.\"Test Value Type\" := IntegerQltyTest.\"Test Value Type\"::\"Value Type Integer\";\n+ IntegerQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to decimal value \"1.5\"\n+ IntegerQltyTest.\"Allowable Values\" := '1.5';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror IntegerQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid text \"not an integer\"\n+ IntegerQltyTest.\"Allowable Values\" := 'not an integer';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror IntegerQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Date_ValidFormats()\n+ var\n+ DateQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat accepts valid date filter expressions\n+\n+ // [GIVEN] A quality test with date type is created\n+ DateQltyTest.Init();\n+ DateQltyTest.Code := 'TESTDATE';\n+ DateQltyTest.Description := 'Test Date';\n+ DateQltyTest.\"Test Value Type\" := DateQltyTest.\"Test Value Type\"::\"Value Type Date\";\n+ DateQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to exact date \"2024-01-01\"\n+ DateQltyTest.\"Allowable Values\" := '2024-01-01';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to date range \"2024-01-01..2024-12-31\"\n+ DateQltyTest.\"Allowable Values\" := '2024-01-01..2024-12-31';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to greater than date \">2024-01-01\"\n+ DateQltyTest.\"Allowable Values\" := '>2024-01-01';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are blank\n+ DateQltyTest.\"Allowable Values\" := '';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values contain expression with brackets \"[Field]\"\n+ DateQltyTest.\"Allowable Values\" := '>[Field]';\n+ // [THEN] ValidateAllowableValuesFormat is deferred and passes without error\n+ DateQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Date_InvalidFormats()\n+ var\n+ DateQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat rejects invalid date filter expressions\n+\n+ // [GIVEN] A quality test with date type is created\n+ DateQltyTest.Init();\n+ DateQltyTest.Code := 'TESTDATE2';\n+ DateQltyTest.Description := 'Test Date Invalid';\n+ DateQltyTest.\"Test Value Type\" := DateQltyTest.\"Test Value Type\"::\"Value Type Date\";\n+ DateQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to invalid date \"99/99/9999\"\n+ DateQltyTest.\"Allowable Values\" := '99/99/9999';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DateQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid text \"not a date\"\n+ DateQltyTest.\"Allowable Values\" := 'not a date';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DateQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_DateTime_ValidFormats()\n+ var\n+ DateTimeQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat accepts valid datetime filter expressions\n+\n+ // [GIVEN] A quality test with datetime type is created\n+ DateTimeQltyTest.Init();\n+ DateTimeQltyTest.Code := 'TESTDT';\n+ DateTimeQltyTest.Description := 'Test DateTime';\n+ DateTimeQltyTest.\"Test Value Type\" := DateTimeQltyTest.\"Test Value Type\"::\"Value Type DateTime\";\n+ DateTimeQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to exact datetime \"2024-01-01 10:30:00\"\n+ DateTimeQltyTest.\"Allowable Values\" := '2024-01-01 10:30:00';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateTimeQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to datetime range \"2024-01-01 00:00:00..2024-12-31 23:59:59\"\n+ DateTimeQltyTest.\"Allowable Values\" := '2024-01-01 00:00:00..2024-12-31 23:59:59';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateTimeQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to greater than datetime \">2024-01-01 10:00:00\"\n+ DateTimeQltyTest.\"Allowable Values\" := '>2024-01-01 10:00:00';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateTimeQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are blank\n+ DateTimeQltyTest.\"Allowable Values\" := '';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ DateTimeQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values contain expression with brackets \"[Field]\"\n+ DateTimeQltyTest.\"Allowable Values\" := '<[Field]';\n+ // [THEN] ValidateAllowableValuesFormat is deferred and passes without error\n+ DateTimeQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_DateTime_InvalidFormats()\n+ var\n+ DateTimeQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat rejects invalid datetime filter expressions\n+\n+ // [GIVEN] A quality test with datetime type is created\n+ DateTimeQltyTest.Init();\n+ DateTimeQltyTest.Code := 'TESTDT2';\n+ DateTimeQltyTest.Description := 'Test DateTime Invalid';\n+ DateTimeQltyTest.\"Test Value Type\" := DateTimeQltyTest.\"Test Value Type\"::\"Value Type DateTime\";\n+ DateTimeQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to invalid datetime \"99/99/9999 99:99:99\"\n+ DateTimeQltyTest.\"Allowable Values\" := '99/99/9999 99:99:99';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DateTimeQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid text \"not a datetime\"\n+ DateTimeQltyTest.\"Allowable Values\" := 'not a datetime';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror DateTimeQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Boolean_ValidFormats()\n+ var\n+ BooleanQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat accepts valid boolean values\n+\n+ // [GIVEN] A quality test with boolean type is created\n+ BooleanQltyTest.Init();\n+ BooleanQltyTest.Code := 'TESTBOOL';\n+ BooleanQltyTest.Description := 'Test Boolean';\n+ BooleanQltyTest.\"Test Value Type\" := BooleanQltyTest.\"Test Value Type\"::\"Value Type Boolean\";\n+ BooleanQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to \"Yes\"\n+ BooleanQltyTest.\"Allowable Values\" := 'Yes';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"No\"\n+ BooleanQltyTest.\"Allowable Values\" := 'No';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"True\"\n+ BooleanQltyTest.\"Allowable Values\" := 'True';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"False\"\n+ BooleanQltyTest.\"Allowable Values\" := 'False';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"1\"\n+ BooleanQltyTest.\"Allowable Values\" := '1';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"0\"\n+ BooleanQltyTest.\"Allowable Values\" := '0';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"On\"\n+ BooleanQltyTest.\"Allowable Values\" := 'On';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to \"Off\"\n+ BooleanQltyTest.\"Allowable Values\" := 'Off';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to single-letter \"Y\"\n+ BooleanQltyTest.\"Allowable Values\" := 'Y';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to single-letter \"N\"\n+ BooleanQltyTest.\"Allowable Values\" := 'N';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are blank\n+ BooleanQltyTest.\"Allowable Values\" := '';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values contain expression with brackets \"[Field]\"\n+ BooleanQltyTest.\"Allowable Values\" := '[Field]';\n+ // [THEN] ValidateAllowableValuesFormat is deferred and passes without error\n+ BooleanQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_Boolean_InvalidFormats()\n+ var\n+ BooleanQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat rejects invalid boolean values\n+\n+ // [GIVEN] A quality test with boolean type is created\n+ BooleanQltyTest.Init();\n+ BooleanQltyTest.Code := 'TESTBOOL2';\n+ BooleanQltyTest.Description := 'Test Boolean Invalid';\n+ BooleanQltyTest.\"Test Value Type\" := BooleanQltyTest.\"Test Value Type\"::\"Value Type Boolean\";\n+ BooleanQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to invalid text \"Maybe\"\n+ BooleanQltyTest.\"Allowable Values\" := 'Maybe';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid number \"2\"\n+ BooleanQltyTest.\"Allowable Values\" := '2';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid text \"not a boolean\"\n+ BooleanQltyTest.\"Allowable Values\" := 'not a boolean';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror BooleanQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to invalid text \"abc\"\n+ BooleanQltyTest.\"Allowable Values\" := 'abc';\n+ // [THEN] ValidateAllowableValuesFormat raises an error\n+ asserterror BooleanQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+ [Test]\n+ procedure ValidateAllowableValuesFormat_NonValidatedTypes()\n+ var\n+ TextQltyTest: Record \"Qlty. Test\";\n+ OptionQltyTest: Record \"Qlty. Test\";\n+ begin\n+ // [SCENARIO] Validate that ValidateAllowableValuesFormat does not validate non-numeric/non-date types\n+\n+ // [GIVEN] A quality test with text type is created\n+ TextQltyTest.Init();\n+ TextQltyTest.Code := 'TESTTEXT';\n+ TextQltyTest.Description := 'Test Text';\n+ TextQltyTest.\"Test Value Type\" := TextQltyTest.\"Test Value Type\"::\"Value Type Text\";\n+ TextQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to any text value \"A|B|C\"\n+ TextQltyTest.\"Allowable Values\" := 'A|B|C';\n+ // [THEN] ValidateAllowableValuesFormat passes without error (no validation for text type)\n+ TextQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [WHEN] Allowable values are set to any arbitrary text\n+ TextQltyTest.\"Allowable Values\" := 'any text value';\n+ // [THEN] ValidateAllowableValuesFormat passes without error\n+ TextQltyTest.ValidateAllowableValuesFormat();\n+\n+ // [GIVEN] A quality test with option type is created\n+ OptionQltyTest.Init();\n+ OptionQltyTest.Code := 'TESTOPT';\n+ OptionQltyTest.Description := 'Test Option';\n+ OptionQltyTest.\"Test Value Type\" := OptionQltyTest.\"Test Value Type\"::\"Value Type Option\";\n+ OptionQltyTest.Insert();\n+\n+ // [WHEN] Allowable values are set to comma-separated options \"Option1,Option2,Option3\"\n+ OptionQltyTest.\"Allowable Values\" := 'Option1,Option2,Option3';\n+ // [THEN] ValidateAllowableValuesFormat passes without error (no validation for option type)\n+ OptionQltyTest.ValidateAllowableValuesFormat();\n+ end;\n+\n+\n local procedure GetTemplateLineConfigFilters(var QltyInspectionTemplateLine: Record \"Qlty. Inspection Template Line\"; var OutTemplateLineQltyIResultConditConf: Record \"Qlty. I. Result Condit. Conf.\")\n begin\n OutTemplateLineQltyIResultConditConf.SetRange(\"Condition Type\", OutTemplateLineQltyIResultConditConf.\"Condition Type\"::Template);\n"}
+{"metadata": {"area": null, "image_count": null}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-8286", "base_commit": "70fd0246a0a4dbc72cb183ca719106722c03be4d", "created_at": "2026-05-22T13:07:41Z", "environment_setup_version": "28.1", "project_paths": ["src\\Apps\\W1\\Subcontracting\\App", "src\\Apps\\W1\\Subcontracting\\Test"], "patch": "diff --git a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPriceManagement.Codeunit.al b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPriceManagement.Codeunit.al\nindex dfb07f0502..a005fa7b7c 100644\n--- a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPriceManagement.Codeunit.al\n+++ b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPriceManagement.Codeunit.al\n@@ -436,7 +436,7 @@ codeunit 99001508 \"Subc. Price Management\"\n \n GetPriceByUOM(SubcontractorPrice, PriceListQty, PriceListCost);\n if PriceListCost <> 0 then begin\n- ConvertPriceToUOM(RequisitionLine.\"Unit of Measure Code\", RequisitionLine.GetQuantityBase(), PriceListUOM, PriceListQtyPerUOM, PriceListCost, DirectCost);\n+ ConvertPriceToUOM(RequisitionLine.\"Unit of Measure Code\", RequisitionLine.GetQuantityForUOM(), PriceListUOM, PriceListQtyPerUOM, PriceListCost, DirectCost);\n ConvertPriceToCurrency(RequisitionLine.\"Currency Code\", SubcontractorPrice.\"Currency Code\", PriceListCost, DirectCost);\n end;\n RequisitionLine.\"Direct Unit Cost\" := DirectCost;\n", "FAIL_TO_PASS": [{"codeunitID": 139989, "functionName": ["WorksheetDirectUnitCostUsesQtyPerUoMNotBaseQtyForUoMConversion"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\nindex 51ef985d36..73e138fe61 100644\n--- a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\n+++ b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al\n@@ -3401,6 +3401,77 @@ codeunit 139989 \"Subc. Subcontracting Test\"\n Assert.AreEqual('', ToPurchaseHeader.\"Subc. Location Code\", 'Subc. Location Code should not be copied from archive by Copy Document');\n end;\n \n+ [Test]\n+ procedure WorksheetDirectUnitCostUsesQtyPerUoMNotBaseQtyForUoMConversion()\n+ var\n+ Item: Record Item;\n+ ItemUOM: Record \"Item Unit of Measure\";\n+ Vendor: Record Vendor;\n+ WorkCenter: Record \"Work Center\";\n+ SubcontractorPrice: Record \"Subcontractor Price\";\n+ RequisitionLine: Record \"Requisition Line\";\n+ SubcPriceManagement: Codeunit \"Subc. Price Management\";\n+ QtyPerSet: Integer;\n+ PriceListUnitCost: Decimal;\n+ begin\n+ // [SCENARIO 636078] Calculate Subcontracts must compute Direct Unit Cost on the Subcontracting\n+ // Worksheet using the per-UoM conversion factor (GetQuantityForUOM()), not the total base\n+ // quantity (GetQuantityBase()) of the order.\n+\n+ // [GIVEN] Item with PCS base UoM and a SET alternative UoM (10 PCS per SET).\n+ Initialize();\n+ LibraryInventory.CreateItem(Item);\n+ QtyPerSet := 10;\n+ LibraryInventory.CreateItemUnitOfMeasureCode(ItemUOM, Item.\"No.\", QtyPerSet);\n+\n+ // [GIVEN] Vendor and Work Center with the vendor as its subcontractor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+ LibraryManufacturing.CreateWorkCenter(WorkCenter);\n+ WorkCenter.Validate(\"Subcontractor No.\", Vendor.\"No.\");\n+ WorkCenter.Modify(true);\n+\n+ // [GIVEN] A subcontractor price in PCS with Minimum Quantity 1 and Direct Unit Cost 1000.\n+ PriceListUnitCost := 1000;\n+ SubcontractingMgmtLibrary.CreateSubContractingPrice(\n+ SubcontractorPrice, WorkCenter.\"No.\", Vendor.\"No.\", Item.\"No.\", '', '', WorkDate(), Item.\"Base Unit of Measure\", 1, '');\n+ SubcontractorPrice.Validate(\"Direct Unit Cost\", PriceListUnitCost);\n+ SubcontractorPrice.Modify(true);\n+\n+ // [GIVEN] A staged Requisition Line for 3 SET (= 30 PCS in base UoM).\n+ RequisitionLine.Init();\n+ RequisitionLine.\"No.\" := Item.\"No.\";\n+ RequisitionLine.\"Unit of Measure Code\" := ItemUOM.Code;\n+ RequisitionLine.\"Vendor No.\" := Vendor.\"No.\";\n+ RequisitionLine.\"Work Center No.\" := WorkCenter.\"No.\";\n+ RequisitionLine.\"Order Date\" := WorkDate();\n+ RequisitionLine.Quantity := 3;\n+\n+ // [WHEN] The subcontractor price is applied to the requisition line.\n+ SubcPriceManagement.GetSubcPriceForReqLine(RequisitionLine, '');\n+\n+ // [THEN] Direct Unit Cost = price-list cost * Qty-per-UoM (1000 * 10 = 10000),\n+ // not price-list cost * total base quantity (1000 * 30 = 30000 — the pre-fix behavior).\n+ Assert.AreEqual(\n+ PriceListUnitCost * QtyPerSet, RequisitionLine.\"Direct Unit Cost\",\n+ 'Direct Unit Cost on the Subcontracting Worksheet must be derived from Qty. per Unit of Measure, not from total base quantity.');\n+\n+ // [WHEN] The same price is applied to a Requisition Line using the base UoM (no conversion needed).\n+ Clear(RequisitionLine);\n+ RequisitionLine.Init();\n+ RequisitionLine.\"No.\" := Item.\"No.\";\n+ RequisitionLine.\"Unit of Measure Code\" := Item.\"Base Unit of Measure\";\n+ RequisitionLine.\"Vendor No.\" := Vendor.\"No.\";\n+ RequisitionLine.\"Work Center No.\" := WorkCenter.\"No.\";\n+ RequisitionLine.\"Order Date\" := WorkDate();\n+ RequisitionLine.Quantity := 30;\n+ SubcPriceManagement.GetSubcPriceForReqLine(RequisitionLine, '');\n+\n+ // [THEN] Direct Unit Cost equals the price-list cost (the same-UoM path is unchanged by the fix).\n+ Assert.AreEqual(\n+ PriceListUnitCost, RequisitionLine.\"Direct Unit Cost\",\n+ 'Direct Unit Cost must equal the price-list cost when the worksheet UoM matches the price-list UoM.');\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Subc. Subcontracting Test\");\n"}
diff --git a/dataset/problemstatement/microsoft__BCApps-7831/README.md b/dataset/problemstatement/microsoft__BCApps-7831/README.md
new file mode 100644
index 000000000..2a39d36fa
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-7831/README.md
@@ -0,0 +1,36 @@
+# Title: [Subcontracting] Standard Task not propagated from Routing to Prod. Order Routing or Subcontracting Worksheet; prices not picked up
+## Repro Steps:
+
+
+## Hints:
+### Repro Steps
+**Summary**: The Subcontracting app needs to be aligned with changes made to the "Description 2" field on various tables. The bug description contains inline screenshots showing the field changes but minimal textual detail.
+
+#### Steps to Reproduce
+1. Open Business Central with the Subcontracting module enabled.
+2. Identify all tables in the Subcontracting app that reference or use the "Description 2" field (e.g., Item, Production Order Line, Purchase Line, or other related tables).
+3. Check that the Subcontracting app properly reads, writes, and displays the "Description 2" field wherever it is used in the base BC application.
+4. If "Description 2" has been modified (renamed, repositioned, or had its properties changed) in the base tables, verify that:
+ - All Subcontracting page extensions show the updated "Description 2" correctly.
+ - All Subcontracting codeunits that reference "Description 2" are aligned with the new field definition.
+ - All API queries or pages that expose "Description 2" reflect the changes.
+5. Look for compilation errors or runtime issues caused by the misalignment.
+
+#### Expected Result
+- The Subcontracting app should be fully aligned with any changes to the "Description 2" field in the base BC application.
+- No compilation errors or data integrity issues related to this field.
+-
+#### Actual Result
+- The Subcontracting app references are not aligned with the "Description 2" field changes, as shown in the inline screenshots.
+-
+#### Additional Context
+- Related to
+620425 [Subcontracting] "Single Instance Dictionary" is a very generic name. Rename & refactor it appropriately (SingleInstanceDictionary naming/refactoring).
+
+#### Self-Review
+- The repro steps cover the general alignment concern but specific tables/pages affected are documented in the screenshots only.
+- This is a code alignment/compatibility issue following upstream changes.
+
+**Score: 5/10** - The bug description is primarily screenshots with limited textual context. Steps provide a reasonable framework for verification.
+
+[AI-REPRO] score=5 | workItemId=620556 | generated=2026-03-25 | sources=Title,Description (inline images)
diff --git a/dataset/problemstatement/microsoft__BCApps-8059/README.md b/dataset/problemstatement/microsoft__BCApps-8059/README.md
new file mode 100644
index 000000000..6fdaf7b36
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-8059/README.md
@@ -0,0 +1,38 @@
+# Title: [master][All-e]Peppol E-Invoice cannot be validated when price incl VAT is used in a document
+## Repro Steps:
+1. Go to Company Information and add a SWIFT Code (you need to created a new one, but it can be any number)
+2. Go to E-Document Services and open the E-DOCUMENTS
+ Document Format should be PEPPOL BIS 3.0
+3. In the E-Document Service use buton "Configure documents to export" and add the sales invoice
+4. Go to Electronic Document Formats and make sure you have the setup for PEPPOL BIS3 / Sales Invoice / Codeunit 1610
+5. Go to Workflows and make sure you have the default workflow for "Send E-Documents to one Service" enabled
+6. Go to Document Sending Profiles, check E-DOCUMENTS and make sure this uses
+ Electronic Document = E-Document Workflow
+ E-Document Workflow = MS-EDOCSTOS-01 (the one from step 5)
+7. Open Customer Card 10000 and change the following:
+ Document Sending Profile = E-DOCUMENTS
+ VAT Registration No = GB123456789
+8. Create a new Sales Invoice for customer 10000
+ Posting / Document Date = (use the suggested ones)
+ Your Reference = TEST
+ Price Incl VAT = YES
+9. Now add a new line to the sales invoice:
+ 1x item 1896-S
+10. Post the Sales invoice with option Post and Send
+11. Go to E-Documents
+ The newest entry should be the one that we just created by posting the sales invoice with post and send
+ Highlight that entry, then go to Actions -> E-Document Logs
+12. From the E-Document Logs you can download the e-invoice with button Export File, an XML file is now exported
+13. Open a Peppol Validator (e.g. [Free Online Peppol Validator. Validate UBL & XML Invoices Instantly](https://peppolvalidator.com/)), upload and validate the e-invoice downloaded in step 12
+
+**Expected Outcome:**
+The file should validate without error messages
+
+**Actual Outcome:**
+The file cannot be validated without error messages:
+
+
+**Troubleshooting Actions Taken:**
+When you post a sales invoice that does not have option Price incl VAT enabled, the created e-document can be validated without error message.
+
+## Description:
diff --git a/dataset/problemstatement/microsoft__BCApps-8059/error_message.png b/dataset/problemstatement/microsoft__BCApps-8059/error_message.png
new file mode 100644
index 000000000..7ca525507
Binary files /dev/null and b/dataset/problemstatement/microsoft__BCApps-8059/error_message.png differ
diff --git a/dataset/problemstatement/microsoft__BCApps-8253/README.md b/dataset/problemstatement/microsoft__BCApps-8253/README.md
new file mode 100644
index 000000000..ffbd4dd13
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-8253/README.md
@@ -0,0 +1,74 @@
+# Title: [Subcontracting] Standard Task not propagated from Routing to Prod. Order Routing or Subcontracting Worksheet; prices not picked up
+## Repro Steps:
+**Issues:**
+
+1. **Standard Task not propagated from Routing:** When a routing line has a Standard Task set, that value is not copied to the corresponding Prod. Order Routing line.
+2. **Standard Task not propagated to Subcontracting Worksheet:** The Standard Task from the routing line is also not populated in the Subcontracting Worksheet when lines are pulled.
+3. **Standard Task not editable in Subcontracting Worksheet:** Even if the field were present, it is not editable in the Subcontracting Worksheet, preventing manual correction.
+4. **Prices not picked up:** If the user has configured prices tied to a Standard Task, those prices are not used because the Standard Task is missing from the subcontracting flow.
+
+**Expected:** Standard Task should be propagated from Routing to Prod. Order Routing and to the Subcontracting Worksheet. The field should be editable in the worksheet. Prices bound to Standard Task should be applied correctly.
+
+## Description:
+
+
+## Hints
+
+### Repro Steps Clarity Score: 6/10
++Specificity +Determinism
+-Missing environment -Unverified UI references
+-Missing data values (no concrete Standard Task / item / routing combo named in the bug)
+
+The bug enumerates 4 related symptoms but provides no concrete data combination. Steps below pick concrete demo values and a sequenced repro for each symptom.
+----
+### Detailed Repro Steps
+#### Environment
+- Build: Master — Subcontracting feature dev build (target branch master).
+- Localization: W1 (any localization should reproduce).
+- Functional area: SCM / Manufacturing — Subcontracting (Standard Task propagation, Subcontracting Worksheet editing, Subcontracting price lookup).
+
+#### Prerequisites
+- Subcontracting feature available with: a Subcontractor vendor, a Subcontracting Work Center, an item with a Production BOM and a Routing.
+- A Standard Task code defined (e.g., STD-PAINT) — choose Search > Standard Tasks > + New to add one.
+- A Routing that includes the Subcontracting Work Center, with at least one Routing Line whose Standard Task Code is set to STD-PAINT.
+- A Subcontracting price (e.g., on the Standard Task card or on the Subcontracting Work Center / Subcontractor Vendor) that is specifically tied to Standard Task STD-PAINT (so that when STD-PAINT is present on the line, the price applies; when absent, it does not).
+- A Released Production Order created from the manufacturing item with the routing above.
+
+#### Steps — Issue 1: Routing → Prod. Order Routing propagation
+1. Choose Search > Routings, open the routing used by the manufacturing item, and confirm the Subcontracting routing line has Standard Task Code = STD-PAINT.
+2. Choose Search > Released Production Orders, open the order created in prerequisites.
+3. Drill into Lines > Routing to open Prod. Order Routing.
+4. Observe Issue 1: the Prod. Order Routing line corresponding to the Subcontracting operation has Standard Task Code = blank (it was not copied from the source Routing).
+
+#### Steps — Issue 2: Routing → Subcontracting Worksheet propagation
+5. Choose Search > Subcontracting Worksheet, choose the related link.
+6. Choose Calculate Subcontracts…, accept defaults, run.
+7. Observe Issue 2: the worksheet line for the production order's subcontracting operation has Standard Task Code = blank, even though the routing line has STD-PAINT set.
+
+#### Steps — Issue 3: Standard Task not editable in Subcontracting Worksheet
+8. On the worksheet line from step 7, attempt to set Standard Task Code = STD-PAINT either by typing or via the lookup.
+9. Observe Issue 3: the field is read-only / not editable, so the missing value cannot be corrected manually before Carry Out Action Message.
+
+#### Steps — Issue 4: Prices not picked up because Standard Task is missing
+Without correcting the Standard Task (since you cannot, per Issue 3), choose Carry Out Action Message… to create the Subcontracting Purchase Order.
+Open the resulting Subcontracting Purchase Order line.
+Observe Issue 4: the Direct Unit Cost / line price is the work-center default price, not the price tied to Standard Task STD-PAINT. Because the Standard Task is missing from both the routing line and the worksheet, the price-lookup step never matches the standard-task-specific price and the wrong (or default) price is applied.
+
+#### Expected Result
+- Routing → Prod. Order Routing → Subcontracting Worksheet → Subcontracting Purchase Order all preserve Standard Task Code end-to-end.
+- The Standard Task Code field is editable in the Subcontracting Worksheet so users can correct or override.
+- Subcontracting price lookup uses the Standard Task Code as a key, so prices defined per Standard Task are applied to the resulting PO line.
+
+#### Actual Result
+- Standard Task Code is dropped at the Routing → Prod. Order Routing step, and remains missing on the Subcontracting Worksheet and the resulting Subcontracting PO. Prices tied to Standard Task are therefore never selected.
+
+#### Notes
+- Severity 3, Priority 2. Issue type: Code Defect. Found by Manual Testing: Other Test Pass on 2026-04-30 by Chethan Thopaiah.
+- Likely fix surfaces:
+ - Refresh production order routine (Codeunit "Prod. Order Routing Mgt." or equivalent) — copy Standard Task Code from Routing Line to Prod. Order Routing Line.
+ - Calculate Subcontracts (Codeunit "Subcontracting Worksheet Mgt." / similar) — copy Standard Task Code from Prod. Order Routing Line into the worksheet line.
+ - Page extension on Subcontracting Worksheet — set the Standard Task Code field Editable = true (subject to UX review).
+ - Subcontracting price lookup — extend the price-source lookup to include Standard Task Code as a key so prices tied to a Standard Task are matched.
+- Sibling Subcontracting bugs that touch the routing → worksheet → PO chain: #633223, #633224, #633227, #633228, #633229.
+
+[AI-REPRO] score=6 | workItemId=633226 | generated=2026-04-30 | sources=repro_steps,documentation
diff --git a/dataset/problemstatement/microsoft__BCApps-8286/README.md b/dataset/problemstatement/microsoft__BCApps-8286/README.md
new file mode 100644
index 000000000..3ce37bb85
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-8286/README.md
@@ -0,0 +1,31 @@
+# (Bug 636078): [Subcontracting] Worksheet pricing passes total base qty instead of qty-per-UoM to ConvertPriceToUOM — wrong Direct Unit Cost
+
+## Summary
+
+Fixes the Subcontracting Worksheet **Direct Unit Cost** when the production order UoM differs from the subcontractor price-list UoM.
+
+`Subc. Price Management.GetSubcPriceForReqLine` passed `RequisitionLine.GetQuantityBase()` (total base quantity of the order) as the per-UoM conversion factor to `ConvertPriceToUOM`. Because `ConvertPriceToUOM` computes `DirectCost := PriceListCost / PriceListQtyPerUOM * ProdQtyPerUoM`, the result was multiplied by the order quantity instead of the UoM conversion factor. The Carry-Out Action Message-created Purchase Order then inherited the inflated cost.
+
+Comparison of the three call sites (only the worksheet path was wrong):
+
+| Path | 2nd param | Correct? |
+|------|-----------|----------|
+| Routing (`SetRoutingPriceListCost`) | `ProdQtyPerUom` | Yes |
+| **Worksheet (`GetSubcPriceForReqLine`)** | **`RequisitionLine.GetQuantityBase()`** | **No (fixed here)** |
+| Purchase Order (`GetSubcPriceForPurchLine`) | `PurchaseLine.GetQuantityPerUOM()` | Yes |
+
+### Fix
+
+Pass `RequisitionLine.GetQuantityForUOM()` instead, matching the routing and purchase paths.
+
+### Test
+
+Added `WorksheetDirectUnitCostUsesQtyPerUoMNotBaseQtyForUoMConversion` in `SubcSubcontractingTest`:
+
+- Item with PCS base UoM + SET alternative UoM (10 PCS per SET), vendor and work center with that vendor as subcontractor, subcontractor price of 1000 / PCS.
+- Stages a Requisition Line for 3 SET (= 30 PCS base) and asserts `Direct Unit Cost = 10000` (price * Qty-per-UoM), not 30000 (pre-fix behavior).
+- Also asserts the same-UoM (PCS) path still returns 1000 - guards against regression.
+
+### Work Item
+
+[AB#636078](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/636078)
diff --git a/dataset/problemstatement/microsoft__BCApps-8287/README.md b/dataset/problemstatement/microsoft__BCApps-8287/README.md
new file mode 100644
index 000000000..0ca474a55
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-8287/README.md
@@ -0,0 +1,15 @@
+# [Quality Management] Add missing validation of "Allowable Values" in Quality Test card
+
+## What & why
+
+
+
+
+## Linked work
+
+Fixes [AB#624240](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/624240)
+
+
+
+
+
diff --git a/dataset/problemstatement/microsoft__BCApps-8293/README.md b/dataset/problemstatement/microsoft__BCApps-8293/README.md
new file mode 100644
index 000000000..250f3cb6e
--- /dev/null
+++ b/dataset/problemstatement/microsoft__BCApps-8293/README.md
@@ -0,0 +1,20 @@
+# Bug 634953: Fix factbox drilldowns for finished production orders
+
+## Summary
+- **Bug**: Subcontracting factbox drilldowns in Purchase Order and Transfer Order break after the linked production order is finished.
+- **Root cause**: \Subc. ProdO. Factbox Mgmt.\ (CU 99001559) hardcodes \SetRange(Status, ::Released)\ in all 5 procedures, so no data is returned once status moves to Finished.
+- **Fix**: Replace \SetRange(Status, ::Released)\ with \SetFilter(Status, '>=%1', ::Released)\ across all filter procedures so that both Released and Finished production orders are found. \ShowProductionOrder\ now opens the correct page (\Released Production Order\ or \Finished Production Order\) based on the resolved status.
+
+## Changes
+- \SubcProdOFactboxMgmt.Codeunit.al\ — Fixed all 5 affected procedures
+- \SubcSubcontractingTest.Codeunit.al\ — Added \ProdOFactboxMgmtShowsDataAfterProdOrderFinished\ test ([SCENARIO 634953])
+
+## Test
+Added \ProdOFactboxMgmtShowsDataAfterProdOrderFinished\ in codeunit 139989 — verifies that \CalcNoOfProductionOrderRoutings\ and \CalcNoOfProductionOrderComponents\ return positive counts after the production order is finished.
+
+Fixes [AB#634953](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/634953)
+
+:robot: Generated with GitHub Copilot
+
+
+