2026-06-30 13:20:41 -03:00
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
|
|
|
|
namespace SeaHaven.Services.Helpers
|
|
|
|
|
{
|
|
|
|
|
public static class WorkOrderNumberNormalizer
|
|
|
|
|
{
|
|
|
|
|
private const int RequiredLength = 11;
|
2026-09-16 15:01:10 -03:00
|
|
|
private const string ProvisionalPrefix = "SH";
|
|
|
|
|
private const int MinimumProvisionalDigits = 5;
|
2026-06-30 13:20:41 -03:00
|
|
|
|
|
|
|
|
public static bool TryNormalize(string? input, out string normalized, out string? error)
|
|
|
|
|
{
|
|
|
|
|
normalized = "";
|
|
|
|
|
error = null;
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(input))
|
|
|
|
|
{
|
|
|
|
|
error = "WO number is required.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-16 15:01:10 -03:00
|
|
|
var trimmed = input.Trim();
|
|
|
|
|
if (WorkOrderNumberRules.IsProvisional(trimmed))
|
|
|
|
|
return TryNormalizeProvisional(trimmed, out normalized, out error);
|
|
|
|
|
|
|
|
|
|
var digits = Regex.Replace(trimmed, @"\D", "");
|
2026-06-30 13:20:41 -03:00
|
|
|
if (digits.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
error = "WO number must contain digits.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (digits.Length > RequiredLength)
|
|
|
|
|
{
|
|
|
|
|
error = $"WO number cannot exceed {RequiredLength} digits.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
normalized = digits.PadLeft(RequiredLength, '0');
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2026-09-16 15:01:10 -03:00
|
|
|
|
|
|
|
|
// SH-320: an SH-prefixed number is the documented placeholder for a WO still
|
|
|
|
|
// awaiting its real APM number; keep the prefix instead of stripping it to digits.
|
|
|
|
|
private static bool TryNormalizeProvisional(string trimmed, out string normalized, out string? error)
|
|
|
|
|
{
|
|
|
|
|
normalized = "";
|
|
|
|
|
error = null;
|
|
|
|
|
|
|
|
|
|
var digits = Regex.Replace(trimmed[ProvisionalPrefix.Length..], @"\D", "");
|
|
|
|
|
if (digits.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
error = "WO number must contain digits.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var candidate = ProvisionalPrefix + digits.PadLeft(MinimumProvisionalDigits, '0');
|
|
|
|
|
if (candidate.Length > RequiredLength)
|
|
|
|
|
{
|
|
|
|
|
error = $"WO number cannot exceed {RequiredLength} characters.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
normalized = candidate;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2026-06-30 13:20:41 -03:00
|
|
|
}
|
|
|
|
|
}
|