[2311] 인증용량 동일PCS다중유닛 대응 — CONN_VOL_W 저장·쿼리·백필 API 추가 #536
@ -87,6 +87,14 @@ public class EstimateController {
|
|||||||
estimateService.updateEstimateLock(estimateRequest);
|
estimateService.updateEstimateLock(estimateRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2026-06-30: 회로 유닛별 접속용량(CONN_VOL_W)만 갱신 (기존 데이터 백필용)
|
||||||
|
@Operation(description = "견적서 회로 유닛별 접속용량(CONN_VOL_W)만 갱신한다.")
|
||||||
|
@PostMapping("/update-conn-vol")
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
public int updateEstimateConnVol(@RequestBody EstimateRequest estimateRequest) throws Exception {
|
||||||
|
return estimateService.updateEstimateConnVol(estimateRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(description = "견적서를 엑셀로 다운로드한다.")
|
@Operation(description = "견적서를 엑셀로 다운로드한다.")
|
||||||
@PostMapping("/excel-download")
|
@PostMapping("/excel-download")
|
||||||
@ResponseStatus(HttpStatus.OK)
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
|||||||
@ -93,6 +93,9 @@ public interface EstimateMapper {
|
|||||||
// 견적서 지붕면 회로구성 아이템 등록
|
// 견적서 지붕면 회로구성 아이템 등록
|
||||||
public int insertEstimateCircuitItem(ItemRequest itemRequest);
|
public int insertEstimateCircuitItem(ItemRequest itemRequest);
|
||||||
|
|
||||||
|
// 2026-06-30: 회로 유닛별 접속용량(CONN_VOL_W)만 비파괴 갱신 (기존 데이터 백필용)
|
||||||
|
public int updateEstimateCircuitConnVol(ItemRequest itemRequest);
|
||||||
|
|
||||||
// 견적서 도면 아이템 등록
|
// 견적서 도면 아이템 등록
|
||||||
public int insertEstimateDrawingItem(ItemRequest itemRequest);
|
public int insertEstimateDrawingItem(ItemRequest itemRequest);
|
||||||
|
|
||||||
|
|||||||
@ -2870,6 +2870,61 @@ public class EstimateService {
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2026-06-30: 기존 견적서의 회로 유닛별 접속용량(CONN_VOL_W) 백필 전용 API.
|
||||||
|
*
|
||||||
|
* <p>전체 저장(insertEstimate) 없이 T_PART_CIRCUIT_ITEM_ESTIMATE 의 CONN_VOL_W 만 비파괴 UPDATE 한다.
|
||||||
|
* 프론트가 재구성한 모듈별 circuit("1-2")·specification 과 PCS 목록을 받아, 저장 시점과 동일한
|
||||||
|
* 규칙(getPcsCircuitList)으로 유닛별 W 합을 계산해 CIRCUIT_NO 순서대로 갱신한다.
|
||||||
|
* 동일 PCS 모델 다중 유닛은 ITEM_ID 가 같아 ITEM_ID 로 못 나누므로, 저장 당시와 동일한
|
||||||
|
* 순차 CIRCUIT_NO(빈 회로 스킵 포함)로 매칭한다.
|
||||||
|
*
|
||||||
|
* @param estimateRequest objectNo, planNo, roofSurfaceList(모듈), circuitItemList(PCS) 필요
|
||||||
|
* @return 갱신된 회로 행 수
|
||||||
|
*/
|
||||||
|
public int updateEstimateConnVol(EstimateRequest estimateRequest) throws Exception {
|
||||||
|
if (StringUtils.isEmpty(estimateRequest.getObjectNo())) {
|
||||||
|
throw new QcastException(ErrorCode.INVALID_INPUT_VALUE,
|
||||||
|
message.getMessage("common.message.required.data", "Object No"));
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(estimateRequest.getPlanNo())) {
|
||||||
|
throw new QcastException(ErrorCode.INVALID_INPUT_VALUE,
|
||||||
|
message.getMessage("common.message.required.data", "Plan No"));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemRequest> circuitItemList = estimateRequest.getCircuitItemList();
|
||||||
|
List<RoofRequest> roofSurfaceList = estimateRequest.getRoofSurfaceList();
|
||||||
|
|
||||||
|
List<ItemRequest> allModuleList = new ArrayList<ItemRequest>();
|
||||||
|
if (roofSurfaceList != null) {
|
||||||
|
for (RoofRequest roofRequest : roofSurfaceList) {
|
||||||
|
if (roofRequest.getModuleList() != null) {
|
||||||
|
allModuleList.addAll(roofRequest.getModuleList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 저장 시점과 동일 규칙으로 유닛별 CONN_VOL_W(+CIRCUIT_CFG) 계산
|
||||||
|
List<ItemRequest> circuitPcsItemList = this.getPcsCircuitList(circuitItemList, allModuleList);
|
||||||
|
|
||||||
|
int updated = 0;
|
||||||
|
int circuitNo = 0;
|
||||||
|
if (circuitPcsItemList != null) {
|
||||||
|
for (ItemRequest circuitItemRequest : circuitPcsItemList) {
|
||||||
|
// insertEstimateCircuitItem 과 동일하게 빈 회로는 저장되지 않았으므로 CIRCUIT_NO 도 증가시키지 않음
|
||||||
|
if (StringUtils.isEmpty(circuitItemRequest.getCircuitCfg())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
circuitNo++;
|
||||||
|
circuitItemRequest.setObjectNo(estimateRequest.getObjectNo());
|
||||||
|
circuitItemRequest.setPlanNo(estimateRequest.getPlanNo());
|
||||||
|
circuitItemRequest.setCircuitNo(String.valueOf(circuitNo));
|
||||||
|
updated += estimateMapper.updateEstimateCircuitConnVol(circuitItemRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PC 회로 구성도 설정
|
* PC 회로 구성도 설정
|
||||||
*
|
*
|
||||||
@ -2880,34 +2935,69 @@ public class EstimateService {
|
|||||||
private List<ItemRequest> getPcsCircuitList(List<ItemRequest> pcsItemList,
|
private List<ItemRequest> getPcsCircuitList(List<ItemRequest> pcsItemList,
|
||||||
List<ItemRequest> moduleList) {
|
List<ItemRequest> moduleList) {
|
||||||
|
|
||||||
if (pcsItemList != null && pcsItemList.size() > 0) {
|
if (pcsItemList == null || pcsItemList.isEmpty()) {
|
||||||
|
return pcsItemList;
|
||||||
for (ItemRequest itemRequest : moduleList) {
|
|
||||||
itemRequest
|
|
||||||
.setCircuit(itemRequest.getCircuit().replaceAll("\\(", "").replaceAll("\\)", ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// circuit 괄호 제거 (예: "(1-1)" -> "1-1")
|
||||||
|
if (moduleList != null) {
|
||||||
|
for (ItemRequest module : moduleList) {
|
||||||
|
if (module.getCircuit() != null) {
|
||||||
|
module.setCircuit(module.getCircuit().replaceAll("\\(", "").replaceAll("\\)", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 단일 PCS: 모든 모듈이 그 유닛에 접속
|
||||||
if (pcsItemList.size() == 1) {
|
if (pcsItemList.size() == 1) {
|
||||||
pcsItemList.get(0).setCircuitCfg(this.getPcsCircuitCtg(moduleList));
|
pcsItemList.get(0).setCircuitCfg(this.getPcsCircuitCtg(moduleList));
|
||||||
} else {
|
// 2026-06-30: 유닛별 접속용량(W) 저장 — 동일 PCS 모델이 여러 유닛일 때 위치기반 추정으로 못 푸는 인증용량을 정확히 계산하기 위함
|
||||||
if (moduleList != null && moduleList.size() > 0) {
|
pcsItemList.get(0).setConnVolW(this.sumModuleSpecW(moduleList));
|
||||||
int j = 1;
|
|
||||||
for (ItemRequest data : pcsItemList) {
|
|
||||||
String val = String.valueOf(j);
|
|
||||||
|
|
||||||
List<ItemRequest> resultList = moduleList.stream()
|
|
||||||
.filter(t -> StringUtils.equals(val, t.getCircuit().split("-")[0]))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
data.setCircuitCfg(this.getPcsCircuitCtg(resultList));
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pcsItemList;
|
return pcsItemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moduleList == null || moduleList.isEmpty()) {
|
||||||
|
return new ArrayList<ItemRequest>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2026-06-30 보강: 다중 PCS 의 유닛 판별을 circuit 첫 숫자 기준으로.
|
||||||
|
// pcsItemList 개수(paralQty 로 과다 펼침 등)나 순서 흔들림에 비의존 —
|
||||||
|
// 실제 존재하는 유닛 index 만큼만 결과 행을 만들고, 유닛 u 의 PCS = pcsItemList[u-1] 로 매칭한다.
|
||||||
|
java.util.TreeSet<Integer> unitKeys = new java.util.TreeSet<Integer>();
|
||||||
|
for (ItemRequest module : moduleList) {
|
||||||
|
String circuit = module.getCircuit();
|
||||||
|
if (!StringUtils.isEmpty(circuit)) {
|
||||||
|
try {
|
||||||
|
unitKeys.add(Integer.parseInt(circuit.split("-")[0].trim()));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 숫자가 아닌 circuit 은 유닛 판별에서 제외
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemRequest> resultPcsList = new ArrayList<ItemRequest>();
|
||||||
|
for (Integer unit : unitKeys) {
|
||||||
|
String unitStr = String.valueOf(unit);
|
||||||
|
List<ItemRequest> unitModules = moduleList.stream()
|
||||||
|
.filter(t -> !StringUtils.isEmpty(t.getCircuit())
|
||||||
|
&& StringUtils.equals(unitStr, t.getCircuit().split("-")[0].trim()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 유닛 index(1-based) 로 PCS 선택. 범위를 벗어나면 마지막 PCS 로 방어적 폴백
|
||||||
|
int idx = unit - 1;
|
||||||
|
ItemRequest pcs = (idx >= 0 && idx < pcsItemList.size())
|
||||||
|
? pcsItemList.get(idx)
|
||||||
|
: pcsItemList.get(pcsItemList.size() - 1);
|
||||||
|
|
||||||
|
pcs.setCircuitCfg(this.getPcsCircuitCtg(unitModules));
|
||||||
|
// 2026-06-30: 이 유닛(circuit 첫 숫자=unit)에 배선된 모듈 W 합 = 접속용량
|
||||||
|
pcs.setConnVolW(this.sumModuleSpecW(unitModules));
|
||||||
|
resultPcsList.add(pcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultPcsList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PC 회로구성도 조회
|
* PC 회로구성도 조회
|
||||||
*
|
*
|
||||||
@ -2948,6 +3038,34 @@ public class EstimateService {
|
|||||||
return circuitCfg;
|
return circuitCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2026-06-30: PCS 유닛별 접속용량(W) 합산
|
||||||
|
*
|
||||||
|
* <p>유닛에 배선된 모듈들의 specification(=모듈 W, 인증 쿼리가 CAST(SPECIFICATION AS FLOAT)로 쓰는 값) 합.
|
||||||
|
* CIRCUIT_CFG 는 회로별 '개수'만 남기고 모듈 타입(435/270 W)을 버리므로, 동일 PCS 모델이 여러 유닛일 때
|
||||||
|
* 위치기반으로는 유닛별 접속용량을 복원할 수 없다. 그래서 모듈 W가 살아있는 저장 시점에 직접 합산해 보관한다.
|
||||||
|
*
|
||||||
|
* @param moduleList 한 PCS 유닛에 배선된 모듈 목록(모듈 1장 = 1 entry)
|
||||||
|
* @return W 합 문자열(모듈 없음이면 null)
|
||||||
|
*/
|
||||||
|
private String sumModuleSpecW(List<ItemRequest> moduleList) {
|
||||||
|
if (moduleList == null || moduleList.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
java.math.BigDecimal sum = java.math.BigDecimal.ZERO;
|
||||||
|
for (ItemRequest module : moduleList) {
|
||||||
|
String spec = module.getSpecification();
|
||||||
|
if (!StringUtils.isEmpty(spec)) {
|
||||||
|
try {
|
||||||
|
sum = sum.add(new java.math.BigDecimal(spec.trim()));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 숫자가 아닌 specification 은 접속용량 합산에서 제외
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum.toPlainString();
|
||||||
|
}
|
||||||
|
|
||||||
public EstimateApiResponse selectAgencyCustList(PriceRequest priceRequest) throws Exception {
|
public EstimateApiResponse selectAgencyCustList(PriceRequest priceRequest) throws Exception {
|
||||||
// Validation
|
// Validation
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,10 @@ public class ItemRequest {
|
|||||||
@Schema(description = "W")
|
@Schema(description = "W")
|
||||||
private String pnowW;
|
private String pnowW;
|
||||||
|
|
||||||
|
// 2026-06-30: PCS 유닛별 접속용량(W) — 저장 시점에 유닛에 배선된 모듈 W 합. 인증용량 계산 시 PNOW_W 와 MIN 비교에 사용
|
||||||
|
@Schema(description = "PCS 유닛별 접속용량(W)")
|
||||||
|
private String connVolW;
|
||||||
|
|
||||||
@Schema(description = "아이템 그룹코드")
|
@Schema(description = "아이템 그룹코드")
|
||||||
private String itemGroup;
|
private String itemGroup;
|
||||||
|
|
||||||
|
|||||||
@ -407,6 +407,7 @@
|
|||||||
SELECT
|
SELECT
|
||||||
cie.CIRCUIT_NO, cie.OBJECT_NO, cie.PLAN_NO,
|
cie.CIRCUIT_NO, cie.OBJECT_NO, cie.PLAN_NO,
|
||||||
cie.ITEM_ID AS CIRCUIT_ITEM_ID, cie.CIRCUIT_CFG,
|
cie.ITEM_ID AS CIRCUIT_ITEM_ID, cie.CIRCUIT_CFG,
|
||||||
|
cie.CONN_VOL_W, -- 2026-06-30: 저장 시점 유닛별 접속용량(W). 있으면 위치기반 추정보다 우선 사용(동일 PCS 모델 다중 유닛 대응)
|
||||||
(SELECT SUM(CAST(LTRIM(RTRIM(x.X.value('.','VARCHAR(10)'))) AS INT))
|
(SELECT SUM(CAST(LTRIM(RTRIM(x.X.value('.','VARCHAR(10)'))) AS INT))
|
||||||
FROM (SELECT CAST('<X>'+REPLACE(cie.CIRCUIT_CFG,',','</X><X>')+'</X>' AS XML) AS d) t
|
FROM (SELECT CAST('<X>'+REPLACE(cie.CIRCUIT_CFG,',','</X><X>')+'</X>' AS XML) AS d) t
|
||||||
CROSS APPLY t.d.nodes('/X') AS x(X)
|
CROSS APPLY t.d.nodes('/X') AS x(X)
|
||||||
@ -417,11 +418,14 @@
|
|||||||
),
|
),
|
||||||
CC AS (
|
CC AS (
|
||||||
SELECT cs.*,
|
SELECT cs.*,
|
||||||
|
-- 2026-06-30: 누적 윈도우를 PCS(CIRCUIT_ITEM_ID) 내부로 한정 — 회로 위치가 다른 PCS 모듈까지 끌어오던 오배분 차단
|
||||||
ISNULL((SELECT SUM(c2.CIRCUIT_SUM) FROM CS c2
|
ISNULL((SELECT SUM(c2.CIRCUIT_SUM) FROM CS c2
|
||||||
WHERE c2.OBJECT_NO=cs.OBJECT_NO AND c2.PLAN_NO=cs.PLAN_NO
|
WHERE c2.OBJECT_NO=cs.OBJECT_NO AND c2.PLAN_NO=cs.PLAN_NO
|
||||||
|
AND c2.CIRCUIT_ITEM_ID = cs.CIRCUIT_ITEM_ID
|
||||||
AND c2.CIRCUIT_NO < cs.CIRCUIT_NO), 0) AS CUM_START,
|
AND c2.CIRCUIT_NO < cs.CIRCUIT_NO), 0) AS CUM_START,
|
||||||
ISNULL((SELECT SUM(c2.CIRCUIT_SUM) FROM CS c2
|
ISNULL((SELECT SUM(c2.CIRCUIT_SUM) FROM CS c2
|
||||||
WHERE c2.OBJECT_NO=cs.OBJECT_NO AND c2.PLAN_NO=cs.PLAN_NO
|
WHERE c2.OBJECT_NO=cs.OBJECT_NO AND c2.PLAN_NO=cs.PLAN_NO
|
||||||
|
AND c2.CIRCUIT_ITEM_ID = cs.CIRCUIT_ITEM_ID
|
||||||
AND c2.CIRCUIT_NO <= cs.CIRCUIT_NO), 0) AS CUM_END
|
AND c2.CIRCUIT_NO <= cs.CIRCUIT_NO), 0) AS CUM_END
|
||||||
FROM CS cs
|
FROM CS cs
|
||||||
),
|
),
|
||||||
@ -430,11 +434,14 @@
|
|||||||
rie.ROOF_ITEM_NO, rie.ROOF_SURFACE_ID, rie.OBJECT_NO, rie.PLAN_NO,
|
rie.ROOF_ITEM_NO, rie.ROOF_SURFACE_ID, rie.OBJECT_NO, rie.PLAN_NO,
|
||||||
rie.ITEM_ID AS ROOF_ITEM_ID, rie.ITEM_NAME,
|
rie.ITEM_ID AS ROOF_ITEM_ID, rie.ITEM_NAME,
|
||||||
CAST(rie.SPECIFICATION AS FLOAT) AS SPEC, rie.AMOUNT, rie.PC_ITEM_ID,
|
CAST(rie.SPECIFICATION AS FLOAT) AS SPEC, rie.AMOUNT, rie.PC_ITEM_ID,
|
||||||
|
-- 2026-06-30: 모듈 누적도 PCS(PC_ITEM_ID) 내부로 한정 — 실제 배선된 PCS의 모듈만 누적
|
||||||
ISNULL((SELECT SUM(r2.AMOUNT) FROM T_PART_ROOF_ITEM_ESTIMATE r2
|
ISNULL((SELECT SUM(r2.AMOUNT) FROM T_PART_ROOF_ITEM_ESTIMATE r2
|
||||||
WHERE r2.OBJECT_NO=rie.OBJECT_NO AND r2.PLAN_NO=rie.PLAN_NO
|
WHERE r2.OBJECT_NO=rie.OBJECT_NO AND r2.PLAN_NO=rie.PLAN_NO
|
||||||
|
AND r2.PC_ITEM_ID = rie.PC_ITEM_ID
|
||||||
AND r2.ROOF_ITEM_NO < rie.ROOF_ITEM_NO), 0) AS CUM_START,
|
AND r2.ROOF_ITEM_NO < rie.ROOF_ITEM_NO), 0) AS CUM_START,
|
||||||
ISNULL((SELECT SUM(r2.AMOUNT) FROM T_PART_ROOF_ITEM_ESTIMATE r2
|
ISNULL((SELECT SUM(r2.AMOUNT) FROM T_PART_ROOF_ITEM_ESTIMATE r2
|
||||||
WHERE r2.OBJECT_NO=rie.OBJECT_NO AND r2.PLAN_NO=rie.PLAN_NO
|
WHERE r2.OBJECT_NO=rie.OBJECT_NO AND r2.PLAN_NO=rie.PLAN_NO
|
||||||
|
AND r2.PC_ITEM_ID = rie.PC_ITEM_ID
|
||||||
AND r2.ROOF_ITEM_NO <= rie.ROOF_ITEM_NO), 0) AS CUM_END
|
AND r2.ROOF_ITEM_NO <= rie.ROOF_ITEM_NO), 0) AS CUM_END
|
||||||
FROM T_PART_ROOF_ITEM_ESTIMATE rie
|
FROM T_PART_ROOF_ITEM_ESTIMATE rie
|
||||||
WHERE rie.OBJECT_NO = #{objectNo} AND rie.PLAN_NO = #{planNo}
|
WHERE rie.OBJECT_NO = #{objectNo} AND rie.PLAN_NO = #{planNo}
|
||||||
@ -447,7 +454,9 @@
|
|||||||
CASE WHEN cc.CUM_END < rc.CUM_END THEN cc.CUM_END ELSE rc.CUM_END END
|
CASE WHEN cc.CUM_END < rc.CUM_END THEN cc.CUM_END ELSE rc.CUM_END END
|
||||||
- CASE WHEN cc.CUM_START > rc.CUM_START THEN cc.CUM_START ELSE rc.CUM_START END AS ALLOCATED_QTY
|
- CASE WHEN cc.CUM_START > rc.CUM_START THEN cc.CUM_START ELSE rc.CUM_START END AS ALLOCATED_QTY
|
||||||
FROM CC cc
|
FROM CC cc
|
||||||
|
-- 2026-06-30: 실제 배선(PCS) 일치 조건 추가 — 회로의 PCS 와 모듈이 배선된 PCS 가 같은 경우만 겹침
|
||||||
INNER JOIN RC rc ON cc.OBJECT_NO = rc.OBJECT_NO AND cc.PLAN_NO = rc.PLAN_NO
|
INNER JOIN RC rc ON cc.OBJECT_NO = rc.OBJECT_NO AND cc.PLAN_NO = rc.PLAN_NO
|
||||||
|
AND cc.CIRCUIT_ITEM_ID = rc.PC_ITEM_ID
|
||||||
WHERE cc.CUM_START < rc.CUM_END AND cc.CUM_END > rc.CUM_START
|
WHERE cc.CUM_START < rc.CUM_END AND cc.CUM_END > rc.CUM_START
|
||||||
),
|
),
|
||||||
DETAIL AS (
|
DETAIL AS (
|
||||||
@ -458,17 +467,27 @@
|
|||||||
(SELECT mi.PNOW_W FROM M_ITEM mi WHERE mi.ITEM_ID = a.CIRCUIT_ITEM_ID) AS PNOW_W
|
(SELECT mi.PNOW_W FROM M_ITEM mi WHERE mi.ITEM_ID = a.CIRCUIT_ITEM_ID) AS PNOW_W
|
||||||
FROM ALLOC a
|
FROM ALLOC a
|
||||||
),
|
),
|
||||||
CIRCUIT_AGG AS (
|
POS AS (
|
||||||
SELECT
|
-- 위치기반(폴백) 유닛별 접속용량 W 합 — CONN_VOL_W 가 없는 기존 데이터에만 사용
|
||||||
CIRCUIT_NO, CIRCUIT_ITEM_ID, CIRCUIT_CFG, CIRCUIT_SUM,
|
SELECT CIRCUIT_NO, CIRCUIT_ITEM_ID, SUM(SPEC_X_QTY) AS POS_W
|
||||||
SUM(SPEC_X_QTY) AS SUM_SPEC_X_QTY, PNOW_W,
|
|
||||||
CASE WHEN SUM(SPEC_X_QTY) <= PNOW_W THEN SUM(SPEC_X_QTY) ELSE PNOW_W END AS MIN_VALUE
|
|
||||||
FROM DETAIL
|
FROM DETAIL
|
||||||
GROUP BY CIRCUIT_NO, CIRCUIT_ITEM_ID, CIRCUIT_CFG, CIRCUIT_SUM, PNOW_W
|
GROUP BY CIRCUIT_NO, CIRCUIT_ITEM_ID
|
||||||
|
),
|
||||||
|
CIRCUIT_AGG AS (
|
||||||
|
-- 2026-06-30 option B: 저장된 CONN_VOL_W 우선, 없으면(NULL=기존 데이터) 위치기반 POS_W 폴백.
|
||||||
|
-- CS(유닛 목록) 기준으로 LEFT JOIN 하므로 유닛별 1행 보장. 유닛별 MIN(접속용량, PNOW_W) 후 합산.
|
||||||
|
SELECT
|
||||||
|
cs.CIRCUIT_NO, cs.CIRCUIT_ITEM_ID,
|
||||||
|
COALESCE(cs.CONN_VOL_W, pos.POS_W, 0) AS CONN_W,
|
||||||
|
(SELECT mi.PNOW_W FROM M_ITEM mi WHERE mi.ITEM_ID = cs.CIRCUIT_ITEM_ID) AS PNOW_W
|
||||||
|
FROM CS cs
|
||||||
|
LEFT JOIN POS pos
|
||||||
|
ON pos.CIRCUIT_NO = cs.CIRCUIT_NO
|
||||||
|
AND pos.CIRCUIT_ITEM_ID = cs.CIRCUIT_ITEM_ID
|
||||||
)
|
)
|
||||||
|
|
||||||
-- 2026-06-05: SQL 은 W 합만 DECIMAL 로 정확히 반환. kW 변환·3자리 절사(FLOOR)는 모듈용량(totVolKw)과 동일하게 Java BigDecimal 에서 수행 → FLOAT 나눗셈 잔여(5.6899999999999995 / 5.339) 원천 차단
|
-- 2026-06-05: SQL 은 W 합만 DECIMAL 로 정확히 반환. kW 변환·3자리 절사(FLOOR)는 모듈용량(totVolKw)과 동일하게 Java BigDecimal 에서 수행 → FLOAT 나눗셈 잔여(5.6899999999999995 / 5.339) 원천 차단
|
||||||
SELECT CAST(SUM(MIN_VALUE) AS DECIMAL(18,3)) AS CERT_VOL_W
|
SELECT CAST(SUM(CASE WHEN CONN_W <= PNOW_W THEN CONN_W ELSE PNOW_W END) AS DECIMAL(18,3)) AS CERT_VOL_W
|
||||||
FROM CIRCUIT_AGG
|
FROM CIRCUIT_AGG
|
||||||
|
|
||||||
]]>
|
]]>
|
||||||
@ -1178,15 +1197,27 @@
|
|||||||
, PLAN_NO
|
, PLAN_NO
|
||||||
, ITEM_ID
|
, ITEM_ID
|
||||||
, CIRCUIT_CFG
|
, CIRCUIT_CFG
|
||||||
|
, CONN_VOL_W /* 2026-06-30: 유닛별 접속용량(W) — 인증용량 MIN 비교용 */
|
||||||
) VALUES (
|
) VALUES (
|
||||||
#{circuitNo}
|
#{circuitNo}
|
||||||
, #{objectNo}
|
, #{objectNo}
|
||||||
, #{planNo}
|
, #{planNo}
|
||||||
, #{itemId}
|
, #{itemId}
|
||||||
, #{circuitCfg}
|
, #{circuitCfg}
|
||||||
|
, #{connVolW}
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateEstimateCircuitConnVol" parameterType="com.interplug.qcast.biz.estimate.dto.ItemRequest">
|
||||||
|
/* sqlid : com.interplug.qcast.biz.estimate.updateEstimateCircuitConnVol */
|
||||||
|
/* 2026-06-30: 기존 데이터 백필용 — 회로 유닛별 접속용량(CONN_VOL_W)만 비파괴 UPDATE. 동일 PCS 모델 다중 유닛은 ITEM_ID 로 못 나누므로 CIRCUIT_NO 로 매칭 */
|
||||||
|
UPDATE T_PART_CIRCUIT_ITEM_ESTIMATE
|
||||||
|
SET CONN_VOL_W = #{connVolW}
|
||||||
|
WHERE OBJECT_NO = #{objectNo}
|
||||||
|
AND PLAN_NO = #{planNo}
|
||||||
|
AND CIRCUIT_NO = #{circuitNo}
|
||||||
|
</update>
|
||||||
|
|
||||||
<delete id="deleteEstimateRoofList" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest">
|
<delete id="deleteEstimateRoofList" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest">
|
||||||
/* sqlid : com.interplug.qcast.biz.estimate.deleteEstimateRoofList */
|
/* sqlid : com.interplug.qcast.biz.estimate.deleteEstimateRoofList */
|
||||||
DELETE FROM T_PART_ROOF_ESTIMATE
|
DELETE FROM T_PART_ROOF_ESTIMATE
|
||||||
@ -1445,6 +1476,7 @@
|
|||||||
, PLAN_NO
|
, PLAN_NO
|
||||||
, ITEM_ID
|
, ITEM_ID
|
||||||
, CIRCUIT_CFG
|
, CIRCUIT_CFG
|
||||||
|
, CONN_VOL_W /* 2026-06-30: 복제 시에도 유닛별 접속용량 보존(미보존 시 인증용량이 위치기반 폴백으로 떨어짐) */
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
PCIE.CIRCUIT_NO
|
PCIE.CIRCUIT_NO
|
||||||
@ -1452,6 +1484,7 @@
|
|||||||
, #{copyPlanNo} AS PLAN_NO
|
, #{copyPlanNo} AS PLAN_NO
|
||||||
, PCIE.ITEM_ID
|
, PCIE.ITEM_ID
|
||||||
, PCIE.CIRCUIT_CFG
|
, PCIE.CIRCUIT_CFG
|
||||||
|
, PCIE.CONN_VOL_W
|
||||||
FROM T_PART_CIRCUIT_ITEM_ESTIMATE PCIE WITH (NOLOCK)
|
FROM T_PART_CIRCUIT_ITEM_ESTIMATE PCIE WITH (NOLOCK)
|
||||||
WHERE PCIE.OBJECT_NO = #{objectNo}
|
WHERE PCIE.OBJECT_NO = #{objectNo}
|
||||||
AND PCIE.PLAN_NO = #{planNo}
|
AND PCIE.PLAN_NO = #{planNo}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user