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' // Constants const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의 // 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, post, promisePost } = useAxios(globalLocaleState) const [isLoading, setIsLoading] = useState(false) const { estimateContextState, setEstimateContextState } = useContext(FloorPlanContext) 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' }) } setEstimateContextState(res.data) } } }) setIsLoading(true) } catch (error) { console.error('견적서 상세조회 Error: ', error) setIsLoading(true) } } const updateItem = (dispOrder, updates) => { setEstimateContextState({ itemList: updateItemInList(estimateContextState.itemList, dispOrder, updates), }) } const addItem = () => { let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder)) newItemDispOrder = (Math.floor(newItemDispOrder / 100) + 1) * 100 setEstimateContextState({ itemList: [ ...estimateContextState.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 addFlg: true, paDispOrder: null, }, ], }) } useEffect(() => { setEstimateData({ ...estimateContextState, userId: session.userId, sapSalesStoreCd: session.custCd }) }, [estimateContextState]) // 첨부파일 다운로드 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 let originFileFlg = false let fileFlg = true let itemFlg = 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')) } //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 if (estimateData?.originFiles?.length > 0) { originFileFlg = true } if (flag) { if (!originFileFlg) { if (estimateData.newFileList.length < 1) { if (estimateData.itemList.length > 1) { estimateData.itemList.map((row) => { if (row.delFlg === '0') { if (row.fileUploadFlg === '1') { if (fileFlg) { if (estimateData.fileFlg === '0') { fileFlg = false return alert(getMessage('estimate.detail.save.requiredFileUpload')) } } } } }) } } } } if (fileFlg) { estimateData.itemList.map((item) => { if (item.delFlg === '0') { item.amount = item.amount?.replaceAll(',', '') item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2) item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) if (!item.paDispOrder) { if (itemFlg) { if (isNaN(item.amount)) { item.amount = '0' } if (item.amount < 1) { itemFlg = false return alert(getMessage('estimate.detail.save.requiredAmount')) } if (estimateData.estimateType !== 'YJSS') { if (isNaN(item.salePrice)) { item.salePrice = '0' } if (item.salePrice < 1) { itemFlg = false return alert(getMessage('estimate.detail.save.requiredSalePrice')) } estimateData.pkgAsp = '0' estimateData.pkgTotPrice = '0' } } } } }) } if (flag && fileFlg && itemFlg) { //1. 첨부파일 저장시작 const formData = new FormData() if (estimateData?.newFileList?.length > 0) { estimateData.newFileList.forEach((file) => { formData.append('files', file) }) 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 !== '') estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) let delCnt = 0 estimateData.itemList.map((item) => { if (item.delFlg === '1') { delCnt++ } }) if (delCnt === estimateData.itemList.length) { return alert(getMessage('estimate.detail.save.requiredItem')) } let option = [] estimateData.itemList.forEach((item) => { if (item.specialNoteCd) { let split2 = item.specialNoteCd.split('、') option = option.concat(split2) } }) let estimateOptions = '' estimateData.specialNoteList.map((item) => { if (item.pkgYn === '0') { if (item.check) { if (estimateOptions === '') { estimateOptions = item.code } else { estimateOptions += '、' + item.code } } } else { if (item.check) { let flg = '0' for (let i = 0; i < estimateData.uniqueData.length; i++) { if (item.code.indexOf(estimateData.uniqueData[i]) > -1) { flg = '1' } if (flg === '1') { estimateOptions += '、' + estimateData.uniqueData[i] } } } } }) estimateData.estimateOption = estimateOptions // console.log('새로추가첨부파일:::', estimateData.newFileList) // console.log('기존첨부파일:::', estimateData.originFiles) // console.log('최종아이템:::', estimateData.itemList) // console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return try { 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) } }) } catch (e) { console.log('error::::::::::::', e.response.data.message) } } } /** * 견적서 복사버튼 * (견적서 번호(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 { estimateContextState, setEstimateContextState, updateItem, addItem, handleEstimateSubmit, fetchSetting, handleEstimateFileDownload, handleEstimateCopy, } }