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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
@using TaxBaik.Domain.Entities
|
||||
@using TaxBaik.Web.Services.AdminClients
|
||||
@inject ICommonCodeBrowserClient CommonCodeClient
|
||||
|
||||
<MudSelect T="string"
|
||||
Value="Value"
|
||||
ValueChanged="ValueChanged"
|
||||
Label="@Label"
|
||||
Variant="@Variant"
|
||||
FullWidth="@FullWidth"
|
||||
Class="@Class"
|
||||
Required="@Required"
|
||||
Clearable="@Clearable"
|
||||
Disabled="@Disabled">
|
||||
@if (!string.IsNullOrWhiteSpace(Placeholder))
|
||||
{
|
||||
<MudSelectItem Value="@string.Empty">@Placeholder</MudSelectItem>
|
||||
}
|
||||
@foreach (var item in items)
|
||||
{
|
||||
<MudSelectItem Value="@item.CodeValue">@item.CodeName</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
@code {
|
||||
[Parameter] public string? Value { get; set; }
|
||||
[Parameter] public EventCallback<string?> ValueChanged { get; set; }
|
||||
[Parameter] public string Group { get; set; } = string.Empty;
|
||||
[Parameter] public string Label { get; set; } = string.Empty;
|
||||
[Parameter] public Variant Variant { get; set; } = Variant.Outlined;
|
||||
[Parameter] public bool FullWidth { get; set; } = true;
|
||||
[Parameter] public string? Class { get; set; }
|
||||
[Parameter] public bool Required { get; set; }
|
||||
[Parameter] public bool Clearable { get; set; }
|
||||
[Parameter] public bool Disabled { get; set; }
|
||||
[Parameter] public string? Placeholder { get; set; }
|
||||
|
||||
private List<CommonCode> items = [];
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
var normalizedGroup = Group?.Trim() ?? string.Empty;
|
||||
if (!string.Equals(normalizedGroup, _loadedGroup, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_loadedGroup = normalizedGroup;
|
||||
items = string.IsNullOrWhiteSpace(normalizedGroup)
|
||||
? []
|
||||
: (await CommonCodeClient.GetByGroupAsync(normalizedGroup))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ThenBy(x => x.CodeName)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private string? _loadedGroup;
|
||||
}
|
||||
Reference in New Issue
Block a user