feat: 분급 비율 회차(월) 단위 등록 지원 (V81)

- installment_ratio.plan_month INT NULL 컬럼 추가
  - NULL = 연 단위(연차 합계, 기존 동작)
  - 1~12 = 해당 회차(월) 단위 비율
- UNIQUE 재정의: NULLS NOT DISTINCT (product_category, plan_year, plan_month, effective_from)
- InstallmentPlanGenerator: planMonth=NULL이면 1, NOT NULL이면 그대로 사용해 settle_month 계산
- 분급비율 화면: 회차(월) 컬럼·입력 추가, "(연차-1)*12+월" 통합 회차 표기
This commit is contained in:
GA Pro
2026-05-24 01:27:47 +09:00
parent 3f52596a8b
commit c005ad705a
10 changed files with 97 additions and 12 deletions
+4
View File
@@ -5,6 +5,7 @@ export interface InstallmentRatioResp {
productCategory: string | null;
productCategoryName: string | null;
planYear: number;
planMonth: number | null;
ratioPercent: number;
effectiveFrom: string;
effectiveTo: string | null;
@@ -14,6 +15,7 @@ export interface InstallmentRatioResp {
export interface InstallmentRatioSaveReq {
productCategory?: string | null;
planYear: number;
planMonth?: number | null;
ratioPercent: number;
effectiveFrom: string;
effectiveTo?: string | null;
@@ -21,6 +23,8 @@ export interface InstallmentRatioSaveReq {
export interface InstallmentRatioSearchParam {
productCategory?: string;
planYear?: number;
planMonth?: number;
pageNum?: number;
pageSize?: number;
}
@@ -37,10 +37,25 @@ const PLAN_YEAR_OPTIONS = [1, 2, 3, 4, 5, 6, 7].map((y) => ({
label: `${y}차년도`,
}));
const PLAN_MONTH_OPTIONS = [
{ value: null as number | null, label: '연 단위(연차 합계)' },
...Array.from({ length: 12 }, (_, i) => ({
value: i + 1,
label: `${i + 1}회차(월)`,
})),
];
function planYearLabel(y: number): string {
return `${y}차년도`;
}
/** 회차 표기: NULL=연 단위, 아니면 "(연차-1)*12 + 월" 통합 회차 + 월 */
function planMonthLabel(planYear: number, planMonth: number | null): string {
if (planMonth == null) return '연 단위';
const seq = (planYear - 1) * 12 + planMonth;
return `${seq}회 (${planMonth}월)`;
}
export default function InstallmentRatioList() {
const actionRef = useRef<ActionType>();
const [searchParam, setSearchParam] = useState<InstallmentRatioSearchParam>({
@@ -57,6 +72,7 @@ export default function InstallmentRatioList() {
const req: InstallmentRatioSaveReq = {
productCategory: v.productCategory || null,
planYear: v.planYear,
planMonth: v.planMonth ?? null,
ratioPercent: v.ratioPercent,
effectiveFrom: dayjs(v.effectiveFrom).format('YYYY-MM-DD'),
effectiveTo: v.effectiveTo ? dayjs(v.effectiveTo).format('YYYY-MM-DD') : null,
@@ -84,6 +100,14 @@ export default function InstallmentRatioList() {
search: false,
render: (_, r) => planYearLabel(r.planYear),
},
{
title: '회차(월)',
dataIndex: 'planMonth',
width: 130,
align: 'center',
search: false,
render: (_, r) => planMonthLabel(r.planYear, r.planMonth),
},
{
title: '비율(%)',
dataIndex: 'ratioPercent',
@@ -168,7 +192,7 @@ export default function InstallmentRatioList() {
return (
<PageContainer
title="분급비율 설정"
description="분급 비율 합계가 100%가 되도록 1~7차년도 각 비율 설정"
description="1~7차년도 각 비율 설정. 회차(월) 미지정 = 연 단위(첫 달 지급), 1~12 지정 = 해당 월만 지급"
>
<ProTable<InstallmentRatioResp>
actionRef={actionRef}
@@ -236,6 +260,17 @@ export default function InstallmentRatioList() {
options={PLAN_YEAR_OPTIONS}
/>
</ProForm.Group>
<ProForm.Group>
<ProFormSelect
name="planMonth"
label="회차(월)"
width="md"
placeholder="비워두면 연 단위"
tooltip="비우면 연차 합계, 1~12 선택 시 그 회차(월)만 적용"
options={PLAN_MONTH_OPTIONS}
allowClear
/>
</ProForm.Group>
<ProForm.Group>
<ProFormDigit
name="ratioPercent"