물건상세 & 견적서 상세

This commit is contained in:
basssy 2024-11-26 18:29:34 +09:00
parent cd1a32eaf9
commit f4a4ac8e36
6 changed files with 95 additions and 69 deletions

View File

@ -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)) {
// ATTR001ATTR002ATTR003ATTR007ATTR009ATTR010ATTR015ATTR019
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)
// //ATTR001ATTR002ATTR009ATTR010
// 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)
}}
/>
<label htmlFor={row.code}>{row.codeNm}</label>
<label htmlFor={row.code}>
{row.codeNm} / {row.code}
</label>
</div>
</div>
)
@ -1188,7 +1180,7 @@ export default function Estimate({ params }) {
</div>
</td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th>
<td>{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}</td>
<td>{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)}</td>
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th>
<td>{convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)}</td>
</tr>
@ -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 }) {
</div>
{productFeaturesPopupOpen && (
<ProductFeaturesPop
specialNoteList={specialNoteList}
popShowSpecialNoteList={popShowSpecialNoteList}
showProductFeatureData={showProductFeatureData}
setProductFeaturesPopupOpen={setProductFeaturesPopupOpen}
/>

View File

@ -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 (
<div className="modal-popup">

View File

@ -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' /* 좌측정렬*/ },

View File

@ -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

View File

@ -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": "作成日",

View File

@ -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": "작성일",