using e_suite.Database.Core.Tables.Sequences; using e_suite.Modules.SequenceManager.Extensions; using eSuite.Core.Clock; using eSuite.Core.Sequences; using System.Text.RegularExpressions; namespace e_suite.Modules.SequenceManager; public static class SequenceNumberBuilder { private const string NumberPattern = @"\[([0-9]+)\]"; private const string DatePattern = @"\{([MM|YY|YYYY|DD|yy|yyyy|mm|dd]+)\}"; private static readonly Regex NumberExpression = new(NumberPattern, RegexOptions.Compiled); private static readonly Regex DateExpression = new(DatePattern, RegexOptions.Compiled); public static string GetNextSequenceNumber(Sequence sequence, IClock clock) { const char CustomYear = 'Y'; const char CustomDay = 'D'; const char CustomMonth = 'm'; const char StandardYear = 'y'; const char StandardDay = 'd'; const char StandardMonth = 'M'; const char Zero = '0'; var number = GenerateNumber(sequence, clock); var date = clock.GetNow; var code = sequence.Pattern; var dateMatches = DateExpression.Matches(sequence.Pattern); for (var index = 0; index < dateMatches.Count; index++) { var match = dateMatches[index]; var dateReplacement = match.Captures[0].Value; var dateFormat = match.Groups[1].Value; dateFormat = dateFormat.Replace(CustomYear, StandardYear); dateFormat = dateFormat.Replace(CustomDay, StandardDay); dateFormat = dateFormat.Replace(CustomMonth, StandardMonth); var formattedDate = date.ToString(dateFormat); code = code.Replace(dateReplacement, formattedDate); } var numberMatches = NumberExpression.Matches(sequence.Pattern); for (var index = 0; index < numberMatches.Count; index++) { var match = numberMatches[index]; var numberReplacement = match.Captures[0].Value; var numberFormat = match.Groups[1].Value; numberFormat = string.Empty.PadRight(numberFormat.Length, Zero); var formattedNumber = number.ToString(numberFormat); code = code.Replace(numberReplacement, formattedNumber); } return code; } private static long GenerateNumber(Sequence sequence, IClock clock) { long number = 0; if (!sequence.LastIssueDate.HasValue) { number = sequence.Seed + sequence.Increment; } else { switch (sequence.Rollover) { case Rollover.Day: if (sequence.LastIssueDate.HasValue) { if (sequence.LastIssueDate.Value.DateTime.IsSameDay(clock.GetNow.DateTime)) { number = (sequence.LastIssueValue ?? sequence.Seed) + sequence.Increment; } else { number = sequence.Seed + sequence.Increment; } } break; case Rollover.Month: if (sequence.LastIssueDate.HasValue) { if (sequence.LastIssueDate.Value.DateTime.IsSameMonth(clock.GetNow.DateTime)) { number = (sequence.LastIssueValue ?? sequence.Seed) + sequence.Increment; } else { number = sequence.Seed + sequence.Increment; } } break; case Rollover.Year: if (sequence.LastIssueDate.HasValue) { if (sequence.LastIssueDate.Value.DateTime.Year == clock.GetNow.Year) { number = (sequence.LastIssueValue ?? sequence.Seed) + sequence.Increment; } else { number = sequence.Seed + sequence.Increment; } } break; case Rollover.Continuous: default: number = (sequence.LastIssueValue ?? 0) + sequence.Increment; break; } } sequence.LastIssueValue = number; sequence.LastIssueDate = clock.GetNow; return number; } }