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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,6 @@ codeunit 6212 "Sustainability Post Mgt"
if TotalCO2e < 0 then
IsNegativeEntry := true;

if ItemLedgerEntry."Entry Type" = ItemLedgerEntry."Entry Type"::Transfer then begin
TotalCO2e := Abs(CO2ePerUnit * ItemLedgerEntry.Quantity);
CorrectSign(TotalCO2e, IsNegativeEntry);
exit;
end;

ShowAppliedEntries.FindAppliedEntries(ItemLedgerEntry, TempItemLedgerEntry);
if TempItemLedgerEntry.IsEmpty() then
GetILEForAssemblyOutputs(ItemLedgerEntry, TempItemLedgerEntry);
Expand All @@ -296,6 +290,15 @@ codeunit 6212 "Sustainability Post Mgt"
GetCO2eAmountAndQuantity(TempItemLedgerEntry."Entry No.", AppliedAmount, AppliedQuantity);
until TempItemLedgerEntry.Next() = 0;

if ItemLedgerEntry."Entry Type" = ItemLedgerEntry."Entry Type"::Transfer then begin
if AppliedQuantity <> 0 then
TotalCO2e := Abs((AppliedAmount / AppliedQuantity) * ItemLedgerEntry.Quantity)
else
TotalCO2e := Abs(CO2ePerUnit * ItemLedgerEntry.Quantity);
CorrectSign(TotalCO2e, IsNegativeEntry);
exit;
end;

if AppliedAmount = 0 then
exit;

Expand Down
224 changes: 224 additions & 0 deletions src/Apps/W1/Sustainability/test/src/SustValueEntryTest.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -4178,6 +4178,204 @@ codeunit 148190 "Sust. Value Entry Test"
Navigate.Run();
end;

[Test]
procedure VerifyItemReclassUsesSpecificLotCO2eForSpecificCarbonTracking()
var
Item: Record Item;
FromLocation: Record Location;
ToLocation: Record Location;
ItemJournalBatch: Record "Item Journal Batch";
ItemJournalLine: Record "Item Journal Line";
ReservationEntry: Record "Reservation Entry";
SustainabilityValueEntry: Record "Sustainability Value Entry";
CategoryCode: Code[20];
SubcategoryCode: Code[20];
AccountCode: Code[20];
LotNo: array[2] of Code[50];
LotTotalCO2e: array[2] of Decimal;
Quantity: Decimal;
begin
// [SCENARIO 641309] Item Reclassification (location move) of a Specific carbon tracking item must transfer the
LibrarySustainability.CleanUpBeforeTesting();

// [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup.
LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true);

// [GIVEN] Create source and destination Locations.
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(FromLocation);
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ToLocation);

// [GIVEN] Create a Sustainability Account.
CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10));

// [GIVEN] Create a lot-tracked Item with Specific Carbon Tracking Method and a Default Sust. Account.
LibraryItemTracking.CreateLotItem(Item);
LibrarySustainability.UpdateCarbonTrackingMethod(Item, Item."Carbon Tracking Method"::Specific);
Item.Validate("Default Sust. Account", AccountCode);
Item.Modify();

// [GIVEN] Post inventory for two lots with clearly different tracked CO2e per unit (so specific <> average).
Quantity := LibraryRandom.RandIntInRange(10, 10);
PostTwoLotsWithSpecificCO2e(Item, FromLocation.Code, AccountCode, Quantity, LotNo, LotTotalCO2e);

// [GIVEN] Create an Item Reclassification (Transfer) line moving the full quantity of the second lot to another location.
CreateItemReclassLine(ItemJournalBatch, ItemJournalLine, Item."No.", FromLocation.Code, ToLocation.Code, AccountCode, Quantity);

// [GIVEN] Set an averaged (incorrect) Total CO2e on the line to satisfy the non-zero validation; posting must ignore it.
ItemJournalLine.Validate("Total CO2e", LotTotalCO2e[1]);
ItemJournalLine.Modify(true);

// [GIVEN] Assign reclassification item tracking selecting the second lot (keeping the same lot on the new location).
LibraryItemTracking.CreateItemReclassJnLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo[2], Quantity);
ReservationEntry.Validate("New Lot No.", ReservationEntry."Lot No.");
ReservationEntry.Modify();

// [WHEN] Post the Item Reclassification Journal.
LibraryInventory.PostItemJournalBatch(ItemJournalBatch);

