feat: 품목 납기일 일괄 적용 기능 추가

- ModalRepeaterTableComponent에 납기일 자동 일괄 적용 로직 구현
- 첫 납기일 선택 시 빈 행에 자동으로 동일 날짜 적용
- isDeliveryDateApplied 플래그로 중복 실행 방지
- ScreenModal 환경에서 onFormDataChange 경로 지원
This commit is contained in:
SeongHyun Kim 2025-11-26 10:07:38 +09:00
parent 0a6c5fbfcc
commit c387221043
2 changed files with 89 additions and 4 deletions

View File

@ -64,6 +64,9 @@ export function OrderRegistrationModal({
// 선택된 품목 목록
const [selectedItems, setSelectedItems] = useState<any[]>([]);
// 납기일 일괄 적용 플래그 (딱 한 번만 실행)
const [isDeliveryDateApplied, setIsDeliveryDateApplied] = useState(false);
// 저장 중
const [isSaving, setIsSaving] = useState(false);
@ -158,6 +161,45 @@ export function OrderRegistrationModal({
hsCode: "",
});
setSelectedItems([]);
setIsDeliveryDateApplied(false); // 플래그 초기화
};
// 품목 목록 변경 핸들러 (납기일 일괄 적용 로직 포함)
const handleItemsChange = (newItems: any[]) => {
// 1⃣ 플래그가 이미 true면 그냥 업데이트만 (일괄 적용 완료 상태)
if (isDeliveryDateApplied) {
setSelectedItems(newItems);
return;
}
// 2⃣ 품목이 없으면 그냥 업데이트
if (newItems.length === 0) {
setSelectedItems(newItems);
return;
}
// 3⃣ 현재 상태: 납기일이 있는 행과 없는 행 개수 체크
const itemsWithDate = newItems.filter((item) => item.delivery_date);
const itemsWithoutDate = newItems.filter((item) => !item.delivery_date);
// 4⃣ 조건: 정확히 1개만 날짜가 있고, 나머지는 모두 비어있을 때 일괄 적용
if (itemsWithDate.length === 1 && itemsWithoutDate.length > 0) {
// 5⃣ 전체 일괄 적용
const selectedDate = itemsWithDate[0].delivery_date;
const updatedItems = newItems.map((item) => ({
...item,
delivery_date: selectedDate, // 모든 행에 동일한 납기일 적용
}));
setSelectedItems(updatedItems);
setIsDeliveryDateApplied(true); // 플래그 활성화 (다음부터는 일괄 적용 안 함)
console.log("✅ 납기일 일괄 적용 완료:", selectedDate);
console.log(` - 대상: ${itemsWithoutDate.length}개 행에 ${selectedDate} 적용`);
} else {
// 그냥 업데이트
setSelectedItems(newItems);
}
};
// 전체 금액 계산
@ -338,7 +380,7 @@ export function OrderRegistrationModal({
<Label className="text-xs sm:text-sm"> </Label>
<OrderItemRepeaterTable
value={selectedItems}
onChange={setSelectedItems}
onChange={handleItemsChange}
/>
</div>

View File

@ -195,17 +195,57 @@ export function ModalRepeaterTableComponent({
const columnName = component?.columnName;
const value = (columnName && formData?.[columnName]) || componentConfig?.value || propValue || [];
// ✅ onChange 래퍼 (기존 onChange 콜백 + onFormDataChange 호출)
// ✅ onChange 래퍼 (기존 onChange 콜백 + onFormDataChange 호출 + 납기일 일괄 적용)
const handleChange = (newData: any[]) => {
console.log("🔄 ModalRepeaterTableComponent.handleChange 호출:", {
dataLength: newData.length,
columnName,
hasExternalOnChange: !!(componentConfig?.onChange || propOnChange),
hasOnFormDataChange: !!(onFormDataChange && columnName),
});
// 🆕 납기일 일괄 적용 로직 (납기일 필드가 있는 경우만)
let processedData = newData;
// 납기일 필드 찾기 (item_due_date, delivery_date, due_date 등)
const dateField = columns.find(
(col) =>
col.field === "item_due_date" ||
col.field === "delivery_date" ||
col.field === "due_date"
);
if (dateField && !isDeliveryDateApplied && newData.length > 0) {
// 현재 상태: 납기일이 있는 행과 없는 행 개수 체크
const itemsWithDate = newData.filter((item) => item[dateField.field]);
const itemsWithoutDate = newData.filter((item) => !item[dateField.field]);
// 정확히 1개만 날짜가 있고, 나머지는 모두 비어있을 때 일괄 적용
if (itemsWithDate.length === 1 && itemsWithoutDate.length > 0) {
const selectedDate = itemsWithDate[0][dateField.field];
processedData = newData.map((item) => ({
...item,
[dateField.field]: selectedDate, // 모든 행에 동일한 납기일 적용
}));
setIsDeliveryDateApplied(true); // 플래그 활성화
console.log("✅ 납기일 일괄 적용 완료:", selectedDate);
console.log(` - 대상: ${itemsWithoutDate.length}개 행에 ${selectedDate} 적용`);
}
}
// 기존 onChange 콜백 호출 (호환성)
const externalOnChange = componentConfig?.onChange || propOnChange;
if (externalOnChange) {
externalOnChange(newData);
console.log("📤 외부 onChange 호출");
externalOnChange(processedData);
}
// 🆕 onFormDataChange 호출하여 EditModal의 groupData 업데이트
if (onFormDataChange && columnName) {
onFormDataChange(columnName, newData);
console.log("📤 onFormDataChange 호출:", columnName);
onFormDataChange(columnName, processedData);
}
};
@ -219,6 +259,9 @@ export function ModalRepeaterTableComponent({
const companyCode = componentConfig?.companyCode || propCompanyCode;
const [modalOpen, setModalOpen] = useState(false);
// 🆕 납기일 일괄 적용 플래그 (딱 한 번만 실행)
const [isDeliveryDateApplied, setIsDeliveryDateApplied] = useState(false);
// columns가 비어있으면 sourceColumns로부터 자동 생성
const columns = React.useMemo((): RepeaterColumnConfig[] => {
const configuredColumns = componentConfig?.columns || propColumns || [];