From 758c5cda63614e90e8a2eac88e1a373c81056aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Bouchex=20Bellomi=C3=A9?= Date: Wed, 20 May 2026 16:15:41 +0200 Subject: [PATCH 1/4] Added fallback --- .../FieldMaps/FieldCalculationMap.cs | 22 ++++++++++++++----- .../FieldMaps/FieldCalculationMapOptions.cs | 17 ++++++++++++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs index 53160fa6b..b97c4c96b 100644 --- a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs +++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using Microsoft.Extensions.Logging; @@ -82,10 +82,20 @@ internal override void InternalExecute(WorkItem source, WorkItem target) } // Convert field value to numeric - if (!TryConvertToNumeric(fieldValue, out var numericValue)) - { - Log.LogWarning("FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. Skipping calculation.", parameter.Value, fieldValue, source.Id); - return; + if (!TryConvertToNumeric(fieldValue, out var numericValue)) { + if (Config.ParsingFallback == FieldCalculationMapParsingFallback.RaiseError) { + Log.LogError( + "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. Skipping calculation.", + parameter.Value, fieldValue, source.Id); + return; + } + + if (Config.ParsingFallback == FieldCalculationMapParsingFallback.ResetToZero) { + Log.LogWarning( + "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. resetting the value to 0.0.", + parameter.Value, fieldValue, source.Id); + numericValue = 0.0; + } } parameterValues[parameter.Key] = numericValue; @@ -216,4 +226,4 @@ private static bool TryConvertToTargetFieldType(object result, Field targetField } } } -} \ No newline at end of file +} diff --git a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs index 7a55e8a29..7a2de7290 100644 --- a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs +++ b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs @@ -1,8 +1,14 @@ -using System.Collections.Generic; +using System.Collections.Generic; using MigrationTools.Tools.Infrastructure; namespace MigrationTools.Tools { + public enum FieldCalculationMapParsingFallback + { + RaiseError, + ResetToZero + } + /// /// Performs mathematical calculations on numeric fields using NCalc expressions during migration. /// @@ -16,6 +22,12 @@ public class FieldCalculationMapOptions : FieldMapOptions /// null public string expression { get; set; } + /// + /// Gets or sets the parsing fallback. + /// + /// null + public FieldCalculationMapParsingFallback ParsingFallback { get; set; } + /// /// Gets or sets a dictionary mapping variable names used in the expression to source field reference names. /// @@ -40,6 +52,7 @@ public void SetExampleConfigDefaults() { "x", "Custom.FieldB" } }; targetField = "Custom.FieldC"; + ParsingFallback = FieldCalculationMapParsingFallback.RaiseError; } /// @@ -50,4 +63,4 @@ public FieldCalculationMapOptions() parameters = new Dictionary(); } } -} \ No newline at end of file +} From 0866bc8a4e377029a7dc0e6698d57a2217f6848e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Bouchex=20Bellomi=C3=A9?= Date: Wed, 20 May 2026 16:46:38 +0200 Subject: [PATCH 2/4] Added fallback --- .../Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs | 4 ++-- .../FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs index b97c4c96b..77a0c2bbd 100644 --- a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs +++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs @@ -83,14 +83,14 @@ internal override void InternalExecute(WorkItem source, WorkItem target) // Convert field value to numeric if (!TryConvertToNumeric(fieldValue, out var numericValue)) { - if (Config.ParsingFallback == FieldCalculationMapParsingFallback.RaiseError) { + if (Config.parsingFallback == FieldCalculationMapParsingFallback.RaiseError) { Log.LogError( "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. Skipping calculation.", parameter.Value, fieldValue, source.Id); return; } - if (Config.ParsingFallback == FieldCalculationMapParsingFallback.ResetToZero) { + if (Config.parsingFallback == FieldCalculationMapParsingFallback.ResetToZero) { Log.LogWarning( "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. resetting the value to 0.0.", parameter.Value, fieldValue, source.Id); diff --git a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs index 7a2de7290..a97d387ed 100644 --- a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs +++ b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs @@ -26,7 +26,7 @@ public class FieldCalculationMapOptions : FieldMapOptions /// Gets or sets the parsing fallback. /// /// null - public FieldCalculationMapParsingFallback ParsingFallback { get; set; } + public FieldCalculationMapParsingFallback parsingFallback { get; set; } /// /// Gets or sets a dictionary mapping variable names used in the expression to source field reference names. @@ -52,7 +52,7 @@ public void SetExampleConfigDefaults() { "x", "Custom.FieldB" } }; targetField = "Custom.FieldC"; - ParsingFallback = FieldCalculationMapParsingFallback.RaiseError; + parsingFallback = FieldCalculationMapParsingFallback.RaiseError; } /// From 9d995667f60e86fffa34d757b61dc63ae2659cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Bouchex=20Bellomi=C3=A9?= Date: Wed, 20 May 2026 17:09:16 +0200 Subject: [PATCH 3/4] Added fallback --- .../FieldMaps/FieldCalculationMap.cs | 30 ++++++++++++------- .../FieldMaps/FieldCalculationMapOptions.cs | 5 ++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs index 77a0c2bbd..86659e1a4 100644 --- a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs +++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs @@ -83,18 +83,26 @@ internal override void InternalExecute(WorkItem source, WorkItem target) // Convert field value to numeric if (!TryConvertToNumeric(fieldValue, out var numericValue)) { - if (Config.parsingFallback == FieldCalculationMapParsingFallback.RaiseError) { - Log.LogError( - "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. Skipping calculation.", - parameter.Value, fieldValue, source.Id); - return; - } - if (Config.parsingFallback == FieldCalculationMapParsingFallback.ResetToZero) { - Log.LogWarning( - "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. resetting the value to 0.0.", - parameter.Value, fieldValue, source.Id); - numericValue = 0.0; + switch (Config.parsingFallback) { + case FieldCalculationMapParsingFallback.RaiseError: + Log.LogError( + "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. Skipping calculation.", + parameter.Value, fieldValue, source.Id); + break; + + case FieldCalculationMapParsingFallback.ResetToZero: + Log.LogWarning( + "FieldCalculationMap: Source field '{SourceField}' with value '{FieldValue}' is not numeric on work item {WorkItemId}. resetting the value to 0.0.", + parameter.Value, fieldValue, source.Id); + numericValue = 0.0; + break; + + default: + Log.LogError( + "FieldCalculationMap: Unsupported parsing fallback '{ParsingFallback}' for source field '{SourceField}' on work item {WorkItemId}. Skipping calculation.", + parameter.Value, fieldValue, source.Id); + break; } } diff --git a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs index a97d387ed..07b717914 100644 --- a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs +++ b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs @@ -5,8 +5,9 @@ namespace MigrationTools.Tools { public enum FieldCalculationMapParsingFallback { - RaiseError, - ResetToZero + None, + RaiseError = 1, + ResetToZero = 2 } /// From 3c501cc0f5b60c2481db6f011bdb392066635b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Bouchex=20Bellomi=C3=A9?= Date: Wed, 20 May 2026 17:53:49 +0200 Subject: [PATCH 4/4] Added fallback --- .../FieldMaps/FieldCalculationMap.cs | 6 ----- .../FieldMaps/FieldCalculationMapOptions.cs | 26 +++++++------------ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs index 86659e1a4..785bd16ce 100644 --- a/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs +++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/FieldMappingTool/FieldMaps/FieldCalculationMap.cs @@ -97,12 +97,6 @@ internal override void InternalExecute(WorkItem source, WorkItem target) parameter.Value, fieldValue, source.Id); numericValue = 0.0; break; - - default: - Log.LogError( - "FieldCalculationMap: Unsupported parsing fallback '{ParsingFallback}' for source field '{SourceField}' on work item {WorkItemId}. Skipping calculation.", - parameter.Value, fieldValue, source.Id); - break; } } diff --git a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs index 07b717914..caaaef1e1 100644 --- a/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs +++ b/src/MigrationTools/Tools/FieldMappingTool/FieldMaps/FieldCalculationMapOptions.cs @@ -1,13 +1,10 @@ using System.Collections.Generic; using MigrationTools.Tools.Infrastructure; -namespace MigrationTools.Tools -{ - public enum FieldCalculationMapParsingFallback - { - None, - RaiseError = 1, - ResetToZero = 2 +namespace MigrationTools.Tools { + public enum FieldCalculationMapParsingFallback { + RaiseError, + ResetToZero } /// @@ -15,8 +12,7 @@ public enum FieldCalculationMapParsingFallback /// /// ready /// Work Item Field - public class FieldCalculationMapOptions : FieldMapOptions - { + public class FieldCalculationMapOptions : FieldMapOptions { /// /// Gets or sets the NCalc expression to evaluate. Variables in the expression should be enclosed in square brackets (e.g., "[x]*2"). /// @@ -27,7 +23,8 @@ public class FieldCalculationMapOptions : FieldMapOptions /// Gets or sets the parsing fallback. /// /// null - public FieldCalculationMapParsingFallback parsingFallback { get; set; } + public FieldCalculationMapParsingFallback parsingFallback { get; set; } = + FieldCalculationMapParsingFallback.RaiseError; /// /// Gets or sets a dictionary mapping variable names used in the expression to source field reference names. @@ -44,12 +41,10 @@ public class FieldCalculationMapOptions : FieldMapOptions /// /// Sets example configuration defaults for documentation purposes. /// - public void SetExampleConfigDefaults() - { + public void SetExampleConfigDefaults() { ApplyTo = new List() { "SomeWorkItemType" }; expression = "[x]*2"; - parameters = new Dictionary - { + parameters = new Dictionary { { "x", "Custom.FieldB" } }; targetField = "Custom.FieldC"; @@ -59,8 +54,7 @@ public void SetExampleConfigDefaults() /// /// Initializes a new instance of the FieldCalculationMapOptions class. /// - public FieldCalculationMapOptions() - { + public FieldCalculationMapOptions() { parameters = new Dictionary(); } }