견적서 상세

This commit is contained in:
basssy 2024-11-09 02:05:26 +09:00
parent ac5038562a
commit 21d758834d
4 changed files with 169 additions and 82 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 EstimateItemTable from './EstimateItemTable' import { convertNumberToPriceDecimal } from '@/util/common-utils'
export default function Estimate({ params }) { export default function Estimate({ params }) {
const { session } = useContext(SessionContext) const { session } = useContext(SessionContext)
@ -36,6 +36,8 @@ 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,
@ -47,7 +49,7 @@ export default function Estimate({ params }) {
// //
const { state, setState } = useEstimateController(params.pid) const { state, setState } = useEstimateController(params.pid)
const [itemList, setItemList] = useState([]) const [itemList, setItemList] = useState([]) //
// List // List
const [specialNoteList, setSpecialNoteList] = useState([]) const [specialNoteList, setSpecialNoteList] = useState([])
@ -151,9 +153,13 @@ export default function Estimate({ params }) {
objectNo: objectNo, objectNo: objectNo,
no: no, no: no,
} }
await promisePost({ url: 'api/file/fileDelete', data: delParams }).then((res) => { await promisePost({ url: 'api/file/fileDelete', data: delParams }).then((res) => {
if (res.status === 204) { if (res.status === 204) {
setOriginFiles(originFiles.filter((file) => file.objectNo === objectNo && file.no !== no)) setOriginFiles(originFiles.filter((file) => file.objectNo === objectNo && file.no !== no))
setState({
fileList: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no),
})
} }
}) })
} }
@ -165,13 +171,14 @@ export default function Estimate({ params }) {
} }
}, [state?.itemList]) }, [state?.itemList])
// option // option
useEffect(() => { useEffect(() => {
const param = { const param = {
saleStoreId: session.storeId, saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd, sapSalesStoreCd: session.custCd,
docTpCd: state?.estimateType, docTpCd: state?.estimateType,
} }
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)) {
@ -180,21 +187,58 @@ export default function Estimate({ params }) {
}) })
}, [state?.estimateType]) }, [state?.estimateType])
useEffect(() => {
if (state.priceCd) {
setTempPriceCd(state.priceCd)
}
}, [state?.priceCd])
// option
useEffect(() => {
if (tempPriceCd !== '') {
const param = {
saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd,
docTpCd: tempPriceCd,
}
const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) {
setStorePriceList(res.data)
}
})
}
}, [tempPriceCd])
//Pricing //Pricing
const handlePricing = async (priceCd) => { const handlePricing = async (priceCd) => {
const param = { const param = {
saleStoreId: session.storeId, saleStoreId: session.storeId,
sapSalesStoreCd: session.custCd, sapSalesStoreCd: session.custCd,
docTpCd: state.estimateType, docTpCd: state.estimateType,
priceCd: priceCd, priceCd: session.storeLvl === '1' ? tempPriceCd : priceCd,
itemIdList: [], // itemIdList: state.itemList, //
} }
console.log('param::', param) // console.log('::', param)
return
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) => {
console.log('프라이싱결과::::::', res) if (res) {
// ............SUCK!!! if (res.status === 200) {
const data = res.data
if (data.result.code === 200) {
if (isNotEmptyArray(data.data2)) {
// ............
//..
//itemList itemId unitPrice 0
//itemId
setState({
priceCd: session.storeLvl === '1' ? tempPriceCd : priceCd,
})
}
}
}
}
}) })
} }
@ -249,7 +293,7 @@ export default function Estimate({ params }) {
<tr> <tr>
{/* 1차 판매점명 */} {/* 1차 판매점명 */}
<th>{getMessage('estimate.detail.saleStoreId')}</th> <th>{getMessage('estimate.detail.saleStoreId')}</th>
<td></td> <td>{state?.firstSaleStoreName}</td>
{/* 견적일 */} {/* 견적일 */}
<th> <th>
{getMessage('estimate.detail.estimateDate')} <span className="important">*</span> {getMessage('estimate.detail.estimateDate')} <span className="important">*</span>
@ -263,7 +307,7 @@ export default function Estimate({ params }) {
<tr> <tr>
{/* 2차 판매점명 */} {/* 2차 판매점명 */}
<th>{getMessage('estimate.detail.otherSaleStoreId')}</th> <th>{getMessage('estimate.detail.otherSaleStoreId')}</th>
<td></td> <td>{state?.agencySaleStoreName}</td>
{/* 담당자 */} {/* 담당자 */}
<th> <th>
{getMessage('estimate.detail.receiveUser')} <span className="important">*</span> {getMessage('estimate.detail.receiveUser')} <span className="important">*</span>
@ -622,7 +666,7 @@ export default function Estimate({ params }) {
<select <select
className="select-light" className="select-light"
onChange={(e) => { onChange={(e) => {
setState({ priceCd: e.target.value }) setTempPriceCd(e.target.value)
}} }}
> >
{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>)}
@ -636,7 +680,6 @@ export default function Estimate({ params }) {
<button <button
className="btn-origin grey ml5" className="btn-origin grey ml5"
onClick={() => { onClick={() => {
// console.log('priceCd::', state.priceCd)
handlePricing(state.priceCd) handlePricing(state.priceCd)
}} }}
> >
@ -696,17 +739,77 @@ export default function Estimate({ params }) {
<label htmlFor="ch97"></label> <label htmlFor="ch97"></label>
</div> </div>
</th> </th>
<th>{getMessage('estimate.detail.itemTableHeader.col1')}</th> <th>{getMessage('estimate.detail.itemTableHeader.dispOrder')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col2')}</th> <th>{getMessage('estimate.detail.itemTableHeader.itemId')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col3')}</th> <th>{getMessage('estimate.detail.itemTableHeader.itemNo')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col4')}</th> <th>{getMessage('estimate.detail.itemTableHeader.amount')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col5')}</th> <th>{getMessage('estimate.detail.itemTableHeader.unit')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col6')}</th> <th>{getMessage('estimate.detail.itemTableHeader.salePrice')}</th>
<th>{getMessage('estimate.detail.itemTableHeader.col7')}</th> <th>{getMessage('estimate.detail.itemTableHeader.saleTotPrice')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> {itemList.length > 0 &&
itemList.map((item, index) => {
return (
<tr key={index}>
<td className="al-c">
<div className="d-check-box light no-text">
<input type="checkbox" id={item?.dispOrder * 100} />
<label htmlFor={item?.dispOrder * 100}></label>
</div>
</td>
<td className="al-r">{item?.dispOrder * 100}</td>
<td>
<div className="form-flex-wrap">
<div className="select-wrap mr5">
<Select />
</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={() => {
console.log('제품특이사항 모달팝업:::::::::', item?.specialNoteCd)
}}
></button>
)}
</div>
</div>
</td>
<td>
<div className="input-wrap" style={{ width: '100%' }}>
<input type="text" className="input-light al-r" defaultValue={item?.amount} />
</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" defaultValue={convertNumberToPriceDecimal(item?.salePrice)} />
</div>
{/* <div className="btn-area">
<span className="tb_ico open_check">OPEN아이콘 처리</span>
</div> */}
</div>
</td>
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice)}</td>
</tr>
)
})}
{/* <tr>
<td className="al-c"> <td className="al-c">
<div className="d-check-box light no-text"> <div className="d-check-box light no-text">
<input type="checkbox" id="ch98" /> <input type="checkbox" id="ch98" />
@ -716,7 +819,7 @@ export default function Estimate({ params }) {
<td className="al-r">100</td> <td className="al-r">100</td>
<td> <td>
<div className="form-flex-wrap"> <div className="form-flex-wrap">
<div className="select-wrap mr5">{/* <Select /> */}</div> <div className="select-wrap mr5"></div>
<div className="btn-area"> <div className="btn-area">
<span className="tb_ico change_check"></span> <span className="tb_ico change_check"></span>
</div> </div>
@ -748,7 +851,7 @@ export default function Estimate({ params }) {
</div> </div>
</td> </td>
<td className="al-r">5,561,000</td> <td className="al-r">5,561,000</td>
</tr> </tr> */}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -22,29 +22,10 @@ const defaultEstimateData = {
estimateType: 'YJOD', //주문분류 estimateType: 'YJOD', //주문분류
remarks: '', //비고 remarks: '', //비고
estimateOption: '', //견적특이사항 estimateOption: '', //견적특이사항
//아이템에 필요없는거 빼기 itemList: [],
itemList: [
// {
// amount: '',
// fileUploadFlg: '',
// itemChangeFlg: '',
// itemGroup: '',
// itemId: '', //키값??
// itemName: '',
// itemNo: '',
// moduleFlg: '',
// objectNo: '',
// pkgMaterialFlg: '',
// planNo: '',
// pnowW: '',
// salePrice: '',
// saleTotPrice: '',
// specification: '',
// unit: '',
// },
],
fileList: [], fileList: [],
fileFlg: '0', //후일 자료 제출 (체크 1 노체크 0) fileFlg: '0', //후일 자료 제출 (체크 1 노체크 0)
priceCd: '',
} }
// Helper functions // Helper functions
@ -100,17 +81,17 @@ export const useEstimateController = (planNo) => {
itemList: [ itemList: [
...state.itemList, ...state.itemList,
{ {
dispOrder: '1',
itemId: newItemId, itemId: newItemId,
amount: '', amount: '',
fileUploadFlg: '', fileUploadFlg: '0',
itemChangeFlg: '', itemChangeFlg: '0',
pkgMaterialFlg: '0',
specialNoteCd: '',
itemGroup: '', itemGroup: '',
itemName: '', itemName: '',
itemNo: '', itemNo: '',
moduleFlg: '', moduleFlg: '',
objectNo: '',
pkgMaterialFlg: '',
planNo: '',
pnowW: '', pnowW: '',
salePrice: '', salePrice: '',
saleTotPrice: '', saleTotPrice: '',
@ -130,6 +111,7 @@ export const useEstimateController = (planNo) => {
//0. 필수체크 //0. 필수체크
let flag = true let flag = true
console.log('::담긴 estimateData:::', estimateData) console.log('::담긴 estimateData:::', estimateData)
//아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼
if (estimateData.itemList.length > 1) { if (estimateData.itemList.length > 1) {
estimateData.itemList.map((row) => { estimateData.itemList.map((row) => {
@ -149,29 +131,31 @@ export const useEstimateController = (planNo) => {
formData.append('planNo', estimateData.planNo) formData.append('planNo', estimateData.planNo)
formData.append('category', '10') formData.append('category', '10')
formData.append('userId', estimateData.userId) formData.append('userId', estimateData.userId)
for (const value of formData.values()) { // for (const value of formData.values()) {
console.log('formData::', value) // console.log('formData::', value)
} // }
await promisePost({ url: '/api/file/fileUpload', data: formData }).then((res) => { await post({ url: '/api/file/fileUpload', data: formData })
console.log('파일저장결과::::::::::', res)
})
//2. 상세데이터 저장 //2. 상세데이터 저장
console.log('상세저장시작!!')
return return
try { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {
const result = await promisePost({ if (res) {
url: ESTIMATE_API_ENDPOINT, alert(getMessage('estimate.detail.save.alertMsg'))
data: estimateData, }
}) })
alert(getMessage('estimate.detail.save.alertMsg'))
return result // try {
} catch (error) { // const result = await promisePost({
console.error('Failed to submit estimate:', error) // url: ESTIMATE_API_ENDPOINT,
throw error // data: estimateData,
} // })
// alert(getMessage('estimate.detail.save.alertMsg'))
// return result
// } catch (error) {
// console.error('Failed to submit estimate:', error)
// throw error
// }
} }
} }

View File

@ -849,13 +849,13 @@
"estimate.detail.showPrice.description4": "クリックして製品の特異性を確認する", "estimate.detail.showPrice.description4": "クリックして製品の特異性を確認する",
"estimate.detail.showPrice.btn2": "製品を追加", "estimate.detail.showPrice.btn2": "製品を追加",
"estimate.detail.showPrice.btn3": "製品削除", "estimate.detail.showPrice.btn3": "製品削除",
"estimate.detail.itemTableHeader.col1": "アイテム", "estimate.detail.itemTableHeader.dispOrder": "アイテム",
"estimate.detail.itemTableHeader.col2": "品番", "estimate.detail.itemTableHeader.itemId": "品番",
"estimate.detail.itemTableHeader.col3": "型板", "estimate.detail.itemTableHeader.itemNo": "型板",
"estimate.detail.itemTableHeader.col4": "数量", "estimate.detail.itemTableHeader.amount": "数量",
"estimate.detail.itemTableHeader.col5": "単位", "estimate.detail.itemTableHeader.unit": "単位",
"estimate.detail.itemTableHeader.col6": "単価", "estimate.detail.itemTableHeader.salePrice": "単価",
"estimate.detail.itemTableHeader.col7": "金額 (税別別)", "estimate.detail.itemTableHeader.saleTotPrice": "金額 (税別別)",
"estimate.detail.docPopup.title": "ドキュメントダウンロードオプションの設定", "estimate.detail.docPopup.title": "ドキュメントダウンロードオプションの設定",
"estimate.detail.docPopup.explane": "ダウンロードする文書のオプションを選択したら、 [文書のダウンロード]ボタンをクリックします.", "estimate.detail.docPopup.explane": "ダウンロードする文書のオプションを選択したら、 [文書のダウンロード]ボタンをクリックします.",
"estimate.detail.docPopup.schUnitPriceFlg": "ダウンロードファイル", "estimate.detail.docPopup.schUnitPriceFlg": "ダウンロードファイル",

View File

@ -855,13 +855,13 @@
"estimate.detail.showPrice.description4": "클릭하여 제품 특이사항 확인", "estimate.detail.showPrice.description4": "클릭하여 제품 특이사항 확인",
"estimate.detail.showPrice.btn2": "제품추가", "estimate.detail.showPrice.btn2": "제품추가",
"estimate.detail.showPrice.btn3": "제품삭제", "estimate.detail.showPrice.btn3": "제품삭제",
"estimate.detail.itemTableHeader.col1": "Item", "estimate.detail.itemTableHeader.dispOrder": "Item",
"estimate.detail.itemTableHeader.col2": "품번", "estimate.detail.itemTableHeader.itemId": "품번",
"estimate.detail.itemTableHeader.col3": "형명", "estimate.detail.itemTableHeader.itemNo": "형명",
"estimate.detail.itemTableHeader.col4": "수량", "estimate.detail.itemTableHeader.amount": "수량",
"estimate.detail.itemTableHeader.col5": "단위", "estimate.detail.itemTableHeader.unit": "단위",
"estimate.detail.itemTableHeader.col6": "단가", "estimate.detail.itemTableHeader.salePrice": "단가",
"estimate.detail.itemTableHeader.col7": "금액(부가세별도)", "estimate.detail.itemTableHeader.saleTotPrice": "금액(부가세별도)",
"estimate.detail.docPopup.title": "문서다운로드 옵션설정", "estimate.detail.docPopup.title": "문서다운로드 옵션설정",
"estimate.detail.docPopup.explane": "다운로드할 문서 옵션을 선택한 후 문서 다운로드 버튼을 클릭합니다.", "estimate.detail.docPopup.explane": "다운로드할 문서 옵션을 선택한 후 문서 다운로드 버튼을 클릭합니다.",
"estimate.detail.docPopup.schUnitPriceFlg": "다운로드 파일", "estimate.detail.docPopup.schUnitPriceFlg": "다운로드 파일",