견적서 상세

This commit is contained in:
basssy 2024-11-15 17:36:50 +09:00
parent 18e3ebe7f5
commit 889ced564d
4 changed files with 243 additions and 148 deletions

View File

@ -28,6 +28,8 @@ export default function Estimate({ params }) {
const [files, setFiles] = useState([]) // const [files, setFiles] = useState([]) //
const [originFiles, setOriginFiles] = useState([]) // const [originFiles, setOriginFiles] = useState([]) //
const [showPriceCd, setShowPriceCd] = useState('')
const [showContentCode, setShowContentCode] = useState('ATTR001') const [showContentCode, setShowContentCode] = useState('ATTR001')
const [productFeaturesPopupOpen, setProductFeaturesPopupOpen] = useState(false) // const [productFeaturesPopupOpen, setProductFeaturesPopupOpen] = useState(false) //
@ -46,8 +48,6 @@ export default function Estimate({ params }) {
const [storePriceList, setStorePriceList] = useState([]) // option const [storePriceList, setStorePriceList] = useState([]) // option
const [tempPriceCd, setTempPriceCd] = useState('')
const [startDate, setStartDate] = useState(new Date()) const [startDate, setStartDate] = useState(new Date())
const singleDatePickerProps = { const singleDatePickerProps = {
startDate, startDate,
@ -182,7 +182,7 @@ export default function Estimate({ params }) {
}) })
} }
// option // option &&
useEffect(() => { useEffect(() => {
if (state.estimateType !== '') { if (state.estimateType !== '') {
const param = { const param = {
@ -200,15 +200,28 @@ export default function Estimate({ params }) {
} }
}, [state?.estimateType]) }, [state?.estimateType])
// option
useEffect(() => { useEffect(() => {
if (tempPriceCd !== '') { if (state?.priceCd) {
setShowPriceCd(state.priceCd)
}
}, [state?.priceCd])
// option
const onChangeStorePriceList = (priceCd) => {
const param = { const param = {
saleStoreId: session.storeId, saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd, sapSalesStoreCd: session.custCd,
docTpCd: tempPriceCd, docTpCd: priceCd,
} }
// tempPriceCd ?
// priceCd setState
// showPriceCd
setShowPriceCd(priceCd)
//setState({
// tempPriceCd: priceCd,
//})
const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}` const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => { get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) { if (isNotEmptyArray(res?.data)) {
@ -216,7 +229,6 @@ export default function Estimate({ params }) {
} }
}) })
} }
}, [tempPriceCd])
//Pricing //Pricing
const handlePricing = async (priceCd) => { const handlePricing = async (priceCd) => {
@ -224,24 +236,55 @@ export default function Estimate({ params }) {
saleStoreId: session.storeId, saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd, sapSalesStoreCd: session.custCd,
docTpCd: state.estimateType, docTpCd: state.estimateType,
priceCd: session.storeLvl === '1' ? tempPriceCd : priceCd, priceCd: priceCd,
itemIdList: state.itemList, // //itemIdList: state.itemList, // delFlg 0..
itemIdList: state.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'))
}
} }
// console.log('::', param)
await promisePost({ url: '/api/estimate/price/item-price-list', data: param }).then((res) => { await promisePost({ url: '/api/estimate/price/item-price-list', data: param }).then((res) => {
let updateList = []
if (res) { if (res) {
if (res.status === 200) { if (res.status === 200) {
const data = res.data const data = res.data
if (data.result.code === 200) {
if (isNotEmptyArray(data.data2)) {
// ............
//..
//itemList itemId unitPrice 0 //itemList itemId unitPrice 0
//itemId //itemId
setState({ if (data.result.code === 200) {
priceCd: session.storeLvl === '1' ? tempPriceCd : priceCd, if (isNotEmptyArray(data.data2)) {
state.itemList.map((item) => {
let checkYn = false
data.data2.map((item2) => {
if (item2.itemId === item.itemId) {
updateList.push({ ...item, unitPrice: item2.unitPrice })
checkYn = true
}
}) })
if (!checkYn) {
updateList.push({ ...item, unitPrice: '0' })
}
})
setState({
priceCd: priceCd,
itemList: updateList,
})
setItemChangeYn(true)
} }
} }
} }
@ -319,13 +362,24 @@ export default function Estimate({ params }) {
}) })
const updateList = state.itemList.map((item) => { const updateList = state.itemList.map((item) => {
const isDeleted = delList.some((row) => item.dispOrder === row.dispOrder) const isDeleted = delList.some((row) => item.delFlg === '1' || item.dispOrder === row.dispOrder)
return { return {
...item, ...item,
delFlg: isDeleted ? '1' : '0', 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'))
}
setState({ setState({
itemList: updateList, itemList: updateList,
}) })
@ -336,7 +390,7 @@ export default function Estimate({ params }) {
useEffect(() => { useEffect(() => {
if (itemChangeYn) { if (itemChangeYn) {
console.log('아이템에 뭔가 변화가 일어났어', itemChangeYn) // console.log(' ', itemChangeYn)
console.log('아이템상태가져오기::::::::::', state.itemList) console.log('아이템상태가져오기::::::::::', state.itemList)
} }
@ -778,8 +832,9 @@ export default function Estimate({ params }) {
key={uuidv4()} key={uuidv4()}
className="select-light" className="select-light"
onChange={(e) => { onChange={(e) => {
setTempPriceCd(e.target.value) onChangeStorePriceList(e.target.value)
}} }}
value={showPriceCd}
> >
{storePriceList.length > 0 && storePriceList.map((row) => <option value={row.priceCd}>{row.priceNm}</option>)} {storePriceList.length > 0 && storePriceList.map((row) => <option value={row.priceCd}>{row.priceNm}</option>)}
</select> </select>
@ -790,9 +845,10 @@ export default function Estimate({ params }) {
)} )}
</div> </div>
<button <button
type="button"
className="btn-origin grey ml5" className="btn-origin grey ml5"
onClick={() => { onClick={() => {
handlePricing(state.priceCd) handlePricing(state?.priceCd)
}} }}
> >
{getMessage('estimate.detail.showPrice.pricingBtn')} {getMessage('estimate.detail.showPrice.pricingBtn')}
@ -818,7 +874,15 @@ 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 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> <span className="plus"></span>
{getMessage('estimate.detail.showPrice.addItem')} {getMessage('estimate.detail.showPrice.addItem')}
</button> </button>
@ -862,8 +926,10 @@ export default function Estimate({ params }) {
</thead> </thead>
<tbody> <tbody>
{state?.itemList.length > 0 && {state?.itemList.length > 0 &&
state.itemList.map((item, index) => { state.itemList.map((item) => {
if (item.delFlg === '0') {
return ( return (
<>
<tr key={uuidv4()}> <tr key={uuidv4()}>
<td className="al-c"> <td className="al-c">
<div className="d-check-box light no-text"> <div className="d-check-box light no-text">
@ -876,7 +942,7 @@ export default function Estimate({ params }) {
<label htmlFor={item?.dispOrder}></label> <label htmlFor={item?.dispOrder}></label>
</div> </div>
</td> </td>
<td className="al-r">{item?.dispOrder * 100}</td> <td className="al-r">{item?.dispOrder}</td>
<td> <td>
<div className="form-flex-wrap"> <div className="form-flex-wrap">
<div className="select-wrap mr5"> <div className="select-wrap mr5">
@ -901,7 +967,6 @@ export default function Estimate({ params }) {
})} })}
/> />
</div> </div>
{/* {item?.partAdd === '1' && ( */}
{item?.itemChangeFlg === '1' && ( {item?.itemChangeFlg === '1' && (
<div className="btn-area"> <div className="btn-area">
<span className="tb_ico change_check"></span> <span className="tb_ico change_check"></span>
@ -949,6 +1014,7 @@ export default function Estimate({ params }) {
type="text" type="text"
className="input-light al-r" className="input-light al-r"
value={convertNumberToPriceDecimal(item?.salePrice)} value={convertNumberToPriceDecimal(item?.salePrice)}
disabled={state?.estimateType === 'YJSS' ? (item.pkgMaterialFlg === '1' ? false : true) : false}
onChange={(e) => { onChange={(e) => {
//onChangeDisplayItem //onChangeDisplayItem
//itemChangeFlg, partAdd //itemChangeFlg, partAdd
@ -963,7 +1029,11 @@ export default function Estimate({ params }) {
</td> </td>
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice)}</td> <td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice)}</td>
</tr> </tr>
</>
) )
} else {
return null
}
})} })}
</tbody> </tbody>
</table> </table>

View File

@ -59,6 +59,12 @@ export const useEstimateController = (planNo) => {
try { try {
await get({ url: `/api/estimate/${objectRecoil.floorPlanObjectNo}/${planNo}/detail` }).then((res) => { await get({ url: `/api/estimate/${objectRecoil.floorPlanObjectNo}/${planNo}/detail` }).then((res) => {
if (isObjectNotEmpty(res)) { if (isObjectNotEmpty(res)) {
if (res.itemList.length > 0) {
res.itemList.map((item) => {
item.delFlg = '0'
})
}
setState(res) setState(res)
} }
}) })
@ -133,27 +139,26 @@ export const useEstimateController = (planNo) => {
const handleEstimateSubmit = async () => { const handleEstimateSubmit = async () => {
//0. 필수체크 //0. 필수체크
let flag = true let flag = true
console.log('::담긴 estimateData:::', estimateData)
// console.log('첨부파일:::::', estimateData.fileList) // console.log('첨부파일:::::', estimateData.fileList)
//첨부파일을 첨부안했는데 //첨부파일을 첨부안했는데
//아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼
if (estimateData.fileList.length < 1) { // if (estimateData.fileList.length < 1) {
if (estimateData.itemList.length > 1) { // if (estimateData.itemList.length > 1) {
estimateData.itemList.map((row) => { // estimateData.itemList.map((row) => {
if (row.fileUploadFlg === '1') { // if (row.fileUploadFlg === '1') {
if (estimateData.fileFlg === '0') { // if (estimateData.fileFlg === '0') {
alert(getMessage('estimate.detail.save.requiredMsg')) // alert(getMessage('estimate.detail.save.requiredMsg'))
flag = false // flag = false
} // }
} // }
}) // })
} // }
} // }
if (flag) { if (flag) {
//1. 첨부파일 저장 //1. 첨부파일 저장시작
const formData = new FormData() const formData = new FormData()
console.log('첨부파일:!!!', estimateData.fileList)
formData.append('file', estimateData.fileList) formData.append('file', estimateData.fileList)
formData.append('objectNo', estimateData.objectNo) formData.append('objectNo', estimateData.objectNo)
formData.append('planNo', estimateData.planNo) formData.append('planNo', estimateData.planNo)
@ -161,7 +166,23 @@ export const useEstimateController = (planNo) => {
formData.append('userId', estimateData.userId) formData.append('userId', estimateData.userId)
await post({ url: '/api/file/fileUpload', data: formData }) 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)
console.log('최종 남은 아이템정보:::', estimateData.itemList)
//2. 상세데이터 저장 //2. 상세데이터 저장
return return
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {

View File

@ -844,6 +844,7 @@
"estimate.detail.header.showPrice": "価格表示", "estimate.detail.header.showPrice": "価格表示",
"estimate.detail.header.unitPrice": "定価", "estimate.detail.header.unitPrice": "定価",
"estimate.detail.showPrice.pricingBtn": "Pricing", "estimate.detail.showPrice.pricingBtn": "Pricing",
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください.",
"estimate.detail.showPrice.description1": "製品価格 OPEN", "estimate.detail.showPrice.description1": "製品価格 OPEN",
"estimate.detail.showPrice.description2": "追加, 変更資材", "estimate.detail.showPrice.description2": "追加, 変更資材",
"estimate.detail.showPrice.description3": "添付必須", "estimate.detail.showPrice.description3": "添付必須",
@ -879,6 +880,7 @@
"estimate.detail.productFeaturesPopup.close": "閉じる", "estimate.detail.productFeaturesPopup.close": "閉じる",
"estimate.detail.save.alertMsg": "保存されている見積書で製品を変更した場合、図面や回路には反映されません.", "estimate.detail.save.alertMsg": "保存されている見積書で製品を変更した場合、図面や回路には反映されません.",
"estimate.detail.save.requiredMsg": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください.", "estimate.detail.save.requiredMsg": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください.",
"estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります.",
"estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?", "estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?",
"simulator.title.sub1": "物件番号", "simulator.title.sub1": "物件番号",
"simulator.title.sub2": "作成日", "simulator.title.sub2": "作成日",

View File

@ -849,11 +849,12 @@
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)", "estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)", "estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액", "estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
"estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(모듈량 * 수량)÷100", "estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(모듈량 * 수량)÷100",
"estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG단가(W) * PKG용량(W)", "estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG단가(W) * PKG용량(W)",
"estimate.detail.header.showPrice": "가격표시", "estimate.detail.header.showPrice": "가격표시",
"estimate.detail.header.unitPrice": "정가", "estimate.detail.header.unitPrice": "정가",
"estimate.detail.showPrice.pricingBtn": "Pricing", "estimate.detail.showPrice.pricingBtn": "Pricing",
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.",
"estimate.detail.showPrice.description1": "제품 가격 OPEN", "estimate.detail.showPrice.description1": "제품 가격 OPEN",
"estimate.detail.showPrice.description2": "추가, 변경 자재", "estimate.detail.showPrice.description2": "추가, 변경 자재",
"estimate.detail.showPrice.description3": "첨부필수", "estimate.detail.showPrice.description3": "첨부필수",
@ -889,6 +890,7 @@
"estimate.detail.productFeaturesPopup.close": "닫기", "estimate.detail.productFeaturesPopup.close": "닫기",
"estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우, 도면 및 회로에 반영되지 않습니다.", "estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우, 도면 및 회로에 반영되지 않습니다.",
"estimate.detail.save.requiredMsg": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.", "estimate.detail.save.requiredMsg": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.",
"estimate.detail.save.requiredItem": "제품은 1개이상 등록해야 됩니다.",
"estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?", "estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?",
"simulator.title.sub1": "물건번호", "simulator.title.sub1": "물건번호",
"simulator.title.sub2": "작성일", "simulator.title.sub2": "작성일",