diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 709c3448..88e2fa1d 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -20,6 +20,7 @@ import ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' export default function Estimate({ params }) { + const [handlePricingFlag, setHandlePricingFlag] = useState(false) const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false) const fixedKey = 'itemKey' const [itemChangeYn, setItemChangeYn] = useState(false) @@ -63,6 +64,7 @@ export default function Estimate({ params }) { //견적특이사항 List const [specialNoteList, setSpecialNoteList] = useState([]) + const [popShowSpecialNoteList, setPopShowSpecialNoteList] = useState([]) const globalLocaleState = useRecoilValue(globalLocaleStore) const { get, promisePost } = useAxios(globalLocaleState) @@ -98,22 +100,40 @@ export default function Estimate({ params }) { setDisplayItemList(res) } }) + //견적특이사항 API호출 + //여러개 선택하면 구분자로 (、) + //제품영역 팝업용 + let url = '/api/estimate/special-note-list' + get({ url: url }).then((res) => { + if (isNotEmptyArray(res)) { + setPopShowSpecialNoteList(res) + } + }) }, []) useEffect(() => { //견적특이사항 API호출 //여러개 선택하면 구분자로 (、) + //체크용 if (!specialNoteFirstFlg) { - let url = `/api/estimate/special-note-list` + let url = `/api/estimate/special-note-title-list` get({ url: url }).then((res) => { if (isNotEmptyArray(res)) { + //디테일 ATTR001、ATTR002、ATTR003、ATTR007、ATTR009、ATTR010、ATTR015、ATTR019 if (estimateContextState?.estimateOption) { res.map((row) => { let estimateOption = estimateContextState?.estimateOption?.split('、') row.check = false estimateOption.map((row2) => { - if (row2 === row.code) { - row.check = true + if (row.pkgYn === '0') { + if (row2 === row.code) { + row.check = true + } + } else { + if (row.code.includes(row2)) { + row.check = true + return + } } }) //detail과 상관없이 디폴트 체크목록 @@ -135,48 +155,6 @@ export default function Estimate({ params }) { } }, [estimateContextState?.estimateOption]) - //변경버전 - // useEffect(() => { - // //견적특이사항 API호출 - // //여러개 선택하면 구분자로 (、) - // let url = `/api/estimate/special-note-title-list` - // // let url = `/api/estimate/special-note-list` - // get({ url: url }).then((res) => { - // if (isNotEmptyArray(res)) { - // if (estimateContextState?.estimateOption) { - // res.map((row) => { - // // console.log('API결과:::', row) - // //ATTR001、ATTR002、ATTR009、ATTR010 - // let estimateOption = estimateContextState?.estimateOption?.split('、') - // row.check = false - // estimateOption.map((row2) => { - // if (row.pkgYn === '0') { - // if (row2 === row.code) { - // row.check = true - // } - // } else { - // if (row.code.includes(row2)) { - // row.check = true - // return - // } - // } - // }) - // //detail과 상관없이 디폴트 체크목록 - // //ATTR003,ATTR007 - // if (row.code === 'ATTR003') { - // row.check = true - // } - // if (row.code === 'ATTR007') { - // row.check = true - // } - // }) - - // setSpecialNoteList(res) - // } - // } - // }) - // }, [estimateContextState?.estimateOption]) - //API데이터로 견적일 셋팅 let begin = 1 useEffect(() => { @@ -276,7 +254,9 @@ export default function Estimate({ params }) { } //YJSS UNIT_PIRCE로 프라이싱 실행 - handlePricing('UNIT_PRICE') + if (handlePricingFlag) { + handlePricing('UNIT_PRICE') + } } else { if (specialNoteList.length > 0) { specialNoteList.map((item) => { @@ -293,7 +273,9 @@ export default function Estimate({ params }) { }) //YJOD로 돌아가도 UNIT_PRICE로 프라이싱 실행해서 정가로 셋팅 - handlePricing('UNIT_PRICE') + if (handlePricingFlag) { + handlePricing('UNIT_PRICE') + } } setItemChangeYn(true) @@ -543,6 +525,7 @@ export default function Estimate({ params }) { updates.itemGroup = res.itemGroup updates.delFlg = '0' // 삭제플래그 0 updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() + updates.amount = '' if (estimateContextState.estimateType === 'YJSS') { if (res.pkgMaterialFlg === '0') { @@ -557,7 +540,8 @@ export default function Estimate({ params }) { if (item.dispOrder === dispOrder) { return { ...item, ...updates } } else if (item.paDispOrder === dispOrder) { - return { ...item, delFlg: '0' } + //봄제품을 바꿨을떄 + return { ...item, delFlg: '1' } } else { return item } @@ -572,14 +556,14 @@ export default function Estimate({ params }) { bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' - bomItem.amount = bomItem.bomAmount + // bomItem.amount = null } else { bomItem.dispOrder = (index + 1 + Number(dispOrder)).toString() bomItem.paDispOrder = dispOrder bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' - bomItem.amount = bomItem.bomAmount + // bomItem.amount = null } bomItem.delFlg = '0' @@ -717,6 +701,11 @@ export default function Estimate({ params }) { const volKw = (item.pnowW * amount) / 1000 totVolKw += volKw } + + setEstimateContextState({ + pkgTotPrice: estimateContextState.pkgAsp.replaceAll(',', '') * totVolKw, + }) + //pkgTotPrice // const saleTotPrice totAmount += amount if (item.pkgMaterialFlg === '1') { @@ -735,7 +724,6 @@ export default function Estimate({ params }) { } } }) - supplyPrice = addSupplyPrice + Number(estimateContextState.pkgTotPrice) vatPrice = supplyPrice * 0.1 totPrice = supplyPrice + vatPrice @@ -905,6 +893,7 @@ export default function Estimate({ params }) { checked={estimateContextState?.estimateType === 'YJSS' ? true : false} onChange={(e) => { //주문분류 + setHandlePricingFlag(true) setEstimateContextState({ estimateType: e.target.value }) }} /> @@ -918,6 +907,7 @@ export default function Estimate({ params }) { value={'YJOD'} checked={estimateContextState?.estimateType === 'YJOD' ? true : false} onChange={(e) => { + setHandlePricingFlag(true) setEstimateContextState({ estimateType: e.target.value }) }} /> @@ -1101,7 +1091,9 @@ export default function Estimate({ params }) { settingShowContent(row.code, event) }} /> - + ) @@ -1188,7 +1180,7 @@ export default function Estimate({ params }) { {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')} - {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)} + {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)} {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')} {convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)} @@ -1222,6 +1214,7 @@ export default function Estimate({ params }) { type="button" className="btn-origin grey ml5" onClick={() => { + setHandlePricingFlag(true) handlePricing(showPriceCd) }} > @@ -1429,7 +1422,7 @@ export default function Estimate({ params }) { {productFeaturesPopupOpen && ( diff --git a/src/components/estimate/popup/ProductFeaturesPop.jsx b/src/components/estimate/popup/ProductFeaturesPop.jsx index d958e7e2..5b1af6aa 100644 --- a/src/components/estimate/popup/ProductFeaturesPop.jsx +++ b/src/components/estimate/popup/ProductFeaturesPop.jsx @@ -1,13 +1,13 @@ 'use client' import { useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' -export default function ProductFeaturesPop({ specialNoteList, showProductFeatureData, setProductFeaturesPopupOpen }) { +export default function ProductFeaturesPop({ popShowSpecialNoteList, showProductFeatureData, setProductFeaturesPopupOpen }) { const [showSpecialNoteList, setShowSpecialNoteList] = useState([]) const { getMessage } = useMessage() useEffect(() => { let pushData = [] - specialNoteList.map((row) => { + popShowSpecialNoteList.map((row) => { let option = showProductFeatureData.split('、') option.map((row2) => { if (row.code === row2) { @@ -16,7 +16,7 @@ export default function ProductFeaturesPop({ specialNoteList, showProductFeature }) }) setShowSpecialNoteList(pushData) - }, [specialNoteList]) + }, [popShowSpecialNoteList]) return (
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 87f07a8e..080a7cb6 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -142,6 +142,16 @@ export default function StuffDetail() { headerName: getMessage('stuff.detail.planGridHeader.capacity'), width: 120, cellStyle: { justifyContent: 'flex-end' /* 우측정렬*/ }, + cellRenderer: (params) => { + let origin = params.value + let capacity + if (origin) { + capacity = origin / 1000 + return capacity.toFixed(3) + } else { + return null + } + }, }, { field: 'roofMaterialIdMulti', @@ -170,8 +180,8 @@ export default function StuffDetail() { }, }, { - field: 'constructSpecification', - headerName: getMessage('stuff.detail.planGridHeader.constructSpecification'), + field: 'constructSpecificationMulti', + headerName: getMessage('stuff.detail.planGridHeader.constructSpecificationMulti'), wrapText: true, autoHeight: true, cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ }, diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 04dcd477..23636c4c 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -141,7 +141,6 @@ export const useEstimateController = (planNo) => { return alert(getMessage('estimate.detail.save.requiredEstimateDate')) } - // console.log('첨부파일:::::', estimateData.fileList) //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 let fileFlg = true @@ -159,8 +158,34 @@ export const useEstimateController = (planNo) => { }) } } + let itemFlg = true + estimateData.itemList.map((item) => { + item.amount = item.amount?.replaceAll(',', '') + item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2) + item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) - if (flag && fileFlg) { + if (!item.paDispOrder) { + if (itemFlg) { + if (isNaN(item.amount)) { + item.amount = 0 + } else { + Number(item.amount) + } + + if (item.amount < 1) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredAmount')) + } + + if (Number(item.salePrice) < 1) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } + } + } + }) + + if (flag && fileFlg && itemFlg) { //1. 첨부파일 저장시작 const formData = new FormData() formData.append('file', estimateData.fileList) @@ -186,12 +211,6 @@ export const useEstimateController = (planNo) => { } console.log('최종 아이템 정보::;', estimateData.itemList) - estimateData.itemList.map((item) => { - item.amount = item.amount?.replaceAll(',', '') - item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2) - item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) - }) - console.log('최종 정보::;', estimateData) //2. 상세데이터 저장 // return diff --git a/src/locales/ja.json b/src/locales/ja.json index 9250fe50..03ec0aa7 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -729,7 +729,7 @@ "stuff.detail.planGridHeader.moduleModel": "モジュール", "stuff.detail.planGridHeader.capacity": "システム容量", "stuff.detail.planGridHeader.roofMaterialIdMulti": "屋根材", - "stuff.detail.planGridHeader.constructSpecification": "施工方法", + "stuff.detail.planGridHeader.constructSpecificationMulti": "施工方法", "stuff.detail.planGridHeader.supportMethodIdMulti": "架台", "stuff.detail.planGridHeader.pcTypeNo": "パワーコンディショナー", "stuff.detail.planGridHeader.management": "管理", @@ -895,6 +895,8 @@ "estimate.detail.save.requiredCharger": "担当者は必須です.", "estimate.detail.save.requiredObjectName": "案件名は必須です.", "estimate.detail.save.requiredEstimateDate": "見積日は必須です.", + "estimate.detail.save.requiredAmount": "数量は0より大きい値を入力してください.", + "estimate.detail.save.requiredSalePrice": "単価は0より大きい値を入力してください.", "estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?", "simulator.title.sub1": "物件番号", "simulator.title.sub2": "作成日", diff --git a/src/locales/ko.json b/src/locales/ko.json index 023ccdc8..85994982 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -739,7 +739,7 @@ "stuff.detail.planGridHeader.moduleModel": "모듈", "stuff.detail.planGridHeader.capacity": "시스템용량", "stuff.detail.planGridHeader.roofMaterialIdMulti": "지붕재", - "stuff.detail.planGridHeader.constructSpecification": "시공방법", + "stuff.detail.planGridHeader.constructSpecificationMulti": "시공방법", "stuff.detail.planGridHeader.supportMethodIdMulti": "가대", "stuff.detail.planGridHeader.pcTypeNo": "파워컨디셔너", "stuff.detail.planGridHeader.management": "관리", @@ -905,6 +905,8 @@ "estimate.detail.save.requiredCharger": "담당자는 필수값 입니다.", "estimate.detail.save.requiredObjectName": "안건명은 필수값 입니다.", "estimate.detail.save.requiredEstimateDate": "견적일은 필수값 입니다.", + "estimate.detail.save.requiredAmount": "수량은 0보다 큰값을 입력해주세요.", + "estimate.detail.save.requiredSalePrice": "단가는 0보다 큰값을 입력해주세요.", "estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?", "simulator.title.sub1": "물건번호", "simulator.title.sub2": "작성일",