견적서 상세

This commit is contained in:
basssy 2024-11-25 17:10:57 +09:00
parent 7bc2d9acd6
commit 0aaa54de73
2 changed files with 128 additions and 51 deletions

View File

@ -15,7 +15,7 @@ import { useCommonCode } from '@/hooks/common/useCommonCode'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
import { SessionContext } from '@/app/SessionProvider' import { SessionContext } from '@/app/SessionProvider'
import Select, { components } from 'react-select' import Select, { components } from 'react-select'
import { convertNumberToPriceDecimal } from '@/util/common-utils' import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop' import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
@ -129,17 +129,21 @@ export default function Estimate({ params }) {
}) })
}, [estimateContextState?.estimateOption]) }, [estimateContextState?.estimateOption])
//API
let begin = 1
useEffect(() => {
if (begin === 1) {
setStartDate(estimateContextState?.estimateDate)
begin++
}
}, [estimateContextState?.estimateDate])
// set // set
useEffect(() => { useEffect(() => {
let estimateDate = dayjs(startDate).format('YYYY-MM-DD') let estimateDate = dayjs(startDate).format('YYYY-MM-DD')
setEstimateContextState({ estimateDate: estimateDate }) setEstimateContextState({ estimateDate: estimateDate })
}, [startDate]) }, [startDate])
//API
useEffect(() => {
setStartDate(estimateContextState?.estimateDate)
}, [estimateContextState?.estimateDate])
useEffect(() => { useEffect(() => {
// setEstimateContextState // setEstimateContextState
if (isNotEmptyArray(specialNoteList)) { if (isNotEmptyArray(specialNoteList)) {
@ -296,9 +300,8 @@ export default function Estimate({ params }) {
//itemList itemId unitPrice 0 //itemList itemId unitPrice 0
//itemId salePrice //itemId salePrice
if (data.result.code === 200) { if (data.result.code === 200) {
console.log('data::확인해서 넣기:::::::::', data.data.pkgUnitPrice)
setEstimateContextState({ setEstimateContextState({
pkgAsp: data.data.pkgUnitPrice, pkgAsp: data?.data?.pkgUnitPrice,
}) })
//PKG //PKG
onChangePkgAsp(data.data.pkgUnitPrice) onChangePkgAsp(data.data.pkgUnitPrice)
@ -333,6 +336,24 @@ export default function Estimate({ params }) {
}) })
} }
const getAbledItems = (items) => {
return items.filter((items) => items.paDispOrder === null)
}
const onChangeSelectAll = (e) => {
if (e.target.checked) {
const allCheckedSelection = new Set(getAbledItems(estimateContextState.itemList).map((item) => item.dispOrder))
setSelection(allCheckedSelection)
} else {
setSelection(new Set())
}
}
const isSelectedAll = () => {
return selection.size === getAbledItems(estimateContextState.itemList).length
}
//row //row
const onChangeSelect = (dispOrder) => { const onChangeSelect = (dispOrder) => {
const newSelection = new Set(selection) const newSelection = new Set(selection)
@ -358,13 +379,12 @@ export default function Estimate({ params }) {
let totVolKw = estimateContextState.totVolKw * 1000 let totVolKw = estimateContextState.totVolKw * 1000
let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw
setEstimateContextState({ setEstimateContextState({
pkgAsp: pkgAsp, pkgAsp: pkgAsp,
pkgTotPrice: pkgTotPrice.toFixed(3), pkgTotPrice: pkgTotPrice.toFixed(3),
}) })
// //
// setItemChangeYn(true) setItemChangeYn(true)
} }
} }
@ -392,7 +412,6 @@ export default function Estimate({ params }) {
return item return item
} }
}) })
setEstimateContextState({ setEstimateContextState({
itemList: updateList, itemList: updateList,
}) })
@ -429,7 +448,7 @@ export default function Estimate({ params }) {
setItemChangeYn(true) setItemChangeYn(true)
} }
// // /
const onChangeDisplayItem = (itemId, dispOrder, index) => { const onChangeDisplayItem = (itemId, dispOrder, index) => {
const param = { const param = {
itemId: itemId, itemId: itemId,
@ -438,7 +457,7 @@ export default function Estimate({ params }) {
let updateList = [] let updateList = []
let updates = {} let updates = {}
get({ url: apiUrl }).then((res) => { get({ url: apiUrl }).then((res) => {
// console.log(':::::::', res) console.log('아이템디테일::::::::', res)
updates.objectNo = objectNo updates.objectNo = objectNo
updates.planNo = planNo updates.planNo = planNo
updates.itemId = res.itemId updates.itemId = res.itemId
@ -460,6 +479,12 @@ export default function Estimate({ params }) {
updates.delFlg = '0' // 0 updates.delFlg = '0' // 0
updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString()
if (estimateContextState.estimateType === 'YJSS') {
if (res.pkgMaterialFlg === '0') {
updates.showSalePrice = '0'
updates.showSaleTotPrice = '0'
}
}
//104671 //104671
let bomList = res.itemBomList let bomList = res.itemBomList
@ -467,7 +492,8 @@ export default function Estimate({ params }) {
if (item.dispOrder === dispOrder) { if (item.dispOrder === dispOrder) {
return { ...item, ...updates } return { ...item, ...updates }
} else if (item.paDispOrder === dispOrder) { } else if (item.paDispOrder === dispOrder) {
return { ...item, delFlg: '1' } return { ...item, delFlg: '0' }
// return { ...item, delFlg: '1' }
} else { } else {
return item return item
} }
@ -476,7 +502,14 @@ export default function Estimate({ params }) {
if (bomList) { if (bomList) {
bomList.map((bomItem, index) => { bomList.map((bomItem, index) => {
let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder)) let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder))
bomItem.dispOrder = index + 1 + newItemDispOrder if (newItemDispOrder == dispOrder) {
bomItem.dispOrder = (index + 1 + newItemDispOrder).toString()
bomItem.paDispOrder = dispOrder
} else {
bomItem.dispOrder = (index + 1 + Number(dispOrder)).toString()
bomItem.paDispOrder = dispOrder
}
bomItem.delFlg = '0' bomItem.delFlg = '0'
bomItem.objectNo = objectNo bomItem.objectNo = objectNo
bomItem.planNo = planNo bomItem.planNo = planNo
@ -539,20 +572,26 @@ export default function Estimate({ params }) {
useEffect(() => { useEffect(() => {
if (itemChangeYn) { if (itemChangeYn) {
console.log(' 토탈만들어주기::::::::::', estimateContextState.itemList)
let totAmount = 0 let totAmount = 0
let totVolKw = 0 let totVolKw = 0
let supplyPrice = 0 let supplyPrice = 0
let vatPrice = 0 let vatPrice = 0
let totPrice = 0 let totPrice = 0
let addPkgPrice = 0 let addSupplyPrice = 0
if (estimateContextState.estimateType === 'YJOD') { if (estimateContextState.estimateType === 'YJOD') {
estimateContextState.itemList.map((item) => { console.log('YJOD 토탈만들어주기::::::::::', estimateContextState.itemList)
if (item.delFlg === '0') {
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', ''))
const price = Number(item.saleTotPrice.replaceAll(',', '')) estimateContextState.itemList.sort((a, b) => {
return a.dispOrder - b.dispOrder
})
estimateContextState.itemList.map((item) => {
delete item.showSalePrice
delete item.showSaleTotPrice
if (item.delFlg === '0') {
const amount = Number(item?.amount?.replace(/[^0-9]/g, '').replaceAll(',', ''))
const price = Number(item?.saleTotPrice?.replaceAll(',', ''))
if (item.moduleFlg === '1') { if (item.moduleFlg === '1') {
//(Kw) 1 //(Kw) 1
@ -567,7 +606,6 @@ export default function Estimate({ params }) {
vatPrice = supplyPrice * 0.1 vatPrice = supplyPrice * 0.1
totPrice = supplyPrice + vatPrice totPrice = supplyPrice + vatPrice
setEstimateContextState({ setEstimateContextState({
totAmount: totAmount, totAmount: totAmount,
totVolKw: totVolKw.toFixed(3), totVolKw: totVolKw.toFixed(3),
@ -577,11 +615,15 @@ export default function Estimate({ params }) {
}) })
} else { } else {
//YJSS //YJSS
console.log('YJSS 토탈만들어주기::::::::::', estimateContextState.itemList)
estimateContextState.itemList.sort((a, b) => {
return a.dispOrder - b.dispOrder
})
estimateContextState.itemList.map((item) => { estimateContextState.itemList.map((item) => {
if (item.delFlg === '0') { if (item.delFlg === '0') {
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', '')) const amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', ''))
const price = Number(item.saleTotPrice.replaceAll(',', '')) const price = Number(item.saleTotPrice?.replaceAll(',', ''))
const salePrice = Number(item.salePrice.replaceAll(',', '')) const salePrice = Number(item.salePrice?.replaceAll(',', ''))
if (item.moduleFlg === '1') { if (item.moduleFlg === '1') {
//(Kw) 1 //(Kw) 1
@ -590,19 +632,27 @@ export default function Estimate({ params }) {
} }
if (item.pkgMaterialFlg === '1') { if (item.pkgMaterialFlg === '1') {
const pkgPrice = amount * salePrice const pkgPrice = amount * salePrice
//YJSS PKG * //YJSS PKG(1) * (supplyPrice)
addPkgPrice += pkgPrice addSupplyPrice += pkgPrice
supplyPrice += price
} }
// const price // const price
totAmount += amount totAmount += amount
supplyPrice += price
if (!item.paDispOrder) {
//paDispOrder
if (item.pkgMaterialFlg === '0') {
item.showSalePrice = '0'
item.showSaleTotPrice = '0'
}
}
} }
}) })
supplyPrice += addSupplyPrice
vatPrice = supplyPrice * 0.1 vatPrice = supplyPrice * 0.1
totPrice = supplyPrice + vatPrice totPrice = supplyPrice + vatPrice
setEstimateContextState({ setEstimateContextState({
totAmount: totAmount, totAmount: totAmount,
totVolKw: totVolKw.toFixed(3), totVolKw: totVolKw.toFixed(3),
@ -845,6 +895,23 @@ export default function Estimate({ params }) {
setEstimateContextState({ setEstimateContextState({
fileFlg: e.target.checked ? '1' : '0', fileFlg: e.target.checked ? '1' : '0',
}) })
if (e.target.checked) {
if (specialNoteList.length > 0) {
specialNoteList.map((item) => {
if (item.code === 'ATTR019') {
item.check = true
}
})
}
} else {
if (specialNoteList.length > 0) {
specialNoteList.map((item) => {
if (item.code === 'ATTR019') {
item.check = false
}
})
}
}
}} }}
/> />
<label htmlFor="next" style={{ color: '#101010' }}> <label htmlFor="next" style={{ color: '#101010' }}>
@ -927,7 +994,6 @@ export default function Estimate({ params }) {
{/* SpecialNoteList반복문 */} {/* SpecialNoteList반복문 */}
{specialNoteList.length > 0 && {specialNoteList.length > 0 &&
specialNoteList.map((row) => { specialNoteList.map((row) => {
// console.log('rowL::::', row)
return ( return (
<div <div
key={uuidv4()} key={uuidv4()}
@ -941,7 +1007,7 @@ export default function Estimate({ params }) {
type="checkbox" type="checkbox"
id={row.code} id={row.code}
checked={!!row.check} checked={!!row.check}
disabled={row.code === 'ATTR001' || row.code === 'ATTR002' ? true : false} disabled={row.code === 'ATTR001' ? true : false}
onChange={(event) => { onChange={(event) => {
setSpecialNoteList((specialNote) => setSpecialNoteList((specialNote) =>
specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)),
@ -990,19 +1056,19 @@ export default function Estimate({ params }) {
</div> </div>
<div className="estimate-box"> <div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div> <div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</div> <div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}</div>
</div> </div>
<div className="estimate-box"> <div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div> <div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.supplyPrice)}</div> <div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.supplyPrice, 2)}</div>
</div> </div>
<div className="estimate-box"> <div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div> <div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div>
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.vatPrice)}</div> <div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.vatPrice, 2)}</div>
</div> </div>
<div className="estimate-box"> <div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}</div> <div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}</div>
<div className="estimate-name red">{convertNumberToPriceDecimal(estimateContextState?.totPrice)}</div> <div className="estimate-name red">{convertNumberToPriceDecimalToFixed(estimateContextState?.totPrice, 2)}</div>
</div> </div>
</div> </div>
</div> </div>
@ -1036,9 +1102,9 @@ export default function Estimate({ params }) {
</div> </div>
</td> </td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th> <th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th>
<td>{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</td> <td>{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}</td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th> <th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th>
<td>{convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)}</td> <td>{convertNumberToPriceDecimalToFixed(estimateContextState?.pkgTotPrice, 2)}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -1096,13 +1162,11 @@ export default function Estimate({ params }) {
</li> </li>
</ul> </ul>
<div className="product-edit-btn"> <div className="product-edit-btn">
{/* <button className="btn-origin navy mr5" type="button" onClick={addItem}> */}
<button <button
className="btn-origin navy mr5" className="btn-origin navy mr5"
type="button" type="button"
onClick={() => { onClick={() => {
addItem() addItem()
// setItemChangeYn(true)
}} }}
> >
<span className="plus"></span> <span className="plus"></span>
@ -1121,19 +1185,20 @@ export default function Estimate({ params }) {
<table> <table>
<colgroup> <colgroup>
<col width={50} /> <col width={50} />
<col width={100} /> <col width={50} />
<col /> <col />
<col width={250} /> <col width={250} />
<col width={100} /> <col width={90} />
<col width={100} /> <col width={80} />
<col width={200} /> <col width={140} />
<col width={240} /> <col width={190} />
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th> <th>
<div className="d-check-box pop no-text" style={{ display: 'none' }}> {/* <div className="d-check-box pop no-text" style={{ display: 'none' }}> */}
<input type="checkbox" id="ch97" /> <div className="d-check-box pop no-text">
<input type="checkbox" id="ch97" checked={isSelectedAll()} onChange={onChangeSelectAll} />
<label htmlFor="ch97"></label> <label htmlFor="ch97"></label>
</div> </div>
</th> </th>
@ -1219,12 +1284,12 @@ export default function Estimate({ params }) {
<input <input
type="text" type="text"
className="input-light al-r" className="input-light al-r"
// value={item?.amount} value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}
value={convertNumberToPriceDecimal(item?.amount.replaceAll(',', ''))}
disabled={item.itemId === '' || !!item?.paDispOrder} disabled={item.itemId === '' || !!item?.paDispOrder}
onChange={(e) => { onChange={(e) => {
onChangeAmount(e.target.value, item.dispOrder, index) onChangeAmount(e.target.value, item.dispOrder, index)
}} }}
maxLength={6}
/> />
</div> </div>
</td> </td>
@ -1235,7 +1300,7 @@ export default function Estimate({ params }) {
<input <input
type="text" type="text"
className="input-light al-r" className="input-light al-r"
value={convertNumberToPriceDecimal(item?.salePrice.replaceAll(',', ''))} value={convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))}
disabled={ disabled={
estimateContextState?.estimateType === 'YJSS' estimateContextState?.estimateType === 'YJSS'
? item?.paDispOrder ? item?.paDispOrder
@ -1246,6 +1311,7 @@ export default function Estimate({ params }) {
onChange={(e) => { onChange={(e) => {
onChangeSalePrice(e.target.value, item.dispOrder, index) onChangeSalePrice(e.target.value, item.dispOrder, index)
}} }}
maxLength={12}
/> />
</div> </div>
{/* <div className="btn-area"> {/* <div className="btn-area">
@ -1253,7 +1319,11 @@ export default function Estimate({ params }) {
</div> */} </div> */}
</div> </div>
</td> </td>
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice.replaceAll(',', ''))}</td> {item?.showSaleTotPrice === '0' ? (
<td className="al-r"></td>
) : (
<td className="al-r">{convertNumberToPriceDecimalToFixed(item?.saleTotPrice?.replaceAll(',', ''), 2)}</td>
)}
</tr> </tr>
) )
} else { } else {

View File

@ -67,6 +67,13 @@ export const convertNumberToPriceDecimal = (value) => {
else return '' else return ''
} }
// 43000.458 --> 43,000.46
export const convertNumberToPriceDecimalToFixed = (value, fixed) => {
if (value) return Number(value).toLocaleString(undefined, { minimumFractionDigits: fixed, maximumFractionDigits: fixed })
else if (value === 0) return 0
else return ''
}
// 전화번호, FAX 번호 숫자 or '-'만 입력 체크 // 전화번호, FAX 번호 숫자 or '-'만 입력 체크
export const inputTelNumberCheck = (e) => { export const inputTelNumberCheck = (e) => {
const input = e.target const input = e.target