using IceImportDAL.DTO.IceImportPipeline; namespace IceImportBLL.FieldResolvers; // ValueType = 0 (Source). Reads the source cell, coerces to the destination member's declared // data type. On coercion failure, returns null with a Warning-severity error — never a silent // default (legacy defaulted a bad int conversion to 0 without recording it). public class SourceValueResolver : IIceFieldValueResolver { public int ValueType => 0; public Task ResolveAsync(FieldResolutionContext ctx, CancellationToken ct) { var fieldName = ctx.DetailConfig.IceMapDetailsSourceFieldName?.Trim().ToUpperInvariant(); string? raw = null; if (!string.IsNullOrEmpty(fieldName) && ctx.SourceRow.Table.Columns.Contains(fieldName)) raw = ctx.SourceRow[fieldName]?.ToString(); else if (ctx.DetailConfig.IceMapDetailsIsOptional == 0) // Optional field whose source column isn't present in this file — fall back to the // configured default. Mandatory-and-missing is instead caught up front, once per file, // by HeaderFieldExistenceValidator. raw = ctx.DetailConfig.IceMapDetailsOptionalFiledValue; if (!IceImportTypeCoercion.TryCoerce(raw, ctx.DetailConfig.DestinationMemberDataType, out var value)) { var warning = new IceImportFieldErrorDTO { RowNumber = ctx.RowNumber, EntityCode = ctx.DetailConfig.EntityCode ?? string.Empty, FieldName = ctx.DetailConfig.DestinationMemberMemberName ?? fieldName ?? string.Empty, Message = $"Value '{raw}' could not be converted to the destination field's declared type.", Severity = IceImportSeverity.Warning }; return Task.FromResult(FieldResolutionResult.WithWarning(null, warning)); } return Task.FromResult(FieldResolutionResult.Ok(value)); } }