diff --git a/src/Layers/BE/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al b/src/Layers/BE/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al index 692b0e4564c..d77a7906f10 100644 --- a/src/Layers/BE/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al +++ b/src/Layers/BE/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al @@ -344,8 +344,8 @@ codeunit 137063 "SCM Manufacturing 7.0" // Exercise: Run Planning Worksheet. LibraryPlanning.CalcRegenPlanForPlanWksh(ParentItem, WorkDate(), WorkDate()); - // Verify: Verify Quantity and Dates in Requisition line. - VerifyValueInRequisitionLine(ParentItem, SalesLine.Quantity, SalesHeader."Order Date"); + // Verify: Verify Quantity in Requisition line. + VerifyQuantityInRequisitionLine(ParentItem, SalesLine.Quantity); // Exercise: Run Carry Out Action Messages to create a Production Order. CarryOutActionMsgForItem(ParentItem."No."); @@ -3039,11 +3039,11 @@ codeunit 137063 "SCM Manufacturing 7.0" LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); // [WHEN] Run Calculation Plan from Req Worksheet for created Item - CalculatePlanForReqWksh(Item, CalcDate('<-CY>', WorkDate()), CalcDate('', WorkDate())); + CalculatePlanForReqWksh(Item, WorkDate(), CalcDate('', WorkDate())); // [THEN] Verify Order Date in Requisition line is calculated correctly FindRequisitionLine(RequisitionLine, Item."No."); - RequisitionLine.TestField("Order Date", CalcDate('<-CY>', WorkDate())); + RequisitionLine.TestField("Order Date", WorkDate()); end; #if not CLEAN29 @@ -5583,16 +5583,12 @@ codeunit 137063 "SCM Manufacturing 7.0" "Due Date", CalcDate(InventorySetup."Default Safety Lead Time", CalcDate(Item."Lead Time Calculation", WorkDate()))); end; - local procedure VerifyValueInRequisitionLine(Item: Record Item; Quantity: Decimal; OrderDate: Date) + local procedure VerifyQuantityInRequisitionLine(Item: Record Item; Quantity: Decimal) var RequisitionLine: Record "Requisition Line"; begin FindRequisitionLine(RequisitionLine, Item."No."); RequisitionLine.TestField(Quantity, Quantity); - RequisitionLine.TestField("Due Date", CalcDate(Item."Lead Time Calculation", WorkDate())); - InventorySetup.Get(); - RequisitionLine.TestField( - "Order Date", CalcDate('<' + '-' + Format(InventorySetup."Default Safety Lead Time") + '>', OrderDate)); end; local procedure VerifyPlanningRoutingLine(RoutingHeader: Record "Routing Header"; RequisitionWkshName: Record "Requisition Wksh. Name"; ItemNo: Code[20]; Quantity: Integer) diff --git a/src/Layers/IT/BaseApp/Inventory/Requisition/RequisitionLine.Table.al b/src/Layers/IT/BaseApp/Inventory/Requisition/RequisitionLine.Table.al index 24f99645e05..37505143483 100644 --- a/src/Layers/IT/BaseApp/Inventory/Requisition/RequisitionLine.Table.al +++ b/src/Layers/IT/BaseApp/Inventory/Requisition/RequisitionLine.Table.al @@ -442,12 +442,10 @@ table 246 "Requisition Line" trigger OnValidate() begin - "Starting Date" := "Order Date"; - GetDirectCost(FieldNo("Order Date")); if CurrFieldNo = FieldNo("Order Date") then - Validate("Starting Date"); + Validate("Starting Date", "Order Date"); end; } field(22; "Vendor Item No."; Text[50]) @@ -2779,7 +2777,11 @@ table 246 "Requisition Line" IsHandled := false; OnCalcStartingDateOnBeforeValidateOrderDate(Rec, LeadTime, IsHandled); if not IsHandled then - Validate("Order Date", "Starting Date"); + // Don't use order date in the past for price calculation + if "Starting Date" >= WorkDate() then + Validate("Order Date", "Starting Date") + else + Validate("Order Date", WorkDate()); if "Ref. Order Type" = "Ref. Order Type"::Transfer then CalcTransferShipmentDate(); @@ -2898,7 +2900,11 @@ table 246 "Requisition Line" begin "Demand Date" := DemandDate; "Starting Date" := "Demand Date"; - "Order Date" := "Demand Date"; + // Don't use order date in the past for price calculation + if DemandDate >= WorkDate() then + "Order Date" := "Demand Date" + else + "Order Date" := WorkDate(); Validate("Due Date", "Demand Date"); if "Planning Level" = 0 then begin diff --git a/src/Layers/IT/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al b/src/Layers/IT/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al index 1cbdef4ee8f..63cc02cccb4 100644 --- a/src/Layers/IT/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al +++ b/src/Layers/IT/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al @@ -344,8 +344,8 @@ codeunit 137063 "SCM Manufacturing 7.0" // Exercise: Run Planning Worksheet. LibraryPlanning.CalcRegenPlanForPlanWksh(ParentItem, WorkDate(), WorkDate()); - // Verify: Verify Quantity and Dates in Requisition line. - VerifyValueInRequisitionLine(ParentItem, SalesLine.Quantity, SalesHeader."Order Date"); + // Verify: Verify Quantity in Requisition line. + VerifyQuantityInRequisitionLine(ParentItem, SalesLine.Quantity); // Exercise: Run Carry Out Action Messages to create a Production Order. CarryOutActionMsgForItem(ParentItem."No."); @@ -3033,11 +3033,11 @@ codeunit 137063 "SCM Manufacturing 7.0" LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); // [WHEN] Run Calculation Plan from Req Worksheet for created Item - CalculatePlanForReqWksh(Item, CalcDate('<-CY>', WorkDate()), CalcDate('', WorkDate())); + CalculatePlanForReqWksh(Item, WorkDate(), CalcDate('', WorkDate())); // [THEN] Verify Order Date in Requisition line is calculated correctly FindRequisitionLine(RequisitionLine, Item."No."); - RequisitionLine.TestField("Order Date", CalcDate('<-CY>', WorkDate())); + RequisitionLine.TestField("Order Date", WorkDate()); end; #if not CLEAN28 @@ -5592,16 +5592,12 @@ codeunit 137063 "SCM Manufacturing 7.0" "Due Date", CalcDate(InventorySetup."Default Safety Lead Time", CalcDate(Item."Lead Time Calculation", WorkDate()))); end; - local procedure VerifyValueInRequisitionLine(Item: Record Item; Quantity: Decimal; OrderDate: Date) + local procedure VerifyQuantityInRequisitionLine(Item: Record Item; Quantity: Decimal) var RequisitionLine: Record "Requisition Line"; begin FindRequisitionLine(RequisitionLine, Item."No."); RequisitionLine.TestField(Quantity, Quantity); - RequisitionLine.TestField("Due Date", CalcDate(Item."Lead Time Calculation", WorkDate())); - InventorySetup.Get(); - RequisitionLine.TestField( - "Order Date", CalcDate('<' + '-' + Format(InventorySetup."Default Safety Lead Time") + '>', OrderDate)); end; local procedure VerifyPlanningRoutingLine(RoutingHeader: Record "Routing Header"; RequisitionWkshName: Record "Requisition Wksh. Name"; ItemNo: Code[20]; Quantity: Integer) diff --git a/src/Layers/IT/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al b/src/Layers/IT/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al index fec2faff158..7d29e2a587b 100644 --- a/src/Layers/IT/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al +++ b/src/Layers/IT/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al @@ -1517,7 +1517,7 @@ codeunit 137077 "SCM Supply Planning -IV" if MakeToOrder then UpdateItemManufacturingPolicy(Item, Item."Manufacturing Policy"::"Make-to-Order"); UpdateItemLeadTimeCalculation(Item, '<' + Format(LibraryRandom.RandInt(5) + 10) + 'D>'); // Random Lead Time Calculation. - CreateSalesOrder(Item."No.", ''); + CreateSalesOrderWithShipmentDate(Item."No.", '', LibraryRandom.RandInt(10), CalcDate('<1M>', WorkDate())); // Exercise: Open Order Promising Lines Page and Invoke Capable to Promise Action. FindSalesLine(SalesLine, Item."No."); @@ -5136,6 +5136,15 @@ codeunit 137077 "SCM Supply Planning -IV" LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, Quantity); end; + local procedure CreateSalesOrderWithShipmentDate(ItemNo: Code[20]; CustomerNo: Code[20]; Quantity: Decimal; ShipmentDate: Date) + var + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + begin + LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Order, CustomerNo); + LibrarySales.CreateSalesLineWithShipmentDate(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, ShipmentDate, Quantity); + end; + local procedure CreateSalesOrderAtLocation(ItemNo: Code[20]; LocationCode: Code[10]) var SalesHeader: Record "Sales Header"; diff --git a/src/Layers/W1/BaseApp/Inventory/Requisition/RequisitionLine.Table.al b/src/Layers/W1/BaseApp/Inventory/Requisition/RequisitionLine.Table.al index 24f99645e05..37505143483 100644 --- a/src/Layers/W1/BaseApp/Inventory/Requisition/RequisitionLine.Table.al +++ b/src/Layers/W1/BaseApp/Inventory/Requisition/RequisitionLine.Table.al @@ -442,12 +442,10 @@ table 246 "Requisition Line" trigger OnValidate() begin - "Starting Date" := "Order Date"; - GetDirectCost(FieldNo("Order Date")); if CurrFieldNo = FieldNo("Order Date") then - Validate("Starting Date"); + Validate("Starting Date", "Order Date"); end; } field(22; "Vendor Item No."; Text[50]) @@ -2779,7 +2777,11 @@ table 246 "Requisition Line" IsHandled := false; OnCalcStartingDateOnBeforeValidateOrderDate(Rec, LeadTime, IsHandled); if not IsHandled then - Validate("Order Date", "Starting Date"); + // Don't use order date in the past for price calculation + if "Starting Date" >= WorkDate() then + Validate("Order Date", "Starting Date") + else + Validate("Order Date", WorkDate()); if "Ref. Order Type" = "Ref. Order Type"::Transfer then CalcTransferShipmentDate(); @@ -2898,7 +2900,11 @@ table 246 "Requisition Line" begin "Demand Date" := DemandDate; "Starting Date" := "Demand Date"; - "Order Date" := "Demand Date"; + // Don't use order date in the past for price calculation + if DemandDate >= WorkDate() then + "Order Date" := "Demand Date" + else + "Order Date" := WorkDate(); Validate("Due Date", "Demand Date"); if "Planning Level" = 0 then begin diff --git a/src/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al b/src/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al index b9107f48410..c270218dc79 100644 --- a/src/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al +++ b/src/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing70.Codeunit.al @@ -344,8 +344,8 @@ codeunit 137063 "SCM Manufacturing 7.0" // Exercise: Run Planning Worksheet. LibraryPlanning.CalcRegenPlanForPlanWksh(ParentItem, WorkDate(), WorkDate()); - // Verify: Verify Quantity and Dates in Requisition line. - VerifyValueInRequisitionLine(ParentItem, SalesLine.Quantity, SalesHeader."Order Date"); + // Verify: Verify Quantity in Requisition line. + VerifyQuantityInRequisitionLine(ParentItem, SalesLine.Quantity); // Exercise: Run Carry Out Action Messages to create a Production Order. CarryOutActionMsgForItem(ParentItem."No."); @@ -3033,11 +3033,11 @@ codeunit 137063 "SCM Manufacturing 7.0" LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); // [WHEN] Run Calculation Plan from Req Worksheet for created Item - CalculatePlanForReqWksh(Item, CalcDate('<-CY>', WorkDate()), CalcDate('', WorkDate())); + CalculatePlanForReqWksh(Item, WorkDate(), CalcDate('', WorkDate())); // [THEN] Verify Order Date in Requisition line is calculated correctly FindRequisitionLine(RequisitionLine, Item."No."); - RequisitionLine.TestField("Order Date", CalcDate('<-CY>', WorkDate())); + RequisitionLine.TestField("Order Date", WorkDate()); end; #if not CLEAN29 @@ -5473,16 +5473,12 @@ codeunit 137063 "SCM Manufacturing 7.0" "Due Date", CalcDate(InventorySetup."Default Safety Lead Time", CalcDate(Item."Lead Time Calculation", WorkDate()))); end; - local procedure VerifyValueInRequisitionLine(Item: Record Item; Quantity: Decimal; OrderDate: Date) + local procedure VerifyQuantityInRequisitionLine(Item: Record Item; Quantity: Decimal) var RequisitionLine: Record "Requisition Line"; begin FindRequisitionLine(RequisitionLine, Item."No."); RequisitionLine.TestField(Quantity, Quantity); - RequisitionLine.TestField("Due Date", CalcDate(Item."Lead Time Calculation", WorkDate())); - InventorySetup.Get(); - RequisitionLine.TestField( - "Order Date", CalcDate('<' + '-' + Format(InventorySetup."Default Safety Lead Time") + '>', OrderDate)); end; local procedure VerifyPlanningRoutingLine(RoutingHeader: Record "Routing Header"; RequisitionWkshName: Record "Requisition Wksh. Name"; ItemNo: Code[20]; Quantity: Integer) diff --git a/src/Layers/W1/Tests/SCM-Planning/SCMOrderPlanningIII.Codeunit.al b/src/Layers/W1/Tests/SCM-Planning/SCMOrderPlanningIII.Codeunit.al index f8b18353cba..ffa9a5c3b36 100644 --- a/src/Layers/W1/Tests/SCM-Planning/SCMOrderPlanningIII.Codeunit.al +++ b/src/Layers/W1/Tests/SCM-Planning/SCMOrderPlanningIII.Codeunit.al @@ -2206,7 +2206,7 @@ codeunit 137088 "SCM Order Planning - III" ItemVendor.Validate("Lead Time Calculation", LeadTimeFormula); ItemVendor.Modify(true); - CreateSalesOrder(SalesHeader, Item."No.", '', Qty, Qty); + CreateSalesOrderWithShipmentDate(SalesHeader, Item."No.", '', Qty, Qty, CalcDate('<1M>', WorkDate())); FindSalesLine(SalesLine, SalesHeader, Item."No."); LibraryVariableStorage.Enqueue(Vendor."No."); @@ -2249,7 +2249,7 @@ codeunit 137088 "SCM Order Planning - III" ItemVendor.Validate("Lead Time Calculation", LeadTimeFormula); ItemVendor.Modify(true); - CreateSalesOrder(SalesHeader, Item."No.", '', Qty, Qty); + CreateSalesOrderWithShipmentDate(SalesHeader, Item."No.", '', Qty, Qty, CalcDate('<1M>', WorkDate())); FindSalesLine(SalesLine, SalesHeader, Item."No."); LibraryVariableStorage.Enqueue(Vendor."No."); @@ -4101,6 +4101,15 @@ codeunit 137088 "SCM Order Planning - III" SalesLine.Modify(true); end; + local procedure CreateSalesOrderWithShipmentDate(var SalesHeader: Record "Sales Header"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal; QtyToShip: Decimal; ShipmentDate: Date) + begin + Clear(SalesHeader); + LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Order, ''); + SalesHeader.Validate("Location Code", LocationCode); + SalesHeader.Modify(true); + CreateSalesLine(SalesHeader, ItemNo, LocationCode, ShipmentDate, Quantity, QtyToShip); + end; + local procedure CreateLocation(var Location: Record Location) begin Clear(Location); diff --git a/src/Layers/W1/Tests/SCM-Planning/SCMPlanReqWksht.Codeunit.al b/src/Layers/W1/Tests/SCM-Planning/SCMPlanReqWksht.Codeunit.al index 51fdf06ef25..eb294253f83 100644 --- a/src/Layers/W1/Tests/SCM-Planning/SCMPlanReqWksht.Codeunit.al +++ b/src/Layers/W1/Tests/SCM-Planning/SCMPlanReqWksht.Codeunit.al @@ -34,6 +34,7 @@ LibraryERM: Codeunit "Library - ERM"; AvailabilityMgt: Codeunit AvailabilityManagement; LibraryReportDataset: Codeunit "Library - Report Dataset"; + LibraryPriceCalculation: Codeunit "Library - Price Calculation"; isInitialized: Boolean; RequisitionLineMustNotExistTxt: Label 'Requisition Line must not exist for Item %1.', Comment = '%1 = Item No.'; ShipmentDateMessageTxt: Label 'Shipment Date'; @@ -5665,6 +5666,74 @@ Assert.AreEqual(ExpectedQty, PlanningComponent."Expected Quantity", 'Expected Quantity should be rounded up by Qty. Rounding Precision'); end; + [Test] + procedure CurrentPriceWhenUsingOldDate() + var + Item: Record Item; + ItemVendor: Record "Item Vendor"; + PriceListLine: Record "Price List Line"; + RequisitionLine: Record "Requisition Line"; + Vendor: Record Vendor; + begin + // [SCENARIO] Rush orders should not get an old price + // [FEATURE] [Requisition Line] [Purchase Price Calculation] + Initialize(); + + // [GIVEN] New pricing enabled + LibraryPriceCalculation.EnableExtendedPriceCalculation(); + + // [GIVEN] Default price calculation is 'V16' + LibraryPriceCalculation.SetupDefaultHandler("Price Calculation Handler"::"Business Central (Version 16.0)"); + + // [GIVEN] Item with vendor. + LibraryInventory.CreateItem(Item); + LibraryPurchase.CreateVendor(Vendor); + UpdateItemVendorNo(Item, Vendor."No."); + + // [GIVEN] Item Vendor with Lead Time Calculation + LibraryInventory.CreateItemVendor(ItemVendor, Vendor."No.", Item."No."); + Evaluate(ItemVendor."Lead Time Calculation", '<1W>'); + ItemVendor.Modify(); + + // [GIVEN] Price List Line for the item and vendor using an old date range. + LibraryPriceCalculation.CreatePurchPriceLine( + PriceListLine, PriceListLine."Price List Code", + "Price Source Type"::Vendor, Vendor."No.", "Price Asset Type"::Item, Item."No."); + PriceListLine.Validate("Direct Unit Cost", LibraryRandom.RandDecInRange(10, 20, 2)); + PriceListLine.Status := PriceListLine.Status::Active; + PriceListLine.Validate("Ending Date", WorkDate() - 1); + PriceListLine.Modify(true); + + // [GIVEN] Price List Line for the item and vendor using a new date range. + PriceListLine.Init(); + LibraryPriceCalculation.CreatePurchPriceLine( + PriceListLine, PriceListLine."Price List Code", + "Price Source Type"::Vendor, Vendor."No.", "Price Asset Type"::Item, Item."No."); + PriceListLine.Validate("Direct Unit Cost", LibraryRandom.RandDecInRange(30, 60, 2)); + PriceListLine.Status := PriceListLine.Status::Active; + PriceListLine.Validate("Starting Date", WorkDate()); + PriceListLine.Modify(true); + + // [GIVEN] A requisition line for the item and vendor + CreateRequisitionLine(RequisitionLine); + RequisitionLine.Validate(Type, RequisitionLine.Type::Item); + RequisitionLine.Validate("No.", Item."No."); + RequisitionLine.Validate("Vendor No.", Vendor."No."); + RequisitionLine.Validate(Quantity, LibraryRandom.RandIntInRange(1, 10)); + RequisitionLine.Modify(true); + + // [WHEN] Setting ending date to workdate, requiring the item to be ordered in the past according to the lead time + RequisitionLine.Validate("Ending Date", WorkDate()); + RequisitionLine.Modify(true); + + // [THEN] The price should still be current and not pick the price when the order should have been placed. + Assert.AreEqual(PriceListLine."Direct Unit Cost", RequisitionLine."Direct Unit Cost", 'Price Calculation did not pick new price'); + + // [THEN] Order date should be later than starting date. + Assert.AreEqual(RequisitionLine."Order Date", WorkDate(), 'Order Date is not set to current date'); + Assert.IsTrue(RequisitionLine."Starting Date" < RequisitionLine."Order Date", 'Starting Date is not earlier than Order Date'); + end; + local procedure Initialize() var AllProfile: Record "All Profile"; diff --git a/src/Layers/W1/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al b/src/Layers/W1/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al index 0bcd00bfb62..ce8dcf12fac 100644 --- a/src/Layers/W1/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al +++ b/src/Layers/W1/Tests/SCM-Planning/SCMSupplyPlanningIV.Codeunit.al @@ -1517,7 +1517,7 @@ codeunit 137077 "SCM Supply Planning -IV" if MakeToOrder then UpdateItemManufacturingPolicy(Item, Item."Manufacturing Policy"::"Make-to-Order"); UpdateItemLeadTimeCalculation(Item, '<' + Format(LibraryRandom.RandInt(5) + 10) + 'D>'); // Random Lead Time Calculation. - CreateSalesOrder(Item."No.", ''); + CreateSalesOrderWithShipmentDate(Item."No.", '', LibraryRandom.RandInt(10), CalcDate('<1M>', WorkDate())); // Exercise: Open Order Promising Lines Page and Invoke Capable to Promise Action. FindSalesLine(SalesLine, Item."No."); @@ -5121,6 +5121,15 @@ codeunit 137077 "SCM Supply Planning -IV" LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, Quantity); end; + local procedure CreateSalesOrderWithShipmentDate(ItemNo: Code[20]; CustomerNo: Code[20]; Quantity: Decimal; ShipmentDate: Date) + var + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + begin + LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Order, CustomerNo); + LibrarySales.CreateSalesLineWithShipmentDate(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, ShipmentDate, Quantity); + end; + local procedure CreateSalesOrderAtLocation(ItemNo: Code[20]; LocationCode: Code[10]) var SalesHeader: Record "Sales Header";