qcast-front/src/hooks/floorPlan/estimate/useEstimateController.js
2024-11-20 16:46:55 +09:00

269 lines
8.8 KiB
JavaScript

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,
}
}