import { useAxios } from '@/hooks/useAxios' import { useContext, useEffect, useReducer, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { globalLocaleStore } from '@/store/localeAtom' import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { isObjectNotEmpty } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { useMessage } from '@/hooks/useMessage' import { useRouter } from 'next/navigation' import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' const reducer = (prevState, nextState) => { return { ...prevState, ...nextState } } // Constants const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의 const defaultEstimateData = { estimateDate: new Date(), //견적일 charger: '', //담당자 objectName: '', //안건명 objectNameOmit: '', //경칭코드 estimateType: '', //주문분류 remarks: '', //비고 estimateOption: '', //견적특이사항 itemList: [], fileList: [], fileFlg: '0', //후일 자료 제출 (체크 1 노체크 0) priceCd: '', } // Helper functions const updateItemInList = (itemList, dispOrder, updates) => { return itemList.map((item) => (item.dispOrder === dispOrder ? { ...item, ...updates } : item)) } export const useEstimateController = (planNo) => { const router = useRouter() const { session } = useContext(SessionContext) const globalLocaleState = useRecoilValue(globalLocaleStore) const objectRecoil = useRecoilValue(floorPlanObjectState) const [estimateData, setEstimateData] = useRecoilState(estimateState) const { getMessage } = useMessage() const { promiseGet, get, post, promisePost } = useAxios(globalLocaleState) const [isLoading, setIsLoading] = useState(false) const [state, setState] = useReducer(reducer, defaultEstimateData) const [newState, setNewState] = useState({}) useEffect(() => { if (planNo && !isLoading) { if (objectRecoil.floorPlanObjectNo && planNo) { fetchSetting(objectRecoil.floorPlanObjectNo, planNo) } } }, []) // 상세 조회 const fetchSetting = async (objectNo, planNo) => { try { await promiseGet({ url: `/api/estimate/${objectNo}/${planNo}/detail` }).then((res) => { if (res.status === 200) { if (isObjectNotEmpty(res.data)) { if (res.data.itemList.length > 0) { res.data.itemList.map((item) => { item.delFlg = '0' }) } console.log('조회결과;', res.data) console.log('수정시간;', res.data.lastEditDatetime) setState(res.data) } } }) setIsLoading(true) } catch (error) { console.error('견적서 상세조회 Error: ', error) setIsLoading(true) } } const updateItem = (dispOrder, updates) => { setState({ itemList: updateItemInList(state.itemList, dispOrder, updates), }) } const addItem = () => { let newItemDispOrder = Math.max(...state.itemList.map((item) => item.dispOrder)) newItemDispOrder = (Math.floor(newItemDispOrder / 100) + 1) * 100 setState({ itemList: [ ...state.itemList, { objectNo: objectRecoil.floorPlanObjectNo, planNo: planNo, dispOrder: newItemDispOrder.toString(), itemId: '', //제품번호 itemNo: '', itemName: '', //형명 amount: '', //수량 unitPrice: '0', unit: '', //단위 salePrice: '', //단가 saleTotPrice: '', //금액(부가세별도) itemChangeFlg: '1', //추가시 체인지플래그 1로 partAdd: '1', //NEW 체인지 플래그 delFlg: '0', //삭제 플래그 0 삭제하면 1 }, ], }) } useEffect(() => { setEstimateData({ ...state, userId: session.userId, sapSalesStoreCd: session.custCd }) }, [state]) // 첨부파일 다운로드 const handleEstimateFileDownload = async (originFile) => { const options = { responseType: 'blob' } await promisePost({ url: `/api/file/fileDownload`, data: originFile, option: options }) .then((resultData) => { if (resultData) { const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' }) const fileUrl = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = fileUrl link.download = originFile.faileName document.body.appendChild(link) link.click() link.remove() window.URL.revokeObjectURL(fileUrl) } }) .catch((error) => { console.log('::FileDownLoad Error::', error) alert('File does not exist.') }) } //견적서 저장 const handleEstimateSubmit = async () => { //0. 필수체크 let flag = true if (estimateData.charger.trim().length === 0) { flag = false return alert(getMessage('estimate.detail.save.requiredCharger')) } if (estimateData.objectName.trim().length === 0) { flag = false return alert(getMessage('estimate.detail.save.requiredObjectName')) } if (isNaN(Date.parse(estimateData.estimateDate))) { flag = false return alert(getMessage('estimate.detail.save.requiredEstimateDate')) } // console.log('첨부파일:::::', estimateData.fileList) //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 let fileFlg = true if (estimateData.fileList.length < 1) { if (estimateData.itemList.length > 1) { estimateData.itemList.map((row) => { if (row.fileUploadFlg === '1') { if (fileFlg) { if (estimateData.fileFlg === '0') { fileFlg = false return alert(getMessage('estimate.detail.save.requiredFileUpload')) } } } }) } } if (flag && fileFlg) { //1. 첨부파일 저장시작 const formData = new FormData() formData.append('file', estimateData.fileList) formData.append('objectNo', estimateData.objectNo) formData.append('planNo', estimateData.planNo) formData.append('category', '10') formData.append('userId', estimateData.userId) await post({ url: '/api/file/fileUpload', data: formData }) //첨부파일저장끝 //제품라인 추가했는데 아이템 안고르고 저장하면itemId=''은 날리고 나머지 저장하기 estimateData.itemList = estimateData.itemList.filter((item) => item.itemId !== '') let delCnt = 0 estimateData.itemList.map((item) => { if (item.delFlg === '1') { delCnt++ } }) if (delCnt === estimateData.itemList.length) { return alert(getMessage('estimate.detail.save.requiredItem')) } // console.log('최종 정보::;', estimateData) //2. 상세데이터 저장 // return await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { if (res.status === 201) { alert(getMessage('estimate.detail.save.alertMsg')) //어디로 보낼지 fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) } }) } } /** * 견적서 복사버튼 * (견적서 번호(estimateData.docNo)가 생성된 이후 버튼 활성화 ) * T01관리자 계정 및 1차판매점에게만 제공 */ const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId) => { if (saleStoreId === '') { return alert(getMessage('estimate.detail.productFeaturesPopup.requiredStoreId')) } if (copyReceiveUser.trim().length === 0) { return alert(getMessage('estimate.detail.productFeaturesPopup.requiredReceiveUser')) } const params = { saleStoreId: session.storeId, sapSalesStoreCd: session.custCd, objectNo: objectRecoil.floorPlanObjectNo, planNo: sendPlanNo, copySaleStoreId: otherSaleStoreId ? otherSaleStoreId : saleStoreId, copyReceiveUser: copyReceiveUser, userId: session.userId, } // return await promisePost({ url: '/api/estimate/save-estimate-copy', data: params }).then((res) => { if (res.status === 201) { if (isObjectNotEmpty(res.data)) { let newObjectNo = res.data.objectNo alert(getMessage('estimate.detail.estimateCopyPopup.copy.alertMessage')) router.push(`/management/stuff/detail?objectNo=${newObjectNo.toString()}`, { scroll: false }) } } }) } return { state, setState, updateItem, addItem, handleEstimateSubmit, fetchSetting, handleEstimateFileDownload, handleEstimateCopy, } }