Merge branch 'dev' into dev-yj
This commit is contained in:
commit
40787942f9
@ -20,6 +20,7 @@ import ProductFeaturesPop from './popup/ProductFeaturesPop'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
export default function Estimate({ params }) {
|
export default function Estimate({ params }) {
|
||||||
|
const fixedKey = 'itemKey'
|
||||||
const [itemChangeYn, setItemChangeYn] = useState(false)
|
const [itemChangeYn, setItemChangeYn] = useState(false)
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const [objectNo, setObjectNo] = useState('') //물건번호
|
const [objectNo, setObjectNo] = useState('') //물건번호
|
||||||
@ -28,6 +29,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 +49,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 +183,7 @@ export default function Estimate({ params }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//가격표시 option 최초세팅
|
//가격표시 option 목록 최초세팅 && 주문분류 변경시
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.estimateType !== '') {
|
if (state.estimateType !== '') {
|
||||||
const param = {
|
const param = {
|
||||||
@ -200,23 +201,35 @@ export default function Estimate({ params }) {
|
|||||||
}
|
}
|
||||||
}, [state?.estimateType])
|
}, [state?.estimateType])
|
||||||
|
|
||||||
//가격표시 option 변경시
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (tempPriceCd !== '') {
|
if (state?.priceCd) {
|
||||||
const param = {
|
setShowPriceCd(state.priceCd)
|
||||||
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])
|
}, [state?.priceCd])
|
||||||
|
|
||||||
|
//가격 표시 option 변경 이벤트
|
||||||
|
const onChangeStorePriceList = (priceCd) => {
|
||||||
|
const param = {
|
||||||
|
saleStoreId: session.storeId,
|
||||||
|
sapSalesStoreCd: session.custCd,
|
||||||
|
docTpCd: priceCd,
|
||||||
|
}
|
||||||
|
|
||||||
|
//가격표시 바꾸만헀을때는 tempPriceCd에 바꾼값 관리 불필요?
|
||||||
|
//프라이싱 했을때 priceCd setState
|
||||||
|
//화면에 보여지는 값은 showPriceCd로 관리
|
||||||
|
setShowPriceCd(priceCd)
|
||||||
|
//setState({
|
||||||
|
// tempPriceCd: priceCd,
|
||||||
|
//})
|
||||||
|
|
||||||
|
const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}`
|
||||||
|
get({ url: apiUrl }).then((res) => {
|
||||||
|
if (isNotEmptyArray(res?.data)) {
|
||||||
|
setStorePriceList(res.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//Pricing 버튼
|
//Pricing 버튼
|
||||||
const handlePricing = async (priceCd) => {
|
const handlePricing = async (priceCd) => {
|
||||||
@ -224,24 +237,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
|
||||||
|
//기존itemList랑 프라이싱결과랑 비교해서 단가만 업뎃 서로 갯수가 안맞을 수 있음 없는 itemId면 unitPrice 0으로
|
||||||
|
//itemId로 비교해서 단가정보만 업데이트
|
||||||
if (data.result.code === 200) {
|
if (data.result.code === 200) {
|
||||||
if (isNotEmptyArray(data.data2)) {
|
if (isNotEmptyArray(data.data2)) {
|
||||||
//아이템쪽 다 새로고침............
|
state.itemList.map((item) => {
|
||||||
//성공후..
|
let checkYn = false
|
||||||
//기존itemList랑 프라이싱결과랑 비교해서 단가만 업뎃 서로 갯수가 안맞을 수 있음 없는 itemId면 unitPrice 0으로
|
data.data2.map((item2) => {
|
||||||
//itemId로 비교해서 단가정보만 업데이트
|
if (item2.itemId === item.itemId) {
|
||||||
setState({
|
updateList.push({ ...item, unitPrice: item2.unitPrice })
|
||||||
priceCd: session.storeLvl === '1' ? tempPriceCd : priceCd,
|
checkYn = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!checkYn) {
|
||||||
|
updateList.push({ ...item, unitPrice: '0' })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setState({
|
||||||
|
priceCd: priceCd,
|
||||||
|
itemList: updateList,
|
||||||
|
})
|
||||||
|
|
||||||
|
setItemChangeYn(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,8 +305,71 @@ export default function Estimate({ params }) {
|
|||||||
setSelection(newSelection)
|
setSelection(newSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 수량 변경
|
||||||
|
const onChangeAmount = (value, dispOrder, index) => {
|
||||||
|
//itemChangeFlg = 1, partAdd = 0 셋팅
|
||||||
|
let amount = value
|
||||||
|
amount = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
||||||
|
if (isNaN(amount)) {
|
||||||
|
amount = 0
|
||||||
|
} else {
|
||||||
|
amount = amount.toLocaleString()
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateList = []
|
||||||
|
let updates = {}
|
||||||
|
updates.amount = amount
|
||||||
|
updates.itemChangeFlg = '1'
|
||||||
|
updates.partAdd = '0'
|
||||||
|
updates.saleTotPrice = (Number(amount.replaceAll(',', '')) * state.itemList[index].salePrice.replaceAll(',', '')).toLocaleString()
|
||||||
|
|
||||||
|
updateList = state.itemList.map((item) => {
|
||||||
|
if (item.dispOrder === dispOrder) {
|
||||||
|
return { ...item, ...updates }
|
||||||
|
} else {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setState({
|
||||||
|
itemList: updateList,
|
||||||
|
})
|
||||||
|
|
||||||
|
setItemChangeYn(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 단가 변경
|
||||||
|
const onChangeSalePrice = (value, dispOrder, index) => {
|
||||||
|
//itemChangeFlg, partAdd 받아온 그대로
|
||||||
|
let salePrice
|
||||||
|
salePrice = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
||||||
|
if (isNaN(salePrice)) {
|
||||||
|
salePrice = 0
|
||||||
|
} else {
|
||||||
|
salePrice = salePrice.toLocaleString()
|
||||||
|
}
|
||||||
|
let updateList = []
|
||||||
|
let updates = {}
|
||||||
|
updates.salePrice = salePrice
|
||||||
|
updates.saleTotPrice = (Number(salePrice.replaceAll(',', '')) * state.itemList[index].amount.replaceAll(',', '')).toLocaleString()
|
||||||
|
|
||||||
|
updateList = state.itemList.map((item) => {
|
||||||
|
if (item.dispOrder === dispOrder) {
|
||||||
|
return { ...item, ...updates }
|
||||||
|
} else {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setState({
|
||||||
|
itemList: updateList,
|
||||||
|
})
|
||||||
|
|
||||||
|
setItemChangeYn(true)
|
||||||
|
}
|
||||||
|
|
||||||
// 아이템 자동완성 검색시 아이템 변경
|
// 아이템 자동완성 검색시 아이템 변경
|
||||||
const onChangeDisplayItem = (itemId, dispOrder) => {
|
const onChangeDisplayItem = (itemId, dispOrder, index) => {
|
||||||
const param = {
|
const param = {
|
||||||
itemId: itemId,
|
itemId: itemId,
|
||||||
}
|
}
|
||||||
@ -290,17 +397,37 @@ export default function Estimate({ params }) {
|
|||||||
updates.specialNoteCd = res.spnAttrCds
|
updates.specialNoteCd = res.spnAttrCds
|
||||||
updates.itemGroup = res.itemGroup
|
updates.itemGroup = res.itemGroup
|
||||||
updates.delFlg = '0' // 삭제플래그 0
|
updates.delFlg = '0' // 삭제플래그 0
|
||||||
|
updates.saleTotPrice = res.salePrice * state.itemList[index].amount
|
||||||
|
//104671
|
||||||
|
let bomList = res.itemBomList
|
||||||
|
|
||||||
updateList = state.itemList.map((item) => {
|
updateList = state.itemList.map((item) => {
|
||||||
if (item.dispOrder === dispOrder) {
|
if (item.dispOrder === dispOrder) {
|
||||||
return { ...item, ...updates }
|
return { ...item, ...updates }
|
||||||
|
} else if (item.paDispOrder === dispOrder) {
|
||||||
|
return { ...item, delFlg: '1' }
|
||||||
} else {
|
} else {
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setState({
|
//paDispOrder
|
||||||
itemList: updateList,
|
if (bomList) {
|
||||||
})
|
bomList.map((bomItem, index) => {
|
||||||
|
let newItemDispOrder = Math.max(...state.itemList.map((item) => item.dispOrder))
|
||||||
|
bomItem.dispOrder = index + 1 + newItemDispOrder
|
||||||
|
bomItem.delFlg = '0'
|
||||||
|
bomItem.objectNo = objectNo
|
||||||
|
bomItem.planNo = planNo
|
||||||
|
})
|
||||||
|
|
||||||
|
setState({
|
||||||
|
itemList: [...updateList, ...bomList],
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setState({
|
||||||
|
itemList: updateList,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
setItemChangeYn(true)
|
setItemChangeYn(true)
|
||||||
})
|
})
|
||||||
@ -315,17 +442,31 @@ export default function Estimate({ params }) {
|
|||||||
if (row2 === row.dispOrder) {
|
if (row2 === row.dispOrder) {
|
||||||
delList.push({ ...row })
|
delList.push({ ...row })
|
||||||
}
|
}
|
||||||
|
if (row2 === row.paDispOrder) {
|
||||||
|
delList.push({ ...row })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
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,12 +477,30 @@ export default function Estimate({ params }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (itemChangeYn) {
|
if (itemChangeYn) {
|
||||||
console.log('아이템에 뭔가 변화가 일어났어', itemChangeYn)
|
// console.log('아이템 상태 가져오기::::::::::', state.itemList)
|
||||||
console.log('아이템상태가져오기::::::::::', state.itemList)
|
// console.log('토탈쪽 셋팅해주기위한 함수::::::', itemList)
|
||||||
}
|
//delFlg 0인거 중에..
|
||||||
|
//수량(PCS) : totAmount
|
||||||
|
//용량( Kw) : totVolKw
|
||||||
|
//공급가액 : supplyPrice
|
||||||
|
//부가세(10%) : vatPrice
|
||||||
|
//총액 :totPrice
|
||||||
|
|
||||||
//다시 false로 돌리기 여기서할지 가격정보 변경하는거 끝나고할지..
|
let totAmount = 0
|
||||||
setItemChangeYn(false)
|
let amount = 0
|
||||||
|
state.itemList.map((item) => {
|
||||||
|
if (item.delFlg === '0') {
|
||||||
|
amount = item.amount.replace(/[^0-9]/g, '').replaceAll(',', '')
|
||||||
|
totAmount += Number(amount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setState({
|
||||||
|
totAmount: totAmount,
|
||||||
|
})
|
||||||
|
|
||||||
|
setItemChangeYn(false)
|
||||||
|
}
|
||||||
}, [itemChangeYn])
|
}, [itemChangeYn])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -534,10 +693,10 @@ export default function Estimate({ params }) {
|
|||||||
<>
|
<>
|
||||||
<div className={`form-flex-wrap ${style}`} key={uuidv4()}>
|
<div className={`form-flex-wrap ${style}`} key={uuidv4()}>
|
||||||
<div className="input-wrap mr5" style={{ width: '610px' }} key={`roof${index}`}>
|
<div className="input-wrap mr5" style={{ width: '610px' }} key={`roof${index}`}>
|
||||||
<input type="text" className="input-light" defaultValue={roofList} readOnly />
|
<input type="text" className="input-light" value={roofList} readOnly />
|
||||||
</div>
|
</div>
|
||||||
<div className="input-wrap" style={{ width: '200px' }}>
|
<div className="input-wrap" style={{ width: '200px' }}>
|
||||||
<input type="text" className="input-light" defaultValue={constructSpecificationMulti[index]} readOnly />
|
<input type="text" className="input-light" value={constructSpecificationMulti[index]} readOnly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -778,8 +937,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 +950,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 +979,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>
|
||||||
@ -863,107 +1032,123 @@ export default function Estimate({ params }) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{state?.itemList.length > 0 &&
|
{state?.itemList.length > 0 &&
|
||||||
state.itemList.map((item, index) => {
|
state.itemList.map((item, index) => {
|
||||||
return (
|
if (item.delFlg === '0') {
|
||||||
<tr key={uuidv4()}>
|
return (
|
||||||
<td className="al-c">
|
<>
|
||||||
<div className="d-check-box light no-text">
|
<tr key={fixedKey}>
|
||||||
<input
|
<td className="al-c">
|
||||||
type="checkbox"
|
<div className="d-check-box light no-text">
|
||||||
id={item?.dispOrder}
|
<input
|
||||||
onChange={() => onChangeSelect(item.dispOrder)}
|
type="checkbox"
|
||||||
checked={selection.has(item.dispOrder) ? true : false}
|
id={item?.dispOrder}
|
||||||
/>
|
disabled={item?.paDispOrder ? true : false}
|
||||||
<label htmlFor={item?.dispOrder}></label>
|
onChange={() => onChangeSelect(item.dispOrder)}
|
||||||
</div>
|
checked={selection.has(item.dispOrder) ? true : false}
|
||||||
</td>
|
/>
|
||||||
<td className="al-r">{item?.dispOrder * 100}</td>
|
<label htmlFor={item?.dispOrder}></label>
|
||||||
<td>
|
|
||||||
<div className="form-flex-wrap">
|
|
||||||
<div className="select-wrap mr5">
|
|
||||||
<Select
|
|
||||||
id="long-value-select1"
|
|
||||||
instanceId="long-value-select1"
|
|
||||||
className="react-select-custom"
|
|
||||||
classNamePrefix="custom"
|
|
||||||
placeholder="Select"
|
|
||||||
options={displayItemList}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (isObjectNotEmpty(e)) {
|
|
||||||
onChangeDisplayItem(e.itemId, item.dispOrder)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
getOptionLabel={(x) => x.itemName}
|
|
||||||
getOptionValue={(x) => x.itemId}
|
|
||||||
isClearable={true}
|
|
||||||
isDisabled={false}
|
|
||||||
value={displayItemList.filter(function (option) {
|
|
||||||
return option.itemId === item.itemId
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* {item?.partAdd === '1' && ( */}
|
|
||||||
{item?.itemChangeFlg === '1' && (
|
|
||||||
<div className="btn-area">
|
|
||||||
<span className="tb_ico change_check"></span>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</td>
|
||||||
</div>
|
<td className="al-r">{item?.dispOrder}</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
<div className="form-flex-wrap">
|
||||||
<div className="form-flex-wrap">
|
<div className="select-wrap mr5">
|
||||||
<div className="name">{item?.itemNo}</div>
|
<Select
|
||||||
<div className="icon-wrap">
|
id="long-value-select1"
|
||||||
{item?.fileUploadFlg === '1' && <span className="tb_ico file_check"></span>}
|
instanceId="long-value-select1"
|
||||||
{item?.specialNoteCd && (
|
className="react-select-custom"
|
||||||
<button
|
classNamePrefix="custom"
|
||||||
type="button"
|
placeholder="Select"
|
||||||
className="grid-tip"
|
options={displayItemList}
|
||||||
onClick={() => {
|
onChange={(e) => {
|
||||||
setProductFeaturesPopupOpen(true)
|
if (isObjectNotEmpty(e)) {
|
||||||
setShowProductFeatureData(item?.specialNoteCd)
|
onChangeDisplayItem(e.itemId, item.dispOrder, index)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
getOptionLabel={(x) => x.itemName}
|
||||||
|
getOptionValue={(x) => x.itemId}
|
||||||
|
isClearable={false}
|
||||||
|
isDisabled={item?.paDispOrder ? true : false}
|
||||||
|
value={displayItemList.filter(function (option) {
|
||||||
|
return option.itemId === item.itemId
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</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={() => {
|
||||||
|
setProductFeaturesPopupOpen(true)
|
||||||
|
setShowProductFeatureData(item?.specialNoteCd)
|
||||||
|
}}
|
||||||
|
></button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="input-wrap" style={{ width: '100%' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-light al-r"
|
||||||
|
value={item?.amount}
|
||||||
|
disabled={item.itemId === '' ? true : item?.paDispOrder ? true : false}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChangeAmount(e.target.value, item.dispOrder, index)
|
||||||
}}
|
}}
|
||||||
></button>
|
/>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</div>
|
<td>{item.unit}</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
<div className="form-flex-wrap">
|
||||||
<div className="input-wrap" style={{ width: '100%' }}>
|
<div className="input-wrap mr5">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-light al-r"
|
className="input-light al-r"
|
||||||
defaultValue={convertNumberToPriceDecimal(item?.amount)}
|
value={item?.salePrice}
|
||||||
onChange={(e) => {
|
disabled={
|
||||||
//onChangeDisplayItem참고
|
state?.estimateType === 'YJSS'
|
||||||
//itemChangeFlg = 1, partAdd = 0 셋팅
|
? item?.paDispOrder
|
||||||
console.log('수량변경::::::::', e.target.value)
|
? true
|
||||||
}}
|
: item.pkgMaterialFlg === '1'
|
||||||
/>
|
? false
|
||||||
</div>
|
: true
|
||||||
</td>
|
: item.itemId === ''
|
||||||
<td>{item.unit}</td>
|
? true
|
||||||
<td>
|
: item?.paDispOrder
|
||||||
<div className="form-flex-wrap">
|
? true
|
||||||
<div className="input-wrap mr5">
|
: false
|
||||||
<input
|
}
|
||||||
type="text"
|
onChange={(e) => {
|
||||||
className="input-light al-r"
|
onChangeSalePrice(e.target.value, item.dispOrder, index)
|
||||||
value={convertNumberToPriceDecimal(item?.salePrice)}
|
}}
|
||||||
onChange={(e) => {
|
/>
|
||||||
//onChangeDisplayItem참고
|
</div>
|
||||||
//itemChangeFlg, partAdd 받아온 그대로
|
{/* <div className="btn-area">
|
||||||
console.log('단가변경:::::::', e.target.value)
|
<span className="tb_ico open_check">OPEN아이콘 처리</span>
|
||||||
}}
|
</div> */}
|
||||||
/>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
{/* <div className="btn-area">
|
<td className="al-r">{item?.saleTotPrice}</td>
|
||||||
<span className="tb_ico open_check">OPEN아이콘 처리</span>
|
</tr>
|
||||||
</div> */}
|
</>
|
||||||
</div>
|
)
|
||||||
</td>
|
} else {
|
||||||
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice)}</td>
|
return null
|
||||||
</tr>
|
}
|
||||||
)
|
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -6,36 +6,74 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
|
|
||||||
export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
||||||
// console.log('플랜번호::::::::::::', planNo)
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { promiseGet } = useAxios()
|
const { promisePost } = useAxios()
|
||||||
|
|
||||||
|
//EXCEL, PDF 구분
|
||||||
|
const [schDownload, setSchDownload] = useState('EXCEL')
|
||||||
//다운로드 파일 EXCEL
|
//다운로드 파일 EXCEL
|
||||||
const [schUnitPriceFlg, setSchUnitPriceFlg] = useState('0')
|
const [schUnitPriceFlg, setSchUnitPriceFlg] = useState('0')
|
||||||
|
|
||||||
//견적제출서 표시명
|
//견적제출서 표시명
|
||||||
const [schDisplayFlg, setSchSchDisplayFlg] = useState('0')
|
const [schDisplayFlg, setSchSchDisplayFlg] = useState('0')
|
||||||
//가대 중량표 포함
|
//가대 중량표 포함(포함:1 미포함 : 0)
|
||||||
const [schWeightFlg, setSchWeightFlg] = useState('0')
|
const [schWeightFlg, setSchWeightFlg] = useState('1')
|
||||||
//도면/시뮬레이션 파일 포함
|
//도면/시뮬레이션 파일 포함(포함:1 미포함 : 0)
|
||||||
const [schDrawingFlg, setSchDrawingFlg] = useState('0')
|
const [schDrawingFlg, setSchDrawingFlg] = useState('1')
|
||||||
|
|
||||||
// recoil 물건번호
|
// recoil 물건번호
|
||||||
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
||||||
|
|
||||||
//문서 다운로드
|
//문서 다운로드
|
||||||
const handleFileDown = async () => {
|
const handleFileDown = async () => {
|
||||||
// console.log('물건번호:::', objectRecoil.floorPlanObjectNo)
|
|
||||||
// console.log('planNo::', planNo)
|
|
||||||
// 고른 옵션값들
|
|
||||||
//0 : 견적가 Excel 1 : 정가용Excel 2: 견적가 PDF 3 :정가용PDF
|
|
||||||
// console.log(schUnitPriceFlg)
|
|
||||||
// console.log(schDisplayFlg)
|
|
||||||
// console.log(schWeightFlg)
|
|
||||||
// console.log(schDrawingFlg)
|
|
||||||
const url = '/api/estimate/excel-download'
|
const url = '/api/estimate/excel-download'
|
||||||
const params = {}
|
let sendUnitPriceFlg
|
||||||
|
if (schUnitPriceFlg === '0') {
|
||||||
|
sendUnitPriceFlg = '0'
|
||||||
|
} else if (schUnitPriceFlg === '1') {
|
||||||
|
sendUnitPriceFlg = '1'
|
||||||
|
} else if (schUnitPriceFlg === '2') {
|
||||||
|
sendUnitPriceFlg = '0'
|
||||||
|
} else {
|
||||||
|
sendUnitPriceFlg = '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
objectNo: objectRecoil.floorPlanObjectNo,
|
||||||
|
planNo: planNo,
|
||||||
|
schDownload: schDownload,
|
||||||
|
schUnitPriceFlg: sendUnitPriceFlg,
|
||||||
|
schDisplayFlg: schDisplayFlg,
|
||||||
|
schWeightFlg: schWeightFlg,
|
||||||
|
schDrawingFlg: schDrawingFlg,
|
||||||
|
}
|
||||||
const options = { responseType: 'blob' }
|
const options = { responseType: 'blob' }
|
||||||
|
await promisePost({ url: url, data: params, option: options })
|
||||||
|
.then((resultData) => {
|
||||||
|
if (resultData) {
|
||||||
|
let fileName = 'unknow'
|
||||||
|
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
|
||||||
|
|
||||||
|
//서버에서 내려오는 파일명
|
||||||
|
const contentDisposition = resultData.headers['content-disposition']
|
||||||
|
if (contentDisposition) {
|
||||||
|
fileName = contentDisposition.split('filename=')[1].replace(/['"]/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
link.download = fileName
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
link.remove()
|
||||||
|
window.URL.revokeObjectURL(fileUrl)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log('::FileDownLoad Error::', error)
|
||||||
|
alert('File does not exist.')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -74,28 +112,30 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
id="schUnitPriceFlg0"
|
id="schUnitPriceExcelFlg0"
|
||||||
name="schUnitPriceFlg"
|
name="schUnitPriceFlg"
|
||||||
value={'0'}
|
value={'0'}
|
||||||
checked={schUnitPriceFlg === '0'}
|
checked={schUnitPriceFlg === '0'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
setSchDownload('EXCEL')
|
||||||
setSchUnitPriceFlg(e.target.value)
|
setSchUnitPriceFlg(e.target.value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="schUnitPriceFlg0">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg0')}</label>
|
<label htmlFor="schUnitPriceExcelFlg0">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.excelFlg0')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
id="schUnitPriceFlg1"
|
id="schUnitPriceExcelFlg1"
|
||||||
name="schUnitPriceFlg"
|
name="schUnitPriceFlg"
|
||||||
value={'1'}
|
value={'1'}
|
||||||
checked={schUnitPriceFlg === '1'}
|
checked={schUnitPriceFlg === '1'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
setSchDownload('EXCEL')
|
||||||
setSchUnitPriceFlg(e.target.value)
|
setSchUnitPriceFlg(e.target.value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="schUnitPriceFlg1">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg1')}</label>
|
<label htmlFor="schUnitPriceExcelFlg1">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.excelFlg1')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
<input
|
<input
|
||||||
@ -105,10 +145,11 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
value={'2'}
|
value={'2'}
|
||||||
checked={schUnitPriceFlg === '2'}
|
checked={schUnitPriceFlg === '2'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
setSchDownload('PDF')
|
||||||
setSchUnitPriceFlg(e.target.value)
|
setSchUnitPriceFlg(e.target.value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="schUnitPricePdfFlg0">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg2')}</label>
|
<label htmlFor="schUnitPricePdfFlg0">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.pdfFlg0')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio light ">
|
<div className="d-check-radio light ">
|
||||||
<input
|
<input
|
||||||
@ -118,10 +159,11 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
value={'3'}
|
value={'3'}
|
||||||
checked={schUnitPriceFlg === '3'}
|
checked={schUnitPriceFlg === '3'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
setSchDownload('PDF')
|
||||||
setSchUnitPriceFlg(e.target.value)
|
setSchUnitPriceFlg(e.target.value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="schUnitPricePdfFlg1">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg3')}</label>
|
<label htmlFor="schUnitPricePdfFlg1">{getMessage('estimate.detail.docPopup.schUnitPriceFlg.pdfFlg1')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -168,19 +210,6 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className="form-flex-wrap">
|
<div className="form-flex-wrap">
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="schWeightFlg"
|
|
||||||
id="schWeightFlg0"
|
|
||||||
value={'0'}
|
|
||||||
checked={schWeightFlg === '0'}
|
|
||||||
onChange={(e) => {
|
|
||||||
setSchWeightFlg(e.target.value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<label htmlFor="schWeightFlg0">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg0')}</label>
|
|
||||||
</div>
|
|
||||||
<div className="d-check-radio light">
|
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="schWeightFlg"
|
name="schWeightFlg"
|
||||||
@ -193,6 +222,19 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
/>
|
/>
|
||||||
<label htmlFor="schWeightFlg1">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg1')}</label>
|
<label htmlFor="schWeightFlg1">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg1')}</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="d-check-radio light">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="schWeightFlg"
|
||||||
|
id="schWeightFlg0"
|
||||||
|
value={'0'}
|
||||||
|
checked={schWeightFlg === '0'}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSchWeightFlg(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label htmlFor="schWeightFlg0">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg0')}</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -201,6 +243,19 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className="form-flex-wrap">
|
<div className="form-flex-wrap">
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="schDrawingFlg"
|
||||||
|
id="schDrawingFlg1"
|
||||||
|
value={'1'}
|
||||||
|
checked={schDrawingFlg === '1'}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSchDrawingFlg(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label htmlFor="schDrawingFlg1">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1')}</label>
|
||||||
|
</div>
|
||||||
|
<div className="d-check-radio light">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="schDrawingFlg"
|
name="schDrawingFlg"
|
||||||
@ -213,19 +268,6 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
/>
|
/>
|
||||||
<label htmlFor="schDrawingFlg0">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0')}</label>
|
<label htmlFor="schDrawingFlg0">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio light">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="schDrawingFlg"
|
|
||||||
id="schDrawingFlg01"
|
|
||||||
value={'1'}
|
|
||||||
checked={schDrawingFlg === '1'}
|
|
||||||
onChange={(e) => {
|
|
||||||
setSchDrawingFlg(e.target.value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<label htmlFor="schDrawingFlg01">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1')}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -184,7 +184,7 @@ export default function CanvasMenu(props) {
|
|||||||
}, [type, globalLocale])
|
}, [type, globalLocale])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (['2', '3'].includes(canvasSetting?.roofSizeSet?.toString())) {
|
if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet)) {
|
||||||
setMenuNumber(3)
|
setMenuNumber(3)
|
||||||
setType('surface')
|
setType('surface')
|
||||||
setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING)
|
setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING)
|
||||||
@ -195,8 +195,12 @@ export default function CanvasMenu(props) {
|
|||||||
}
|
}
|
||||||
}, [canvasSetting])
|
}, [canvasSetting])
|
||||||
|
|
||||||
|
const checkMenuState = (menu) => {
|
||||||
|
return ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`canvas-menu-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
|
<div className={`canvas-menu-wrap ${[2, 3, 4].some((num) => num === menuNumber) ? 'active' : ''}`}>
|
||||||
<div className="canvas-menu-inner">
|
<div className="canvas-menu-inner">
|
||||||
<ul className="canvas-menu-list">
|
<ul className="canvas-menu-list">
|
||||||
{canvasMenus.map((menu) => {
|
{canvasMenus.map((menu) => {
|
||||||
@ -205,11 +209,12 @@ export default function CanvasMenu(props) {
|
|||||||
key={`canvas-menu-${menu.index}`}
|
key={`canvas-menu-${menu.index}`}
|
||||||
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (['2', '3'].includes(canvasSetting?.roofSizeSet?.toString()) && menu.index === 2) return
|
if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) return
|
||||||
|
if (menuNumber === 4 && menu.index === 2) return
|
||||||
onClickNav(menu)
|
onClickNav(menu)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button className={['2', '3'].includes(canvasSetting?.roofSizeSet?.toString()) && menu.index === 2 ? 'no-click' : ''}>
|
<button className={checkMenuState(menu) ? 'no-click' : ''}>
|
||||||
<span className={`menu-icon ${menu.icon}`}></span>
|
<span className={`menu-icon ${menu.icon}`}></span>
|
||||||
{getMessage(menu.name)}
|
{getMessage(menu.name)}
|
||||||
</button>
|
</button>
|
||||||
@ -218,7 +223,7 @@ export default function CanvasMenu(props) {
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="canvas-side-btn-wrap">
|
<div className="canvas-side-btn-wrap">
|
||||||
{menuNumber !== 6 && menuNumber !== 5 && (
|
{![5, 6].some((num) => num === menuNumber) && (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
<div className={`vertical-horizontal ${verticalHorizontalMode ? 'on' : ''}`}>
|
<div className={`vertical-horizontal ${verticalHorizontalMode ? 'on' : ''}`}>
|
||||||
@ -248,7 +253,7 @@ export default function CanvasMenu(props) {
|
|||||||
handleZoom(false)
|
handleZoom(false)
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<span>{canvasZoom}%</span>
|
<span onClick={handleZoomClear}>{canvasZoom}%</span>
|
||||||
<button
|
<button
|
||||||
className="control-btn plus"
|
className="control-btn plus"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -314,8 +319,8 @@ export default function CanvasMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`canvas-depth2-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
|
<div className={`canvas-depth2-wrap ${[2, 3, 4].some((num) => num === menuNumber) ? 'active' : ''}`}>
|
||||||
{(menuNumber === 2 || menuNumber === 3 || menuNumber === 4) && <MenuDepth01 />}
|
{[2, 3, 4].some((num) => num === menuNumber) && <MenuDepth01 />}
|
||||||
</div>
|
</div>
|
||||||
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */}
|
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */}
|
||||||
{estimatePopupOpen && <DocDownOptionPop planNo={estimateRecoilState?.planNo} setEstimatePopupOpen={setEstimatePopupOpen} />}
|
{estimatePopupOpen && <DocDownOptionPop planNo={estimateRecoilState?.planNo} setEstimatePopupOpen={setEstimatePopupOpen} />}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { forwardRef, useImperativeHandle, useState } from 'react'
|
import { forwardRef, useImperativeHandle, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useOrientation } from '@/hooks/popup/useOrientation'
|
import { useOrientation } from '@/hooks/module/useOrientation'
|
||||||
import { getDegreeInOrientation } from '@/util/canvas-util'
|
import { getDegreeInOrientation } from '@/util/canvas-util'
|
||||||
|
|
||||||
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { contextPopupPositionState } from '@/store/popupAtom'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||||
import { FLOW_DIRECTION_TYPE, useFlowDirectionSetting } from '@/hooks/popup/useFlowDirectionSetting'
|
import { FLOW_DIRECTION_TYPE, useFlowDirectionSetting } from '@/hooks/contextpopup/useFlowDirectionSetting'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
export default function FlowDirectionSetting(props) {
|
export default function FlowDirectionSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
|
||||||
import { useState } from 'react'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { useRecoilValue } from 'recoil'
|
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
|
|
||||||
export default function ImageSizeSetting(props) {
|
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
|
||||||
const { id, pos = contextPopupPosition, size, setSize } = props
|
|
||||||
const [sizeValue, setSizeValue] = useState(100)
|
|
||||||
const { getMessage } = useMessage()
|
|
||||||
const { closePopup } = usePopup()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
|
||||||
<div className={`modal-pop-wrap xxxm mount`}>
|
|
||||||
<div className="modal-head">
|
|
||||||
<h1 className="title">{getMessage('modal.image.size.setting')} </h1>
|
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
|
||||||
닫기
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="modal-body">
|
|
||||||
<div className="range-wrap">
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
id="size"
|
|
||||||
name="volume"
|
|
||||||
min="20"
|
|
||||||
max="200"
|
|
||||||
step={10}
|
|
||||||
value={sizeValue}
|
|
||||||
onChange={(e) => setSizeValue(e.target.value)}
|
|
||||||
/>
|
|
||||||
<label htmlFor="size">{sizeValue}%</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</WithDraggable>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -12,7 +12,6 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide'
|
import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide'
|
||||||
import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide'
|
import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide'
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
|
||||||
|
|
||||||
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
||||||
const [objectNo, setObjectNo] = useState('test123241008001') // 후에 삭제 필요
|
const [objectNo, setObjectNo] = useState('test123241008001') // 후에 삭제 필요
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { Fragment, useCallback, useEffect, useState } from 'react'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { usePathname } from 'next/navigation'
|
import { usePathname } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { dimmedStore, sessionStore } from '@/store/commonAtom'
|
import { dimmedStore, sessionStore } from '@/store/commonAtom'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
@ -16,6 +16,8 @@ import UserInfoModal from '@/components/myInfo/UserInfoModal'
|
|||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
|
import { stuffSearchState } from '@/store/stuffAtom'
|
||||||
|
|
||||||
export const ToggleonMouse = (e, act, target) => {
|
export const ToggleonMouse = (e, act, target) => {
|
||||||
const listWrap = e.target.closest(target)
|
const listWrap = e.target.closest(target)
|
||||||
const ListItem = Array.from(listWrap.childNodes)
|
const ListItem = Array.from(listWrap.childNodes)
|
||||||
@ -34,6 +36,8 @@ export const ToggleonMouse = (e, act, target) => {
|
|||||||
export default function Header(props) {
|
export default function Header(props) {
|
||||||
const [userInfoModal, setUserInfoModal] = useState(false)
|
const [userInfoModal, setUserInfoModal] = useState(false)
|
||||||
|
|
||||||
|
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
|
||||||
|
|
||||||
const { userSession } = props
|
const { userSession } = props
|
||||||
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -184,7 +188,14 @@ export default function Header(props) {
|
|||||||
{userInfoModal && <UserInfoModal userId={sessionState.userId} userInfoModal={userInfoModal} setUserInfoModal={setUserInfoModal} />}
|
{userInfoModal && <UserInfoModal userId={sessionState.userId} userInfoModal={userInfoModal} setUserInfoModal={setUserInfoModal} />}
|
||||||
</div>
|
</div>
|
||||||
<div className="sign-out-box">
|
<div className="sign-out-box">
|
||||||
<button className="sign-out" onClick={() => logout()}>
|
<button
|
||||||
|
className="sign-out"
|
||||||
|
onClick={() => {
|
||||||
|
//리코일은 새로고침 하지 않으면 남아있어서 로그아웃해도 남아있음..
|
||||||
|
resetStuffRecoil()
|
||||||
|
logout()
|
||||||
|
}}
|
||||||
|
>
|
||||||
{getMessage('header.logout')}
|
{getMessage('header.logout')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -39,9 +39,9 @@ export default function Stuff() {
|
|||||||
const copyNo = async (value) => {
|
const copyNo = async (value) => {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(value)
|
await navigator.clipboard.writeText(value)
|
||||||
alert(getMessage('stuff.detail.header.message2'))
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(getMessage('stuff.detail.header.message3'))
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +209,7 @@ export default function Stuff() {
|
|||||||
endRow: pageNo * pageSize,
|
endRow: pageNo * pageSize,
|
||||||
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
||||||
schSortType: 'R',
|
schSortType: 'R',
|
||||||
|
code: 'S',
|
||||||
}
|
}
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
...params,
|
...params,
|
||||||
|
|||||||
@ -19,10 +19,15 @@ 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'
|
import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||||
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
|
|
||||||
export default function StuffDetail() {
|
export default function StuffDetail() {
|
||||||
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //견적서 화면용 물건번호리코일
|
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //견적서 화면용 물건번호리코일
|
||||||
|
|
||||||
|
const [estimatePopupOpen, setEstimatePopupOpen] = useState(false)
|
||||||
|
|
||||||
|
const [popPlanNo, setPopPlanNo] = useState('1') //default 1
|
||||||
|
|
||||||
//공통코드
|
//공통코드
|
||||||
const { commonCode, findCommonCode } = useCommonCode()
|
const { commonCode, findCommonCode } = useCommonCode()
|
||||||
const [selOptions, setSelOptions] = useState('') //선택한 1차점
|
const [selOptions, setSelOptions] = useState('') //선택한 1차점
|
||||||
@ -266,11 +271,12 @@ export default function StuffDetail() {
|
|||||||
type="button"
|
type="button"
|
||||||
className="grid-btn"
|
className="grid-btn"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log('엑셀버튼클릭')
|
setFloorPlanObjectNo({ floorPlanObjectNo: params.data.objectNo })
|
||||||
|
handleEstimatePopup(params.data.planNo)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="excel"></span>
|
<span className="excel"></span>
|
||||||
{getMessage('stuff.detail.planGrid.btn2')}
|
{getMessage('stuff.detail.planGrid.docDownload')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -280,6 +286,12 @@ export default function StuffDetail() {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 문서다운로드 팝업 오픈 셋팅
|
||||||
|
const handleEstimatePopup = (planNo) => {
|
||||||
|
setPopPlanNo(planNo)
|
||||||
|
setEstimatePopupOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (objectNo) {
|
if (objectNo) {
|
||||||
setEditMode('EDIT')
|
setEditMode('EDIT')
|
||||||
@ -289,10 +301,12 @@ 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 (isObjectNotEmpty(res.data)) {
|
||||||
setManagementState(res.data)
|
setManagementState(res.data)
|
||||||
} else {
|
} else {
|
||||||
setManagementState({})
|
setManagementState({})
|
||||||
|
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
||||||
|
router.push('/management/stuff')
|
||||||
}
|
}
|
||||||
if (isNotEmptyArray(res.data.planList)) {
|
if (isNotEmptyArray(res.data.planList)) {
|
||||||
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
|
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
|
||||||
@ -302,6 +316,9 @@ export default function StuffDetail() {
|
|||||||
} else {
|
} else {
|
||||||
setManagementState({})
|
setManagementState({})
|
||||||
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
||||||
|
|
||||||
|
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
||||||
|
router.push('/management/stuff')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -2433,6 +2450,8 @@ export default function StuffDetail() {
|
|||||||
{showWindSpeedButtonValid && (
|
{showWindSpeedButtonValid && (
|
||||||
<WindSelectPop setShowWindSpeedButtonValid={setShowWindSpeedButtonValid} prefName={form.watch('prefName')} windSpeedInfo={setWindSppedInfo} />
|
<WindSelectPop setShowWindSpeedButtonValid={setShowWindSpeedButtonValid} prefName={form.watch('prefName')} windSpeedInfo={setWindSppedInfo} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{estimatePopupOpen && <DocDownOptionPop planNo={popPlanNo} setEstimatePopupOpen={setEstimatePopupOpen} />}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,8 +116,10 @@ export default function StuffSearchCondition() {
|
|||||||
schAddress: address,
|
schAddress: address,
|
||||||
schObjectName: objectName,
|
schObjectName: objectName,
|
||||||
schDispCompanyName: dispCompanyName,
|
schDispCompanyName: dispCompanyName,
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId,
|
// schSelSaleStoreId: stuffSearch?.schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId,
|
// schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId,
|
||||||
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: receiveUser,
|
schReceiveUser: receiveUser,
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
||||||
@ -157,6 +159,7 @@ export default function StuffSearchCondition() {
|
|||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schSelSaleStoreId: '',
|
schSelSaleStoreId: '',
|
||||||
schOtherSelSaleStoreId: '',
|
schOtherSelSaleStoreId: '',
|
||||||
|
schDateType: 'U',
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (otherSaleStoreList.length > 1) {
|
if (otherSaleStoreList.length > 1) {
|
||||||
@ -312,8 +315,8 @@ export default function StuffSearchCondition() {
|
|||||||
} else {
|
} else {
|
||||||
//X누름
|
//X누름
|
||||||
//화면에선 지우는데 리코일은 조회누르지 않으면 보존
|
//화면에선 지우는데 리코일은 조회누르지 않으면 보존
|
||||||
setSchSelSaleStoreId('')
|
// setSchSelSaleStoreId('') //값이 안비워짐..
|
||||||
// stuffSearch.schSelSaleStoreId = ''
|
setSchSelSaleStoreId(null)
|
||||||
|
|
||||||
//2차점 판매점목록비우기
|
//2차점 판매점목록비우기
|
||||||
setOtherSaleStoreList([])
|
setOtherSaleStoreList([])
|
||||||
@ -333,7 +336,6 @@ export default function StuffSearchCondition() {
|
|||||||
if (session.storeLvl === '1') {
|
if (session.storeLvl === '1') {
|
||||||
if (stuffSearch.schOtherSelSaleStoreId === '') {
|
if (stuffSearch.schOtherSelSaleStoreId === '') {
|
||||||
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
||||||
// stuffSearch.schSelSaleStoreId = ''
|
|
||||||
setSchSelSaleStoreId(session.storeId)
|
setSchSelSaleStoreId(session.storeId)
|
||||||
} else {
|
} else {
|
||||||
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
||||||
@ -357,6 +359,7 @@ export default function StuffSearchCondition() {
|
|||||||
setobjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
|
setobjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
|
||||||
setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName)
|
setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName)
|
||||||
setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser)
|
setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser)
|
||||||
|
setDateType(stuffSearch.schDateType ? stuffSearch.schDateType : dateType)
|
||||||
}, [stuffSearch])
|
}, [stuffSearch])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -638,7 +641,7 @@ export default function StuffSearchCondition() {
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="radio_ptype"
|
name="radio_ptype"
|
||||||
id="radio_u"
|
id="radio_u"
|
||||||
checked={stuffSearch.schDateType === 'U' ? true : false}
|
checked={dateType === 'U' ? true : false}
|
||||||
value={'U'}
|
value={'U'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setDateType(e.target.value)
|
setDateType(e.target.value)
|
||||||
@ -652,7 +655,7 @@ export default function StuffSearchCondition() {
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="radio_ptype"
|
name="radio_ptype"
|
||||||
id="radio_r"
|
id="radio_r"
|
||||||
checked={stuffSearch.schDateType === 'R' ? true : false}
|
checked={dateType === 'R' ? true : false}
|
||||||
value={'R'}
|
value={'R'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setDateType(e.target.value)
|
setDateType(e.target.value)
|
||||||
|
|||||||
@ -105,8 +105,8 @@ export default function Simulator() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (objectNo) {
|
if (objectNo) {
|
||||||
fetchObjectDetail(objectNo)
|
fetchObjectDetail(objectNo)
|
||||||
|
fetchSimulatorNotice()
|
||||||
}
|
}
|
||||||
fetchSimulatorNotice()
|
|
||||||
}, [objectNo, plan])
|
}, [objectNo, plan])
|
||||||
|
|
||||||
// 물건 상세 정보 조회
|
// 물건 상세 정보 조회
|
||||||
@ -158,23 +158,25 @@ export default function Simulator() {
|
|||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub1')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub1')}</div>
|
||||||
<div className="estimate-name">
|
<div className="estimate-name">
|
||||||
{objectDetail.objectNo} (Plan No: {objectDetail.planNo})
|
{objectDetail.objectNo} (Plan No: {plan?.id})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 작성일 */}
|
{/* 작성일 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub2')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub2')}</div>
|
||||||
<div className="estimate-name">{`${dayjs(objectDetail.drawingEstimateCreateDate).format('YYYY.MM.DD')}`}</div>
|
<div className="estimate-name">
|
||||||
|
{objectDetail.drawingEstimateCreateDate ? `${dayjs(objectDetail.drawingEstimateCreateDate).format('YYYY.MM.DD')}` : ''}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 시스템용량 */}
|
{/* 시스템용량 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub3')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub3')}</div>
|
||||||
<div className="estimate-name">{convertNumberToPriceDecimal(objectDetail.capacity)}kW</div>
|
<div className="estimate-name">{objectDetail.capacity ? `${convertNumberToPriceDecimal(objectDetail.capacity)}kW` : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 연간예측발전량 */}
|
{/* 연간예측발전량 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub4')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub4')}</div>
|
||||||
<div className="estimate-name">{convertNumberToPriceDecimal(objectDetail.anlFrcsGnrt)}</div>
|
<div className="estimate-name">{objectDetail.anlFrcsGnrt ? convertNumberToPriceDecimal(objectDetail.anlFrcsGnrt) : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-list-wrap">
|
<div className="estimate-list-wrap">
|
||||||
|
|||||||
@ -40,19 +40,19 @@ export function useCanvasConfigInitialize() {
|
|||||||
const flowTexts = canvas.getObjects().filter((obj) => obj.name === 'flowText')
|
const flowTexts = canvas.getObjects().filter((obj) => obj.name === 'flowText')
|
||||||
if (basicSetting.roofAngleSet === 'slope') {
|
if (basicSetting.roofAngleSet === 'slope') {
|
||||||
offsetTexts.forEach((obj) => {
|
offsetTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${obj.pitch}${angleUnit}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${angleUnit}` })
|
||||||
})
|
})
|
||||||
flowTexts.forEach((obj) => {
|
flowTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${obj.pitch}${pitchText}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${pitchText}` })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basicSetting.roofAngleSet === 'flat') {
|
if (basicSetting.roofAngleSet === 'flat') {
|
||||||
offsetTexts.forEach((obj) => {
|
offsetTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${getDegreeByChon(obj.pitch)}${angleUnit}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${angleUnit}` })
|
||||||
})
|
})
|
||||||
flowTexts.forEach((obj) => {
|
flowTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${getDegreeByChon(obj.pitch)}${pitchText}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${pitchText}` })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -76,7 +82,9 @@ export const useEstimateController = (planNo) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addItem = () => {
|
const addItem = () => {
|
||||||
const newItemDispOrder = Math.max(...state.itemList.map((item) => item.dispOrder)) + 1
|
// const newItemDispOrder = (Math.max(...state.itemList.map((item) => item.dispOrder)) / 100 + 1) * 100
|
||||||
|
let newItemDispOrder = Math.max(...state.itemList.map((item) => item.dispOrder))
|
||||||
|
newItemDispOrder = (Math.floor(newItemDispOrder / 100) + 1) * 100
|
||||||
setState({
|
setState({
|
||||||
itemList: [
|
itemList: [
|
||||||
...state.itemList,
|
...state.itemList,
|
||||||
@ -90,8 +98,8 @@ export const useEstimateController = (planNo) => {
|
|||||||
amount: '', //수량
|
amount: '', //수량
|
||||||
unitPrice: '0',
|
unitPrice: '0',
|
||||||
unit: '', //단위
|
unit: '', //단위
|
||||||
salePrice: '0', //단가
|
salePrice: '', //단가
|
||||||
saleTotPrice: '0', //금액(부가세별도)
|
saleTotPrice: '', //금액(부가세별도)
|
||||||
itemChangeFlg: '1', //추가시 체인지플래그 1로
|
itemChangeFlg: '1', //추가시 체인지플래그 1로
|
||||||
partAdd: '1', //NEW 체인지 플래그
|
partAdd: '1', //NEW 체인지 플래그
|
||||||
delFlg: '0', //삭제 플래그 0 삭제하면 1
|
delFlg: '0', //삭제 플래그 0 삭제하면 1
|
||||||
@ -133,7 +141,7 @@ 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 저장안돼
|
||||||
@ -151,9 +159,8 @@ export const useEstimateController = (planNo) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,26 +168,30 @@ 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) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
alert(getMessage('estimate.detail.save.alertMsg'))
|
alert(getMessage('estimate.detail.save.alertMsg'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// try {
|
|
||||||
// const result = await promisePost({
|
|
||||||
// url: ESTIMATE_API_ENDPOINT,
|
|
||||||
// data: estimateData,
|
|
||||||
// })
|
|
||||||
// alert(getMessage('estimate.detail.save.alertMsg'))
|
|
||||||
// return result
|
|
||||||
// } catch (error) {
|
|
||||||
// console.error('Failed to submit estimate:', error)
|
|
||||||
// throw error
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { canvasState } from '@/store/canvasAtom'
|
|||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { compasDegAtom } from '@/store/orientationAtom'
|
import { compasDegAtom } from '@/store/orientationAtom'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
// 모듈,회로 구성 탭 기본설정 > 방위설정 탭
|
// 모듈,회로 구성 탭 기본설정 > 방위설정 탭
|
||||||
export function useOrientation() {
|
export function useOrientation() {
|
||||||
@ -11,6 +12,16 @@ export function useOrientation() {
|
|||||||
|
|
||||||
const { drawDirectionArrow } = usePolygon()
|
const { drawDirectionArrow } = usePolygon()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
roof.set({
|
||||||
|
moduleCompass: null,
|
||||||
|
})
|
||||||
|
drawDirectionArrow(roof)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
const nextStep = () => {
|
const nextStep = () => {
|
||||||
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
roofs.forEach((roof) => {
|
roofs.forEach((roof) => {
|
||||||
@ -277,7 +277,7 @@ export function useCanvasSetting() {
|
|||||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||||
break
|
break
|
||||||
case 'gridDisplay': //그리드 표시
|
case 'gridDisplay': //그리드 표시
|
||||||
optionName = ['lindGrid', 'dotGrid']
|
optionName = ['lindGrid', 'dotGrid', 'tempGrid']
|
||||||
break
|
break
|
||||||
case 'lineDisplay': //지붕선 표시
|
case 'lineDisplay': //지붕선 표시
|
||||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
|
||||||
import { useEffect } from 'react'
|
|
||||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
|
||||||
|
|
||||||
export function useFirstOption() {
|
|
||||||
const canvas = useRecoilValue(canvasState)
|
|
||||||
|
|
||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const option1 = settingModalFirstOptions.option1
|
|
||||||
|
|
||||||
// 'allocDisplay' 할당 표시
|
|
||||||
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
|
||||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
|
||||||
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
|
||||||
// 'wordDisplay' 문자 표시
|
|
||||||
// 'circuitNumDisplay' 회로번호 표시
|
|
||||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
|
||||||
// 'trestleDisplay' 가대 표시
|
|
||||||
// 'totalDisplay' 집계표 표시
|
|
||||||
|
|
||||||
let optionName //옵션명
|
|
||||||
let optionSelected //옵션상태
|
|
||||||
|
|
||||||
for (let i = 0; i < option1.length; i++) {
|
|
||||||
switch (option1[i].column) {
|
|
||||||
case 'allocDisplay': //할당 표시
|
|
||||||
optionName = ['1']
|
|
||||||
break
|
|
||||||
case 'outlineDisplay': //외벽선 표시
|
|
||||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
|
||||||
break
|
|
||||||
case 'gridDisplay': //그리드 표시
|
|
||||||
optionName = ['lineGrid', 'dotGrid', 'adsorptionPoint', 'tempGrid']
|
|
||||||
break
|
|
||||||
case 'lineDisplay': //지붕선 표시
|
|
||||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
|
||||||
break
|
|
||||||
case 'wordDisplay': //문자 표시
|
|
||||||
optionName = ['commonText']
|
|
||||||
break
|
|
||||||
case 'circuitNumDisplay': //회로번호 표시
|
|
||||||
optionName = ['7']
|
|
||||||
break
|
|
||||||
case 'flowDisplay': //흐름방향 표시
|
|
||||||
optionName = ['arrow', 'flowText']
|
|
||||||
break
|
|
||||||
case 'trestleDisplay': //가대 표시
|
|
||||||
optionName = ['8']
|
|
||||||
break
|
|
||||||
case 'totalDisplay': //집계표 표시
|
|
||||||
optionName = ['9']
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// 표시 선택 상태(true/false)
|
|
||||||
optionSelected = option1[i].selected
|
|
||||||
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => optionName.includes(obj.name))
|
|
||||||
//.filter((obj) => obj.name === optionName)
|
|
||||||
.forEach((obj) => {
|
|
||||||
obj.set({ visible: optionSelected })
|
|
||||||
//obj.set({ visible: !obj.visible })
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
// console.log(
|
|
||||||
// 'optionName',
|
|
||||||
// optionName,
|
|
||||||
// canvas.getObjects().filter((obj) => optionName.includes(obj.name)),
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
}, [settingModalFirstOptions])
|
|
||||||
|
|
||||||
return { settingModalFirstOptions, setSettingModalFirstOptions }
|
|
||||||
}
|
|
||||||
@ -455,9 +455,24 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
name: 'auxiliaryLine',
|
name: 'auxiliaryLine',
|
||||||
})
|
})
|
||||||
|
|
||||||
lineHistory.current.push(line)
|
const historyLines = [...lineHistory.current]
|
||||||
|
|
||||||
|
const hasSameLine = historyLines.some((history) => {
|
||||||
|
return (
|
||||||
|
(isSamePoint(history.startPoint, line.startPoint) && isSamePoint(history.endPoint, line.endPoint)) ||
|
||||||
|
(isSamePoint(history.startPoint, line.endPoint) && isSamePoint(history.endPoint, line.startPoint))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
mousePointerArr.current = []
|
mousePointerArr.current = []
|
||||||
clear()
|
clear()
|
||||||
|
|
||||||
|
if (hasSameLine) {
|
||||||
|
canvas.remove(line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lineHistory.current.push(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mouseDown = (e) => {
|
const mouseDown = (e) => {
|
||||||
|
|||||||
@ -125,6 +125,12 @@ export function usePropertiesSetting(id) {
|
|||||||
}
|
}
|
||||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
const notSetAttributes = lines.filter((line) => !line.attributes?.type)
|
||||||
|
if (notSetAttributes.length > 0) {
|
||||||
|
alert('설정되지 않은 외벽선이 있습니다.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
line.set({
|
line.set({
|
||||||
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||||
|
|||||||
@ -377,20 +377,20 @@ export function useRoofShapeSetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 기존 wallLine, roofBase 제거
|
// 기존 wallLine, roofBase 제거
|
||||||
/*canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
.forEach((line) => {
|
.forEach((line) => {
|
||||||
canvas.remove(line)
|
canvas.remove(line)
|
||||||
})*/
|
})
|
||||||
|
|
||||||
/*canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
|
||||||
.forEach((obj) => {
|
.forEach((obj) => {
|
||||||
canvas.remove(...obj.innerLines)
|
canvas.remove(...obj.innerLines)
|
||||||
canvas.remove(obj)
|
canvas.remove(obj)
|
||||||
})*/
|
})
|
||||||
|
|
||||||
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction })
|
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction })
|
||||||
polygon.lines = [...outerLines]
|
polygon.lines = [...outerLines]
|
||||||
|
|||||||
@ -446,19 +446,24 @@ export function useContextMenu() {
|
|||||||
])
|
])
|
||||||
break
|
break
|
||||||
case 'lineGrid':
|
case 'lineGrid':
|
||||||
|
case 'dotGrid':
|
||||||
|
case 'tempGrid':
|
||||||
setContextMenu([
|
setContextMenu([
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'gridMove',
|
id: 'gridMove',
|
||||||
name: getMessage('modal.grid.move'),
|
name: getMessage('modal.grid.move'),
|
||||||
|
component: <GridMove id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gridCopy',
|
id: 'gridCopy',
|
||||||
name: getMessage('modal.grid.copy'),
|
name: getMessage('modal.grid.copy'),
|
||||||
|
component: <GridCopy id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('contextmenu.grid.color.edit'),
|
name: getMessage('contextmenu.grid.color.edit'),
|
||||||
|
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
|
|||||||
@ -284,7 +284,6 @@
|
|||||||
"modal.panel.batch.statistic.total": "合計",
|
"modal.panel.batch.statistic.total": "合計",
|
||||||
"modal.flow.direction.setting": "流れ方向の設定",
|
"modal.flow.direction.setting": "流れ方向の設定",
|
||||||
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
|
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
|
||||||
"modal.image.size.setting": "画像のサイズ変更",
|
|
||||||
"modal.actual.size.setting": "実測値設定",
|
"modal.actual.size.setting": "実測値設定",
|
||||||
"modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。",
|
"modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。",
|
||||||
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)",
|
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)",
|
||||||
@ -733,7 +732,7 @@
|
|||||||
"stuff.detail.planGridHeader.pcTypeNo": "パワーコンディショナー",
|
"stuff.detail.planGridHeader.pcTypeNo": "パワーコンディショナー",
|
||||||
"stuff.detail.planGridHeader.management": "管理",
|
"stuff.detail.planGridHeader.management": "管理",
|
||||||
"stuff.detail.planGrid.btn1": "見積書の照会",
|
"stuff.detail.planGrid.btn1": "見積書の照会",
|
||||||
"stuff.detail.planGrid.btn2": "Excel",
|
"stuff.detail.planGrid.docDownload": "文書のダウンロード",
|
||||||
"stuff.grid.noData": "照会されたデータがありません",
|
"stuff.grid.noData": "照会されたデータがありません",
|
||||||
"length": "長さ",
|
"length": "長さ",
|
||||||
"height": "高さ",
|
"height": "高さ",
|
||||||
@ -844,6 +843,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": "添付必須",
|
||||||
@ -860,25 +860,26 @@
|
|||||||
"estimate.detail.docPopup.title": "ドキュメントダウンロードオプションの設定",
|
"estimate.detail.docPopup.title": "ドキュメントダウンロードオプションの設定",
|
||||||
"estimate.detail.docPopup.explane": "ダウンロードする文書のオプションを選択したら、 [文書のダウンロード]ボタンをクリックします.",
|
"estimate.detail.docPopup.explane": "ダウンロードする文書のオプションを選択したら、 [文書のダウンロード]ボタンをクリックします.",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg": "ダウンロードファイル",
|
"estimate.detail.docPopup.schUnitPriceFlg": "ダウンロードファイル",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg0": "見積もり Excel",
|
"estimate.detail.docPopup.schUnitPriceFlg.excelFlg0": "見積もり Excel",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg1": "定価用 Excel",
|
"estimate.detail.docPopup.schUnitPriceFlg.excelFlg1": "定価用 Excel",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg2": "見積もり PDF",
|
"estimate.detail.docPopup.schUnitPriceFlg.pdfFlg0": "見積もり PDF",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg3": "定価用 PDF",
|
"estimate.detail.docPopup.schUnitPriceFlg.pdfFlg1": "定価用 PDF",
|
||||||
"estimate.detail.docPopup.schDisplayFlg": "見積提出先表示名",
|
"estimate.detail.docPopup.schDisplayFlg": "見積提出先表示名",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "販売店名",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "販売店名",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "案件名",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "案件名",
|
||||||
"estimate.detail.docPopup.schWeightFlg": "架台重量表を含む",
|
"estimate.detail.docPopup.schWeightFlg": "架台重量表を含む",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "含む",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "含む",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "含まない",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "含まない",
|
||||||
"estimate.detail.docPopup.schDrawingFlg": "図面/シミュレーションファイルを含む",
|
"estimate.detail.docPopup.schDrawingFlg": "図面/シミュレーションファイルを含む",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "含む",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "含む",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "含まない",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "含まない",
|
||||||
"estimate.detail.docPopup.close": "閉じる",
|
"estimate.detail.docPopup.close": "閉じる",
|
||||||
"estimate.detail.docPopup.docDownload": "文書のダウンロード",
|
"estimate.detail.docPopup.docDownload": "文書のダウンロード",
|
||||||
"estimate.detail.productFeaturesPopup.title": "製品特異事項",
|
"estimate.detail.productFeaturesPopup.title": "製品特異事項",
|
||||||
"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": "作成日",
|
||||||
|
|||||||
@ -289,7 +289,6 @@
|
|||||||
"modal.panel.batch.statistic.total": "합계",
|
"modal.panel.batch.statistic.total": "합계",
|
||||||
"modal.flow.direction.setting": "흐름 방향 설정",
|
"modal.flow.direction.setting": "흐름 방향 설정",
|
||||||
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
|
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
|
||||||
"modal.image.size.setting": "이미지 크기 조절",
|
|
||||||
"modal.actual.size.setting": "실측치 설정",
|
"modal.actual.size.setting": "실측치 설정",
|
||||||
"modal.actual.size.setting.info": "※隅棟・谷・棟의 실제 치수를 입력해주세요.",
|
"modal.actual.size.setting.info": "※隅棟・谷・棟의 실제 치수를 입력해주세요.",
|
||||||
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요",
|
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요",
|
||||||
@ -743,7 +742,7 @@
|
|||||||
"stuff.detail.planGridHeader.pcTypeNo": "파워컨디셔너",
|
"stuff.detail.planGridHeader.pcTypeNo": "파워컨디셔너",
|
||||||
"stuff.detail.planGridHeader.management": "관리",
|
"stuff.detail.planGridHeader.management": "관리",
|
||||||
"stuff.detail.planGrid.btn1": "견적서 조회",
|
"stuff.detail.planGrid.btn1": "견적서 조회",
|
||||||
"stuff.detail.planGrid.btn2": "Excel",
|
"stuff.detail.planGrid.docDownload": "문서 다운로드",
|
||||||
"stuff.grid.noData": "조회된 데이터가 없습니다",
|
"stuff.grid.noData": "조회된 데이터가 없습니다",
|
||||||
"length": "길이",
|
"length": "길이",
|
||||||
"height": "높이",
|
"height": "높이",
|
||||||
@ -849,11 +848,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": "첨부필수",
|
||||||
@ -870,25 +870,26 @@
|
|||||||
"estimate.detail.docPopup.title": "문서다운로드 옵션설정",
|
"estimate.detail.docPopup.title": "문서다운로드 옵션설정",
|
||||||
"estimate.detail.docPopup.explane": "다운로드할 문서 옵션을 선택한 후 문서 다운로드 버튼을 클릭합니다.",
|
"estimate.detail.docPopup.explane": "다운로드할 문서 옵션을 선택한 후 문서 다운로드 버튼을 클릭합니다.",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg": "다운로드 파일",
|
"estimate.detail.docPopup.schUnitPriceFlg": "다운로드 파일",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg0": "견적가 Excel",
|
"estimate.detail.docPopup.schUnitPriceFlg.excelFlg0": "견적가 Excel",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg1": "정가용 Excel",
|
"estimate.detail.docPopup.schUnitPriceFlg.excelFlg1": "정가용 Excel",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg2": "견적가 PDF",
|
"estimate.detail.docPopup.schUnitPriceFlg.pdfFlg0": "견적가 PDF",
|
||||||
"estimate.detail.docPopup.schUnitPriceFlg.schUnitPriceFlg3": "정가용 PDF",
|
"estimate.detail.docPopup.schUnitPriceFlg.pdfFlg1": "정가용 PDF",
|
||||||
"estimate.detail.docPopup.schDisplayFlg": "견적제출서 표시명",
|
"estimate.detail.docPopup.schDisplayFlg": "견적제출서 표시명",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "판매점명",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "판매점명",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "안건명",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "안건명",
|
||||||
"estimate.detail.docPopup.schWeightFlg": "가대 중량표 포함",
|
"estimate.detail.docPopup.schWeightFlg": "가대 중량표 포함",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "포함",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "포함",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "미포함",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "미포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg": "도면/시뮬레이션 파일 포함",
|
"estimate.detail.docPopup.schDrawingFlg": "도면/시뮬레이션 파일 포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "포함",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "미포함",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "미포함",
|
||||||
"estimate.detail.docPopup.close": "닫기",
|
"estimate.detail.docPopup.close": "닫기",
|
||||||
"estimate.detail.docPopup.docDownload": "문서 다운로드",
|
"estimate.detail.docPopup.docDownload": "문서 다운로드",
|
||||||
"estimate.detail.productFeaturesPopup.title": "제품특이사항",
|
"estimate.detail.productFeaturesPopup.title": "제품특이사항",
|
||||||
"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": "작성일",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1201,7 +1201,7 @@ export function removeDuplicatePolygons(polygons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const isSamePoint = (a, b) => {
|
export const isSamePoint = (a, b) => {
|
||||||
return Math.abs(Math.round(a.x) - Math.round(b.x)) <= 1 && Math.abs(Math.round(a.y) - Math.round(b.y)) <= 1
|
return Math.abs(Math.round(a.x) - Math.round(b.x)) <= 2 && Math.abs(Math.round(a.y) - Math.round(b.y)) <= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user