fix(oa-board): align stage overtime followups
This commit is contained in:
parent
adc97204ff
commit
19ce18fa0b
@ -3,6 +3,7 @@ import ExcelJS from 'exceljs'
|
||||
import { handleRequest, jsonError } from '@/server/core/response'
|
||||
import { ErrorCode } from '@/server/core/errors'
|
||||
import {
|
||||
hasOaBoardProjectOvertime,
|
||||
oaBoardService,
|
||||
type OaBoardProjectListFilter,
|
||||
} from '@/server/services/oa-board.service'
|
||||
@ -382,7 +383,7 @@ export async function GET(request: NextRequest) {
|
||||
overallTargetHours: item.overallTargetHours ?? '',
|
||||
overallActualHours: item.overallActualHours ?? '',
|
||||
overallTimeoutHours: item.overallTimeoutHours ?? '',
|
||||
overallTimeoutFlag: item.overallTimeoutFlag ? '是' : '否',
|
||||
overallTimeoutFlag: hasOaBoardProjectOvertime(item) ? '是' : '否',
|
||||
firstImageUrl: item.styleImages[0]?.url || '',
|
||||
workflowLink: item.formSummary.workflowLink || '',
|
||||
})
|
||||
@ -494,7 +495,7 @@ export async function GET(request: NextRequest) {
|
||||
creatorLabel: item.originatorUserName || '',
|
||||
overallTargetHours: item.overallTargetHours ?? '',
|
||||
overallActualHours: item.overallActualHours ?? '',
|
||||
isOvertime: item.overallTimeoutFlag ? '是' : '否',
|
||||
isOvertime: hasOaBoardProjectOvertime(item) ? '是' : '否',
|
||||
...timeoutFollowupValues,
|
||||
...Object.fromEntries(
|
||||
TIMING_DETAIL_DEFINITIONS.map((field) => [
|
||||
|
||||
@ -615,11 +615,13 @@ function filterOaBoardItems(items: OaBoardProjectListItemDTO[], filters: FilterS
|
||||
return false
|
||||
}
|
||||
|
||||
if (filters.timeoutStatus === 'YES' && !item.overallTimeoutFlag) {
|
||||
const isOvertime = item.overallTimeoutFlag || getOvertimeStages(item).length > 0
|
||||
|
||||
if (filters.timeoutStatus === 'YES' && !isOvertime) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (filters.timeoutStatus === 'NO' && item.overallTimeoutFlag) {
|
||||
if (filters.timeoutStatus === 'NO' && isOvertime) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1814,6 +1816,7 @@ function DetailTableRow({
|
||||
}) {
|
||||
const timingFields = buildTimingDetailFields(item)
|
||||
const overtimeStages = getOvertimeStages(item)
|
||||
const isOvertime = item.overallTimeoutFlag || overtimeStages.length > 0
|
||||
const timeoutFollowupSummary = getTimeoutFollowupSummary(overtimeStages, timeoutFollowups)
|
||||
const competitorLink = formatCompetitorLinkSummary(item.formSummary.competitorLink)
|
||||
const primaryStyleImage = item.styleImages[0]
|
||||
@ -1989,8 +1992,8 @@ function DetailTableRow({
|
||||
<td className="px-3 py-3 align-top text-[11px]">{formatDayValue(item.overallActualHours)}</td>
|
||||
<td className="px-3 py-3 align-top text-[11px]">
|
||||
<StatusBadge
|
||||
label={item.overallTimeoutFlag ? '是' : '否'}
|
||||
tone={item.overallTimeoutFlag ? 'danger' : 'success'}
|
||||
label={isOvertime ? '是' : '否'}
|
||||
tone={isOvertime ? 'danger' : 'success'}
|
||||
/>
|
||||
</td>
|
||||
<td className="px-3 py-3 align-top text-[11px]">
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
type OaBoardFlowType,
|
||||
type OaBoardStageGraphLane,
|
||||
} from './oa-board.constants'
|
||||
import { pickCurrentOverdueStageMetric } from '@/lib/oa-board-overtime'
|
||||
import {
|
||||
queryOaBoardPreview,
|
||||
queryOaBoardSnapshotLatestSyncedAt,
|
||||
@ -713,7 +714,7 @@ export function createMockOaBoardDashboard(): OaBoardDashboardDTO {
|
||||
items,
|
||||
summary: {
|
||||
totalProjects: items.length,
|
||||
timeoutProjects: items.filter((item) => item.overallTimeoutFlag).length,
|
||||
timeoutProjects: items.filter(hasOaBoardProjectOvertime).length,
|
||||
runningProjects: items.filter((item) => item.overallStatus === 'RUNNING').length,
|
||||
completedProjects: items.filter((item) => item.overallStatus === 'COMPLETED').length,
|
||||
productTypes,
|
||||
@ -1071,6 +1072,37 @@ function resolveCurrentApproverDisplay(item: OaBoardProjectListItemDTO) {
|
||||
return Array.from(new Set(owners)).join(';')
|
||||
}
|
||||
|
||||
export function hasOaBoardProjectOvertime(item: OaBoardProjectListItemDTO) {
|
||||
if (item.overallTimeoutFlag) return true
|
||||
|
||||
const stageNames = splitApprovalStages(
|
||||
item.formSummary.approvalStageDisplay || item.currentApprovalStageName,
|
||||
)
|
||||
const currentNodeNames = splitApprovalStages(item.formSummary.currentNodeDisplay)
|
||||
const hasCurrentNodeOvertime = item.nodeAssessments.some((assessment) => {
|
||||
if (assessment.status !== 'RUNNING' || !assessment.isOvertime) return false
|
||||
if (
|
||||
assessment.targetHours === null ||
|
||||
assessment.actualHours === null ||
|
||||
assessment.overtimeHours === null ||
|
||||
assessment.overtimeHours <= 0
|
||||
) {
|
||||
return false
|
||||
}
|
||||
if (currentNodeNames.length > 0 && !currentNodeNames.includes(assessment.nodeName)) return false
|
||||
if (
|
||||
stageNames.length > 0 &&
|
||||
assessment.approvalStageName &&
|
||||
!stageNames.includes(assessment.approvalStageName)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return hasCurrentNodeOvertime || Boolean(pickCurrentOverdueStageMetric(stageNames, item.timelineMetrics))
|
||||
}
|
||||
|
||||
export function filterOaBoardProjectItems(
|
||||
allItems: OaBoardProjectListItemDTO[],
|
||||
filter: OaBoardProjectListFilter = {},
|
||||
@ -1199,15 +1231,17 @@ export function filterOaBoardProjectItems(
|
||||
return false
|
||||
}
|
||||
|
||||
if (filter.timeoutOnly && !item.overallTimeoutFlag) {
|
||||
const isOvertime = hasOaBoardProjectOvertime(item)
|
||||
|
||||
if (filter.timeoutOnly && !isOvertime) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (filter.timeoutStatus === 'YES' && !item.overallTimeoutFlag) {
|
||||
if (filter.timeoutStatus === 'YES' && !isOvertime) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (filter.timeoutStatus === 'NO' && item.overallTimeoutFlag) {
|
||||
if (filter.timeoutStatus === 'NO' && isOvertime) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1278,7 +1312,7 @@ export class OaBoardService {
|
||||
items,
|
||||
summary: {
|
||||
totalProjects: items.length,
|
||||
timeoutProjects: items.filter((item) => item.overallTimeoutFlag).length,
|
||||
timeoutProjects: items.filter(hasOaBoardProjectOvertime).length,
|
||||
runningProjects: items.filter((item) => item.overallStatus === 'RUNNING').length,
|
||||
completedProjects: items.filter((item) => item.overallStatus === 'COMPLETED').length,
|
||||
productTypes,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user