- 범용 컴포넌트 3종 개발 및 레지스트리 등록: * AutocompleteSearchInput: 자동완성 검색 입력 컴포넌트 * EntitySearchInput: 엔티티 검색 모달 컴포넌트 * ModalRepeaterTable: 모달 기반 반복 테이블 컴포넌트 - 수주등록 전용 컴포넌트: * OrderCustomerSearch: 거래처 검색 (AutocompleteSearchInput 래퍼) * OrderItemRepeaterTable: 품목 관리 (ModalRepeaterTable 래퍼) * OrderRegistrationModal: 수주등록 메인 모달 - 백엔드 API: * Entity 검색 API (멀티테넌시 지원) * 수주 등록 API (자동 채번) - 화면 편집기 통합: * 컴포넌트 레지스트리에 등록 * ConfigPanel을 통한 설정 기능 * 드래그앤드롭으로 배치 가능 - 개발 문서: * 수주등록_화면_개발_계획서.md (상세 설계 문서)
57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
import { useCallback } from "react";
|
|
import { CalculationRule } from "./types";
|
|
|
|
/**
|
|
* 계산 필드 자동 업데이트 훅
|
|
*/
|
|
export function useCalculation(calculationRules: CalculationRule[] = []) {
|
|
/**
|
|
* 단일 행의 계산 필드 업데이트
|
|
*/
|
|
const calculateRow = useCallback(
|
|
(row: any): any => {
|
|
if (calculationRules.length === 0) return row;
|
|
|
|
const updatedRow = { ...row };
|
|
|
|
for (const rule of calculationRules) {
|
|
try {
|
|
// formula에서 필드명 추출 및 값으로 대체
|
|
let formula = rule.formula;
|
|
|
|
for (const dep of rule.dependencies) {
|
|
const value = parseFloat(row[dep]) || 0;
|
|
formula = formula.replace(new RegExp(dep, "g"), value.toString());
|
|
}
|
|
|
|
// 계산 실행 (eval 대신 Function 사용)
|
|
const result = new Function(`return ${formula}`)();
|
|
updatedRow[rule.result] = result;
|
|
} catch (error) {
|
|
console.error(`계산 오류 (${rule.formula}):`, error);
|
|
updatedRow[rule.result] = 0;
|
|
}
|
|
}
|
|
|
|
return updatedRow;
|
|
},
|
|
[calculationRules]
|
|
);
|
|
|
|
/**
|
|
* 전체 데이터의 계산 필드 업데이트
|
|
*/
|
|
const calculateAll = useCallback(
|
|
(data: any[]): any[] => {
|
|
return data.map((row) => calculateRow(row));
|
|
},
|
|
[calculateRow]
|
|
);
|
|
|
|
return {
|
|
calculateRow,
|
|
calculateAll,
|
|
};
|
|
}
|
|
|