shoc-backend/SeaHaven.Services/Helpers/WorkOrderNumberNormalizer.cs

69 lines
2.2 KiB
C#
Raw Normal View History

using System.Text.RegularExpressions;
namespace SeaHaven.Services.Helpers
{
public static class WorkOrderNumberNormalizer
{
private const int RequiredLength = 11;
private const string ProvisionalPrefix = "SH";
private const int MinimumProvisionalDigits = 5;
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;
}
var trimmed = input.Trim();
if (WorkOrderNumberRules.IsProvisional(trimmed))
return TryNormalizeProvisional(trimmed, out normalized, out error);
var digits = Regex.Replace(trimmed, @"\D", "");
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;
}
// 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;
}
}
}