wr: 시설부대경비 요율 수정
This commit is contained in:
@@ -210,8 +210,8 @@ export default function CoMatRvw() {
|
||||
*/
|
||||
const constCostSimulation = () => {
|
||||
const url = `/constCostSimulation`;
|
||||
const width = Math.floor(window.screen.availWidth * 0.8);
|
||||
const height = Math.floor(window.screen.availHeight * 0.8);
|
||||
const width = Math.floor(window.screen.availWidth * 0.6);
|
||||
const height = Math.floor(window.screen.availHeight * 0.6);
|
||||
const left = Math.floor(window.screenX + (window.outerWidth - width) / 2);
|
||||
const top = Math.floor(window.screenY + (window.outerHeight - height) / 2);
|
||||
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
|
||||
@@ -334,10 +334,9 @@ export default function CoMatRvw() {
|
||||
getSearch(val, Number(fromDate), Number(toDate), con, dmdCoNm);
|
||||
}}
|
||||
></UiTable>
|
||||
<div ref={bottomRef} />
|
||||
<div ref={bottomRef} className="scroll-mt-[45px]"/>
|
||||
</ListDiv>
|
||||
<br /><hr />
|
||||
<br />
|
||||
<hr className="my-4"/>
|
||||
{/* <ScrollArea className="h-[49vh]"> */}
|
||||
<ListDiv>
|
||||
<div className="card-header flex items-center justify-between">
|
||||
|
||||
@@ -57,13 +57,15 @@ export type comFcltState = {
|
||||
rateFeeRes:rateFeeType[],
|
||||
|
||||
};
|
||||
type comFcltActions = {
|
||||
type comFcltActions = {
|
||||
getSwtrmtFcltNm: (searchNm: string) => void;
|
||||
getDemandCompList: (searchNm: string, cnt: number) => void;
|
||||
regDemandCompany: (data: DemandCompType) => Promise<string>;
|
||||
updateDemandCompany: (data: DemandCompType) => Promise<string>;
|
||||
getConstCostFee: (year: string) => void;
|
||||
getRateFee: (year: string) => void;
|
||||
getConstCostFeeRtn: (year: string) => conCostFeeType[];
|
||||
getRateFeeRtn: (year: string) => rateFeeType[];
|
||||
};
|
||||
|
||||
export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
|
||||
@@ -168,6 +170,18 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
|
||||
console.log(" error ", e);
|
||||
}
|
||||
},
|
||||
// 요율정보 조회 : ONSEMIRO_NEW.EM_STD_COST_INC_EXP_RT 설치관리표준사업비 부대경비요율
|
||||
// 팝업에서 연도 변경하여 볼 수 있도록 데이터를 return한다.
|
||||
getRateFeeRtn: async (year: string) => {
|
||||
try {
|
||||
const url = `/prcsFclt/CstRt/${year}`;
|
||||
const rateFeeRes = await getFetch(fetchType.COMMON, url);
|
||||
|
||||
return rateFeeRes;
|
||||
} catch (e) {
|
||||
console.log(" error ", e);
|
||||
}
|
||||
},
|
||||
// 공사금액 (공사비 산정표) 조회 : ONSEMIRO_NEW.EM_STD_COST_REUSE 설치관리표준사업비 재이용시설 공사비
|
||||
getConstCostFee: async (year: string) => {
|
||||
try {
|
||||
@@ -185,6 +199,17 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
|
||||
console.log('getConstCostFee ', e)
|
||||
}
|
||||
|
||||
},
|
||||
// 공사금액 (공사비 산정표) 조회 : ONSEMIRO_NEW.EM_STD_COST_REUSE 설치관리표준사업비 재이용시설 공사비
|
||||
getConstCostFeeRtn: async (year: string) => {
|
||||
try {
|
||||
const url = `/prcsFclt/CstRuse/${year}`;
|
||||
const constCost = await getFetch(fetchType.COMMON, url);
|
||||
return constCost;
|
||||
} catch (e) {
|
||||
console.log('getConstCostFee ', e)
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -136,8 +136,7 @@ export default function ConCostForm({
|
||||
String(useUsgCdWatch ?? "");
|
||||
|
||||
useEffect(() => {
|
||||
const calculatedTotalConstCost =
|
||||
Number(prcsFcltCpctCstrnCst) + Number(fcltSbsdCstrnCst);
|
||||
const calculatedTotalConstCost = Number(prcsFcltCpctCstrnCst) + Number(fcltSbsdCstrnCst);
|
||||
|
||||
if ((totalConstCost ?? 0) !== calculatedTotalConstCost) {
|
||||
activeForm.setValue("totalConstCost", calculatedTotalConstCost);
|
||||
@@ -197,7 +196,7 @@ export default function ConCostForm({
|
||||
const firstProc = getConstFctCode(usgPrcsProcs?.split("+")[0] || "") || ""; // 첫번째 공정
|
||||
const secondProc = getConstFctCode(usgPrcsProcs?.split("+")[1] || "") || ""; // 두번째 공정
|
||||
|
||||
// 첫번째 처리공정 코드에 해당하는 표준공사비 테이블이서 요구수량을 감싸는 하한/상한 구간을 찾는 부분이다.
|
||||
// 첫번째 처리공정 코드에 해당하는 표준공사비 테이블에서 요구수량을 감싸는 하한/상한 구간을 찾는 부분이다.
|
||||
const { lower: firstLower, upper: firstUpper } = findBounds(
|
||||
constCostRes, // 표준공사비
|
||||
firstProc || "",
|
||||
@@ -559,7 +558,7 @@ export default function ConCostForm({
|
||||
<ConstCostFeeTable />
|
||||
</>
|
||||
}
|
||||
bodyClassName={"w-fit max-w-[40vw]"}
|
||||
bodyClassName={"w-fit max-w-[400] overflow-x-auto"}
|
||||
></PopoverUi>
|
||||
</div>
|
||||
<FormField
|
||||
@@ -597,7 +596,7 @@ export default function ConCostForm({
|
||||
<RateFeeTableModal />
|
||||
</>
|
||||
}
|
||||
bodyClassName={"w-[22vw]"}
|
||||
bodyClassName={"w-fit max-w-[100] overflow-x-auto"}
|
||||
></PopoverUi>
|
||||
</div>
|
||||
<FormField
|
||||
|
||||
@@ -8,30 +8,24 @@ import type {
|
||||
conCostFeeType,
|
||||
ContCostMap,
|
||||
} from "@/app/store/common/searchCode/type";
|
||||
import { UiTable } from "@common/business_components/ui";
|
||||
import { SelectBox, UiTable } from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Label, } from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function ConstCostFeeTable() {
|
||||
const { coRvw, constCostRes } = useWrStore((state) => state);
|
||||
const { coRvw, constCostRes, getConstCostFeeRtn } = useWrStore((state) => state);
|
||||
|
||||
const [constCostData, setConstCostData] = useState<ContCostMap[]>([]);
|
||||
const 기준년도 = constCostRes?.[0]?.yr ?? "";
|
||||
const [selectedYear, setSelectedYear] = useState<string>(String(new Date().getFullYear()));
|
||||
|
||||
// 연도 선택을 위한 옵션 생성 (예: 현재 연도부터 10년 전까지)
|
||||
const yearOptions = Array.from({ length: 10 }, (_, i) => {
|
||||
const year = new Date().getFullYear() - i;
|
||||
return { val: String(year), text: String(year) };
|
||||
});
|
||||
|
||||
const getFctDescription = (fctCd: string) => {
|
||||
const fctMap: { [key: string]: string } = {
|
||||
"001": "총인처리시설",
|
||||
"002": "염소소독",
|
||||
"003": "UV소독",
|
||||
"004": "전처리시설",
|
||||
"005": "RO",
|
||||
};
|
||||
|
||||
return fctMap[fctCd];
|
||||
}
|
||||
useEffect(() => {
|
||||
const fetchData = async (constCostRes: conCostFeeType[]) => {
|
||||
const tableData = constCostRes?.reduce(
|
||||
(acc: ContCostMap[], cur: conCostFeeType) => {
|
||||
const key = cur.fctCd;
|
||||
@@ -64,21 +58,64 @@ export function ConstCostFeeTable() {
|
||||
gubun: getFctDescription(item.gubun) || item.gubun,
|
||||
};
|
||||
});
|
||||
setConstCostData(formattedTableData);
|
||||
|
||||
return formattedTableData;
|
||||
};
|
||||
|
||||
const getFctDescription = (fctCd: string) => {
|
||||
const fctMap: { [key: string]: string } = {
|
||||
"001": "총인처리시설",
|
||||
"002": "염소소독",
|
||||
"003": "UV소독",
|
||||
"004": "전처리시설",
|
||||
"005": "RO",
|
||||
};
|
||||
|
||||
return fctMap[fctCd];
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const fetchConstCost = async () => {
|
||||
const data = await fetchData(constCostRes);
|
||||
setConstCostData(data);
|
||||
};
|
||||
fetchConstCost();
|
||||
}, [constCostRes]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchConstCost = async () => {
|
||||
if (selectedYear) {
|
||||
const result = await getConstCostFeeRtn(selectedYear);
|
||||
if (result && result.length > 0) {
|
||||
const data = await fetchData(result);
|
||||
setConstCostData(data);
|
||||
} else {
|
||||
alert(selectedYear+'년 데이터가 없습니다.');
|
||||
}
|
||||
}
|
||||
}
|
||||
fetchConstCost();
|
||||
}, [selectedYear]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <ListDiv className="h-[calc(100vh-60vh)] overflow-auto"> */}
|
||||
<ListDiv className="overflow-visible">
|
||||
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">
|
||||
<ListDiv className="min-w-[600px] h-[48vh] overflow-auto">
|
||||
<div className="p-4">
|
||||
<h3 className="text-2xl font-medium text-label">
|
||||
공사비 산정표 보기
|
||||
</h3>
|
||||
<hr />
|
||||
<hr className="mt-4 mb-4"/>
|
||||
<div className="col-span-5 flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Label className="ml-2 mr-1 text-xl text-gray-600">기준년도</Label>
|
||||
<span>{기준년도}</span>
|
||||
<Label className="mr-1 text-xl text-gray-600">기준년도</Label>
|
||||
<SelectBox
|
||||
className="h-full w-32 text-2xl"
|
||||
label=""
|
||||
selectClass={""}
|
||||
selectArray={yearOptions}
|
||||
value={selectedYear}
|
||||
onSelectValue={(val) => setSelectedYear(String(val))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<span className="mr-2 text-xl text-gray-600">단위: 백만원</span>
|
||||
</div>
|
||||
@@ -91,7 +128,10 @@ export function ConstCostFeeTable() {
|
||||
cellClick={undefined}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
</ListDiv>
|
||||
</>
|
||||
<div className="px-3 text-lg text-gray-700 leading-relaxed">
|
||||
시설용량 구간내 공사비는 직선보간법에 의하여 산출
|
||||
</div>
|
||||
</div>
|
||||
</ListDiv>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,24 @@
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { rateFeeType } from "@/app/store/common/searchCode/type";
|
||||
import { UiTable } from "@common/business_components/ui";
|
||||
import { SelectBox, UiTable } from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Label } from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function RateFeeTableModal() {
|
||||
const { coRvw, rateFeeRes } = useWrStore((state) => state);
|
||||
const [reateFeeTable, setRateFeeTable] = useState<rateFeeType[]>([]);
|
||||
const 기준년도 = rateFeeRes?.[0]?.yr ?? "";
|
||||
const { coRvw, rateFeeRes, getRateFeeRtn } = useWrStore((state) => state);
|
||||
const [rateFeeTable, setRateFeeTable] = useState<rateFeeType[]>([]);
|
||||
const [selectedYear, setSelectedYear] = useState<string>(String(new Date().getFullYear()));
|
||||
|
||||
// 연도 선택을 위한 옵션 생성 (예: 현재 연도부터 10년 전까지)
|
||||
const yearOptions = Array.from({ length: 10 }, (_, i) => {
|
||||
const year = new Date().getFullYear() - i;
|
||||
return { val: String(year), text: String(year) };
|
||||
});
|
||||
|
||||
// const 기준년도 = rateFeeRes?.[0]?.yr ?? selectedYear; // 실제 데이터의 기준년도 또는 선택된 연도
|
||||
// setSelectedYear(rateFeeRes?.[0]?.yr ?? selectedYear);
|
||||
|
||||
const gubunLabelMap: Record<number, string> = {
|
||||
50: "5천만원까지",
|
||||
@@ -32,6 +41,11 @@ export function RateFeeTableModal() {
|
||||
500000: "5000억원까지",
|
||||
};
|
||||
|
||||
/**
|
||||
* rateFeeRes 데이터를 가공하여 테이블에 표시하기 적합한 형태로 변환합니다.
|
||||
* - 'SS' 코드를 제외하고, stdCost 기준으로 그룹화하여 BD, SE, CE 요율을 컬럼으로 피벗합니다.
|
||||
* - gubunLabelMap을 사용하여 stdCost에 해당하는 한글 라벨을 추가합니다.
|
||||
*/
|
||||
const fetchData = async (rateFeeRes: rateFeeType[]) => {
|
||||
const data = await rateFeeRes
|
||||
?.filter((item: rateFeeType) => {
|
||||
@@ -65,40 +79,68 @@ export function RateFeeTableModal() {
|
||||
|
||||
useEffect(() => {
|
||||
if (rateFeeRes?.length >= 0) {
|
||||
setSelectedYear(rateFeeRes?.[0]?.yr ?? selectedYear);
|
||||
fetchData(rateFeeRes).then((data) => {
|
||||
setRateFeeTable(data);
|
||||
});
|
||||
}
|
||||
}, [rateFeeRes]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ListDiv className="min-w-[600px] h-[calc(100vh-60vh)] overflow-auto">
|
||||
<div className="sticky top-0 z-10 grid grid-cols-6 gap-4 p-4 bg-white">
|
||||
<h3 className="col-span-6 text-2xl font-medium text-label">
|
||||
요율표 보기
|
||||
</h3>
|
||||
<hr className="col-span-6 border-gray-300" />
|
||||
// 컴포넌트 마운트 시 또는 선택된 연도가 변경될 때 데이터 조회
|
||||
useEffect(() => {
|
||||
const fetchRateFee = async () => {
|
||||
if (selectedYear) {
|
||||
const result = await getRateFeeRtn(selectedYear);
|
||||
if (result && result.length > 0) {
|
||||
const data = await fetchData(result);
|
||||
setRateFeeTable(data);
|
||||
} else {
|
||||
alert(selectedYear+'년 데이터가 없습니다.');
|
||||
}
|
||||
}
|
||||
}
|
||||
fetchRateFee();
|
||||
}, [selectedYear]);
|
||||
|
||||
<div className="col-span-5 flex items-center">
|
||||
<Label className="mr-1 text-xl text-gray-600">기준년도</Label>
|
||||
<span>{기준년도}</span>
|
||||
</div>
|
||||
<div className="col-span-6 pr-6">
|
||||
<UiTable
|
||||
className="min-w-full pr-12"
|
||||
key={"rateTable" + reateFeeTable?.length}
|
||||
headName={""}
|
||||
tableData={reateFeeTable || []}
|
||||
headlist={coRvw.rateFeeHeadList}
|
||||
onPageChange={() => {}}
|
||||
pageSize={0}
|
||||
total={0}
|
||||
cellClick={undefined}
|
||||
/>
|
||||
</div>
|
||||
return (
|
||||
<ListDiv className="min-w-[460px] h-[50vh] overflow-auto">
|
||||
<div className="sticky top-0 z-10 grid grid-cols-6 gap-4 p-4 bg-white">
|
||||
<h3 className="col-span-6 text-2xl font-medium text-label">
|
||||
시설부대경비 요율(%)
|
||||
</h3>
|
||||
<hr className="col-span-6 border-gray-300" />
|
||||
|
||||
<div className="col-span-5 flex items-center">
|
||||
<Label className="mr-1 text-xl text-gray-600">기준년도</Label>
|
||||
<SelectBox
|
||||
className="h-full w-32 text-2xl"
|
||||
label=""
|
||||
selectClass={""}
|
||||
selectArray={yearOptions}
|
||||
value={selectedYear}
|
||||
onSelectValue={(val) => setSelectedYear(String(val))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</ListDiv>
|
||||
</>
|
||||
<div className="col-span-6 pr-6">
|
||||
<UiTable
|
||||
className="min-w-full pr-12"
|
||||
key={"rateTable" + rateFeeTable?.length}
|
||||
headName={""}
|
||||
tableData={rateFeeTable || []}
|
||||
headlist={coRvw.rateFeeHeadList}
|
||||
onPageChange={() => {}}
|
||||
pageSize={0}
|
||||
total={0}
|
||||
cellClick={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-6 px-3 text-lg text-gray-700 leading-relaxed">
|
||||
출처 : 하수도분야 보조금 편성 및 실무요령
|
||||
<br />
|
||||
시설부대경비 및 감리비 요율적용시 공사비가 요율표의 중간에 있을 때는 직선보간법에 의하여 산출
|
||||
</div>
|
||||
</div>
|
||||
</ListDiv>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function PopoverUi({
|
||||
<>
|
||||
<Popover>
|
||||
<PopoverTrigger>{childrenTriger}</PopoverTrigger>
|
||||
<PopoverContent className={bodyClassName}>
|
||||
<PopoverContent className={bodyClassName} onOpenAutoFocus={(e) => e.preventDefault()}>
|
||||
{childrenBody}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
Reference in New Issue
Block a user