108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
/**
|
|
* 完成工单前置校验:生产接收登记 + 步骤负责人/计划开始时间/产出物条码。
|
|
*/
|
|
import type { ProductionWorkOrderItem } from '@/api/production-work-order'
|
|
import {
|
|
fetchProductionTaskDetail,
|
|
fetchProductionTaskList
|
|
} from '@/api/production-task'
|
|
import { fetchProductionReceptionBySampleCode } from '@/api/sample-production-reception'
|
|
import {
|
|
classifyTasksForCompleteWorkOrderGate,
|
|
findTaskStepGateIssue,
|
|
needsProductionReceptionGate
|
|
} from '@/utils/production-complete-work-order-gate-logic'
|
|
|
|
export {
|
|
classifyTasksForCompleteWorkOrderGate,
|
|
findTaskStepGateIssue,
|
|
needsProductionReceptionGate
|
|
} from '@/utils/production-complete-work-order-gate-logic'
|
|
|
|
export type CompleteWorkOrderGateOk = { ok: true }
|
|
|
|
export type CompleteWorkOrderGateBlock =
|
|
| { ok: false; action: 'sample_reception'; message: string }
|
|
| { ok: false; action: 'no_tasks'; message: string }
|
|
| {
|
|
ok: false
|
|
action: 'open_task_execution'
|
|
message: string
|
|
taskId: string
|
|
taskName: string
|
|
stepId?: string
|
|
}
|
|
|
|
export type CompleteWorkOrderGateResult = CompleteWorkOrderGateOk | CompleteWorkOrderGateBlock
|
|
|
|
export async function checkCompleteProductionWorkOrderGate(
|
|
row: ProductionWorkOrderItem
|
|
): Promise<CompleteWorkOrderGateResult> {
|
|
if (needsProductionReceptionGate(row)) {
|
|
const sampleCode = String(row.sampleCode || '').trim()
|
|
if (!sampleCode) {
|
|
return {
|
|
ok: false,
|
|
action: 'sample_reception',
|
|
message: '缺少样本编码,无法校验生产接收登记,请先完善样本信息'
|
|
}
|
|
}
|
|
const receptionRes = await fetchProductionReceptionBySampleCode({
|
|
sampleCode,
|
|
sourceType: row.receptionSource
|
|
})
|
|
const acceptConclusion = String(receptionRes?.qcReception?.acceptConclusion || '').trim()
|
|
if (acceptConclusion && acceptConclusion !== 'js') {
|
|
// 质检拒收等:无需生产接收登记
|
|
} else {
|
|
const prod = receptionRes?.productionReception
|
|
if (!prod || !String(prod.id || '').trim()) {
|
|
return {
|
|
ok: false,
|
|
action: 'sample_reception',
|
|
message: '请先填写生产接收登记'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const tasksRes = await fetchProductionTaskList({
|
|
workOrderId: row.id,
|
|
pageSize: 100,
|
|
includeStepSummary: true
|
|
})
|
|
const taskDecision = classifyTasksForCompleteWorkOrderGate(tasksRes?.list || [])
|
|
if (taskDecision.kind === 'no_tasks') {
|
|
return {
|
|
ok: false,
|
|
action: 'no_tasks',
|
|
message: '请先派发生产任务后再完成工单'
|
|
}
|
|
}
|
|
if (taskDecision.kind === 'all_done') {
|
|
return { ok: true }
|
|
}
|
|
|
|
const tasks = taskDecision.incomplete
|
|
const details = await Promise.all(
|
|
tasks.map((t: Record<string, any>) => fetchProductionTaskDetail(String(t.id)))
|
|
)
|
|
|
|
for (let i = 0; i < details.length; i++) {
|
|
const detail = details[i] || {}
|
|
const task = tasks[i] || {}
|
|
const issue = findTaskStepGateIssue(detail)
|
|
if (!issue) continue
|
|
return {
|
|
ok: false,
|
|
action: 'open_task_execution',
|
|
message: issue.message,
|
|
taskId: String(detail.id || task.id || ''),
|
|
taskName: String(detail.taskName || task.taskName || ''),
|
|
stepId: issue.stepId
|
|
}
|
|
}
|
|
|
|
return { ok: true }
|
|
}
|