diff --git a/src/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al b/src/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al index 930e988661e..9dac5126b0e 100644 --- a/src/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al +++ b/src/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al @@ -8,6 +8,8 @@ using Microsoft.Sustainability.Journal; codeunit 6218 "Sustainability Calc. Mgt." { var + EmissionScopeCache: Dictionary of [Code[20], Enum "Emission Scope"]; + CalculationFoundationCache: Dictionary of [Code[20], Enum "Calculation Foundation"]; FromToFilterLbl: Label '%1..%2', Locked = true; internal procedure CalculationEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") @@ -109,6 +111,102 @@ codeunit 6218 "Sustainability Calc. Mgt." PurchaseLine.Validate("Emission N2O", 0); end; + internal procedure GetFormulaInputEditability(SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var FuelElectricityEditable: Boolean; var DistanceEditable: Boolean; var CustomAmountEditable: Boolean; var InstallationMultiplierEditable: Boolean; var TimeFactorEditable: Boolean) + begin + Clear(FuelElectricityEditable); + Clear(DistanceEditable); + Clear(CustomAmountEditable); + Clear(InstallationMultiplierEditable); + Clear(TimeFactorEditable); + + if SustainabilityJnlLine."Manual Input" then + exit; + + GetFormulaInputEditability(SustainabilityJnlLine."Account Category", false, FuelElectricityEditable, DistanceEditable, CustomAmountEditable, InstallationMultiplierEditable, TimeFactorEditable); + end; + + internal procedure GetFormulaInputEditability(PurchaseLine: Record "Purchase Line"; var FuelElectricityEditable: Boolean; var DistanceEditable: Boolean; var CustomAmountEditable: Boolean; var InstallationMultiplierEditable: Boolean; var TimeFactorEditable: Boolean) + begin + Clear(FuelElectricityEditable); + Clear(DistanceEditable); + Clear(CustomAmountEditable); + Clear(InstallationMultiplierEditable); + Clear(TimeFactorEditable); + + GetFormulaInputEditability(PurchaseLine."Sust. Account Category", true, FuelElectricityEditable, DistanceEditable, CustomAmountEditable, InstallationMultiplierEditable, TimeFactorEditable); + end; + + local procedure GetFormulaInputEditability(AccountCategoryCode: Code[20]; PurchaseSurface: Boolean; var FuelElectricityEditable: Boolean; var DistanceEditable: Boolean; var CustomAmountEditable: Boolean; var InstallationMultiplierEditable: Boolean; var TimeFactorEditable: Boolean) + var + EmissionScope: Enum "Emission Scope"; + CalculationFoundation: Enum "Calculation Foundation"; + begin + Clear(FuelElectricityEditable); + Clear(DistanceEditable); + Clear(CustomAmountEditable); + Clear(InstallationMultiplierEditable); + Clear(TimeFactorEditable); + + if not GetCalculationParameters(AccountCategoryCode, EmissionScope, CalculationFoundation) then + exit; + + case EmissionScope of + Enum::"Emission Scope"::"Scope 1": + case CalculationFoundation of + Enum::"Calculation Foundation"::"Fuel/Electricity": + FuelElectricityEditable := true; + Enum::"Calculation Foundation"::Distance: + DistanceEditable := true; + Enum::"Calculation Foundation"::Installations: + begin + CustomAmountEditable := true; + InstallationMultiplierEditable := true; + TimeFactorEditable := true; + end; + end; + Enum::"Emission Scope"::"Scope 2": + case CalculationFoundation of + Enum::"Calculation Foundation"::"Fuel/Electricity": + FuelElectricityEditable := true; + Enum::"Calculation Foundation"::Custom: + CustomAmountEditable := true; + end; + Enum::"Emission Scope"::"Scope 3": + case CalculationFoundation of + Enum::"Calculation Foundation"::"Fuel/Electricity": + FuelElectricityEditable := true; + Enum::"Calculation Foundation"::Distance: + begin + DistanceEditable := true; + InstallationMultiplierEditable := true; + end; + Enum::"Calculation Foundation"::Custom: + CustomAmountEditable := true; + end; + Enum::"Emission Scope"::"Water/Waste": + if (not PurchaseSurface) and (CalculationFoundation = Enum::"Calculation Foundation"::Custom) then + CustomAmountEditable := true; + end; + end; + + local procedure GetCalculationParameters(AccountCategoryCode: Code[20]; var EmissionScope: Enum "Emission Scope"; var CalculationFoundation: Enum "Calculation Foundation"): Boolean + var + SustainAccountCategory: Record "Sustain. Account Category"; + begin + if EmissionScopeCache.Get(AccountCategoryCode, EmissionScope) and CalculationFoundationCache.Get(AccountCategoryCode, CalculationFoundation) then + exit(true); + + SustainAccountCategory.SetLoadFields("Emission Scope", "Calculation Foundation"); + if not SustainAccountCategory.Get(AccountCategoryCode) then + exit(false); + + EmissionScope := SustainAccountCategory."Emission Scope"; + CalculationFoundation := SustainAccountCategory."Calculation Foundation"; + EmissionScopeCache.Set(AccountCategoryCode, EmissionScope); + CalculationFoundationCache.Set(AccountCategoryCode, CalculationFoundation); + exit(true); + end; + /// /// Filter general ledger entries by criteria defined in sustainability category and by date and calculate the total /// diff --git a/src/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al b/src/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al index 5e4f348c7f5..d5781768320 100644 --- a/src/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al +++ b/src/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al @@ -122,6 +122,7 @@ page 6219 "Sustainability Journal" DimMgt: Codeunit DimensionManagement; begin DimMgt.GetShortcutDimensions(Rec."Dimension Set ID", ShortcutDimCode); + SetFormulaInputEditability(); CurrPage.Update(); end; } @@ -150,6 +151,11 @@ page 6219 "Sustainability Journal" field("Manual Input"; Rec."Manual Input") { ToolTip = 'Specifies whether the amounts will be input manually.'; + + trigger OnValidate() + begin + SetFormulaInputEditability(); + end; } field("Renewable Energy"; Rec."Renewable Energy") { @@ -166,7 +172,7 @@ page 6219 "Sustainability Journal" } field("Fuel/Electricity"; Rec."Fuel/Electricity") { - Editable = not Rec."Manual Input"; + Editable = FuelElectricityEditable; ToolTip = 'Specifies the fuel or electricity of the journal line.'; trigger OnValidate() begin @@ -175,7 +181,7 @@ page 6219 "Sustainability Journal" } field(Distance; Rec.Distance) { - Editable = not Rec."Manual Input"; + Editable = DistanceEditable; ToolTip = 'Specifies the distance of the journal line.'; trigger OnValidate() begin @@ -184,7 +190,7 @@ page 6219 "Sustainability Journal" } field("Custom Amount"; Rec."Custom Amount") { - Editable = not Rec."Manual Input"; + Editable = CustomAmountEditable; ToolTip = 'Specifies the custom amount of the journal line.'; trigger OnValidate() begin @@ -193,12 +199,12 @@ page 6219 "Sustainability Journal" } field("Installation Multiplier"; Rec."Installation Multiplier") { - Editable = not Rec."Manual Input"; + Editable = InstallationMultiplierEditable; ToolTip = 'Specifies the installation multiplier of the journal line.'; } field("Time Factor"; Rec."Time Factor") { - Editable = not Rec."Manual Input"; + Editable = TimeFactorEditable; ToolTip = 'Specifies the time factor of the journal line.'; } field("Emission CO2"; Rec."Emission CO2") @@ -698,10 +704,13 @@ page 6219 "Sustainability Journal" var SustApprovalMgmt: Codeunit "Sust. Approvals Mgmt."; + SustainabilityCalcMgt: Codeunit "Sustainability Calc. Mgt."; CurrentJournalBatchName: Code[10]; ShortcutDimCode: array[8] of Code[20]; DimVisible1, DimVisible2, DimVisible3, DimVisible4, DimVisible5, DimVisible6, DimVisible7, DimVisible8 : Boolean; IsRecurringView, EnableWater, EnableWaste : Boolean; + FuelElectricityEditable, DistanceEditable, CustomAmountEditable : Boolean; + InstallationMultiplierEditable, TimeFactorEditable : Boolean; OpenApprovalEntriesOnBatchOrAnyJnlLineExist: Boolean; EnabledSustJnlBatchWorkflowsExist: Boolean; ShowWorkflowStatusOnBatch: Boolean; @@ -729,12 +738,14 @@ page 6219 "Sustainability Journal" begin DimMgt.GetShortcutDimensions(Rec."Dimension Set ID", ShortcutDimCode); InitializeAndEnableIntensityControl(); + SetFormulaInputEditability(); SetControlAppearanceFromBatch(); end; trigger OnAfterGetCurrRecord() begin InitializeAndEnableIntensityControl(); + SetFormulaInputEditability(); SetControlAppearanceFromBatch(); SustApprovalMgmt.GetSustJnlBatchApprovalStatus(Rec, SustJnlBatchApprovalStatus, EnabledSustJnlBatchWorkflowsExist); @@ -813,6 +824,11 @@ page 6219 "Sustainability Journal" EnableWaste := false; end; + local procedure SetFormulaInputEditability() + begin + SustainabilityCalcMgt.GetFormulaInputEditability(Rec, FuelElectricityEditable, DistanceEditable, CustomAmountEditable, InstallationMultiplierEditable, TimeFactorEditable); + end; + local procedure SetControlAppearanceFromBatch() var SustJournalBatch: Record "Sustainability Jnl. Batch"; diff --git a/src/Apps/W1/Sustainability/app/src/Purchase/SustPurchOrderSubform.PageExt.al b/src/Apps/W1/Sustainability/app/src/Purchase/SustPurchOrderSubform.PageExt.al index 3a279a003ba..1e9aa468e84 100644 --- a/src/Apps/W1/Sustainability/app/src/Purchase/SustPurchOrderSubform.PageExt.al +++ b/src/Apps/W1/Sustainability/app/src/Purchase/SustPurchOrderSubform.PageExt.al @@ -1,6 +1,7 @@ namespace Microsoft.Sustainability.Purchase; using Microsoft.Purchases.Document; +using Microsoft.Sustainability.Calculation; using Microsoft.Sustainability.Setup; pageextension 6211 "Sust. Purch. Order Subform" extends "Purchase Order Subform" @@ -14,6 +15,11 @@ pageextension 6211 "Sust. Purch. Order Subform" extends "Purchase Order Subform" Visible = SustainabilityVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + + trigger OnValidate() + begin + SetFormulaInputEditability(); + end; } field("Energy Source Code"; Rec."Energy Source Code") { @@ -32,30 +38,35 @@ pageextension 6211 "Sust. Purch. Order Subform" extends "Purchase Order Subform" } field("Fuel/Electricity"; Rec."Fuel/Electricity") { + Editable = FuelElectricityEditable; Visible = SustainabilityFormulasFieldVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the fuel or electricity of the purchase line.'; } field(Distance; Rec.Distance) { + Editable = DistanceEditable; Visible = SustainabilityFormulasFieldVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the distance of the purchase line.'; } field("Custom Amount"; Rec."Custom Amount") { + Editable = CustomAmountEditable; Visible = SustainabilityFormulasFieldVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the custom amount of the purchase line.'; } field("Installation Multiplier"; Rec."Installation Multiplier") { + Editable = InstallationMultiplierEditable; Visible = SustainabilityFormulasFieldVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the installation multiplier of the purchase line.'; } field("Time Factor"; Rec."Time Factor") { + Editable = TimeFactorEditable; Visible = SustainabilityFormulasFieldVisible; ApplicationArea = Basic, Suite; ToolTip = 'Specifies the time factor of the purchase line.'; @@ -122,6 +133,16 @@ pageextension 6211 "Sust. Purch. Order Subform" extends "Purchase Order Subform" VisibleSustainabilityControls(); end; + trigger OnAfterGetRecord() + begin + SetFormulaInputEditability(); + end; + + trigger OnAfterGetCurrRecord() + begin + SetFormulaInputEditability(); + end; + local procedure VisibleSustainabilityControls() var SustainabilitySetup: Record "Sustainability Setup"; @@ -132,7 +153,15 @@ pageextension 6211 "Sust. Purch. Order Subform" extends "Purchase Order Subform" SustainabilityFormulasFieldVisible := SustainabilitySetup."Use Formulas In Purch. Docs"; end; + local procedure SetFormulaInputEditability() + begin + SustainabilityCalcMgt.GetFormulaInputEditability(Rec, FuelElectricityEditable, DistanceEditable, CustomAmountEditable, InstallationMultiplierEditable, TimeFactorEditable); + end; + var + SustainabilityCalcMgt: Codeunit "Sustainability Calc. Mgt."; SustainabilityVisible: Boolean; SustainabilityFormulasFieldVisible: Boolean; + FuelElectricityEditable, DistanceEditable, CustomAmountEditable : Boolean; + InstallationMultiplierEditable, TimeFactorEditable : Boolean; } \ No newline at end of file diff --git a/src/Apps/W1/Sustainability/test/src/SustainabilityFormulasTest.Codeunit.al b/src/Apps/W1/Sustainability/test/src/SustainabilityFormulasTest.Codeunit.al index 568e11946c4..ad6629b9f05 100644 --- a/src/Apps/W1/Sustainability/test/src/SustainabilityFormulasTest.Codeunit.al +++ b/src/Apps/W1/Sustainability/test/src/SustainabilityFormulasTest.Codeunit.al @@ -22,6 +22,7 @@ codeunit 148216 "Sustainability Formulas Test" LibraryPurchase: Codeunit "Library - Purchase"; LibraryInventory: Codeunit "Library - Inventory"; LibrarySustainability: Codeunit "Library - Sustainability"; + LibraryUtility: Codeunit "Library - Utility"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; IsInitialized: Boolean; ValueMustBeEqualErr: Label '%1 must be equal to %2 in the %3.', Comment = '%1 = Field Caption , %2 = Expected Value, %3 = Table Caption'; @@ -1868,6 +1869,96 @@ codeunit 148216 "Sustainability Formulas Test" StrSubstNo(ValueMustBeEqualErr, PurchRcptLine.FieldCaption(Distance), Distance, PurchRcptLine.TableCaption())); end; + [Test] + procedure TestPurchaseOrderFormulaInputEditabilityMatrix() + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Formula inputs on purchase orders are editable only when the calculation uses them. + Initialize(); + + // [GIVEN] Purchase formulas are enabled in Sustainability Setup. + LibrarySustainability.EnableFormulaInPurchDocsInSustainabilitySetup(); + + // [WHEN] Purchase Order lines are opened for each supported and unsupported matrix combination. + + // [THEN] Each line exposes only the formula inputs used by its scope and calculation foundation. + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 1", "Calculation Foundation"::Distance, false, true, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 1", "Calculation Foundation"::Installations, false, false, true, true, true); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 1", "Calculation Foundation"::Custom, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 2", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 2", "Calculation Foundation"::Distance, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 2", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 2", "Calculation Foundation"::Custom, false, false, true, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 3", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 3", "Calculation Foundation"::Distance, false, true, false, true, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 3", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 3", "Calculation Foundation"::Custom, false, false, true, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Water/Waste", "Calculation Foundation"::"Fuel/Electricity", false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Water/Waste", "Calculation Foundation"::Distance, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Water/Waste", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Water/Waste", "Calculation Foundation"::Custom, false, false, false, false, false); + VerifyPurchaseOrderFormulaInputEditability("Emission Scope"::"Scope 1", "Calculation Foundation"::" ", false, false, false, false, false); + end; + + [Test] + procedure TestPurchaseOrderFormulaInputEditabilityFallbacks() + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Incomplete account context disables formula inputs without making the unit read-only. + Initialize(); + + // [GIVEN] Purchase formulas are enabled in Sustainability Setup. + LibrarySustainability.EnableFormulaInPurchDocsInSustainabilitySetup(); + + // [WHEN] Purchase Order lines are opened with a blank scope, missing category, or blank account. + + // [THEN] All numeric formula inputs are disabled and the formula unit remains editable. + VerifyPurchaseOrderBlankScopeFormulaInputEditability(); + VerifyPurchaseOrderMissingCategoryFormulaInputEditability(); + VerifyPurchaseOrderBlankAccountFormulaInputEditability(); + end; + + [Test] + procedure TestPurchaseOrderFormulaInputEditabilityRefresh() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + Scope1SustainabilityAccount: Record "Sustainability Account"; + Scope3SustainabilityAccount: Record "Sustainability Account"; + PurchaseOrder: TestPage "Purchase Order"; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Changing or clearing the sustainability account refreshes purchase formula editability immediately. + Initialize(); + + // [GIVEN] Purchase formulas are enabled and a Purchase Order line uses a Scope 1 Fuel/Electricity account. + LibrarySustainability.EnableFormulaInPurchDocsInSustainabilitySetup(); + Scope1SustainabilityAccount := CreateFormulaEditabilitySustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity"); + Scope3SustainabilityAccount := CreateFormulaEditabilitySustainabilityAccount("Emission Scope"::"Scope 3", "Calculation Foundation"::Distance); + CreatePurchaseOrderLineWithSustainabilityAccount(PurchaseHeader, PurchaseLine, Scope1SustainabilityAccount."No."); + + // [WHEN] The Purchase Order line is opened. + PurchaseOrder.OpenEdit(); + PurchaseOrder.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseOrder.PurchLines.Filter.SetFilter("Line No.", Format(PurchaseLine."Line No.")); + + // [THEN] Only Fuel/Electricity is editable. + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, true, false, false, false, false); + + // [WHEN] The account is changed to Scope 3 Distance. + PurchaseOrder.PurchLines."Sust. Account No.".SetValue(Scope3SustainabilityAccount."No."); + + // [THEN] Distance and Installation Multiplier become editable. + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, false, true, false, true, false); + + // [WHEN] The sustainability account is cleared. + PurchaseOrder.PurchLines."Sust. Account No.".SetValue(''); + + // [THEN] All numeric formula inputs are disabled. + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, false, false, false, false, false); + end; + local procedure Initialize() var LibraryERMCountryData: Codeunit "Library - ERM Country Data"; @@ -1893,6 +1984,134 @@ codeunit 148216 "Sustainability Formulas Test" LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"Sustainability Formulas Test"); end; + local procedure VerifyPurchaseOrderFormulaInputEditability(Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation"; ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean) + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + SustainabilityAccount: Record "Sustainability Account"; + PurchaseOrder: TestPage "Purchase Order"; + begin + SustainabilityAccount := CreateFormulaEditabilitySustainabilityAccount(Scope, CalcFoundation); + CreatePurchaseOrderLineWithSustainabilityAccount(PurchaseHeader, PurchaseLine, SustainabilityAccount."No."); + + PurchaseOrder.OpenEdit(); + PurchaseOrder.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseOrder.PurchLines.Filter.SetFilter("Line No.", Format(PurchaseLine."Line No.")); + + AssertPurchaseOrderFormulaInputEditability( + PurchaseOrder, ExpectedFuelElectricityEditable, ExpectedDistanceEditable, ExpectedCustomAmountEditable, + ExpectedInstallationMultiplierEditable, ExpectedTimeFactorEditable); + PurchaseOrder.Close(); + end; + + local procedure VerifyPurchaseOrderBlankScopeFormulaInputEditability() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + SustainAccountCategory: Record "Sustain. Account Category"; + SustainabilityAccount: Record "Sustainability Account"; + PurchaseOrder: TestPage "Purchase Order"; + begin + SustainabilityAccount := CreateFormulaEditabilitySustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::Custom); + CreatePurchaseOrderLineWithSustainabilityAccount(PurchaseHeader, PurchaseLine, SustainabilityAccount."No."); + SustainAccountCategory.Get(SustainabilityAccount.Category); + SustainAccountCategory."Emission Scope" := "Emission Scope"::" "; + SustainAccountCategory.Modify(false); + + PurchaseOrder.OpenEdit(); + PurchaseOrder.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseOrder.PurchLines.Filter.SetFilter("Line No.", Format(PurchaseLine."Line No.")); + + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, false, false, false, false, false); + PurchaseOrder.Close(); + end; + + local procedure VerifyPurchaseOrderMissingCategoryFormulaInputEditability() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + SustainabilityAccount: Record "Sustainability Account"; + PurchaseOrder: TestPage "Purchase Order"; + begin + SustainabilityAccount := CreateFormulaEditabilitySustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity"); + CreatePurchaseOrderLineWithSustainabilityAccount(PurchaseHeader, PurchaseLine, SustainabilityAccount."No."); + PurchaseLine."Sust. Account Category" := 'MISSING'; + PurchaseLine.Modify(false); + + PurchaseOrder.OpenEdit(); + PurchaseOrder.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseOrder.PurchLines.Filter.SetFilter("Line No.", Format(PurchaseLine."Line No.")); + + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, false, false, false, false, false); + PurchaseOrder.Close(); + end; + + local procedure VerifyPurchaseOrderBlankAccountFormulaInputEditability() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchaseOrder: TestPage "Purchase Order"; + begin + LibraryPurchase.CreatePurchHeader(PurchaseHeader, "Purchase Document Type"::Order, LibraryPurchase.CreateVendorNo()); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, "Purchase Line Type"::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + PurchaseOrder.OpenEdit(); + PurchaseOrder.Filter.SetFilter("No.", PurchaseHeader."No."); + PurchaseOrder.PurchLines.Filter.SetFilter("Line No.", Format(PurchaseLine."Line No.")); + + AssertPurchaseOrderFormulaInputEditability(PurchaseOrder, false, false, false, false, false); + PurchaseOrder.Close(); + end; + + local procedure CreatePurchaseOrderLineWithSustainabilityAccount(var PurchaseHeader: Record "Purchase Header"; var PurchaseLine: Record "Purchase Line"; AccountCode: Code[20]) + begin + LibraryPurchase.CreatePurchHeader(PurchaseHeader, "Purchase Document Type"::Order, LibraryPurchase.CreateVendorNo()); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, "Purchase Line Type"::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + PurchaseLine.Validate("Sust. Account No.", AccountCode); + PurchaseLine.Modify(true); + end; + + local procedure AssertPurchaseOrderFormulaInputEditability(var PurchaseOrder: TestPage "Purchase Order"; ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean) + begin + AssertFormulaInputEditability( + ExpectedFuelElectricityEditable, ExpectedDistanceEditable, ExpectedCustomAmountEditable, + ExpectedInstallationMultiplierEditable, ExpectedTimeFactorEditable, + PurchaseOrder.PurchLines."Fuel/Electricity".Editable(), PurchaseOrder.PurchLines.Distance.Editable(), + PurchaseOrder.PurchLines."Custom Amount".Editable(), PurchaseOrder.PurchLines."Installation Multiplier".Editable(), + PurchaseOrder.PurchLines."Time Factor".Editable()); + Assert.IsTrue(PurchaseOrder.PurchLines."Unit for Sust. Formulas".Editable(), 'Unit for Sust. Formulas must remain editable.'); + Assert.AreEqual(1, PurchaseOrder.PurchLines."Installation Multiplier".AsDecimal(), 'Installation Multiplier must retain its default value.'); + end; + + local procedure AssertFormulaInputEditability(ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean; ActualFuelElectricityEditable: Boolean; ActualDistanceEditable: Boolean; ActualCustomAmountEditable: Boolean; ActualInstallationMultiplierEditable: Boolean; ActualTimeFactorEditable: Boolean) + begin + Assert.AreEqual(ExpectedFuelElectricityEditable, ActualFuelElectricityEditable, 'Unexpected Fuel/Electricity editability.'); + Assert.AreEqual(ExpectedDistanceEditable, ActualDistanceEditable, 'Unexpected Distance editability.'); + Assert.AreEqual(ExpectedCustomAmountEditable, ActualCustomAmountEditable, 'Unexpected Custom Amount editability.'); + Assert.AreEqual(ExpectedInstallationMultiplierEditable, ActualInstallationMultiplierEditable, 'Unexpected Installation Multiplier editability.'); + Assert.AreEqual(ExpectedTimeFactorEditable, ActualTimeFactorEditable, 'Unexpected Time Factor editability.'); + end; + + local procedure CreateFormulaEditabilitySustainabilityAccount(Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation") SustainabilityAccount: Record "Sustainability Account" + var + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + TracksEmissions: Boolean; + begin + CategoryCode := LibraryUtility.GenerateGUID(); + SubcategoryCode := LibraryUtility.GenerateGUID(); + AccountCode := LibraryUtility.GenerateGUID(); + TracksEmissions := Scope <> "Emission Scope"::"Water/Waste"; + LibrarySustainability.InsertAccountCategory( + CategoryCode, CategoryCode, Scope, CalcFoundation, TracksEmissions, TracksEmissions, TracksEmissions, '', false); + LibrarySustainability.InsertAccountSubcategory(CategoryCode, SubcategoryCode, SubcategoryCode, 1, 1, 1, false); + SustainabilityAccount := LibrarySustainability.InsertSustainabilityAccount( + AccountCode, AccountCode, CategoryCode, SubcategoryCode, "Sustainability Account Type"::Posting, '', true); + end; + local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer; Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation"; CO2: Boolean; CH4: Boolean; N2O: Boolean; CustomValue: Text; CalcFromGL: Boolean; EFCO2: Decimal; EFCH4: Decimal; EFN2O: Decimal; RenewableEnergy: Boolean): Record "Sustainability Account" begin CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i, Scope, CalcFoundation, CO2, CH4, N2O, CustomValue, CalcFromGL, EFCO2, EFCH4, EFN2O, RenewableEnergy); diff --git a/src/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al b/src/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al index df1a6f1ffe5..45994063291 100644 --- a/src/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al +++ b/src/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al @@ -148,6 +148,264 @@ codeunit 148181 "Sustainability Journal Test" Assert.AreEqual(Abs(GLAmount), CustomAmount, CustomAmountMustBePositiveLbl); end; + [Test] + procedure TestSustainabilityJournalFormulaInputEditabilityMatrix() + var + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; + SustainabilityJournalMgt: Codeunit "Sustainability Journal Mgt."; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Formula inputs on sustainability journals are editable only when the calculation uses them. + Initialize(); + + // [GIVEN] Sustainability journal setup is clean and one journal batch is available for all matrix cases. + SustainabilityJnlBatch := SustainabilityJournalMgt.GetASustainabilityJournalBatch(false); + + // [WHEN] Journal lines are opened for each supported and unsupported matrix combination. + + // [THEN] Each line exposes only the formula inputs used by its scope and calculation foundation. + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 1", "Calculation Foundation"::Distance, false, true, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 1", "Calculation Foundation"::Installations, false, false, true, true, true); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 1", "Calculation Foundation"::Custom, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 2", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 2", "Calculation Foundation"::Distance, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 2", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 2", "Calculation Foundation"::Custom, false, false, true, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 3", "Calculation Foundation"::"Fuel/Electricity", true, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 3", "Calculation Foundation"::Distance, false, true, false, true, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 3", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 3", "Calculation Foundation"::Custom, false, false, true, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Water/Waste", "Calculation Foundation"::"Fuel/Electricity", false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Water/Waste", "Calculation Foundation"::Distance, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Water/Waste", "Calculation Foundation"::Installations, false, false, false, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Water/Waste", "Calculation Foundation"::Custom, false, false, true, false, false); + VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch, "Emission Scope"::"Scope 1", "Calculation Foundation"::" ", false, false, false, false, false); + end; + + [Test] + procedure TestSustainabilityJournalFormulaInputEditabilityFallbacks() + var + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; + SustainabilityJournalMgt: Codeunit "Sustainability Journal Mgt."; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Incomplete journal account context disables formula inputs without making the unit read-only. + Initialize(); + + // [GIVEN] Sustainability journal setup is clean and one journal batch is available for all fallback cases. + SustainabilityJnlBatch := SustainabilityJournalMgt.GetASustainabilityJournalBatch(false); + + // [WHEN] Journal lines are opened with a blank scope, missing category, or blank account. + + // [THEN] All numeric formula inputs are disabled and Unit of Measure remains editable. + VerifySustainabilityJournalBlankScopeFormulaInputEditability(SustainabilityJnlBatch); + VerifySustainabilityJournalMissingCategoryFormulaInputEditability(SustainabilityJnlBatch); + VerifySustainabilityJournalBlankAccountFormulaInputEditability(SustainabilityJnlBatch); + end; + + [Test] + procedure TestSustainabilityJournalFormulaInputEditabilityRefresh() + var + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + Scope1SustainabilityAccount: Record "Sustainability Account"; + Scope3SustainabilityAccount: Record "Sustainability Account"; + SustainabilityJournalMgt: Codeunit "Sustainability Journal Mgt."; + SustainabilityJournal: TestPage "Sustainability Journal"; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO 641058] Account and Manual Input changes refresh journal formula editability immediately. + Initialize(); + + // [GIVEN] A journal line uses a Scope 1 Fuel/Electricity account and a Scope 3 Distance account exists. + SustainabilityJnlBatch := SustainabilityJournalMgt.GetASustainabilityJournalBatch(false); + Scope1SustainabilityAccount := CreateSustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity"); + Scope3SustainabilityAccount := CreateSustainabilityAccount("Emission Scope"::"Scope 3", "Calculation Foundation"::Distance); + SustainabilityJournalLine := LibrarySustainability.InsertSustainabilityJournalLine( + SustainabilityJnlBatch, Scope1SustainabilityAccount, GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch)); + + // [WHEN] The journal line is opened. + SustainabilityJournal.OpenEdit(); + SustainabilityJournal.Filter.SetFilter("Journal Template Name", SustainabilityJournalLine."Journal Template Name"); + SustainabilityJournal.Filter.SetFilter("Journal Batch Name", SustainabilityJournalLine."Journal Batch Name"); + SustainabilityJournal.Filter.SetFilter("Line No.", Format(SustainabilityJournalLine."Line No.")); + Assert.IsTrue(SustainabilityJournal.First(), 'The Sustainability Journal line must be available.'); + + // [THEN] Only Fuel/Electricity is editable. + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, true, false, false, false, false); + + // [WHEN] The account is changed to Scope 3 Distance. + SustainabilityJournal."Sustainability Account No.".SetValue(Scope3SustainabilityAccount."No."); + + // [THEN] Distance and Installation Multiplier become editable. + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, true, false, true, false); + + // [WHEN] Manual Input is enabled. + SustainabilityJournal."Manual Input".SetValue(true); + + // [THEN] All numeric formula inputs are disabled. + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, false, false, false, false); + + // [WHEN] Manual Input is disabled. + SustainabilityJournal."Manual Input".SetValue(false); + + // [THEN] The Scope 3 Distance editability is restored. + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, true, false, true, false); + + // [WHEN] The sustainability account is cleared. + SustainabilityJournal."Sustainability Account No.".SetValue(''); + + // [THEN] All numeric formula inputs are disabled. + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, false, false, false, false); + end; + + local procedure Initialize() + var + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + begin + SustainabilityJournalLine.DeleteAll(); + LibrarySustainability.CleanUpBeforeTesting(); + end; + + local procedure GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"): Integer + var + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + begin + SustainabilityJournalLine."Journal Template Name" := SustainabilityJnlBatch."Journal Template Name"; + SustainabilityJournalLine."Journal Batch Name" := SustainabilityJnlBatch.Name; + exit(LibraryUtility.GetNewRecNo(SustainabilityJournalLine, SustainabilityJournalLine.FieldNo("Line No."))); + end; + + local procedure VerifySustainabilityJournalFormulaInputEditability(SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation"; ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean) + var + SustainabilityAccount: Record "Sustainability Account"; + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + SustainabilityJournal: TestPage "Sustainability Journal"; + begin + SustainabilityAccount := CreateSustainabilityAccount(Scope, CalcFoundation); + SustainabilityJournalLine := LibrarySustainability.InsertSustainabilityJournalLine( + SustainabilityJnlBatch, SustainabilityAccount, GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch)); + + SustainabilityJournal.OpenEdit(); + SustainabilityJournal.Filter.SetFilter("Journal Template Name", SustainabilityJournalLine."Journal Template Name"); + SustainabilityJournal.Filter.SetFilter("Journal Batch Name", SustainabilityJournalLine."Journal Batch Name"); + SustainabilityJournal.Filter.SetFilter("Line No.", Format(SustainabilityJournalLine."Line No.")); + Assert.IsTrue(SustainabilityJournal.First(), 'The Sustainability Journal line must be available.'); + + AssertSustainabilityJournalFormulaInputEditability( + SustainabilityJournal, ExpectedFuelElectricityEditable, ExpectedDistanceEditable, ExpectedCustomAmountEditable, + ExpectedInstallationMultiplierEditable, ExpectedTimeFactorEditable); + SustainabilityJournal.Close(); + end; + + local procedure VerifySustainabilityJournalBlankScopeFormulaInputEditability(SustainabilityJnlBatch: Record "Sustainability Jnl. Batch") + var + SustainAccountCategory: Record "Sustain. Account Category"; + SustainabilityAccount: Record "Sustainability Account"; + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + SustainabilityJournal: TestPage "Sustainability Journal"; + begin + SustainabilityAccount := CreateSustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::Custom); + SustainabilityJournalLine := LibrarySustainability.InsertSustainabilityJournalLine( + SustainabilityJnlBatch, SustainabilityAccount, GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch)); + SustainAccountCategory.Get(SustainabilityAccount.Category); + SustainAccountCategory."Emission Scope" := "Emission Scope"::" "; + SustainAccountCategory.Modify(false); + + SustainabilityJournal.OpenEdit(); + SustainabilityJournal.Filter.SetFilter("Journal Template Name", SustainabilityJournalLine."Journal Template Name"); + SustainabilityJournal.Filter.SetFilter("Journal Batch Name", SustainabilityJournalLine."Journal Batch Name"); + SustainabilityJournal.Filter.SetFilter("Line No.", Format(SustainabilityJournalLine."Line No.")); + Assert.IsTrue(SustainabilityJournal.First(), 'The Sustainability Journal line must be available.'); + + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, false, false, false, false); + SustainabilityJournal.Close(); + end; + + local procedure VerifySustainabilityJournalMissingCategoryFormulaInputEditability(SustainabilityJnlBatch: Record "Sustainability Jnl. Batch") + var + SustainabilityAccount: Record "Sustainability Account"; + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + SustainabilityJournal: TestPage "Sustainability Journal"; + begin + SustainabilityAccount := CreateSustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity"); + SustainabilityJournalLine := LibrarySustainability.InsertSustainabilityJournalLine( + SustainabilityJnlBatch, SustainabilityAccount, GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch)); + SustainabilityJournalLine."Account Category" := 'MISSING'; + SustainabilityJournalLine.Modify(false); + + SustainabilityJournal.OpenEdit(); + SustainabilityJournal.Filter.SetFilter("Journal Template Name", SustainabilityJournalLine."Journal Template Name"); + SustainabilityJournal.Filter.SetFilter("Journal Batch Name", SustainabilityJournalLine."Journal Batch Name"); + SustainabilityJournal.Filter.SetFilter("Line No.", Format(SustainabilityJournalLine."Line No.")); + Assert.IsTrue(SustainabilityJournal.First(), 'The Sustainability Journal line must be available.'); + + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, false, false, false, false); + SustainabilityJournal.Close(); + end; + + local procedure VerifySustainabilityJournalBlankAccountFormulaInputEditability(SustainabilityJnlBatch: Record "Sustainability Jnl. Batch") + var + SustainabilityAccount: Record "Sustainability Account"; + SustainabilityJournalLine: Record "Sustainability Jnl. Line"; + SustainabilityJournal: TestPage "Sustainability Journal"; + begin + SustainabilityAccount := CreateSustainabilityAccount("Emission Scope"::"Scope 1", "Calculation Foundation"::"Fuel/Electricity"); + SustainabilityJournalLine := LibrarySustainability.InsertSustainabilityJournalLine( + SustainabilityJnlBatch, SustainabilityAccount, GetNewSustainabilityJournalLineNo(SustainabilityJnlBatch)); + SustainabilityJournalLine.Validate("Account No.", ''); + SustainabilityJournalLine.Modify(true); + + SustainabilityJournal.OpenEdit(); + SustainabilityJournal.Filter.SetFilter("Journal Template Name", SustainabilityJournalLine."Journal Template Name"); + SustainabilityJournal.Filter.SetFilter("Journal Batch Name", SustainabilityJournalLine."Journal Batch Name"); + SustainabilityJournal.Filter.SetFilter("Line No.", Format(SustainabilityJournalLine."Line No.")); + Assert.IsTrue(SustainabilityJournal.First(), 'The Sustainability Journal line must be available.'); + + AssertSustainabilityJournalFormulaInputEditability(SustainabilityJournal, false, false, false, false, false); + SustainabilityJournal.Close(); + end; + + local procedure CreateSustainabilityAccount(Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation") SustainabilityAccount: Record "Sustainability Account" + var + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + TracksEmissions: Boolean; + begin + CategoryCode := LibraryUtility.GenerateGUID(); + SubcategoryCode := LibraryUtility.GenerateGUID(); + AccountCode := LibraryUtility.GenerateGUID(); + TracksEmissions := Scope <> "Emission Scope"::"Water/Waste"; + LibrarySustainability.InsertAccountCategory( + CategoryCode, CategoryCode, Scope, CalcFoundation, TracksEmissions, TracksEmissions, TracksEmissions, '', false); + LibrarySustainability.InsertAccountSubcategory(CategoryCode, SubcategoryCode, SubcategoryCode, 1, 1, 1, false); + SustainabilityAccount := LibrarySustainability.InsertSustainabilityAccount( + AccountCode, AccountCode, CategoryCode, SubcategoryCode, "Sustainability Account Type"::Posting, '', true); + end; + + local procedure AssertSustainabilityJournalFormulaInputEditability(var SustainabilityJournal: TestPage "Sustainability Journal"; ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean) + begin + AssertFormulaInputEditability( + ExpectedFuelElectricityEditable, ExpectedDistanceEditable, ExpectedCustomAmountEditable, + ExpectedInstallationMultiplierEditable, ExpectedTimeFactorEditable, + SustainabilityJournal."Fuel/Electricity".Editable(), SustainabilityJournal.Distance.Editable(), + SustainabilityJournal."Custom Amount".Editable(), SustainabilityJournal."Installation Multiplier".Editable(), + SustainabilityJournal."Time Factor".Editable()); + Assert.IsTrue(SustainabilityJournal."Unit of Measure".Editable(), 'Unit of Measure must remain editable.'); + Assert.AreEqual(1, SustainabilityJournal."Installation Multiplier".AsDecimal(), 'Installation Multiplier must retain its default value.'); + end; + + local procedure AssertFormulaInputEditability(ExpectedFuelElectricityEditable: Boolean; ExpectedDistanceEditable: Boolean; ExpectedCustomAmountEditable: Boolean; ExpectedInstallationMultiplierEditable: Boolean; ExpectedTimeFactorEditable: Boolean; ActualFuelElectricityEditable: Boolean; ActualDistanceEditable: Boolean; ActualCustomAmountEditable: Boolean; ActualInstallationMultiplierEditable: Boolean; ActualTimeFactorEditable: Boolean) + begin + Assert.AreEqual(ExpectedFuelElectricityEditable, ActualFuelElectricityEditable, 'Unexpected Fuel/Electricity editability.'); + Assert.AreEqual(ExpectedDistanceEditable, ActualDistanceEditable, 'Unexpected Distance editability.'); + Assert.AreEqual(ExpectedCustomAmountEditable, ActualCustomAmountEditable, 'Unexpected Custom Amount editability.'); + Assert.AreEqual(ExpectedInstallationMultiplierEditable, ActualInstallationMultiplierEditable, 'Unexpected Installation Multiplier editability.'); + Assert.AreEqual(ExpectedTimeFactorEditable, ActualTimeFactorEditable, 'Unexpected Time Factor editability.'); + end; + local procedure CreateSustAccountCategoryWithGLAccountNo(GLAccountNo: Code[20]) SustainAccountCategory: Record "Sustain. Account Category" begin SustainAccountCategory := LibrarySustainability.InsertAccountCategory(LibraryUtility.GenerateGUID(), LibraryUtility.GenerateGUID(), Enum::"Emission Scope"::"Scope 2", Enum::"Calculation Foundation"::Custom, true, true, true, 'GL', true);