378 lines
12 KiB
JavaScript
378 lines
12 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, isEmptyArray } 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 [fileList, setFileList] = useState([])
|
|
const [deleteFileList, setDeleteFileList] = useState([])
|
|
|
|
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)
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (fileList.length > 0) {
|
|
realSave(fileList)
|
|
}
|
|
}, [fileList])
|
|
|
|
// 상세 조회
|
|
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'))
|
|
}
|
|
|
|
//기존에 첨부된 파일이 있으면 파일첨부관련 통과
|
|
if (estimateData?.originFiles?.length > 0) {
|
|
originFileFlg = true
|
|
}
|
|
if (flag) {
|
|
if (!originFileFlg) {
|
|
//기존에 첨부된 파일이 없으면
|
|
if (isEmptyArray(estimateData.newFileList)) {
|
|
//새로 첨부한 파일이 없으면
|
|
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.openFlg !== '1') {
|
|
if (item.salePrice < 1) {
|
|
itemFlg = false
|
|
return alert(getMessage('estimate.detail.save.requiredSalePrice'))
|
|
}
|
|
}
|
|
|
|
estimateData.pkgAsp = '0'
|
|
estimateData.pkgTotPrice = '0'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
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'))
|
|
}
|
|
}
|
|
|
|
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 }).then((res) => {
|
|
setFileList(res)
|
|
})
|
|
} else {
|
|
setFileList([])
|
|
realSave()
|
|
}
|
|
}
|
|
}
|
|
|
|
const realSave = async (fileList) => {
|
|
//첨부파일저장끝
|
|
|
|
let option = []
|
|
estimateData.itemList.forEach((item) => {
|
|
if (item.specialNoteCd) {
|
|
let split2 = item.specialNoteCd.split('、')
|
|
option = option.concat(split2)
|
|
}
|
|
})
|
|
|
|
let estimateOptions = ''
|
|
let estimateOptionsArray
|
|
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]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
estimateOptionsArray = estimateOptions.split('、').sort()
|
|
estimateOptionsArray = Array.from(new Set(estimateOptionsArray))
|
|
|
|
estimateOptions = estimateOptionsArray.join('、')
|
|
|
|
estimateData.estimateOption = estimateOptions
|
|
// console.log('최종아이템:::', estimateData.itemList)
|
|
if (fileList?.length > 0) {
|
|
estimateData.fileList = fileList
|
|
} else {
|
|
estimateData.fileList = []
|
|
}
|
|
if (estimateData.originFiles?.length > 0) {
|
|
estimateData.deleteFileList = estimateData.originFiles?.filter((item) => item.delFlg === '1')
|
|
} else {
|
|
estimateData.deleteFileList = []
|
|
}
|
|
|
|
console.log('최종저장::', estimateData)
|
|
//2. 상세데이터 저장
|
|
// return
|
|
try {
|
|
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {
|
|
if (res.status === 201) {
|
|
estimateData.newFileList = []
|
|
estimateData.originFileList = []
|
|
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,
|
|
}
|
|
}
|