// [THEN] The Sustainability Value Entry reflects the specific tracked CO2e of the moved lot, not the averaged value.
SustainabilityValueEntry.SetRange("Item No.", Item."No.");
SustainabilityValueEntry.SetRange("Item Ledger Entry Type", SustainabilityValueEntry."Item Ledger Entry Type"::Transfer);
SustainabilityValueEntry.FindFirst();
Assert.AreEqual(
LotTotalCO2e[2],
SustainabilityValueEntry."CO2e Amount (Actual)",
StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), LotTotalCO2e[2], SustainabilityValueEntry.TableCaption()));
end;

[Test]
procedure VerifyItemReclassUsesFirstSelectedLotCO2eForSpecificCarbonTracking()
var
Item: Record Item;
FromLocation: Record Location;
ToLocation: Record Location;
ItemJournalBatch: Record "Item Journal Batch";
ItemJournalLine: Record "Item Journal Line";
ReservationEntry: Record "Reservation Entry";
SustainabilityValueEntry: Record "Sustainability Value Entry";
CategoryCode: Code[20];
SubcategoryCode: Code[20];
AccountCode: Code[20];
LotNo: array[2] of Code[50];
LotTotalCO2e: array[2] of Decimal;
Quantity: Decimal;
begin
// [SCENARIO 641309] Item Reclassification must follow the CO2e of whichever specific lot is moved (here the first lot).
LibrarySustainability.CleanUpBeforeTesting();

// [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup.
LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true);

// [GIVEN] Create source and destination Locations.
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(FromLocation);
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ToLocation);

// [GIVEN] Create a Sustainability Account.
CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10));

// [GIVEN] Create a lot-tracked Item with Specific Carbon Tracking Method and a Default Sust. Account.
LibraryItemTracking.CreateLotItem(Item);
LibrarySustainability.UpdateCarbonTrackingMethod(Item, Item."Carbon Tracking Method"::Specific);
Item.Validate("Default Sust. Account", AccountCode);
Item.Modify();

// [GIVEN] Post inventory for two lots with clearly different tracked CO2e per unit.
Quantity := LibraryRandom.RandIntInRange(10, 10);
PostTwoLotsWithSpecificCO2e(Item, FromLocation.Code, AccountCode, Quantity, LotNo, LotTotalCO2e);

// [GIVEN] Create an Item Reclassification (Transfer) line moving the full quantity of the first lot to another location.
CreateItemReclassLine(ItemJournalBatch, ItemJournalLine, Item."No.", FromLocation.Code, ToLocation.Code, AccountCode, Quantity);

// [GIVEN] Set an averaged (incorrect) Total CO2e on the line to satisfy the non-zero validation; posting must ignore it.
ItemJournalLine.Validate("Total CO2e", LotTotalCO2e[2]);
ItemJournalLine.Modify(true);

// [GIVEN] Assign reclassification item tracking selecting the first lot (keeping the same lot on the new location).
LibraryItemTracking.CreateItemReclassJnLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo[1], Quantity);
ReservationEntry.Validate("New Lot No.", ReservationEntry."Lot No.");
ReservationEntry.Modify();

// [WHEN] Post the Item Reclassification Journal.
LibraryInventory.PostItemJournalBatch(ItemJournalBatch);

// [THEN] The Sustainability Value Entry reflects the specific tracked CO2e of the first lot.
SustainabilityValueEntry.SetRange("Item No.", Item."No.");
SustainabilityValueEntry.SetRange("Item Ledger Entry Type", SustainabilityValueEntry."Item Ledger Entry Type"::Transfer);
SustainabilityValueEntry.FindFirst();
Assert.AreEqual(
LotTotalCO2e[1],
SustainabilityValueEntry."CO2e Amount (Actual)",
StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), LotTotalCO2e[1], SustainabilityValueEntry.TableCaption()));
end;

[Test]
procedure VerifyItemReclassSumsSpecificLotCO2eWhenMovingMultipleLots()
var
Item: Record Item;
FromLocation: Record Location;
ToLocation: Record Location;
ItemJournalBatch: Record "Item Journal Batch";
ItemJournalLine: Record "Item Journal Line";
ReservationEntry: Record "Reservation Entry";
SustainabilityValueEntry: Record "Sustainability Value Entry";
CategoryCode: Code[20];
SubcategoryCode: Code[20];
AccountCode: Code[20];
LotNo: array[2] of Code[50];
LotTotalCO2e: array[2] of Decimal;
Quantity: Decimal;
Index: Integer;
begin
// [SCENARIO 641309] Moving two specific lots in one Item Reclassification must transfer the sum of the specific lot CO2e
LibrarySustainability.CleanUpBeforeTesting();

// [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup.
LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true);

