admin: add common-code crud and business-day rules
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
namespace TaxBaik.Web.Components.Admin.Shared;
|
||||
|
||||
public static class BusinessDayCalculator
|
||||
{
|
||||
private sealed record HolidayWindow(DateOnly Start, DateOnly End)
|
||||
{
|
||||
public IEnumerable<DateOnly> Dates()
|
||||
{
|
||||
for (var date = Start; date <= End; date = date.AddDays(1))
|
||||
{
|
||||
yield return date;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HolidayWindow[] HolidayWindows =
|
||||
{
|
||||
new(new DateOnly(2026, 1, 1), new DateOnly(2026, 1, 1)),
|
||||
new(new DateOnly(2026, 2, 16), new DateOnly(2026, 2, 18)),
|
||||
new(new DateOnly(2026, 3, 1), new DateOnly(2026, 3, 2)),
|
||||
new(new DateOnly(2026, 5, 5), new DateOnly(2026, 5, 5)),
|
||||
new(new DateOnly(2026, 6, 6), new DateOnly(2026, 6, 6)),
|
||||
new(new DateOnly(2026, 8, 15), new DateOnly(2026, 8, 17)),
|
||||
new(new DateOnly(2026, 9, 24), new DateOnly(2026, 9, 26)),
|
||||
new(new DateOnly(2026, 10, 3), new DateOnly(2026, 10, 5)),
|
||||
new(new DateOnly(2026, 10, 9), new DateOnly(2026, 10, 9)),
|
||||
new(new DateOnly(2026, 12, 25), new DateOnly(2026, 12, 25))
|
||||
};
|
||||
|
||||
private static readonly HashSet<DateOnly> HolidayDates = BuildHolidayDates();
|
||||
|
||||
public static DateOnly GetEffectiveDueDate(DateOnly dueDate)
|
||||
{
|
||||
var effectiveDate = dueDate;
|
||||
while (!IsBusinessDay(effectiveDate))
|
||||
{
|
||||
effectiveDate = effectiveDate.AddDays(1);
|
||||
}
|
||||
|
||||
return effectiveDate;
|
||||
}
|
||||
|
||||
public static int GetDday(DateOnly dueDate, DateOnly? referenceDate = null)
|
||||
{
|
||||
var today = referenceDate ?? DateOnly.FromDateTime(DateTime.Today);
|
||||
var effectiveDueDate = GetEffectiveDueDate(dueDate);
|
||||
return effectiveDueDate.DayNumber - today.DayNumber;
|
||||
}
|
||||
|
||||
public static bool IsBusinessDay(DateOnly date)
|
||||
=> date.DayOfWeek is not DayOfWeek.Saturday and not DayOfWeek.Sunday
|
||||
&& !HolidayDates.Contains(date);
|
||||
|
||||
private static HashSet<DateOnly> BuildHolidayDates()
|
||||
{
|
||||
var holidays = new HashSet<DateOnly>();
|
||||
|
||||
foreach (var window in HolidayWindows)
|
||||
{
|
||||
foreach (var date in window.Dates())
|
||||
{
|
||||
holidays.Add(date);
|
||||
}
|
||||
}
|
||||
|
||||
// 주말과 연속 공휴일 뒤에 붙는 대체휴일을 다음 영업일로 자동 확장한다.
|
||||
foreach (var window in HolidayWindows)
|
||||
{
|
||||
foreach (var date in window.Dates())
|
||||
{
|
||||
if (date.DayOfWeek is not DayOfWeek.Saturday and not DayOfWeek.Sunday)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var substitute = date.AddDays(1);
|
||||
while (substitute.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday || holidays.Contains(substitute))
|
||||
{
|
||||
substitute = substitute.AddDays(1);
|
||||
}
|
||||
|
||||
holidays.Add(substitute);
|
||||
}
|
||||
}
|
||||
|
||||
return holidays;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user