[as fr] 하수도 기본계획 무조건 병렬 Join 결재로 표시되도록 정리함
This commit is contained in:
@@ -54,14 +54,49 @@ const ROLE_USER01_ATRZ_STATUS_ACTIONS: Record<
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Fork-Join (병렬 결재 6인 체제: 관로2 + 시설2 + 정책병합2) 전용 상태별 버튼 액션 매핑
|
||||
* - Stage 2: 관로/시설 실무검토자(ATRZ02), 부서승인자(ATRZ03)
|
||||
* - Stage 3: 정책총괄 종합병합자(ATRZ04), 최종회신자(ATRZ99)
|
||||
* - 하수도기본계획은 100% 무조건 Fork-Join 결재 라인으로 동작
|
||||
*/
|
||||
const ROLE_USER01_FORK_JOIN_ATRZ_STATUS_ACTIONS: Record<
|
||||
string,
|
||||
Record<string, SewerBscPlanViewButtonAction[]>
|
||||
> = {
|
||||
ER: {
|
||||
ATRZ01: [SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.dsgntRvwr],
|
||||
},
|
||||
TE: {
|
||||
ATRZ02: [
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.rvwStrg,
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.rvwCmptn,
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.dmndSplmnt,
|
||||
],
|
||||
ATRZ03: [SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzRply],
|
||||
ATRZ04: [SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzAprv],
|
||||
ATRZ99: [SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzRply],
|
||||
},
|
||||
TP: {},
|
||||
};
|
||||
|
||||
function resolveButtonConfigs(
|
||||
actions: SewerBscPlanViewButtonAction[],
|
||||
): SewerBscPlanViewButtonAction[] {
|
||||
return actions.map((action) => SEWER_BSC_PLAN_VIEW_BUTTON_ACTION[action]);
|
||||
}
|
||||
|
||||
interface GetButtonConfigsOptions {
|
||||
const PENDING_APPROVAL_ACTIONS = new Set<SewerBscPlanViewButtonAction>([
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.rvwCmptn,
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzAprv,
|
||||
SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzRply,
|
||||
]);
|
||||
|
||||
export interface GetButtonConfigsOptions {
|
||||
hasPendingApprovalRequest?: boolean;
|
||||
isForkJoin?: boolean;
|
||||
branchSeCd?: string;
|
||||
branchSttsCd?: string;
|
||||
}
|
||||
|
||||
function resolveRoleUser01AtrzButtonActions(
|
||||
@@ -69,11 +104,28 @@ function resolveRoleUser01AtrzButtonActions(
|
||||
atrzSeComCdList: string[],
|
||||
options?: GetButtonConfigsOptions,
|
||||
): SewerBscPlanViewButtonAction[] {
|
||||
if (prgrsSttsComCd === "TE" && options?.hasPendingApprovalRequest === false) {
|
||||
return [];
|
||||
let effectiveStatus = prgrsSttsComCd;
|
||||
const isForkJoin = options?.isForkJoin ?? true;
|
||||
|
||||
if (isForkJoin && options?.branchSttsCd) {
|
||||
switch (options.branchSttsCd) {
|
||||
case "SUPPLEMENT":
|
||||
// 본인 브랜치가 보완요청 중이면 검토/승인 버튼 숨김
|
||||
return [];
|
||||
case "COMPLETED":
|
||||
// 본인 브랜치 승인 완료 후 타 브랜치 대기 중이면 검토/승인 버튼 숨김
|
||||
return [];
|
||||
case "WAITING":
|
||||
return [];
|
||||
case "IN_PROGRESS":
|
||||
effectiveStatus = "TE";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const atrzStatusMap = ROLE_USER01_ATRZ_STATUS_ACTIONS[prgrsSttsComCd];
|
||||
const atrzStatusMap = isForkJoin
|
||||
? ROLE_USER01_FORK_JOIN_ATRZ_STATUS_ACTIONS[effectiveStatus]
|
||||
: ROLE_USER01_ATRZ_STATUS_ACTIONS[effectiveStatus];
|
||||
if (!atrzStatusMap || atrzSeComCdList.length === 0) return [];
|
||||
|
||||
const seen = new Set<SewerBscPlanViewButtonAction>();
|
||||
@@ -90,7 +142,11 @@ function resolveRoleUser01AtrzButtonActions(
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
return actions.filter((action) => {
|
||||
const needsPendingApproval = PENDING_APPROVAL_ACTIONS.has(action);
|
||||
if (needsPendingApproval && options?.hasPendingApprovalRequest === false) return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function needsRoleUser01AtrzResolve(
|
||||
|
||||
@@ -101,3 +101,19 @@ export const sewerBscPlanRegistSchema = z.object({
|
||||
});
|
||||
|
||||
export type SewerBscPlanRegistFormData = z.infer<typeof sewerBscPlanRegistSchema>;
|
||||
|
||||
/**
|
||||
* 하수도기본계획 전자결재 전용 공종코드 정규화 헬퍼
|
||||
* 하수도기본계획은 변경구분(CP, AP, MP)과 무관하게 상시 관로/시설/총괄 병렬 6인 결재 대상
|
||||
*/
|
||||
export function normalizeTaskSeComCdForElapr(_taskSeComCd?: string | null): string {
|
||||
return "SF_SP";
|
||||
}
|
||||
|
||||
/**
|
||||
* 전자결재 복합병렬결재(Fork-Join) 대상 업무 여부 판단
|
||||
* 하수도기본계획은 100% 무조건 Fork-Join 대상
|
||||
*/
|
||||
export function isForkJoinTask(_taskSeComCd?: string | null): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
type ElaprTmpltPickerConfirmPayload,
|
||||
ElaprTmpltPickerDialog,
|
||||
hasCurrentUserPendingApprovalRequest,
|
||||
useElaprBranchesByDocNo,
|
||||
useElaprDocPrgrsByDocNo,
|
||||
} from "@/entities/elapr";
|
||||
import { instlSncnService } from "@/entities/instl-sncn";
|
||||
@@ -42,6 +43,10 @@ import {
|
||||
buildTechReviewReplyPayload,
|
||||
toSplmntDmndSaveItem,
|
||||
} from "../../lib/payload-utils";
|
||||
import {
|
||||
isForkJoinTask,
|
||||
normalizeTaskSeComCdForElapr,
|
||||
} from "../../lib/sewer-bsc-plan-regist-schema";
|
||||
import { type ChecklistFormState } from "../../model/view-types";
|
||||
import type { TechReviewOpinionSectionHandle } from "../sections/tech-review-opinion-section";
|
||||
|
||||
@@ -85,31 +90,92 @@ function FloatingActionButtons({
|
||||
const docNo = data.detDto?.sewerBscPlanDocNo ?? sewerBscPlanDocNo;
|
||||
const isRegister = data.detDto?.rgtr === userInfo?.userUnqId;
|
||||
|
||||
// 하수도기본계획은 100% 무조건 Fork-Join (6인 체제)
|
||||
const isForkJoin = isForkJoinTask(data.detDto?.taskSeComCd);
|
||||
|
||||
const needsAtrzResolve = needsRoleUser01AtrzResolve(dtlInstCd, prgrsSttsComCd);
|
||||
const needsTeApprovalCheck = needsAtrzResolve && prgrsSttsComCd === "TE";
|
||||
const { data: elaprDocPrgrsList = [], isLoading: isElaprDocPrgrsLoading } =
|
||||
useElaprDocPrgrsByDocNo(needsTeApprovalCheck ? docNo : null);
|
||||
const { data: elaprBranchList = [], isLoading: isElaprBranchLoading } =
|
||||
useElaprBranchesByDocNo(needsTeApprovalCheck && isForkJoin ? docNo : null);
|
||||
|
||||
const hasPendingApprovalRequest = hasCurrentUserPendingApprovalRequest(
|
||||
elaprDocPrgrsList,
|
||||
userInfo?.userUnqId,
|
||||
);
|
||||
|
||||
const currentUserPrgrsRow = elaprDocPrgrsList.find(
|
||||
(row) => row.aprvrUuid?.toLowerCase() === userInfo?.userUnqId?.toLowerCase(),
|
||||
);
|
||||
const userPendingPrgrs = elaprDocPrgrsList.find(
|
||||
(row) =>
|
||||
row.aprvrUuid?.toLowerCase() === userInfo?.userUnqId?.toLowerCase() &&
|
||||
row.atrzPrgrsSttsComCd === "ATRZ_PRGRS_002",
|
||||
);
|
||||
const userBranchId = userPendingPrgrs?.branchId ?? currentUserPrgrsRow?.branchId;
|
||||
const userBranchSeCd = (userPendingPrgrs?.branchSeCd ?? currentUserPrgrsRow?.branchSeCd) as
|
||||
| "SP"
|
||||
| "SF"
|
||||
| "TOTAL_AGG"
|
||||
| "MAIN"
|
||||
| undefined;
|
||||
const userPendingBranchSeCd = userPendingPrgrs?.branchSeCd ?? userBranchSeCd;
|
||||
const userPendingAtrzSeComCd = userPendingPrgrs?.atrzSeComCd;
|
||||
|
||||
const effectiveAtrzSeComCdList = useMemo(() => {
|
||||
if (isForkJoin && userPendingAtrzSeComCd) {
|
||||
return [userPendingAtrzSeComCd];
|
||||
}
|
||||
if (isForkJoin && currentUserPrgrsRow?.atrzSeComCd) {
|
||||
return [currentUserPrgrsRow.atrzSeComCd];
|
||||
}
|
||||
return atrzSeComCdList;
|
||||
}, [atrzSeComCdList, currentUserPrgrsRow?.atrzSeComCd, isForkJoin, userPendingAtrzSeComCd]);
|
||||
|
||||
const userBranchSttsCd = useMemo<string | undefined>(() => {
|
||||
if (!isForkJoin || !userBranchSeCd) return undefined;
|
||||
|
||||
const matchedBranch = userBranchId
|
||||
? elaprBranchList.find((b) => b.branchId === userBranchId)
|
||||
: elaprBranchList.findLast((b) => b.branchSeCd === userBranchSeCd);
|
||||
if (matchedBranch?.branchSttsCd) {
|
||||
return matchedBranch.branchSttsCd;
|
||||
}
|
||||
|
||||
if (prgrsSttsComCd === "TE") {
|
||||
return "IN_PROGRESS";
|
||||
}
|
||||
if (prgrsSttsComCd === "TP") {
|
||||
return "COMPLETED";
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [elaprBranchList, isForkJoin, prgrsSttsComCd, userBranchId, userBranchSeCd]);
|
||||
|
||||
const actionButtons = useMemo(() => {
|
||||
if (needsAtrzResolve && isRvwLoginUserLoading) return [];
|
||||
if (needsTeApprovalCheck && isElaprDocPrgrsLoading) return [];
|
||||
return getButtonConfigs(dtlInstCd, prgrsSttsComCd, atrzSeComCdList, {
|
||||
if (isForkJoin && isElaprBranchLoading) return [];
|
||||
return getButtonConfigs(dtlInstCd, prgrsSttsComCd, effectiveAtrzSeComCdList, {
|
||||
hasPendingApprovalRequest: needsTeApprovalCheck ? hasPendingApprovalRequest : undefined,
|
||||
isForkJoin,
|
||||
branchSeCd: userBranchSeCd,
|
||||
branchSttsCd: userBranchSttsCd,
|
||||
});
|
||||
}, [
|
||||
atrzSeComCdList,
|
||||
dtlInstCd,
|
||||
effectiveAtrzSeComCdList,
|
||||
hasPendingApprovalRequest,
|
||||
isElaprBranchLoading,
|
||||
isElaprDocPrgrsLoading,
|
||||
isForkJoin,
|
||||
isRvwLoginUserLoading,
|
||||
needsAtrzResolve,
|
||||
needsTeApprovalCheck,
|
||||
prgrsSttsComCd,
|
||||
userBranchSeCd,
|
||||
userBranchSttsCd,
|
||||
]);
|
||||
|
||||
const canEdit =
|
||||
@@ -254,6 +320,9 @@ function FloatingActionButtons({
|
||||
dmndCn: data.activeDtlDto?.bizOtlnCn ?? "",
|
||||
elaprCycl: 1,
|
||||
docPrgrsSttsComCd: data.detDto?.prgrsSttsComCd,
|
||||
taskSeComCd: "SF_SP",
|
||||
forkJoinSeCd: "FORK_JOIN",
|
||||
crntStageNo: 2,
|
||||
elaprPrgrsSttsList: buildElaprPrgrsSttsListFromAplnRows(aplnRows),
|
||||
};
|
||||
await executeAction({
|
||||
@@ -264,6 +333,9 @@ function FloatingActionButtons({
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.AS_ELAPR_SERVICE.ELAPR_DMND, "findDocPrgrsByDocNo", docNo],
|
||||
});
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.AS_ELAPR_SERVICE.ELAPR_BRANCH, "findBranchesByDocNo", docNo],
|
||||
});
|
||||
}
|
||||
|
||||
async function handleRvwStrgClick() {
|
||||
@@ -389,16 +461,33 @@ function FloatingActionButtons({
|
||||
보완요청
|
||||
</Button>
|
||||
)}
|
||||
{shouldShowButton(SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzAprv) && (
|
||||
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isProcessing}>
|
||||
결재(승인)
|
||||
</Button>
|
||||
)}
|
||||
{shouldShowButton(SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzRply) && (
|
||||
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isProcessing}>
|
||||
결재(회신)
|
||||
</Button>
|
||||
)}
|
||||
{shouldShowButton(SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzAprv) &&
|
||||
(!isForkJoin ||
|
||||
(userPendingBranchSeCd === "TOTAL_AGG" && userPendingAtrzSeComCd === "ATRZ04")) && (
|
||||
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isProcessing}>
|
||||
{isForkJoin ? "결재 (병합)" : "결재(승인)"}
|
||||
</Button>
|
||||
)}
|
||||
{shouldShowButton(SEWER_BSC_PLAN_VIEW_BUTTON_ACTION.atrzRply) &&
|
||||
(!isForkJoin ||
|
||||
(userPendingBranchSeCd !== "TOTAL_AGG" && userPendingAtrzSeComCd === "ATRZ03") ||
|
||||
(userPendingBranchSeCd === "TOTAL_AGG" && userPendingAtrzSeComCd === "ATRZ99")) && (
|
||||
<Button
|
||||
color={
|
||||
isForkJoin && userPendingBranchSeCd !== "TOTAL_AGG"
|
||||
? "green"
|
||||
: undefined
|
||||
}
|
||||
onClick={() => setActiveDialog("elaprApproval")}
|
||||
disabled={isProcessing}
|
||||
>
|
||||
{isForkJoin
|
||||
? userPendingBranchSeCd === "TOTAL_AGG"
|
||||
? "결재 (환경청에 회신)"
|
||||
: "결재 (병합에 회신)"
|
||||
: "결재(회신)"}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -406,6 +495,7 @@ function FloatingActionButtons({
|
||||
open={activeDialog === "elaprTmplt"}
|
||||
onClose={() => setActiveDialog(null)}
|
||||
docSeComCd={docSeComCd}
|
||||
taskSeComCd="SF_SP"
|
||||
onConfirm={handleElaprTmpltConfirm}
|
||||
/>
|
||||
|
||||
@@ -424,6 +514,12 @@ function FloatingActionButtons({
|
||||
currentUserUuid={userInfo?.userUnqId ?? ""}
|
||||
onSuccess={() => {
|
||||
queryClient.invalidateQueries({ queryKey: sewerBscPlanKeys.all });
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.AS_ELAPR_SERVICE.ELAPR_DMND, "findDocPrgrsByDocNo", docNo],
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.AS_ELAPR_SERVICE.ELAPR_BRANCH, "findBranchesByDocNo", docNo],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -127,7 +127,10 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) {
|
||||
/>
|
||||
<BasicInfoSection det={detDto} dtl={activeDtlDto} />
|
||||
<ContactInfoSection dtl={activeDtlDto} />
|
||||
<ElaprDocPrgrsStatus elaprDocNo={detDto.sewerBscPlanDocNo} />
|
||||
<ElaprDocPrgrsStatus
|
||||
elaprDocNo={detDto.sewerBscPlanDocNo}
|
||||
taskSeComCd="SF_SP"
|
||||
/>
|
||||
<OutlineSection
|
||||
otlnList={otlnList}
|
||||
dtl={activeDtlDto}
|
||||
|
||||
Reference in New Issue
Block a user