diff --git a/frontend/components/order/OrderRegistrationModal.tsx b/frontend/components/order/OrderRegistrationModal.tsx index bd780038..615f0426 100644 --- a/frontend/components/order/OrderRegistrationModal.tsx +++ b/frontend/components/order/OrderRegistrationModal.tsx @@ -64,6 +64,9 @@ export function OrderRegistrationModal({ // 선택된 품목 목록 const [selectedItems, setSelectedItems] = useState([]); + // 납기일 일괄 적용 플래그 (딱 한 번만 실행) + 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({ diff --git a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx index 91d7b36f..109c5c56 100644 --- a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx +++ b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx @@ -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 || [];