using System;
using System.Collections.Generic;
using System.Linq;
namespace rgbc_sds.services.Models
{
///
/// Raw data from an Excel row during import
///
public class ExcelRowData
{
///
/// Row number in the Excel file (1-based)
///
public int RowNumber { get; set; }
///
/// Dictionary of column values by header name
///
public Dictionary ColumnValues { get; set; } = new Dictionary();
///
/// Whether this row has any data
///
public bool HasData => ColumnValues.Values.Any(v => !string.IsNullOrWhiteSpace(v));
///
/// Gets a column value by header name
///
/// Column header name
/// Column value or empty string if not found
public string GetValue(string headerName)
{
return ColumnValues.TryGetValue(headerName, out var value) ? value : string.Empty;
}
///
/// Gets a column value by header name with fallback
///
/// Column header name
/// Fallback value if column not found
/// Column value or fallback value
public string GetValue(string headerName, string fallbackValue)
{
return ColumnValues.TryGetValue(headerName, out var value) ? value : fallbackValue;
}
///
/// Checks if a column exists and has a value
///
/// Column header name
/// True if column exists and has non-empty value
public bool HasValue(string headerName)
{
return ColumnValues.TryGetValue(headerName, out var value) && !string.IsNullOrWhiteSpace(value);
}
}
///
/// Column mapping information for Excel import
///
public class ColumnMapping
{
///
/// Expected column headers in the Excel file
///
public static readonly string[] ExpectedHeaders = new[]
{
"Supplier",
"Indent Number",
"Shipshape Number",
"Mother Vessel",
"E.T.A",
"Bill of Entry Number",
"Container Number",
"Offloading Port",
"Container Received",
"No of Flatcases",
"Voyage",
"M/BL Number",
"Redirect to SACD"
};
///
/// Maps Excel column headers to entity property names
///
public static readonly Dictionary HeaderToPropertyMap = new()
{
{ "Supplier", "SupplierName" },
{ "Indent Number", "IndentNumber" },
{ "Shipshape Number", "ShipshapeNumber" },
{ "Mother Vessel", "MotherVessel" },
{ "E.T.A", "ETA" },
{ "Bill of Entry Number", "BillOfEntryNumber" },
{ "Container Number", "ContainerNumber" },
{ "Offloading Port", "OffloadingPort" },
{ "Container Received", "ContainerReceived" },
{ "No of Flatcases", "NoOfFlatcases" },
{ "Voyage", "Voyage" },
{ "M/BL Number", "MBLNumber" },
{ "Redirect to SACD", "RedirectToSACD" }
};
///
/// Required columns that must be present
///
public static readonly string[] RequiredColumns = new[]
{
"Supplier",
"Indent Number",
"Shipshape Number",
"Mother Vessel",
"E.T.A",
"Bill of Entry Number",
"Container Number",
"Offloading Port",
"Container Received",
"No of Flatcases",
"Voyage",
"M/BL Number",
"Redirect to SACD"
};
///
/// Date columns that need special parsing
///
public static readonly string[] DateColumns = new[]
{
"E.T.A",
"Container Received",
"Redirect to SACD"
};
///
/// Validates that all required columns are present
///
/// Headers found in the Excel file
/// Validation result with missing columns
public static ColumnValidationResult ValidateHeaders(IEnumerable foundHeaders)
{
var foundHeadersSet = foundHeaders.Select(h => h.Trim()).ToHashSet(StringComparer.OrdinalIgnoreCase);
var missingColumns = RequiredColumns
.Where(required => !foundHeadersSet.Contains(required))
.ToList();
return new ColumnValidationResult
{
IsValid = missingColumns.Count == 0,
MissingColumns = missingColumns,
FoundHeaders = foundHeadersSet.ToList()
};
}
}
///
/// Result of column validation
///
public class ColumnValidationResult
{
public bool IsValid { get; set; }
public List MissingColumns { get; set; } = new List();
public List FoundHeaders { get; set; } = new List();
public string ErrorMessage => MissingColumns.Count > 0
? $"Missing required columns: {string.Join(", ", MissingColumns)}"
: string.Empty;
}
///
/// Import configuration options
///
public class ImportConfiguration
{
///
/// Maximum number of records allowed per import
///
public const int MaxRecordsPerImport = 200;
///
/// Maximum file size in bytes (10MB)
///
public const long MaxFileSizeBytes = 10 * 1024 * 1024;
///
/// Allowed file extensions
///
public static readonly string[] AllowedExtensions = { ".xlsx", ".xls" };
///
/// Whether to allow updates to existing records
///
public bool AllowUpdates { get; set; } = true;
///
/// Whether to create new suppliers if they don't exist
///
public bool CreateMissingSuppliers { get; set; } = false;
///
/// Whether to create new ports if they don't exist
///
public bool CreateMissingPorts { get; set; } = false;
///
/// Default import mode
///
public string DefaultImportMode { get; set; } = "UpdateExisting";
}
}