diff --git a/backend-node/src/controllers/authController.ts b/backend-node/src/controllers/authController.ts index ad66a7c2..b841af44 100644 --- a/backend-node/src/controllers/authController.ts +++ b/backend-node/src/controllers/authController.ts @@ -376,6 +376,8 @@ export class AuthController { userType: userInfo.userType || dbUserInfo.userType || "USER", // JWT 토큰 우선 userTypeName: dbUserInfo.userTypeName || "일반사용자", email: dbUserInfo.email || "", + tel: dbUserInfo.tel || "", + cellPhone: dbUserInfo.cellPhone || "", photo: dbUserInfo.photo, locale: dbUserInfo.locale || "KR", // locale 정보 추가 deptCode: dbUserInfo.deptCode, // 추가 필드 diff --git a/frontend/app/(main)/COMPANY_16/sales/estimate/template1/pop/[contractObjid]/page.tsx b/frontend/app/(main)/COMPANY_16/sales/estimate/template1/pop/[contractObjid]/page.tsx index 0390d071..e61ddd6e 100644 --- a/frontend/app/(main)/COMPANY_16/sales/estimate/template1/pop/[contractObjid]/page.tsx +++ b/frontend/app/(main)/COMPANY_16/sales/estimate/template1/pop/[contractObjid]/page.tsx @@ -80,6 +80,7 @@ export default function EstimateTemplate1Page() { // 헤더 필드 const [executor, setExecutor] = useState(""); // 시행일자 (YYYY-MM-DD) + const executorDateRef = useRef(null); const [recipient, setRecipient] = useState(""); // 수신처 (customer_objid) const [estimateNo, setEstimateNo] = useState(""); const [contactPerson, setContactPerson] = useState(""); @@ -161,15 +162,12 @@ export default function EstimateTemplate1Page() { } } - if (contractInfo?.header) { - const h = contractInfo.header; - if (!cancel) { - setExchangeRate(parseFloat(h.exchange_rate || "1") || 1); - // 통화명: comm_code lookup이 필요한데 detail이 raw코드만 줄 수도 있음 → 일단 코드 사용 - setCurrencyName(h.contract_currency_name || h.contract_currency || "KRW"); - // 수신처는 customer_objid (예: 'C_RPS001') - if (h.customer_objid) setRecipient(h.customer_objid); - } + // getById 응답: { ...contract_mgmt 헤더 필드들, items: [...] } (평면 구조) + if (contractInfo && !cancel) { + setExchangeRate(parseFloat(contractInfo.exchange_rate || "1") || 1); + setCurrencyName(contractInfo.contract_currency_name || contractInfo.contract_currency || "KRW"); + // 수신처는 customer_objid (예: 'C_RPS001') — 견적요청의 고객사를 견적서에 자동 채움 + if (contractInfo.customer_objid) setRecipient(contractInfo.customer_objid); } // 2) 기존 견적 차수 수정 (templateObjid 지정) — 우선 @@ -241,7 +239,8 @@ export default function EstimateTemplate1Page() { if (!user) return; if (templateObjidParam) return; // 기존 견적서 수정 모드는 건드리지 않음 setManagerName(prev => prev || `${user.deptName ?? ""} ${user.userName ?? ""}`.trim()); - setManagerContact(prev => prev || user.tel ?? ""); + // wace MailUtil 패턴: cell_phone 우선, 없으면 tel + setManagerContact(prev => prev || user.cellPhone || user.tel || ""); }, [user, templateObjidParam]); // ─── 저장 (wace fn_save 1:1) ───────────────────────────────── @@ -511,13 +510,26 @@ export default function EstimateTemplate1Page() { 시행일자 - setExecutor(e.target.value)} - readOnly={readOnly} - style={{ width: 150 }} - /> + {/* 표시는 YYYY-MM-DD (text), 클릭 시 숨겨진 type=date의 showPicker 트리거 */} +
+ { if (!readOnly) executorDateRef.current?.showPicker?.(); }} + style={{ width: "100%", cursor: readOnly ? "default" : "pointer" }} + /> + setExecutor(e.target.value)} + tabIndex={-1} + aria-hidden="true" + style={{ position: "absolute", left: 0, top: 0, width: 1, height: 1, opacity: 0, pointerEvents: "none" }} + /> +
diff --git a/frontend/app/(main)/COMPANY_16/sales/estimate/template2/pop/[contractObjid]/page.tsx b/frontend/app/(main)/COMPANY_16/sales/estimate/template2/pop/[contractObjid]/page.tsx index 489ec521..749ff195 100644 --- a/frontend/app/(main)/COMPANY_16/sales/estimate/template2/pop/[contractObjid]/page.tsx +++ b/frontend/app/(main)/COMPANY_16/sales/estimate/template2/pop/[contractObjid]/page.tsx @@ -109,6 +109,7 @@ export default function EstimateTemplate2Page() { // 헤더 const [executorDate, setExecutorDate] = useState(""); + const executorDateRef = React.useRef(null); const [recipient, setRecipient] = useState(""); const [partName, setPartName] = useState(""); const [partObjid, setPartObjid] = useState(""); @@ -201,10 +202,10 @@ export default function EstimateTemplate2Page() { console.warn("영업정보 로드 실패", e); } } - if (contractInfo?.header && !cancel) { - const h = contractInfo.header; - setExchangeRate(parseFloat(h.exchange_rate || "1") || 1); - if (h.customer_objid) setRecipient(h.customer_objid); + // getById 응답: { ...contract_mgmt 헤더 필드들, items: [...] } (평면 구조) + if (contractInfo && !cancel) { + setExchangeRate(parseFloat(contractInfo.exchange_rate || "1") || 1); + if (contractInfo.customer_objid) setRecipient(contractInfo.customer_objid); } // 신규: contract_item[0]의 part_name을 품명/Model로 if (contractInfo?.items?.[0] && !cancel) { @@ -454,13 +455,26 @@ export default function EstimateTemplate2Page() {
시행일자 :{" "} - setExecutorDate(e.target.value)} - readOnly={readOnly} - style={{ width: 200, borderBottom: "1px solid #999", padding: "2px 5px" }} - /> + {/* 표시는 YYYY-MM-DD (text), 클릭 시 숨겨진 type=date의 showPicker 트리거 */} + + { if (!readOnly) executorDateRef.current?.showPicker?.(); }} + style={{ width: "100%", borderBottom: "1px solid #999", padding: "2px 5px", cursor: readOnly ? "default" : "pointer" }} + /> + setExecutorDate(e.target.value)} + tabIndex={-1} + aria-hidden="true" + style={{ position: "absolute", left: 0, top: 0, width: 1, height: 1, opacity: 0, pointerEvents: "none" }} + /> +
수 신 처 :{" "}