// [GIVEN] Create source and destination Locations.
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(FromLocation);
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ToLocation);

// [GIVEN] Create a Sustainability Account.
CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10));

// [GIVEN] Create a lot-tracked Item with Specific Carbon Tracking Method and a Default Sust. Account.
LibraryItemTracking.CreateLotItem(Item);
LibrarySustainability.UpdateCarbonTrackingMethod(Item, Item."Carbon Tracking Method"::Specific);
Item.Validate("Default Sust. Account", AccountCode);
Item.Modify();

// [GIVEN] Post inventory for two lots with clearly different tracked CO2e per unit.
Quantity := LibraryRandom.RandIntInRange(10, 10);
PostTwoLotsWithSpecificCO2e(Item, FromLocation.Code, AccountCode, Quantity, LotNo, LotTotalCO2e);

// [GIVEN] Create an Item Reclassification (Transfer) line moving both lots (full quantity) to another location.
CreateItemReclassLine(ItemJournalBatch, ItemJournalLine, Item."No.", FromLocation.Code, ToLocation.Code, AccountCode, Quantity * ArrayLen(LotNo));

// [GIVEN] Set a non-zero Total CO2e on the line to satisfy the non-zero validation; posting must ignore it.
ItemJournalLine.Validate("Total CO2e", LotTotalCO2e[1]);
ItemJournalLine.Modify(true);

// [GIVEN] Assign reclassification item tracking selecting both lots (keeping the same lot on the new location).
for Index := 1 to ArrayLen(LotNo) do begin
LibraryItemTracking.CreateItemReclassJnLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo[Index], Quantity);
ReservationEntry.Validate("New Lot No.", ReservationEntry."Lot No.");
ReservationEntry.Modify();
end;

// [WHEN] Post the Item Reclassification Journal.
LibraryInventory.PostItemJournalBatch(ItemJournalBatch);

// [THEN] The total transferred CO2e equals the sum of the specific lot CO2e values.
SustainabilityValueEntry.SetRange("Item No.", Item."No.");
SustainabilityValueEntry.SetRange("Item Ledger Entry Type", SustainabilityValueEntry."Item Ledger Entry Type"::Transfer);
SustainabilityValueEntry.CalcSums("CO2e Amount (Actual)");
Assert.AreEqual(
LotTotalCO2e[1] + LotTotalCO2e[2],
SustainabilityValueEntry."CO2e Amount (Actual)",
StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), LotTotalCO2e[1] + LotTotalCO2e[2], SustainabilityValueEntry.TableCaption()));
end;

local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer): Record "Sustainability Account"
begin
CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i);
Expand Down Expand Up @@ -4344,6 +4542,32 @@ codeunit 148190 "Sust. Value Entry Test"
exit(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true));
end;

local procedure PostTwoLotsWithSpecificCO2e(Item: Record Item; LocationCode: Code[10]; AccountCode: Code[20]; Quantity: Decimal; var LotNo: array[2] of Code[50]; var LotTotalCO2e: array[2] of Decimal)
var
Index: Integer;
begin
for Index := 1 to ArrayLen(LotNo) do
LotNo[Index] := LibraryUtility.GenerateGUID();

LotTotalCO2e[1] := LibraryRandom.RandDecInRange(100, 200, 2);
LotTotalCO2e[2] := LibraryRandom.RandDecInRange(400, 600, 2);

for Index := 1 to ArrayLen(LotNo) do
LibrarySustainability.PostPositiveAdjustmentWithItemTracking(
Item, LocationCode, AccountCode, '', Quantity, WorkDate(), '', LotNo[Index], LotTotalCO2e[Index]);
end;

local procedure CreateItemReclassLine(var ItemJournalBatch: Record "Item Journal Batch"; var ItemJournalLine: Record "Item Journal Line"; ItemNo: Code[20]; FromLocationCode: Code[10]; ToLocationCode: Code[10]; AccountCode: Code[20]; Quantity: Decimal)
begin
SelectItemJournalTransferBatch(ItemJournalBatch);
LibraryInventory.CreateItemJournalLine(
ItemJournalLine, ItemJournalBatch."Journal Template Name", ItemJournalBatch.Name,
ItemJournalLine."Entry Type"::Transfer, ItemNo, Quantity);
ItemJournalLine.Validate("Location Code", FromLocationCode);
ItemJournalLine.Validate("New Location Code", ToLocationCode);
ItemJournalLine.Validate("Sust. Account No.", AccountCode);
end;

local procedure PostInventoryForItem(ItemNo: Code[20])
var
ItemJournalBatch: Record "Item Journal Batch";
Expand Down
Loading