From 6961baa4c999e08fd1214458a6dd3834a574e930 Mon Sep 17 00:00:00 2001 From: likp Date: Tue, 20 May 2025 16:14:06 +0200 Subject: [PATCH 1/7] Add codelist handling and update API methods - Introduced `FixVariableRefsAndApplyCodelists` method in `ISelectionHandler` for fixing variable references and applying codelists. - Changed visibility of `FixVariableRefsAndApplyCodelists` in `SelectionHandler` to public. - Updated `GetMetadataById` in `TableApiController` to accept a new `codelist` parameter. - Added logic in `TableApiController` to process the `codelist` and handle potential errors. - Created `CreateVariablesSelectionFromCodelists` method in `SelectionUtil` to build `VariablesSelection` from codelists. - Updated `PxWeb.Api2.Server` package version to `2.0.0-beta.17`. --- .../Code/Api2/DataSelection/ISelectionHandler.cs | 1 + PxWeb/Code/Api2/DataSelection/SelectionHandler.cs | 2 +- PxWeb/Controllers/Api2/TableApiController.cs | 10 +++++++++- PxWeb/Helper/Api2/SelectionUtil.cs | 15 +++++++++++++++ PxWeb/PxWeb.csproj | 2 +- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/PxWeb/Code/Api2/DataSelection/ISelectionHandler.cs b/PxWeb/Code/Api2/DataSelection/ISelectionHandler.cs index 100b798c..78f95999 100644 --- a/PxWeb/Code/Api2/DataSelection/ISelectionHandler.cs +++ b/PxWeb/Code/Api2/DataSelection/ISelectionHandler.cs @@ -8,5 +8,6 @@ public interface ISelectionHandler { bool ExpandAndVerfiySelections(VariablesSelection variablesSelection, IPXModelBuilder builder, out Problem? problem); Selection[] Convert(VariablesSelection variablesSelection); + bool FixVariableRefsAndApplyCodelists(IPXModelBuilder builder, VariablesSelection variablesSelection, out Problem? problem); } } diff --git a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs index 81982a7d..8a69e258 100644 --- a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs +++ b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs @@ -195,7 +195,7 @@ private static bool ExpandSelectionExpression(VariableSelection variable, Variab /// The VariablesSelection object to verify and apply codelists for /// Null if everything is ok, otherwise it describes whats wrong /// True if everything was ok, else false - private static bool FixVariableRefsAndApplyCodelists(IPXModelBuilder builder, VariablesSelection variablesSelection, out Problem? problem) + public bool FixVariableRefsAndApplyCodelists(IPXModelBuilder builder, VariablesSelection variablesSelection, out Problem? problem) { problem = null; diff --git a/PxWeb/Controllers/Api2/TableApiController.cs b/PxWeb/Controllers/Api2/TableApiController.cs index b60ba3fc..ec136228 100644 --- a/PxWeb/Controllers/Api2/TableApiController.cs +++ b/PxWeb/Controllers/Api2/TableApiController.cs @@ -72,7 +72,7 @@ public TableApiController(IDataSource dataSource, ILanguageHelper languageHelper _savedQueryBackendProxy = savedQueryBackendProxy; } - public override IActionResult GetMetadataById([FromRoute(Name = "id"), Required] string id, [FromQuery(Name = "lang")] string? lang, [FromQuery(Name = "defaultSelection")] bool? defaultSelection) + public override IActionResult GetMetadataById([FromRoute(Name = "id"), Required] string id, [FromQuery(Name = "lang")] string? lang, [FromQuery(Name = "defaultSelection")] bool? defaultSelection, [FromQuery(Name = "codelist")] Dictionary? codelist) { lang = _languageHelper.HandleLanguage(lang); IPXModelBuilder? builder = _dataSource.CreateBuilder(id, lang); @@ -98,6 +98,14 @@ public override IActionResult GetMetadataById([FromRoute(Name = "id"), Required] _defaultSelectionAlgorithm.GetDefaultSelection(builder); } } + else if (codelist is not null && codelist.Keys.Count > 0) //Check that we have codelist specified + { + var selections = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); + if (!_selectionHandler.FixVariableRefsAndApplyCodelists(builder, selections, out Problem? problem)) + { + return BadRequest(problem); + } + } var model = builder.Model; Dataset ds = _datasetMapper.Map(model, id, lang); diff --git a/PxWeb/Helper/Api2/SelectionUtil.cs b/PxWeb/Helper/Api2/SelectionUtil.cs index 24bd2385..f5947518 100644 --- a/PxWeb/Helper/Api2/SelectionUtil.cs +++ b/PxWeb/Helper/Api2/SelectionUtil.cs @@ -66,6 +66,21 @@ public static VariablesSelection CreateEmptyVariablesSelection() return selections; } + public static VariablesSelection CreateVariablesSelectionFromCodelists(Dictionary codelist) + { + var selections = CreateEmptyVariablesSelection(); + + foreach (var key in codelist.Keys) + { + var selection = new VariableSelection(); + selection.VariableCode = key; + selection.CodeList = codelist[key]; + selections.Selection.Add(selection); + } + + return selections; + } + /// /// Adds a value to a variable selection. Only adds the value if it is not already in the selection /// diff --git a/PxWeb/PxWeb.csproj b/PxWeb/PxWeb.csproj index 8c34195a..3ef440f0 100644 --- a/PxWeb/PxWeb.csproj +++ b/PxWeb/PxWeb.csproj @@ -49,7 +49,7 @@ - + From c31582a0ca1dab0a987a1449481da333fbb0e23e Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 11:09:06 +0200 Subject: [PATCH 2/7] Preserve value notes and remove no valid cellnotes when changing codelist --- .../Api2/DataSelection/SelectionHandler.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs index 8a69e258..4f6e8c3d 100644 --- a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs +++ b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs @@ -262,6 +262,17 @@ private static bool ApplyCodelist(IPXModelBuilder builder, Variable pxVariable, if (!string.IsNullOrWhiteSpace(variable.CodeList)) { + + // Extract notes + var notes = new Dictionary(); + foreach (var value in pxVariable.Values) + { + if (value.HasNotes()) + { + notes.Add(value.Code, value.Notes); + } + } + if (variable.CodeList.StartsWith("agg_")) { if (!ApplyGrouping(builder, pxVariable, variable, out problem)) @@ -281,8 +292,37 @@ private static bool ApplyCodelist(IPXModelBuilder builder, Variable pxVariable, problem = ProblemUtility.NonExistentCodelist(); return false; } + + // Restore notes + foreach (var valueCode in notes.Keys) + { + if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(valueCode, System.StringComparison.InvariantCultureIgnoreCase)) is Value value) + { + foreach (var note in notes[valueCode]) + { + value.AddNote(note); + } + } + } + // Remove cellnotes + for (int i = builder.Model.Meta.CellNotes.Count - 1; i >= 0; i--) + { + var cellNote = builder.Model.Meta.CellNotes[i]; + foreach (var condition in cellNote.Conditions) + { + // Check if there is a condition for the variable with a value that is no longer in the list of values + if (string.Equals(condition.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase)) + { + if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) + { + builder.Model.Meta.CellNotes.RemoveAt(i); + } + } + } + } } + return true; } From 6a2f51d0c0584396c54b7897c0eca65865989e17 Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 11:28:05 +0200 Subject: [PATCH 3/7] Added tests for SelectionUtil --- PxWeb.UnitTests/Helpers/SelectionUtilTests.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs b/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs index 855ec0d8..f9f33a70 100644 --- a/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs +++ b/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs @@ -102,5 +102,40 @@ public void UseDefaultSelection_OneSelectionsDefined_ReturnsFalse() Assert.IsFalse(useDefaultSelection); } + + [TestMethod] + public void CreateVariablesSelectionFromCodelists_WhenNoCodelist_ReturnsEmptySelection() + { + // Arrange + var codelist = new Dictionary(); + // Act + var result = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); + // Assert + Assert.IsNotNull(result); + Assert.IsNotNull(result.Selection); + Assert.AreEqual(0, result.Selection.Count); + Assert.IsNotNull(result.Placement); + Assert.AreEqual(0, result.Placement.Heading.Count); + Assert.AreEqual(0, result.Placement.Stub.Count); + } + + [TestMethod] + public void VariablesSelectionFromCodelists_WhenOneCodelist_ReturnsSelectionWithOneValue() + { + // Arrange + var codelist = new Dictionary + { + { "A", "B" } + }; + // Act + var result = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); + // Assert + Assert.IsNotNull(result); + Assert.IsNotNull(result.Selection); + Assert.AreEqual(1, result.Selection.Count); + Assert.AreEqual("A", result.Selection[0].VariableCode); + Assert.AreEqual("B", result.Selection[0].CodeList); + + } } } From d9cb4ea21bbc22715cf551a6ae33dee7a4e07380 Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 12:29:10 +0200 Subject: [PATCH 4/7] Added edge cases test for SelectionHander --- PxWeb.UnitTests/Data/SelectionHandlerTests.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/PxWeb.UnitTests/Data/SelectionHandlerTests.cs b/PxWeb.UnitTests/Data/SelectionHandlerTests.cs index b9414743..b09beb92 100644 --- a/PxWeb.UnitTests/Data/SelectionHandlerTests.cs +++ b/PxWeb.UnitTests/Data/SelectionHandlerTests.cs @@ -132,6 +132,47 @@ public void Convert_InvalidSelection_ReturnsValidSelection() Assert.AreEqual(3, result.Length); } + [TestMethod] + public void FixVariableRefsAndApplyCodelists_WhenNoExistingVaiableSpecified_ReturnFalseAndProblem() + { + // Arrange + var codelist = new Dictionary(); + codelist.Add("THIS_IS_A_INVALID_CODE", "m1"); + var variablesSelection = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); + var configMock = GetConfigMock(); + var handler = new SelectionHandler(configMock.Object); + var model = ModelStore.CreateModelA(); + var builderMock = new Mock(); + builderMock.Setup(x => x.Model).Returns(model); + handler.ExpandAndVerfiySelections(variablesSelection, builderMock.Object, out var problem); + // Act + var result = handler.FixVariableRefsAndApplyCodelists(builderMock.Object, variablesSelection, out problem); + // Assert + Assert.IsFalse(result); + Assert.IsNotNull(problem); + } + + [TestMethod] + public void FixVariableRefsAndApplyCodelists_WhenNoExistingCodeListSpecified_ReturnFalseAndProblem() + { + // Arrange + var codelist = new Dictionary(); + codelist.Add("measure", "THIS_VALUE_DOES_NOT_EXIST"); + var variablesSelection = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); + var configMock = GetConfigMock(); + var handler = new SelectionHandler(configMock.Object); + var model = ModelStore.CreateModelA(); + var builderMock = new Mock(); + builderMock.Setup(x => x.Model).Returns(model); + handler.ExpandAndVerfiySelections(variablesSelection, builderMock.Object, out var problem); + // Act + var result = handler.FixVariableRefsAndApplyCodelists(builderMock.Object, variablesSelection, out problem); + // Assert + Assert.IsFalse(result); + Assert.IsNotNull(problem); + } + + private static VariablesSelection CreateValidSelection() { var selection = new VariablesSelection(); From cf22a8c81bc714f119d22e3d1485fa8e50f0c07e Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 13:36:49 +0200 Subject: [PATCH 5/7] Refactored code and added test --- PxWeb.UnitTests/Data/PaxiomFixUtilTests.cs | 158 ++++++++++++++++++ .../Code/Api2/DataSelection/PaxiomFixUtil.cs | 61 +++++++ .../Api2/DataSelection/SelectionHandler.cs | 38 +---- 3 files changed, 222 insertions(+), 35 deletions(-) create mode 100644 PxWeb.UnitTests/Data/PaxiomFixUtilTests.cs create mode 100644 PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs diff --git a/PxWeb.UnitTests/Data/PaxiomFixUtilTests.cs b/PxWeb.UnitTests/Data/PaxiomFixUtilTests.cs new file mode 100644 index 00000000..10b4ac9f --- /dev/null +++ b/PxWeb.UnitTests/Data/PaxiomFixUtilTests.cs @@ -0,0 +1,158 @@ +using Note = PCAxis.Paxiom.Note; + +namespace PxWeb.UnitTests.Data +{ + [TestClass] + public class PaxiomFixUtilTests + { + [TestMethod] + public void ExtractNotes_WhenNoNotes_ReturnsEmptyDictionary() + { + // Arrange + var variable = new Variable(); + + // Act + var result = PaxiomFixUtil.ExtractNotes(variable); + // Assert + Assert.AreEqual(0, result.Count); + } + + [TestMethod] + public void ExtractNotes_WhenNotesExist_ReturnsNotes() + { + // Arrange + var variable = new Variable("VAR1", "VAR1", PlacementType.Heading, 1); + var value = new Value("v1"); + PaxiomUtil.SetCode(value, "v1"); + variable.Values.Add(value); + value = new Value("v2"); + PaxiomUtil.SetCode(value, "v2"); + variable.Values.Add(value); + value = new Value("v3"); + PaxiomUtil.SetCode(value, "v3"); + variable.Values.Add(value); + variable.Values[0].AddNote(new Note("My note", NoteType.Value, true)); + + // Act + var result = PaxiomFixUtil.ExtractNotes(variable); + // Assert + Assert.AreEqual(1, result.Count); + Assert.IsTrue(result.ContainsKey("v1")); + Assert.AreEqual(1, result["v1"].Count); + } + + [TestMethod] + public void RestoreNotes_WhenNotesExist_ReturnsNotes() + { + // Arrange + var variable = new Variable("VAR1", "VAR1", PlacementType.Heading, 1); + var value = new Value("v1"); + PaxiomUtil.SetCode(value, "v1"); + variable.Values.Add(value); + value = new Value("v2"); + PaxiomUtil.SetCode(value, "v2"); + variable.Values.Add(value); + value = new Value("v3"); + PaxiomUtil.SetCode(value, "v3"); + variable.Values.Add(value); + var notes = new Dictionary(); + var list = new Notes(); + list.Add(new Note("My note", NoteType.Value, true)); + notes.Add("v1", list); + + // Act + PaxiomFixUtil.RestoreNotes(variable, notes); + + // Assert + Assert.AreEqual(1, variable.Values[0].Notes.Count); + } + + [TestMethod] + public void RestoreNotes_WhenNotesNotApplicable_ReturnsNotes() + { + // Arrange + var variable = new Variable("VAR1", "VAR1", PlacementType.Heading, 1); + var value = new Value("v1"); + PaxiomUtil.SetCode(value, "v1"); + variable.Values.Add(value); + value = new Value("v2"); + PaxiomUtil.SetCode(value, "v2"); + variable.Values.Add(value); + value = new Value("v3"); + PaxiomUtil.SetCode(value, "v3"); + variable.Values.Add(value); + var notes = new Dictionary(); + var list = new Notes(); + list.Add(new Note("My note", NoteType.Value, true)); + notes.Add("v4", list); + + // Act + PaxiomFixUtil.RestoreNotes(variable, notes); + + // Assert + Assert.IsFalse(variable.Values[0].HasNotes()); + } + + [TestMethod] + public void CleanCellnotes_WhenNoCellNotes_NoException() + { + // Arrange + var variable = new Variable("VAR1", "VAR1", PlacementType.Heading, 1); + var value = new Value("v1"); + PaxiomUtil.SetCode(value, "v1"); + variable.Values.Add(value); + value = new Value("v2"); + PaxiomUtil.SetCode(value, "v2"); + variable.Values.Add(value); + value = new Value("v3"); + PaxiomUtil.SetCode(value, "v3"); + variable.Values.Add(value); + + var meta = new PXMeta(); + + // Act + var result = PaxiomFixUtil.CleanCellnotes(meta, variable); + + // Assert + Assert.AreEqual(0, result); + } + + [TestMethod] + public void CleanCellnotes_WhenCellNotes_MatchingWillBeRemoved() + { + // Arrange + var variable = new Variable("VAR1", "VAR1", PlacementType.Heading, 1); + var value = new Value("v1"); + PaxiomUtil.SetCode(value, "v1"); + variable.Values.Add(value); + value = new Value("v2"); + PaxiomUtil.SetCode(value, "v2"); + variable.Values.Add(value); + value = new Value("v3"); + PaxiomUtil.SetCode(value, "v3"); + variable.Values.Add(value); + + var meta = new PXMeta(); + + var cellNote = new CellNote(); + cellNote.Conditions.Add(new VariableValuePair("VAR1", "v4")); + cellNote.Conditions.Add(new VariableValuePair("VAR2", "v3")); + meta.CellNotes.Add(cellNote); + + cellNote = new CellNote(); + cellNote.Conditions.Add(new VariableValuePair("VAR2", "v3")); + meta.CellNotes.Add(cellNote); + + cellNote = new CellNote(); + cellNote.Conditions.Add(new VariableValuePair("VAR1", "v3")); + meta.CellNotes.Add(cellNote); + + // Act + var result = PaxiomFixUtil.CleanCellnotes(meta, variable); + + // Assert + Assert.AreEqual(1, result); + Assert.AreEqual(2, meta.CellNotes.Count); + } + } +} diff --git a/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs new file mode 100644 index 00000000..d153b323 --- /dev/null +++ b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs @@ -0,0 +1,61 @@ +using System.Linq; + +using PCAxis.Paxiom; + +namespace PxWeb.Code.Api2.DataSelection +{ + public static class PaxiomFixUtil + { + public static int CleanCellnotes(PXMeta meta, Variable pxVariable) + { + int removed = 0; + for (int i = meta.CellNotes.Count - 1; i >= 0; i--) + { + var cellNote = meta.CellNotes[i]; + foreach (var condition in cellNote.Conditions) + { + // Check if there is a condition for the variable with a value that is no longer in the list of values + if (string.Equals(condition.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase)) + { + if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) + { + meta.CellNotes.RemoveAt(i); + removed++; + } + } + } + } + return removed; + } + + public static void RestoreNotes(Variable variable, Dictionary notes) + { + foreach (var valueCode in notes.Keys) + { + if (variable.Values.FirstOrDefault(x => x.Code.Equals(valueCode, System.StringComparison.InvariantCultureIgnoreCase)) is Value value) + { + foreach (var note in notes[valueCode]) + { + value.AddNote(note); + } + } + } + } + + public static Dictionary ExtractNotes(Variable variable) + { + + // Extract notes + var notes = new Dictionary(); + foreach (var value in variable.Values) + { + if (value.HasNotes()) + { + notes.Add(value.Code, value.Notes); + } + } + + return notes; + } + } +} diff --git a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs index 4f6e8c3d..a2646176 100644 --- a/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs +++ b/PxWeb/Code/Api2/DataSelection/SelectionHandler.cs @@ -262,16 +262,7 @@ private static bool ApplyCodelist(IPXModelBuilder builder, Variable pxVariable, if (!string.IsNullOrWhiteSpace(variable.CodeList)) { - - // Extract notes - var notes = new Dictionary(); - foreach (var value in pxVariable.Values) - { - if (value.HasNotes()) - { - notes.Add(value.Code, value.Notes); - } - } + var notes = PaxiomFixUtil.ExtractNotes(pxVariable); if (variable.CodeList.StartsWith("agg_")) { @@ -294,32 +285,9 @@ private static bool ApplyCodelist(IPXModelBuilder builder, Variable pxVariable, } // Restore notes - foreach (var valueCode in notes.Keys) - { - if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(valueCode, System.StringComparison.InvariantCultureIgnoreCase)) is Value value) - { - foreach (var note in notes[valueCode]) - { - value.AddNote(note); - } - } - } + PaxiomFixUtil.RestoreNotes(pxVariable, notes); // Remove cellnotes - for (int i = builder.Model.Meta.CellNotes.Count - 1; i >= 0; i--) - { - var cellNote = builder.Model.Meta.CellNotes[i]; - foreach (var condition in cellNote.Conditions) - { - // Check if there is a condition for the variable with a value that is no longer in the list of values - if (string.Equals(condition.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase)) - { - if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) - { - builder.Model.Meta.CellNotes.RemoveAt(i); - } - } - } - } + PaxiomFixUtil.CleanCellnotes(builder.Model.Meta, pxVariable); } From fc7e1266672a6e9e13d97f1bfaf82de132681de7 Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 13:48:58 +0200 Subject: [PATCH 6/7] Did some minor improvment that SonarCloud suggested to fix --- PxWeb.UnitTests/Helpers/SelectionUtilTests.cs | 2 -- PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs | 13 +++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs b/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs index f9f33a70..88400a2c 100644 --- a/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs +++ b/PxWeb.UnitTests/Helpers/SelectionUtilTests.cs @@ -112,7 +112,6 @@ public void CreateVariablesSelectionFromCodelists_WhenNoCodelist_ReturnsEmptySel var result = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); // Assert Assert.IsNotNull(result); - Assert.IsNotNull(result.Selection); Assert.AreEqual(0, result.Selection.Count); Assert.IsNotNull(result.Placement); Assert.AreEqual(0, result.Placement.Heading.Count); @@ -131,7 +130,6 @@ public void VariablesSelectionFromCodelists_WhenOneCodelist_ReturnsSelectionWith var result = SelectionUtil.CreateVariablesSelectionFromCodelists(codelist); // Assert Assert.IsNotNull(result); - Assert.IsNotNull(result.Selection); Assert.AreEqual(1, result.Selection.Count); Assert.AreEqual("A", result.Selection[0].VariableCode); Assert.AreEqual("B", result.Selection[0].CodeList); diff --git a/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs index d153b323..216ac978 100644 --- a/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs +++ b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs @@ -12,16 +12,13 @@ public static int CleanCellnotes(PXMeta meta, Variable pxVariable) for (int i = meta.CellNotes.Count - 1; i >= 0; i--) { var cellNote = meta.CellNotes[i]; - foreach (var condition in cellNote.Conditions) + // Check if there is a condition for the variable with a value that is no longer in the list of values + foreach (var condition in cellNote.Conditions.Where(c => string.Equals(c.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase))) { - // Check if there is a condition for the variable with a value that is no longer in the list of values - if (string.Equals(condition.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase)) + if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) { - if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) - { - meta.CellNotes.RemoveAt(i); - removed++; - } + meta.CellNotes.RemoveAt(i); + removed++; } } } From 52c53a83bf7822cf1670465fa3777d8818cf9ae2 Mon Sep 17 00:00:00 2001 From: likp Date: Thu, 22 May 2025 13:54:03 +0200 Subject: [PATCH 7/7] Some more improvments --- PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs index 216ac978..8fb01e04 100644 --- a/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs +++ b/PxWeb/Code/Api2/DataSelection/PaxiomFixUtil.cs @@ -13,13 +13,11 @@ public static int CleanCellnotes(PXMeta meta, Variable pxVariable) { var cellNote = meta.CellNotes[i]; // Check if there is a condition for the variable with a value that is no longer in the list of values - foreach (var condition in cellNote.Conditions.Where(c => string.Equals(c.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase))) + foreach (var condition in cellNote.Conditions.Where(c => string.Equals(c.VariableCode, pxVariable.Code, StringComparison.OrdinalIgnoreCase) && + pxVariable.Values.FirstOrDefault(x => x.Code.Equals(c.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null)) { - if (pxVariable.Values.FirstOrDefault(x => x.Code.Equals(condition.ValueCode, StringComparison.InvariantCultureIgnoreCase)) is null) - { - meta.CellNotes.RemoveAt(i); - removed++; - } + meta.CellNotes.RemoveAt(i); + removed++; } } return removed; @@ -44,12 +42,9 @@ public static Dictionary ExtractNotes(Variable variable) // Extract notes var notes = new Dictionary(); - foreach (var value in variable.Values) + foreach (var value in variable.Values.Where(v => v.HasNotes())) { - if (value.HasNotes()) - { - notes.Add(value.Code, value.Notes); - } + notes.Add(value.Code, value.Notes); } return notes;