2024-11-22 13:17:53 +09:00

1241 lines
49 KiB
JavaScript

'use client'
import { useEffect, useState, useContext } from 'react'
import { useRecoilValue } from 'recoil'
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
import { useMessage } from '@/hooks/useMessage'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import SingleDatePicker from '../common/datepicker/SingleDatePicker'
import EstimateFileUploader from './EstimateFileUploader'
import { useAxios } from '@/hooks/useAxios'
import { globalLocaleStore } from '@/store/localeAtom'
import { isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
import dayjs from 'dayjs'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
import { SessionContext } from '@/app/SessionProvider'
import Select, { components } from 'react-select'
import { convertNumberToPriceDecimal } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid'
export default function Estimate({ params }) {
const fixedKey = 'itemKey'
const [itemChangeYn, setItemChangeYn] = useState(false)
const { session } = useContext(SessionContext)
const [objectNo, setObjectNo] = useState('') //물건번호
const [planNo, setPlanNo] = useState('') //플랜번호
const [files, setFiles] = useState([]) // 보내는 첨부파일
const [originFiles, setOriginFiles] = useState([]) //기존 첨부파일
const [showPriceCd, setShowPriceCd] = useState('')
const [showContentCode, setShowContentCode] = useState('ATTR001')
const [productFeaturesPopupOpen, setProductFeaturesPopupOpen] = useState(false) //견적특이사항 팝업
const [showProductFeatureData, setShowProductFeatureData] = useState([]) //팝업에 보여줄 견적특이사항 데이터
const [selection, setSelection] = useState(new Set())
//견적특이사항 접고 펼치기
const [hidden, setHidden] = useState(false)
//아이템 자동완성 리스트
const [displayItemList, setDisplayItemList] = useState([])
//공통코드
const { findCommonCode } = useCommonCode()
const [honorificCodeList, setHonorificCodeList] = useState([]) //경칭 공통코드
const [storePriceList, setStorePriceList] = useState([]) //가격표시 option
const [startDate, setStartDate] = useState(new Date())
const singleDatePickerProps = {
startDate,
setStartDate,
}
const objectRecoil = useRecoilValue(floorPlanObjectState)
//견적서 상세데이터
const { estimateContextState, setEstimateContextState, addItem, handleEstimateFileDownload } = useEstimateController(params.pid)
//견적특이사항 List
const [specialNoteList, setSpecialNoteList] = useState([])
const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get, promisePost } = useAxios(globalLocaleState)
const { getMessage } = useMessage()
const { setMenuNumber } = useCanvasMenu()
//새로 추가한 첨부파일 props
const fileUploadProps = {
uploadFiles: files,
setUploadFiles: setFiles,
}
useEffect(() => {
setMenuNumber(5)
setObjectNo(objectRecoil.floorPlanObjectNo)
setPlanNo(params.pid)
// 공통코드
const code1 = findCommonCode(200800)
if (code1 != null) {
setHonorificCodeList(code1)
}
//아이템 자동완성 목록 가져오기
const param = {
saleStoreId: session.storeId,
}
const apiUrl = `/api/display-item/item-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (res.length > 0) {
setDisplayItemList(res)
}
})
}, [])
useEffect(() => {
//견적특이사항 API호출
//여러개 선택하면 구분자로 (、)
let url = `/api/estimate/special-note-list`
get({ url: url }).then((res) => {
if (isNotEmptyArray(res)) {
if (estimateContextState?.estimateOption) {
res.map((row) => {
let estimateOption = estimateContextState?.estimateOption?.split('、')
row.text = false
estimateOption.map((row2) => {
if (row2 === row.code) {
row.text = true
}
})
})
setSpecialNoteList(res)
}
}
})
}, [estimateContextState?.estimateOption])
//견적일 set
useEffect(() => {
let estimateDate = dayjs(startDate).format('YYYY-MM-DD')
setEstimateContextState({ estimateDate: estimateDate })
}, [startDate])
//API데이터로 견적일 셋팅
useEffect(() => {
setStartDate(estimateContextState?.estimateDate)
}, [estimateContextState?.estimateDate])
useEffect(() => {
//선택된 견적특이사항 setEstimateContextState
if (isNotEmptyArray(specialNoteList)) {
const liveCheckedData = specialNoteList.filter((row) => row.text === true)
const data = []
for (let ele of liveCheckedData) {
data.push(ele.code)
}
const newData = data.join('、')
setEstimateContextState({ estimateOption: newData })
}
}, [specialNoteList])
// 견적특이사항 remark 보여주기
const settingShowContent = (code, event) => {
setShowContentCode(code)
event.stopPropagation()
}
// 추가한 첨부파일 estimateContextState에 넣기
useEffect(() => {
if (isNotEmptyArray(files)) {
files.map((row) => {
setEstimateContextState({ fileList: row.data })
})
} else {
setEstimateContextState({ fileList: [] })
}
}, [files])
//상세에서 내려온 첨부파일 set 만들기
useEffect(() => {
if (isNotEmptyArray(estimateContextState.fileList)) {
setOriginFiles(estimateContextState.fileList)
}
}, [estimateContextState?.fileList])
// 기존첨부파일 삭제
const deleteOriginFile = async (objectNo, no) => {
const delParams = {
userId: session.userId,
objectNo: objectNo,
no: no,
}
await promisePost({ url: 'api/file/fileDelete', data: delParams }).then((res) => {
if (res.status === 204) {
setOriginFiles(originFiles.filter((file) => file.objectNo === objectNo && file.no !== no))
setEstimateContextState({
fileList: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no),
})
}
})
}
//가격표시 option 목록 최초세팅 && 주문분류 변경시
useEffect(() => {
if (estimateContextState.estimateType !== '') {
const param = {
saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd,
docTpCd: estimateContextState?.estimateType,
}
const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) {
setStorePriceList(res.data)
}
})
setItemChangeYn(true)
}
}, [estimateContextState?.estimateType])
useEffect(() => {
if (estimateContextState?.priceCd) {
setShowPriceCd(estimateContextState.priceCd)
}
}, [estimateContextState?.priceCd])
//가격 표시 option 변경 이벤트
const onChangeStorePriceList = (priceCd) => {
const param = {
saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd,
docTpCd: priceCd,
}
//프라이싱 했을때 priceCd setEstimateContextState
//화면에 보여지는 값은 showPriceCd로 관리
setShowPriceCd(priceCd)
const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) {
setStorePriceList(res.data)
}
})
}
//Pricing 버튼
const handlePricing = async (showPriceCd) => {
const param = {
saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd,
docTpCd: estimateContextState.estimateType,
priceCd: showPriceCd,
//itemIdList: estimateContextState.itemList, //아이템 최초정보로 호출 delFlg 0인거만..
itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0'),
}
if (param.itemIdList.length > 0) {
let pass = true
param.itemIdList.map((item) => {
if (item.itemId === '') {
pass = false
}
})
if (!pass) {
//Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.
return alert(getMessage('estimate.detail.showPrice.pricingBtn.noItemId'))
}
}
await promisePost({ url: '/api/estimate/price/item-price-list', data: param }).then((res) => {
let updateList = []
if (res) {
if (res.status === 200) {
const data = res.data
//기존itemList랑 프라이싱결과랑 비교해서 단가만 업뎃 서로 갯수가 안맞을 수 있음 없는 itemId면 unitPrice 0으로
//itemId로 비교해서 단가정보만 업데이트
if (data.result.code === 200) {
if (isNotEmptyArray(data.data2)) {
estimateContextState.itemList.map((item) => {
let checkYn = false
data.data2.map((item2) => {
if (item2) {
if (item2.itemId === item.itemId) {
updateList.push({ ...item, unitPrice: item2.unitPrice })
checkYn = true
}
}
})
if (!checkYn) {
updateList.push({ ...item, unitPrice: '0' })
}
})
setEstimateContextState({
priceCd: showPriceCd,
itemList: updateList,
})
setItemChangeYn(true)
}
}
}
}
})
}
//row 체크박스 컨트롤
const onChangeSelect = (dispOrder) => {
const newSelection = new Set(selection)
if (newSelection.has(dispOrder)) {
newSelection.delete(dispOrder)
} else {
newSelection.add(dispOrder)
}
setSelection(newSelection)
}
//주택PKG input 변경
const onChangePkgAsp = (value) => {
if (estimateContextState.estimateType === 'YJSS') {
let pkgAsp = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
if (isNaN(pkgAsp)) {
pkgAsp = 0
} else {
pkgAsp = pkgAsp.toLocaleString()
}
//현재 PKG용량값 가져오기
let totVolKw = estimateContextState.totVolKw * 1000
let pkgTotPrice = pkgAsp * totVolKw
setEstimateContextState({
pkgAsp: pkgAsp,
pkgTotPrice: pkgTotPrice.toFixed(3),
})
}
}
// 수량 변경
const onChangeAmount = (value, dispOrder, index) => {
//itemChangeFlg = 1, partAdd = 0 셋팅
let amount = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
if (isNaN(amount)) {
amount = 0
} else {
amount = amount.toLocaleString()
}
let updateList = []
let updates = {}
updates.amount = amount
updates.itemChangeFlg = '1'
updates.partAdd = '0'
updates.saleTotPrice = (Number(amount.replaceAll(',', '')) * estimateContextState.itemList[index].salePrice.replaceAll(',', '')).toLocaleString()
updateList = estimateContextState.itemList.map((item) => {
if (item.dispOrder === dispOrder) {
return { ...item, ...updates }
} else {
return item
}
})
setEstimateContextState({
itemList: updateList,
})
setItemChangeYn(true)
}
// 단가 변경
const onChangeSalePrice = (value, dispOrder, index) => {
//itemChangeFlg, partAdd 받아온 그대로
let salePrice = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
if (isNaN(salePrice)) {
salePrice = 0
} else {
salePrice = salePrice.toLocaleString()
}
let updateList = []
let updates = {}
updates.salePrice = salePrice
updates.saleTotPrice = (Number(salePrice.replaceAll(',', '')) * estimateContextState.itemList[index].amount.replaceAll(',', '')).toLocaleString()
updateList = estimateContextState.itemList.map((item) => {
if (item.dispOrder === dispOrder) {
return { ...item, ...updates }
} else {
return item
}
})
setEstimateContextState({
itemList: updateList,
})
setItemChangeYn(true)
}
// 아이템 자동완성 검색시 아이템 변경
const onChangeDisplayItem = (itemId, dispOrder, index) => {
const param = {
itemId: itemId,
}
const apiUrl = `/api/display-item/item-detail?${queryStringFormatter(param)}`
let updateList = []
let updates = {}
get({ url: apiUrl }).then((res) => {
// console.log('아이템상세정보:::::::', res)
updates.objectNo = objectNo
updates.planNo = planNo
updates.itemId = res.itemId
updates.itemNo = res.itemNo
updates.itemName = res.itemName
updates.itemChangeFlg = '1' //무조건 1
updates.partAdd = '1' //무조건1 NEW
updates.fileUploadFlg = res.fileUploadFlg
updates.unit = res.unit
updates.unitPrice = res.salePrice //unitPrice도 salePrice로
updates.moduleFlg = res.moduleFlg
updates.pkgMaterialFlg = res.pkgMaterialFlg
updates.pnowW = res.pnowW
updates.salePrice = res.salePrice
updates.specification = res.specification
updates.unit = res.unit
updates.specialNoteCd = res.spnAttrCds
updates.itemGroup = res.itemGroup
updates.delFlg = '0' // 삭제플래그 0
// updates.saleTotPrice = res.salePrice * estimateContextState.itemList[index].amount
updates.saleTotPrice = '0' //추가때는 수량을 안받아서 합계를 무조건 0으로
//104671
let bomList = res.itemBomList
updateList = estimateContextState.itemList.map((item) => {
if (item.dispOrder === dispOrder) {
return { ...item, ...updates }
} else if (item.paDispOrder === dispOrder) {
return { ...item, delFlg: '1' }
} else {
return item
}
})
//paDispOrder
if (bomList) {
bomList.map((bomItem, index) => {
let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder))
bomItem.dispOrder = index + 1 + newItemDispOrder
bomItem.delFlg = '0'
bomItem.objectNo = objectNo
bomItem.planNo = planNo
})
setEstimateContextState({
itemList: [...updateList, ...bomList],
})
} else {
setEstimateContextState({
itemList: updateList,
})
}
setItemChangeYn(true)
})
}
//제품 삭제
const removeItem = () => {
const array = [...selection]
let delList = []
estimateContextState.itemList.filter((row) => {
array.map((row2) => {
if (row2 === row.dispOrder) {
delList.push({ ...row })
}
if (row2 === row.paDispOrder) {
delList.push({ ...row })
}
})
})
const updateList = estimateContextState.itemList.map((item) => {
const isDeleted = delList.some((row) => item.delFlg === '1' || item.dispOrder === row.dispOrder)
return {
...item,
delFlg: isDeleted ? '1' : '0',
}
})
let delCnt = 0
updateList.map((item) => {
if (item.delFlg === '1') {
delCnt++
}
})
if (delCnt === updateList.length) {
return alert(getMessage('estimate.detail.save.requiredItem'))
}
setEstimateContextState({
itemList: updateList,
})
setSelection(new Set())
setItemChangeYn(true)
}
useEffect(() => {
if (itemChangeYn) {
let totAmount = 0
let totVolKw = 0
let supplyPrice = 0
let vatPrice = 0
let totPrice = 0
let addPkgPrice = 0
if (estimateContextState.estimateType === 'YJOD') {
estimateContextState.itemList.map((item) => {
if (item.delFlg === '0') {
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', ''))
const price = Number(item.saleTotPrice.replaceAll(',', ''))
if (item.moduleFlg === '1') {
//용량(Kw)은 모듈플래그 1만 합산
const volKw = (item.pnowW * amount) / 1000
totVolKw += volKw
}
// const price
totAmount += amount
supplyPrice += price
}
})
vatPrice = supplyPrice * 0.1
totPrice = supplyPrice + vatPrice
setEstimateContextState({
totAmount: totAmount,
totVolKw: totVolKw.toFixed(3),
supplyPrice: supplyPrice.toFixed(3),
vatPrice: vatPrice.toFixed(3),
totPrice: totPrice.toFixed(3),
})
} else {
//YJSS
estimateContextState.itemList.map((item) => {
if (item.delFlg === '0') {
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', ''))
const price = Number(item.saleTotPrice.replaceAll(',', ''))
const salePrice = Number(item.salePrice.replaceAll(',', ''))
if (item.moduleFlg === '1') {
//용량(Kw)은 모듈플래그 1만 합산
const volKw = (item.pnowW * amount) / 1000
totVolKw += volKw
}
if (item.pkgMaterialFlg === '1') {
const pkgPrice = amount * salePrice
//YJSS는 PKG제외상품들만 모아서 수량 * 단가를 공급가액에 추가로 더해줌
addPkgPrice += pkgPrice
}
// const price
totAmount += amount
supplyPrice += price
}
})
vatPrice = supplyPrice * 0.1
totPrice = supplyPrice + vatPrice
setEstimateContextState({
totAmount: totAmount,
totVolKw: totVolKw.toFixed(3),
supplyPrice: supplyPrice.toFixed(3),
vatPrice: vatPrice.toFixed(3),
totPrice: totPrice.toFixed(3),
})
}
setItemChangeYn(false)
}
}, [itemChangeYn, estimateContextState.itemList])
//안건명 인풋 변경
const handleBlurObjectName = (e) => {
setEstimateContextState({ objectName: e.target.value })
}
//담당자 인풋 변경
const handleBlurCharger = (e) => {
setEstimateContextState({ charger: e.target.value })
}
//비고 인풋 변경
const handleBlurRemarks = (e) => {
setEstimateContextState({ remarks: e.target.value })
}
return (
<div className="sub-content estimate">
<div className="sub-content-inner">
{/* 물건번호, 견적서번호, 등록일, 변경일시 시작 */}
<div className="sub-content-box">
<div className="sub-table-box">
<div className="estimate-list-wrap one">
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.objectNo')}</div>
<div className="estimate-name">
{objectNo} (Plan No: {planNo})
</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.docNo')}</div>
<div className="estimate-name">{estimateContextState.docNo}</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.drawingEstimateCreateDate')}</div>
<div className="estimate-name">
{estimateContextState?.drawingEstimateCreateDate
? `${dayjs(estimateContextState.drawingEstimateCreateDate).format('YYYY.MM.DD')}`
: ''}
</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.lastEditDatetime')}</div>
<div className="estimate-name">
{estimateContextState?.lastEditDatetime ? `${dayjs(estimateContextState.lastEditDatetime).format('YYYY.MM.DD HH:mm')}` : ''}
</div>
</div>
</div>
</div>
</div>
{/* 물건번호, 견적서번호, 등록일, 변경일시 끝 */}
{/* 기본정보 시작 */}
<div className="sub-content-box">
<div className="sub-table-box">
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3>{getMessage('estimate.detail.header.title')}</h3>
</div>
</div>
<div className="common-table bt-able">
<table>
<colgroup>
<col style={{ width: '160px' }} />
<col />
<col style={{ width: '160px' }} />
<col />
</colgroup>
<tbody>
<tr>
{/* 1차 판매점명 */}
<th>{getMessage('estimate.detail.saleStoreId')}</th>
<td>{estimateContextState?.firstSaleStoreName}</td>
{/* 견적일 */}
<th>
{getMessage('estimate.detail.estimateDate')} <span className="important">*</span>
</th>
<td>
<div className="date-picker" style={{ width: '350px' }}>
<SingleDatePicker {...singleDatePickerProps} />
</div>
</td>
</tr>
<tr>
{/* 2차 판매점명 */}
<th>{getMessage('estimate.detail.otherSaleStoreId')}</th>
<td>{estimateContextState?.agencySaleStoreName}</td>
{/* 담당자 */}
<th>
{getMessage('estimate.detail.receiveUser')} <span className="important">*</span>
</th>
<td>
<div className="input-wrap" style={{ width: '350px' }}>
<input type="text" className="input-light" defaultValue={estimateContextState?.charger} onBlur={handleBlurCharger} />
</div>
</td>
</tr>
<tr>
{/* 안건명 */}
<th>
{getMessage('estimate.detail.objectName')} <span className="important">*</span>
</th>
<td colSpan={3}>
<div className="form-flex-wrap">
<div className="input-wrap mr5" style={{ width: '610px' }}>
<input type="text" className="input-light" defaultValue={estimateContextState?.objectName} onBlur={handleBlurObjectName} />
</div>
<div className="select-wrap" style={{ width: '200px' }}>
<Select
id="objectNameOmit"
instanceId="objectNameOmit"
className="react-select-custom"
classNamePrefix="custom"
placeholder="Select"
options={honorificCodeList}
onChange={(e) => {
if (isObjectNotEmpty(e)) {
setEstimateContextState({ objectNameOmit: e.clCodeNm })
} else {
setEstimateContextState({ objectNameOmit: '' })
}
}}
getOptionLabel={(x) => x.clCodeNm}
getOptionValue={(x) => x.clCode}
isClearable={false}
isSearchable={false}
value={honorificCodeList.filter(function (option) {
return option.clCodeNm === estimateContextState.objectNameOmit
})}
/>
</div>
</div>
</td>
</tr>
<tr>
{/* 물건정보에서 입력한 메모 */}
<th>{getMessage('estimate.detail.objectRemarks')}</th>
<td colSpan={3}>{estimateContextState?.objectRemarks}</td>
</tr>
<tr>
{/* 주문분류 */}
<th>
{getMessage('estimate.detail.estimateType')} <span className="important">*</span>
</th>
<td colSpan={3}>
<div className="radio-wrap">
<div className="d-check-radio light mr10">
<input
type="radio"
name="estimateType"
id="YJSS"
value={'YJSS'}
checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
onChange={(e) => {
//주문분류
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>
</div>
<div className="d-check-radio light">
<input
type="radio"
name="estimateType"
id="YJOD"
value={'YJOD'}
checked={estimateContextState?.estimateType === 'YJOD' ? true : false}
onChange={(e) => {
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJOD">{getMessage('estimate.detail.estimateType.yjod')}</label>
</div>
</div>
</td>
</tr>
<tr>
{/* 지붕재・사양시공 최대4개*/}
<th>{getMessage('estimate.detail.roofCns')}</th>
<td colSpan={3}>
{estimateContextState?.roofMaterialIdMulti?.split('、').map((row, index) => {
//지붕재
let roofList = row
let roofListLength = estimateContextState?.roofMaterialIdMulti?.split('、').length
let style = 'mb5'
if (roofListLength == index + 1) {
style = ''
}
//사양시공
let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('、')
return (
<>
<div className={`form-flex-wrap ${style}`} key={fixedKey}>
<div className="input-wrap mr5" style={{ width: '610px' }} key={`roof${index}`}>
<input type="text" className="input-light" value={roofList} readOnly />
</div>
<div className="input-wrap" style={{ width: '200px' }}>
<input type="text" className="input-light" value={constructSpecificationMulti[index]} readOnly />
</div>
</div>
</>
)
})}
</td>
</tr>
<tr>
{/* 비고 */}
<th>{getMessage('estimate.detail.remarks')}</th>
<td colSpan={3}>
<div className="input-wrap">
<input type="text" className="input-light" defaultValue={estimateContextState?.remarks} onBlur={handleBlurRemarks} />
</div>
</td>
</tr>
</tbody>
</table>
</div>
{/* 파일첨부 시작 */}
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3>{getMessage('estimate.detail.header.fileList1')}</h3>
<div className="d-check-box light mr5">
<input
type="checkbox"
id="next"
checked={estimateContextState?.fileFlg === '0' ? false : true}
onChange={(e) => {
setEstimateContextState({
fileFlg: e.target.checked ? '1' : '0',
})
}}
/>
<label htmlFor="next" style={{ color: '#101010' }}>
{getMessage('estimate.detail.fileFlg')}
</label>
</div>
</div>
</div>
<div className="common-table mb10">
<table>
<colgroup>
<col style={{ width: '160px' }} />
<col />
</colgroup>
<tbody>
<tr>
<th>{getMessage('estimate.detail.header.fileList1')}</th>
<td>
<EstimateFileUploader {...fileUploadProps} />
</td>
</tr>
</tbody>
</table>
</div>
{/* 첨부파일 목록 시작 */}
<div className="common-table bt-able">
<table>
<colgroup>
<col style={{ width: '160px' }} />
<col />
</colgroup>
<tbody>
<tr>
<th>{getMessage('estimate.detail.header.fileList2')}</th>
<td>
<div className="drag-file-box">
<ul className="file-list">
{originFiles.length > 0 &&
originFiles.map((originFile) => {
return (
<li className="file-item" key={uuidv4()}>
<span onClick={() => handleEstimateFileDownload(originFile)}>
{originFile.faileName}
<button
type="button"
className="delete"
onClick={(e) => {
deleteOriginFile(originFile.objectNo, originFile.no)
e.stopPropagation()
}}
></button>
</span>
</li>
)
})}
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
{/* 첨부파일 목록 끝 */}
{/* 파일첨부 끝 */}
{/* 견적특이사항 시작 */}
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3 className="product">{getMessage('estimate.detail.header.specialEstimate')}</h3>
<div className="product_tit">{getMessage('estimate.detail.header.specialEstimateProductInfo')}</div>
</div>
<div className="left-unit-box">
<button className={`estimate-arr-btn down mr5 ${hidden ? '' : 'on'}`} onClick={() => setHidden(false)}></button>
<button className={`estimate-arr-btn up ${hidden ? 'on' : ''}`} onClick={() => setHidden(true)}></button>
</div>
</div>
{/* 견적 특이사항 코드영역시작 */}
<div className={`estimate-check-wrap ${hidden ? 'hide' : ''}`}>
<div className="estimate-check-inner">
<div className="special-note-check-wrap">
{/* SpecialNoteList반복문 */}
{specialNoteList.length > 0 &&
specialNoteList.map((row) => {
return (
<div
key={uuidv4()}
className="special-note-check-item"
onClick={(event) => {
settingShowContent(row.code, event)
}}
>
<div className="d-check-box light">
<input
type="checkbox"
id={row.code}
checked={!!row.text}
disabled={row.code === 'ATTR001' ? true : false}
onChange={(event) => {
setSpecialNoteList((specialNote) =>
specialNote.map((temp) => (temp.code === row.code ? { ...temp, text: !temp.text } : temp)),
)
settingShowContent(row.code, event)
}}
/>
<label htmlFor={row.code}>{row.codeNm}</label>
</div>
</div>
)
})}
</div>
{/* 견적특이사항 선택한 내용 영역시작 */}
<div className="calculation-estimate">
{specialNoteList.map((row) => {
if (row.code === showContentCode) {
return (
<dl key={uuidv4()}>
<dt>{row.codeNm}</dt>
<dd dangerouslySetInnerHTML={{ __html: row.remarks }}></dd>
</dl>
)
}
})}
</div>
{/* 견적특이사항 선택한 내용 영역끝 */}
</div>
</div>
{/* 견적 특이사항 코드영역 끝 */}
{/* 견적특이사항 영역끝 */}
{/* 제품정보 시작 */}
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3>{getMessage('estimate.detail.header.specialEstimateProductInfo')}</h3>
</div>
</div>
<div className="esimate-wrap">
<div className="estimate-list-wrap one">
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totAmount')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.totAmount)}</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.supplyPrice)}</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.vatPrice)}</div>
</div>
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}</div>
<div className="estimate-name red">{convertNumberToPriceDecimal(estimateContextState?.totPrice)}</div>
</div>
</div>
</div>
{/* YJOD면 아래영역 숨김 */}
<div className="common-table bt-able" style={{ display: estimateContextState?.estimateType === 'YJSS' ? '' : 'none' }}>
<table>
<colgroup>
<col style={{ width: '160px' }} />
<col />
<col style={{ width: '160px' }} />
<col />
<col style={{ width: '160px' }} />
<col />
</colgroup>
<tbody>
<tr>
<th>
{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice')}
<span className="important">*</span>
</th>
<td>
<div className="input-wrap">
<input
type="text"
className="input-light"
value={estimateContextState?.pkgAsp}
onChange={(e) => {
onChangePkgAsp(e.target.value)
}}
/>
</div>
</td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th>
<td>{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th>
<td>{convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)}</td>
</tr>
</tbody>
</table>
</div>
{/* 제품정보 끝 */}
{/* 가격표시영역시작 */}
<div className="estimate-product-option">
<div className="product-price-wrap">
<div className="product-price-tit">{getMessage('estimate.detail.header.showPrice')}</div>
<div className="select-wrap">
{session?.storeLvl === '1' ? (
<select
key={uuidv4()}
className="select-light"
onChange={(e) => {
onChangeStorePriceList(e.target.value)
}}
value={showPriceCd}
>
{storePriceList.length > 0 && storePriceList.map((row) => <option value={row.priceCd}>{row.priceNm}</option>)}
</select>
) : (
<select key={uuidv4()} className="select-light">
<option value="UNIT_PRICE">{getMessage('estimate.detail.header.unitPrice')}</option>
</select>
)}
</div>
<button
type="button"
className="btn-origin grey ml5"
onClick={() => {
handlePricing(showPriceCd)
}}
>
{getMessage('estimate.detail.showPrice.pricingBtn')}
</button>
</div>
<div className="product-edit-wrap">
<ul className="product-edit-explane">
<li className="explane-item item01">
<span className="ico"></span>
{getMessage('estimate.detail.showPrice.description1')}
</li>
<li className="explane-item item02">
<span className="ico"></span>
{getMessage('estimate.detail.showPrice.description2')}
</li>
<li className="explane-item item03">
<span className="ico"></span>
{getMessage('estimate.detail.showPrice.description3')}
</li>
<li className="explane-item item04">
<span className="ico"></span>
{getMessage('estimate.detail.showPrice.description4')}
</li>
</ul>
<div className="product-edit-btn">
{/* <button className="btn-origin navy mr5" type="button" onClick={addItem}> */}
<button
className="btn-origin navy mr5"
type="button"
onClick={() => {
addItem()
// setItemChangeYn(true)
}}
>
<span className="plus"></span>
{getMessage('estimate.detail.showPrice.addItem')}
</button>
<button className="btn-origin grey" type="button" onClick={removeItem}>
<span className="minus"></span>
{getMessage('estimate.detail.showPrice.delItem')}
</button>
</div>
</div>
</div>
{/* 가격표시영역끝 */}
{/* html테이블시작 */}
<div className="esimate-table">
<table>
<colgroup>
<col width={50} />
<col width={100} />
<col />
<col width={200} />
<col width={100} />
<col width={100} />
<col width={200} />
<col width={240} />
</colgroup>
<thead>
<tr>
<th>
<div className="d-check-box pop no-text" style={{ display: 'none' }}>
<input type="checkbox" id="ch97" />
<label htmlFor="ch97"></label>
</div>
</th>
<th>{getMessage('estimate.detail.itemTableHeader.dispOrder')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.itemId')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.itemNo')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.amount')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.unit')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.salePrice')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.saleTotPrice')}</th>
</tr>
</thead>
<tbody>
{estimateContextState?.itemList.length > 0 &&
estimateContextState.itemList.map((item, index) => {
if (item.delFlg === '0') {
return (
<tr key={item?.dispOrder || index}>
<td className="al-c">
<div className="d-check-box light no-text">
<input
type="checkbox"
id={item?.dispOrder}
disabled={!!item?.paDispOrder}
onChange={() => onChangeSelect(item.dispOrder)}
checked={!!selection.has(item.dispOrder)}
/>
<label htmlFor={item?.dispOrder}></label>
</div>
</td>
<td className="al-r">{item?.dispOrder}</td>
<td>
<div className="form-flex-wrap">
<div className="select-wrap mr5">
<Select
id="long-value-select1"
instanceId="long-value-select1"
className="react-select-custom"
classNamePrefix="custom"
placeholder="Select"
options={displayItemList}
onChange={(e) => {
if (isObjectNotEmpty(e)) {
onChangeDisplayItem(e.itemId, item.dispOrder, index)
}
}}
getOptionLabel={(x) => x.itemName}
getOptionValue={(x) => x.itemId}
isClearable={false}
isDisabled={!!item?.paDispOrder}
value={displayItemList.filter(function (option) {
return option.itemId === item.itemId
})}
/>
</div>
{item?.itemChangeFlg === '1' && (
<div className="btn-area">
<span className="tb_ico change_check"></span>
</div>
)}
</div>
</td>
<td>
<div className="form-flex-wrap">
<div className="name">{item?.itemNo}</div>
<div className="icon-wrap">
{item?.fileUploadFlg === '1' && <span className="tb_ico file_check"></span>}
{item?.specialNoteCd && (
<button
type="button"
className="grid-tip"
onClick={() => {
setProductFeaturesPopupOpen(true)
setShowProductFeatureData(item?.specialNoteCd)
}}
></button>
)}
</div>
</div>
</td>
<td>
<div className="input-wrap" style={{ width: '100%' }}>
<input
type="text"
className="input-light al-r"
// value={item?.amount}
value={convertNumberToPriceDecimal(item?.amount.replaceAll(',', ''))}
disabled={item.itemId === '' || !!item?.paDispOrder}
onChange={(e) => {
onChangeAmount(e.target.value, item.dispOrder, index)
}}
/>
</div>
</td>
<td>{item.unit}</td>
<td>
<div className="form-flex-wrap">
<div className="input-wrap mr5">
<input
type="text"
className="input-light al-r"
value={convertNumberToPriceDecimal(item?.salePrice.replaceAll(',', ''))}
disabled={
estimateContextState?.estimateType === 'YJSS'
? item?.paDispOrder
? true
: item.pkgMaterialFlg !== '1'
: item.itemId === '' || !!item?.paDispOrder
}
onChange={(e) => {
onChangeSalePrice(e.target.value, item.dispOrder, index)
}}
/>
</div>
{/* <div className="btn-area">
<span className="tb_ico open_check">OPEN아이콘 처리</span>
</div> */}
</div>
</td>
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice.replaceAll(',', ''))}</td>
</tr>
)
} else {
return null
}
})}
</tbody>
</table>
</div>
{/* html테이블끝 */}
</div>
</div>
{/* 기본정보끝 */}
</div>
{productFeaturesPopupOpen && (
<ProductFeaturesPop
specialNoteList={specialNoteList}
showProductFeatureData={showProductFeatureData}
setProductFeaturesPopupOpen={setProductFeaturesPopupOpen}
/>
)}
</div>
)
}