Merge branch 'dev' into dev-yj

This commit is contained in:
yjnoh 2024-11-14 15:17:59 +09:00
commit 221a498431
11 changed files with 263 additions and 148 deletions

View File

@ -0,0 +1,20 @@
'ues client'
import { createContext, useEffect, useState } from 'react'
export const ManagementContext = createContext({
managementState: {},
setManagementState: () => {},
})
const ManagementProvider = ({ children }) => {
const [managementState, setManagementState] = useState({})
useEffect(() => {
console.log('🚀 ~ managementState:', managementState)
}, [managementState])
return <ManagementContext.Provider value={{ managementState, setManagementState }}>{children}</ManagementContext.Provider>
}
export default ManagementProvider

View File

@ -0,0 +1,7 @@
'use client'
import ManagementProvider from './ManagementProvider'
export default function ManagementLayout({ children }) {
return <ManagementProvider>{children}</ManagementProvider>
}

View File

@ -18,6 +18,7 @@ import Select, { components } from 'react-select'
import { convertNumberToPriceDecimal } from '@/util/common-utils' import { convertNumberToPriceDecimal } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop' import ProductFeaturesPop from './popup/ProductFeaturesPop'
export default function Estimate({ params }) { export default function Estimate({ params }) {
const [itemChangeYn, setItemChangeYn] = useState(false)
const { session } = useContext(SessionContext) const { session } = useContext(SessionContext)
const [objectNo, setObjectNo] = useState('') // const [objectNo, setObjectNo] = useState('') //
const [planNo, setPlanNo] = useState('') // const [planNo, setPlanNo] = useState('') //
@ -54,7 +55,7 @@ export default function Estimate({ params }) {
const objectRecoil = useRecoilValue(floorPlanObjectState) const objectRecoil = useRecoilValue(floorPlanObjectState)
// //
const { state, setState, addItem } = useEstimateController(params.pid) const { state, setState, addItem, handleEstimateFileDownload } = useEstimateController(params.pid)
// List // List
const [specialNoteList, setSpecialNoteList] = useState([]) const [specialNoteList, setSpecialNoteList] = useState([])
@ -169,7 +170,6 @@ 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))
@ -180,13 +180,6 @@ export default function Estimate({ params }) {
}) })
} }
//
// useEffect(() => {
// if (isNotEmptyArray(state.itemList)) {
// setItemList(state.itemList)
// }
// }, [state?.itemList])
// option // option
useEffect(() => { useEffect(() => {
if (state.estimateType !== '') { if (state.estimateType !== '') {
@ -266,19 +259,49 @@ export default function Estimate({ params }) {
setSelection(newSelection) setSelection(newSelection)
} }
// //
const onChangeDisplayItem = (itemId, dispOrder) => { const onChangeDisplayItem = (itemId, dispOrder) => {
console.log('아이템 자동완성:::::::', dispOrder)
const param = { const param = {
itemId: itemId, itemId: itemId,
} }
const apiUrl = `/api/display-item/item-detail?${queryStringFormatter(param)}` const apiUrl = `/api/display-item/item-detail?${queryStringFormatter(param)}`
let updateList = []
let updates = {}
get({ url: apiUrl }).then((res) => { get({ url: apiUrl }).then((res) => {
console.log('제품상세 결과::::::::', res) console.log('아이템상세정보:::::::', res)
updates.objectNo = objectNo
updates.planNo = planNo
updates.itemId = res.itemId
updates.itemNo = res.itemNo
updates.itemName = res.itemName
updates.itemChangeFlg = '1' // 1
updates.partAdd = '1' //1 NEW
updates.fileUploadFlg = res.fileUploadFlg
updates.unit = res.unit
updates.unitPrice = res.salePrice //unitPrice salePrice
updates.moduleFlg = res.moduleFlg
updates.pkgMaterialFlg = res.pkgMaterialFlg
updates.pnowW = res.pnowW
updates.salePrice = res.salePrice
updates.specification = res.specification
updates.unit = res.unit
updates.specialNoteCd = res.spnAttrCds
updates.itemGroup = res.itemGroup
updates.delFlg = '0' // 0
updateList = state.itemList.map((item) => {
if (item.dispOrder === dispOrder) {
return { ...item, ...updates }
} else {
return item
}
})
setState({
itemList: updateList,
})
setItemChangeYn(true)
}) })
// setState({
// itemList: [{ itemNo: '123123123123' }],
// })
} }
// //
@ -293,6 +316,7 @@ export default function Estimate({ params }) {
}) })
}) })
//
const result = state.itemList.filter((item) => { const result = state.itemList.filter((item) => {
return !tempList.some((other) => other.dispOrder === item.dispOrder) return !tempList.some((other) => other.dispOrder === item.dispOrder)
}) })
@ -302,8 +326,19 @@ export default function Estimate({ params }) {
}) })
setSelection(new Set()) setSelection(new Set())
setItemChangeYn(true)
} }
useEffect(() => {
if (itemChangeYn) {
// console.log(' ', itemChangeYn)
// console.log('::::::::::', state.itemList)
}
// false ..
setItemChangeYn(false)
}, [itemChangeYn])
return ( return (
<div className="sub-content estimate"> <div className="sub-content estimate">
<div className="sub-content-inner"> <div className="sub-content-inner">
@ -579,9 +614,16 @@ export default function Estimate({ params }) {
originFiles.map((originFile) => { originFiles.map((originFile) => {
return ( return (
<li className="file-item"> <li className="file-item">
<span> <span onClick={() => handleEstimateFileDownload(originFile)}>
{originFile.faileName} {originFile.faileName}
<button className="delete" onClick={() => deleteOriginFile(originFile.objectNo, originFile.no)}></button> <button
type="button"
className="delete"
onClick={(e) => {
deleteOriginFile(originFile.objectNo, originFile.no)
e.stopPropagation()
}}
></button>
</span> </span>
</li> </li>
) )
@ -838,18 +880,21 @@ export default function Estimate({ params }) {
classNamePrefix="custom" classNamePrefix="custom"
placeholder="Select" placeholder="Select"
options={displayItemList} options={displayItemList}
onChange={(e) => onChangeDisplayItem(e.itemId, item.dispOrder)} onChange={(e) => {
if (isObjectNotEmpty(e)) {
onChangeDisplayItem(e.itemId, item.dispOrder)
}
}}
getOptionLabel={(x) => x.itemName} getOptionLabel={(x) => x.itemName}
getOptionValue={(x) => x.itemId} getOptionValue={(x) => x.itemId}
isClearable={true} isClearable={true}
isDisabled={false} isDisabled={false}
value={displayItemList.filter(function (option) { value={displayItemList.filter(function (option) {
// console.log('???', option.itemId)
// console.log(' ???', item.itemId)
return option.itemId === item.itemId return option.itemId === item.itemId
})} })}
/> />
</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>
@ -877,14 +922,32 @@ export default function Estimate({ params }) {
</td> </td>
<td> <td>
<div className="input-wrap" style={{ width: '100%' }}> <div className="input-wrap" style={{ width: '100%' }}>
<input type="text" className="input-light al-r" defaultValue={item?.amount} /> <input
type="text"
className="input-light al-r"
defaultValue={convertNumberToPriceDecimal(item?.amount)}
onChange={(e) => {
//onChangeDisplayItem
//itemChangeFlg = 1, partAdd = 0
console.log('수량변경::::::::', e.target.value)
}}
/>
</div> </div>
</td> </td>
<td>{item.unit}</td> <td>{item.unit}</td>
<td> <td>
<div className="form-flex-wrap"> <div className="form-flex-wrap">
<div className="input-wrap mr5"> <div className="input-wrap mr5">
<input type="text" className="input-light al-r" defaultValue={convertNumberToPriceDecimal(item?.salePrice)} /> <input
type="text"
className="input-light al-r"
value={convertNumberToPriceDecimal(item?.salePrice)}
onChange={(e) => {
//onChangeDisplayItem
//itemChangeFlg, partAdd
console.log('단가변경:::::::', e.target.value)
}}
/>
</div> </div>
{/* <div className="btn-area"> {/* <div className="btn-area">
<span className="tb_ico open_check">OPEN아이콘 처리</span> <span className="tb_ico open_check">OPEN아이콘 처리</span>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react' import { useEffect, useState, useContext } from 'react'
import ProductItem from './ProductItem' import ProductItem from './ProductItem'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import Image from 'next/image' import Image from 'next/image'
@ -8,17 +8,16 @@ import { useRecoilValue } from 'recoil'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { globalLocaleStore } from '@/store/localeAtom' import { globalLocaleStore } from '@/store/localeAtom'
import { queryStringFormatter } from '@/util/common-utils' import { queryStringFormatter } from '@/util/common-utils'
import { sessionStore } from '@/store/commonAtom'
import MainSkeleton from '../ui/MainSkeleton' import MainSkeleton from '../ui/MainSkeleton'
import { SessionContext } from '@/app/SessionProvider'
export default function MainContents() { export default function MainContents() {
const { session } = useContext(SessionContext)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const router = useRouter() const router = useRouter()
const globalLocaleState = useRecoilValue(globalLocaleStore) const globalLocaleState = useRecoilValue(globalLocaleStore)
const { promiseGet } = useAxios(globalLocaleState) const { promiseGet } = useAxios(globalLocaleState)
const sessionState = useRecoilValue(sessionStore)
// //
const [objectList, setObjectList] = useState([]) const [objectList, setObjectList] = useState([])
@ -36,12 +35,12 @@ export default function MainContents() {
fetchObjectList() fetchObjectList()
fetchNoticeList() fetchNoticeList()
fetchFaqList() fetchFaqList()
}, [sessionState]) }, [])
// / Sales Contact info // / Sales Contact info
const fetchObjectList = async () => { const fetchObjectList = async () => {
try { try {
const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list` const apiUrl = `/api/main-page/object/${session?.storeId}/list`
await promiseGet({ await promiseGet({
url: apiUrl, url: apiUrl,
}).then((res) => { }).then((res) => {

View File

@ -218,10 +218,6 @@ export default function Stuff() {
stuffSearchParams.endRow = 1 * pageSize stuffSearchParams.endRow = 1 * pageSize
stuffSearchParams.schSortType = defaultSortType stuffSearchParams.schSortType = defaultSortType
setPageNo(1) setPageNo(1)
setStuffSearch({
...stuffSearch,
code: 'FINISH',
})
async function fetchData() { async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}` const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
@ -239,6 +235,25 @@ export default function Stuff() {
fetchData() fetchData()
} else if (stuffSearchParams?.code === 'C') { } else if (stuffSearchParams?.code === 'C') {
resetStuffRecoil() resetStuffRecoil()
} else if (stuffSearchParams?.code === 'FINISH') {
stuffSearchParams.startRow = 1
stuffSearchParams.endRow = 1 * pageSize
stuffSearchParams.schSortType = defaultSortType
setPageNo(1)
async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
setTotalCount(res[0].totCnt)
} else {
setGridProps({ ...gridProps, gridData: [], count: 0 })
setTotalCount(0)
}
})
}
fetchData()
} }
}, [stuffSearchParams]) }, [stuffSearchParams])

View File

@ -18,6 +18,7 @@ import WindSelectPop from './popup/WindSelectPop'
import { useCommonCode } from '@/hooks/common/useCommonCode' import { useCommonCode } from '@/hooks/common/useCommonCode'
import StuffPlanQGrid from './StuffPlanQGrid' import StuffPlanQGrid from './StuffPlanQGrid'
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
import { ManagementContext } from '@/app/management/ManagementProvider'
export default function StuffDetail() { export default function StuffDetail() {
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) // const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //
@ -96,7 +97,7 @@ export default function StuffDetail() {
const objectNo = searchParams.get('objectNo') //url set const objectNo = searchParams.get('objectNo') //url set
const [editMode, setEditMode] = useState('NEW') const [editMode, setEditMode] = useState('NEW')
const [detailData, setDetailData] = useState({}) const { managementState, setManagementState } = useContext(ManagementContext)
const [planGridProps, setPlanGridProps] = useState({ const [planGridProps, setPlanGridProps] = useState({
planGridData: [], planGridData: [],
@ -289,9 +290,9 @@ export default function StuffDetail() {
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => { promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
if (res.status === 200) { if (res.status === 200) {
if (res.data != null) { if (res.data != null) {
setDetailData(res.data) setManagementState(res.data)
} else { } else {
setDetailData({}) setManagementState({})
} }
if (isNotEmptyArray(res.data.planList)) { if (isNotEmptyArray(res.data.planList)) {
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList }) setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
@ -299,7 +300,7 @@ export default function StuffDetail() {
setPlanGridProps({ ...planGridProps, planGridData: [] }) setPlanGridProps({ ...planGridProps, planGridData: [] })
} }
} else { } else {
setDetailData({}) setManagementState({})
setPlanGridProps({ ...planGridProps, planGridData: [] }) setPlanGridProps({ ...planGridProps, planGridData: [] })
} }
}) })
@ -415,7 +416,7 @@ export default function StuffDetail() {
}, [commonCode]) }, [commonCode])
useEffect(() => { useEffect(() => {
if (isObjectNotEmpty(detailData)) { if (isObjectNotEmpty(managementState)) {
// API // API
get({ url: '/api/object/prefecture/list' }).then((res) => { get({ url: '/api/object/prefecture/list' }).then((res) => {
if (!isEmptyArray(res)) { if (!isEmptyArray(res)) {
@ -449,18 +450,17 @@ export default function StuffDetail() {
setFavoriteStoreList(favList) setFavoriteStoreList(favList)
setShowSaleStoreList(favList) setShowSaleStoreList(favList)
if (detailData.firstAgentId != null) { if (managementState.firstAgentId != null) {
form.setValue('saleStoreId', detailData.firstAgentId) form.setValue('saleStoreId', managementState.firstAgentId)
setSelOptions(detailData.firstAgentId) setSelOptions(managementState.firstAgentId)
} else { } else {
form.setValue('saleStoreId', detailData.saleStoreId) form.setValue('saleStoreId', managementState.saleStoreId)
setSelOptions(detailData.saleStoreId) setSelOptions(managementState.saleStoreId)
} }
// 1 2 // 1 2
let data = detailData?.firstAgentId ? detailData.firstAgentId : detailData.saleStoreId let data = managementState?.firstAgentId ? managementState.firstAgentId : managementState.saleStoreId
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=0&userId=${session?.userId}`
url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}` url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}`
get({ url: url }).then((res) => { get({ url: url }).then((res) => {
@ -502,74 +502,74 @@ export default function StuffDetail() {
// 1 1 // 1 1
// 2 2 1 // 2 2 1
if (detailData.saleStoreLevel === '1') { if (managementState.saleStoreLevel === '1') {
setSelOptions(detailData.saleStoreId) setSelOptions(managementState.saleStoreId)
form.setValue('saleStoreId', detailData.saleStoreId) form.setValue('saleStoreId', managementState.saleStoreId)
form.setValue('saleStoreLevel', detailData.saleStoreLevel) form.setValue('saleStoreLevel', managementState.saleStoreLevel)
} else { } else {
setOtherSelOptions(detailData.saleStoreId) setOtherSelOptions(managementState.saleStoreId)
form.setValue('otherSaleStoreId', detailData.saleStoreId) form.setValue('otherSaleStoreId', managementState.saleStoreId)
form.setValue('otherSaleStoreLevel', detailData.saleStoreLevel) form.setValue('otherSaleStoreLevel', managementState.saleStoreLevel)
form.setValue('saleStoreLevel', '1') form.setValue('saleStoreLevel', '1')
} }
//No. //No.
form.setValue('planReqNo', detailData.planReqNo) form.setValue('planReqNo', managementState.planReqNo)
// //
form.setValue('receiveUser', detailData.receiveUser) form.setValue('receiveUser', managementState.receiveUser)
//objectStatusId //objectStatusId
setSelectObjectStatusId(detailData.objectStatusId) setSelectObjectStatusId(managementState.objectStatusId)
form.setValue('objectStatusId', detailData.objectStatusId) form.setValue('objectStatusId', managementState.objectStatusId)
// //
form.setValue('objectName', detailData.objectName) form.setValue('objectName', managementState.objectName)
// //
setSelHonorificCode(detailData.objectNameOmit) setSelHonorificCode(managementState.objectNameOmit)
form.setValue('objectNameOmit', detailData.objectNameOmit) form.setValue('objectNameOmit', managementState.objectNameOmit)
// //
form.setValue('objectNameKana', detailData.objectNameKana) form.setValue('objectNameKana', managementState.objectNameKana)
// //
form.setValue('zipNo', detailData.zipNo) form.setValue('zipNo', managementState.zipNo)
// / // /
setPrefValue(detailData.prefId) setPrefValue(managementState.prefId)
form.setValue('prefId', detailData.prefId) form.setValue('prefId', managementState.prefId)
form.setValue('prefName', detailData.prefName) form.setValue('prefName', managementState.prefName)
form.setValue('address', detailData.address) form.setValue('address', managementState.address)
// //
form.setValue('areaId', detailData.areaId) form.setValue('areaId', managementState.areaId)
// //
form.setValue('standardWindSpeedId', detailData.standardWindSpeedId) form.setValue('standardWindSpeedId', managementState.standardWindSpeedId)
// //
form.setValue('verticalSnowCover', detailData.verticalSnowCover) form.setValue('verticalSnowCover', managementState.verticalSnowCover)
// coldRegionFlg 1 true // coldRegionFlg 1 true
form.setValue('coldRegionFlg', detailData.coldRegionFlg === '1' ? true : false) form.setValue('coldRegionFlg', managementState.coldRegionFlg === '1' ? true : false)
// surfaceType null // surfaceType null
// form.setValue('surfaceType', '') // form.setValue('surfaceType', '')
// form.setValue('surfaceType', '') // form.setValue('surfaceType', '')
form.setValue('surfaceType', detailData.surfaceType) form.setValue('surfaceType', managementState.surfaceType)
// saltAreaFlg 1 true // saltAreaFlg 1 true
form.setValue('saltAreaFlg', detailData.saltAreaFlg === '1' ? true : false) form.setValue('saltAreaFlg', managementState.saltAreaFlg === '1' ? true : false)
// //
form.setValue('installHeight', detailData.installHeight) form.setValue('installHeight', managementState.installHeight)
// null 0 // null 0
if (detailData.conType === null) { if (managementState.conType === null) {
form.setValue('conType', '0') form.setValue('conType', '0')
} else { } else {
form.setValue('conType', detailData.conType) form.setValue('conType', managementState.conType)
} }
// //
form.setValue('remarks', detailData.remarks) form.setValue('remarks', managementState.remarks)
}) })
} }
}, [detailData, session]) }, [managementState, session])
// //
const onChangeHonorificCode = (key) => { const onChangeHonorificCode = (key) => {
@ -1189,9 +1189,9 @@ export default function StuffDetail() {
return alert(getMessage('stuff.detail.save.valierror2')) return alert(getMessage('stuff.detail.save.valierror2'))
} }
let detail_sort = Object.keys(detailData) let detail_sort = Object.keys(managementState)
.sort() .sort()
.reduce((obj, key) => ((obj[key] = detailData[key]), obj), {}) .reduce((obj, key) => ((obj[key] = managementState[key]), obj), {})
let params_sort = Object.keys(params) let params_sort = Object.keys(params)
.sort() .sort()
.reduce((obj, key) => ((obj[key] = params[key]), obj), {}) .reduce((obj, key) => ((obj[key] = params[key]), obj), {})
@ -1313,7 +1313,7 @@ export default function StuffDetail() {
// //
const onDelete = () => { const onDelete = () => {
const specificationConfirmDate = detailData.specificationConfirmDate const specificationConfirmDate = managementState.specificationConfirmDate
if (specificationConfirmDate != null) { if (specificationConfirmDate != null) {
alert(getMessage('stuff.detail.delete.message1')) alert(getMessage('stuff.detail.delete.message1'))
} else { } else {
@ -1860,8 +1860,7 @@ export default function StuffDetail() {
<div className="flx-box"> <div className="flx-box">
<div className="product-input-wrap mr5"> <div className="product-input-wrap mr5">
<input type="text" className="product-input" readOnly value={form.watch('planReqNo') || ''} /> <input type="text" className="product-input" readOnly value={form.watch('planReqNo') || ''} />
{/* {detailData?.tempFlg === '1' && form.watch('planReqNo') ? ( */} {managementState?.tempFlg === '1' && form.watch('planReqNo') ? (
{detailData?.tempFlg === '1' && form.watch('planReqNo') ? (
<button <button
type="button" type="button"
className="product-delete" className="product-delete"
@ -1871,7 +1870,7 @@ export default function StuffDetail() {
></button> ></button>
) : null} ) : null}
</div> </div>
{detailData?.tempFlg === '1' ? ( {managementState?.tempFlg === '1' ? (
<> <>
<Button className="btn-origin grey" onPress={onSearchDesignRequestPopOpen}> <Button className="btn-origin grey" onPress={onSearchDesignRequestPopOpen}>
{getMessage('stuff.planReqPopup.title')} {getMessage('stuff.planReqPopup.title')}
@ -1977,8 +1976,8 @@ export default function StuffDetail() {
onChange={onSelectionChange} onChange={onSelectionChange}
getOptionLabel={(x) => x.saleStoreName} getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId} getOptionValue={(x) => x.saleStoreId}
isClearable={detailData.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false} isClearable={managementState.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false}
isDisabled={detailData.tempFlg === '0' ? true : session?.storeLvl !== '1' ? true : false} isDisabled={managementState.tempFlg === '0' ? true : session?.storeLvl !== '1' ? true : false}
value={saleStoreList.filter(function (option) { value={saleStoreList.filter(function (option) {
return option.saleStoreId === selOptions return option.saleStoreId === selOptions
})} })}
@ -2011,7 +2010,13 @@ export default function StuffDetail() {
getOptionValue={(x) => x.saleStoreId} getOptionValue={(x) => x.saleStoreId}
isClearable={false} isClearable={false}
isDisabled={ isDisabled={
detailData.tempFlg === '0' ? true : session?.storeLvl !== '1' ? true : session?.storeId !== 'T01' ? true : false managementState.tempFlg === '0'
? true
: session?.storeLvl !== '1'
? true
: session?.storeId !== 'T01'
? true
: false
} }
value={showSaleStoreList.filter(function (option) { value={showSaleStoreList.filter(function (option) {
return option.saleStoreId === selOptions return option.saleStoreId === selOptions
@ -2090,9 +2095,9 @@ export default function StuffDetail() {
getOptionLabel={(x) => x.saleStoreName} getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId} getOptionValue={(x) => x.saleStoreId}
isDisabled={ isDisabled={
detailData.tempFlg === '0' ? true : session?.storeLvl === '1' && form.watch('saleStoreId') != '' ? false : true managementState.tempFlg === '0' ? true : session?.storeLvl === '1' && form.watch('saleStoreId') != '' ? false : true
} }
isClearable={detailData.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false} isClearable={managementState.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false}
value={otherSaleStoreList.filter(function (option) { value={otherSaleStoreList.filter(function (option) {
return option.saleStoreId === otherSelOptions return option.saleStoreId === otherSelOptions
})} })}
@ -2345,8 +2350,7 @@ export default function StuffDetail() {
</table> </table>
</div> </div>
</div> </div>
{/* {detailData?.tempFlg === '0' ? ( */} {managementState?.tempFlg === '0' ? (
{detailData?.tempFlg === '0' ? (
<> <>
{/* 진짜R 플랜시작 */} {/* 진짜R 플랜시작 */}
<div className="table-box-title-wrap"> <div className="table-box-title-wrap">
@ -2355,7 +2359,7 @@ export default function StuffDetail() {
<ul className="info-wrap"> <ul className="info-wrap">
<li> <li>
{getMessage('stuff.detail.planList.cnt')} {getMessage('stuff.detail.planList.cnt')}
<span className="red"> {detailData.planList?.length}</span> <span className="red"> {managementState.planList?.length}</span>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,40 +1,21 @@
'use client' 'use client'
import React, { useState, useEffect } from 'react' import { useContext } from 'react'
import { useAxios } from '@/hooks/useAxios'
import { useRouter, useSearchParams } from 'next/navigation'
import { globalLocaleStore } from '@/store/localeAtom'
import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ManagementContext } from '@/app/management/ManagementProvider'
export default function StuffHeader() { export default function StuffHeader() {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const router = useRouter()
const searchParams = useSearchParams()
const objectNo = searchParams.get('objectNo') //url set
const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get } = useAxios(globalLocaleState)
const [headerData, setHeaderData] = useState({})
useEffect(() => { const { managementState } = useContext(ManagementContext)
get({ url: `/api/object/${objectNo}/detail` }).then((res) => {
if (res != null && res != '') {
setHeaderData(res)
} else {
alert(getMessage('stuff.detail.header.message1'))
router.push('/management/stuff')
}
})
}, [objectNo])
// //
const copyObjectNo = async (objectNo) => { const copyObjectNo = async (objectNo) => {
await navigator.clipboard.writeText(objectNo) await navigator.clipboard.writeText(objectNo)
alert(getMessage('stuff.detail.header.message2')) alert(getMessage('stuff.detail.header.successCopy'))
try { try {
} catch (error) { } catch (error) {
alert(getMessage('stuff.detail.header.message3')) alert(getMessage('stuff.detail.header.failCopy'))
} }
} }
@ -43,31 +24,31 @@ export default function StuffHeader() {
<div className="sub-table-box"> <div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.objectNo')}</div> <div className="info-title">{getMessage('stuff.detail.header.objectNo')}</div>
<div className="info-inner"> <div className="info-inner">
{headerData.objectNo}{' '} {managementState?.objectNo}{' '}
<button <button
className="copy-ico" className="copy-ico"
onClick={() => { onClick={() => {
copyObjectNo(headerData.objectNo) copyObjectNo(managementState?.objectNo)
}} }}
></button> ></button>
</div> </div>
</div> </div>
<div className="sub-table-box"> <div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.specificationConfirmDate')}</div> <div className="info-title">{getMessage('stuff.detail.header.specificationConfirmDate')}</div>
<div className="info-inner">{headerData.specificationConfirmDate}</div> <div className="info-inner">{managementState?.specificationConfirmDate}</div>
</div> </div>
<div className="sub-table-box"> <div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.lastEditDatetime')}</div> <div className="info-title">{getMessage('stuff.detail.header.lastEditDatetime')}</div>
<div className="info-inner"> <div className="info-inner">
{headerData?.lastEditDatetime ? `${dayjs(headerData.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')}` : ''}{' '} {managementState?.lastEditDatetime ? `${dayjs(managementState.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')}` : ''}{' '}
{headerData?.lastEditUserName ? `(${headerData.lastEditUserName})` : null} {managementState?.lastEditUserName ? `(${managementState.lastEditUserName})` : null}
</div> </div>
</div> </div>
<div className="sub-table-box"> <div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.createDatetime')}</div> <div className="info-title">{getMessage('stuff.detail.header.createDatetime')}</div>
<div className="info-inner"> <div className="info-inner">
{headerData?.createDatetime ? `${dayjs(headerData.lastEditDatetime).format('YYYY.MM.DD')}` : ''}{' '} {managementState?.createDatetime ? `${dayjs(managementState.lastEditDatetime).format('YYYY.MM.DD')}` : ''}{' '}
{headerData?.createUserName ? `(${headerData.createUserName})` : null} {managementState?.createUserName ? `(${managementState.createUserName})` : null}
</div> </div>
</div> </div>
</div> </div>

View File

@ -223,10 +223,6 @@ export default function StuffSearchCondition() {
} }
}) })
} }
// setStuffSearch({
// ...stuffSearch,
// code: 'S',
// })
} else { } else {
if (session?.storeLvl === '1') { if (session?.storeLvl === '1') {
allList = res allList = res

View File

@ -29,8 +29,8 @@ const defaultEstimateData = {
} }
// Helper functions // Helper functions
const updateItemInList = (itemList, itemId, updates) => { const updateItemInList = (itemList, dispOrder, updates) => {
return itemList.map((item) => (item.itemId === itemId ? { ...item, ...updates } : item)) return itemList.map((item) => (item.dispOrder === dispOrder ? { ...item, ...updates } : item))
} }
export const useEstimateController = (planNo) => { export const useEstimateController = (planNo) => {
@ -69,9 +69,9 @@ export const useEstimateController = (planNo) => {
} }
} }
const updateItem = (itemId, updates) => { const updateItem = (dispOrder, updates) => {
setState({ setState({
itemList: updateItemInList(state.itemList, itemId, updates), itemList: updateItemInList(state.itemList, dispOrder, updates),
}) })
} }
@ -85,14 +85,16 @@ export const useEstimateController = (planNo) => {
planNo: planNo, planNo: planNo,
dispOrder: newItemDispOrder.toString(), dispOrder: newItemDispOrder.toString(),
itemId: '', //제품번호 itemId: '', //제품번호
itemNo: '', //형명 itemNo: '',
itemName: '', itemName: '', //형명
amount: '', //수량 amount: '', //수량
unitPrice: '0', unitPrice: '0',
unit: '', //단위 unit: '', //단위
salePrice: '0', //단가 salePrice: '0', //단가
saleTotPrice: '0', //금액(부가세별도) saleTotPrice: '0', //금액(부가세별도)
itemChangeFlg: '1', //추가시 체인지플래그 1로 itemChangeFlg: '1', //추가시 체인지플래그 1로
partAdd: '1', //NEW 체인지 플래그
delFlg: '0', //삭제 플래그 0 삭제하면 1
}, },
], ],
}) })
@ -102,34 +104,61 @@ export const useEstimateController = (planNo) => {
setEstimateData({ ...state, userId: session.userId, sapSalesStoreCd: session.custCd }) setEstimateData({ ...state, userId: session.userId, sapSalesStoreCd: session.custCd })
}, [state]) }, [state])
// 첨부파일 다운로드
const handleEstimateFileDownload = async (originFile) => {
const options = { responseType: 'blob' }
await promisePost({ url: `/api/file/fileDownload`, data: originFile, option: options })
.then((resultData) => {
if (resultData) {
const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' })
const fileUrl = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = fileUrl
link.download = originFile.faileName
document.body.appendChild(link)
link.click()
link.remove()
window.URL.revokeObjectURL(fileUrl)
}
})
.catch((error) => {
console.log('::FileDownLoad Error::', error)
alert('File does not exist.')
})
}
//견적서 저장 //견적서 저장
const handleEstimateSubmit = async () => { const handleEstimateSubmit = async () => {
//0. 필수체크 //0. 필수체크
let flag = true let flag = true
console.log('::담긴 estimateData:::', estimateData) console.log('::담긴 estimateData:::', estimateData)
// console.log('첨부파일:::::', estimateData.fileList)
//첨부파일을 첨부안했는데
//아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼
if (estimateData.itemList.length > 1) { if (estimateData.fileList.length < 1) {
estimateData.itemList.map((row) => { if (estimateData.itemList.length > 1) {
if (row.fileUploadFlg === '1') { estimateData.itemList.map((row) => {
if (estimateData.fileFlg === '0') { if (row.fileUploadFlg === '1') {
alert(getMessage('estimate.detail.save.requiredMsg')) if (estimateData.fileFlg === '0') {
flag = false alert(getMessage('estimate.detail.save.requiredMsg'))
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)
formData.append('category', '10') formData.append('category', '10')
formData.append('userId', estimateData.userId) formData.append('userId', estimateData.userId)
// for (const value of formData.values()) {
// console.log('formData::', value)
// }
await post({ url: '/api/file/fileUpload', data: formData }) await post({ url: '/api/file/fileUpload', data: formData })
@ -162,5 +191,6 @@ export const useEstimateController = (planNo) => {
addItem, addItem,
handleEstimateSubmit, handleEstimateSubmit,
fetchSetting, fetchSetting,
handleEstimateFileDownload,
} }
} }

View File

@ -616,9 +616,9 @@
"stuff.planReqPopup.title": "設計依頼のインポート", "stuff.planReqPopup.title": "設計依頼のインポート",
"stuff.temp.subTitle": "商品情報", "stuff.temp.subTitle": "商品情報",
"stuff.temp.subTitle2": "作図", "stuff.temp.subTitle2": "作図",
"stuff.detail.header.message1": "存在しないものです。", "stuff.detail.header.notExistObjectNo": "存在しないものです。",
"stuff.detail.header.message2": "商品番号がコピーされました。", "stuff.detail.header.successCopy": "商品番号がコピーされました。",
"stuff.detail.header.message3": "存在しないものです。", "stuff.detail.header.failCopy": "存在しないものです。",
"stuff.detail.header.objectNo": "商品番号のコピーに失敗しました。", "stuff.detail.header.objectNo": "商品番号のコピーに失敗しました。",
"stuff.detail.header.specificationConfirmDate": "仕様拡張日", "stuff.detail.header.specificationConfirmDate": "仕様拡張日",
"stuff.detail.header.lastEditDatetime": "更新日時", "stuff.detail.header.lastEditDatetime": "更新日時",

View File

@ -626,9 +626,9 @@
"stuff.planReqPopup.title": "설계의뢰 불러오기", "stuff.planReqPopup.title": "설계의뢰 불러오기",
"stuff.temp.subTitle": "물건정보", "stuff.temp.subTitle": "물건정보",
"stuff.temp.subTitle2": "도면작성", "stuff.temp.subTitle2": "도면작성",
"stuff.detail.header.message1": "존재하지 않는 물건입니다.", "stuff.detail.header.notExistObjectNo": "존재하지 않는 물건입니다.",
"stuff.detail.header.message2": "물건번호가 복사되었습니다.", "stuff.detail.header.successCopy": "물건번호가 복사되었습니다.",
"stuff.detail.header.message3": "물건번호 복사에 실패했습니다.", "stuff.detail.header.failCopy": "물건번호 복사에 실패했습니다.",
"stuff.detail.header.objectNo": "물건번호", "stuff.detail.header.objectNo": "물건번호",
"stuff.detail.header.specificationConfirmDate": "사양확장일", "stuff.detail.header.specificationConfirmDate": "사양확장일",
"stuff.detail.header.lastEditDatetime": "갱신일시", "stuff.detail.header.lastEditDatetime": "갱신일시",