feat(08-05-contract-detail-workspace): 完成合同详情与终止状态治理
这个提交包含在:
@@ -7,6 +7,23 @@ const ExcelJS = require('exceljs');
|
||||
const { createPrismaClient } = require('../prismaClient');
|
||||
|
||||
const SUPPORTED_TYPES = ['projects', 'members', 'milestones', 'risks', 'contracts'];
|
||||
const CONTRACT_IMPORT_STATUS_VALUES = new Set(['draft', 'active', 'archived']);
|
||||
|
||||
function validateContractImportStatus(importedStatus, currentStatus = null) {
|
||||
if (!CONTRACT_IMPORT_STATUS_VALUES.has(importedStatus)) {
|
||||
return `status_not_importable:${importedStatus}`;
|
||||
}
|
||||
if (currentStatus === 'terminated') {
|
||||
return 'terminated_contract_is_final';
|
||||
}
|
||||
if (currentStatus === 'archived') {
|
||||
return 'archived_contract_requires_correction_api';
|
||||
}
|
||||
if (currentStatus && currentStatus !== importedStatus) {
|
||||
return 'status_change_requires_contract_api';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function printHelp() {
|
||||
console.log(`用法:
|
||||
@@ -310,7 +327,7 @@ async function handleRisks({ prisma, rows, apply, summary }) {
|
||||
async function handleContracts({ prisma, rows, apply, summary }) {
|
||||
assertRequiredHeaders(rows, ['contract_no', 'counterparty_name', 'summary', 'archive_location', 'owner_employee_no']);
|
||||
const refs = await buildReferenceMaps(prisma);
|
||||
const existing = new Map((await prisma.contractRegistry.findMany({ select: { id: true, contract_no: true } })).map((item) => [item.contract_no, item]));
|
||||
const existing = new Map((await prisma.contractRegistry.findMany({ select: { id: true, contract_no: true, status: true } })).map((item) => [item.contract_no, item]));
|
||||
|
||||
for (const row of rows) {
|
||||
const data = row.data;
|
||||
@@ -325,6 +342,14 @@ async function handleContracts({ prisma, rows, apply, summary }) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const importedStatus = data.status || 'active';
|
||||
const current = existing.get(data.contract_no);
|
||||
const statusError = validateContractImportStatus(importedStatus, current?.status ?? null);
|
||||
if (statusError) {
|
||||
pushError(summary, row.rowNumber, statusError);
|
||||
continue;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
contract_no: data.contract_no,
|
||||
project_id: project?.id ?? null,
|
||||
@@ -334,10 +359,9 @@ async function handleContracts({ prisma, rows, apply, summary }) {
|
||||
archive_location: data.archive_location,
|
||||
offline_archive_no: data.offline_archive_no || null,
|
||||
owner_employee_id: owner.id,
|
||||
status: data.status || 'active',
|
||||
status: importedStatus,
|
||||
};
|
||||
|
||||
const current = existing.get(data.contract_no);
|
||||
if (!current) summary.createCount += 1;
|
||||
else summary.updateCount += 1;
|
||||
|
||||
@@ -400,7 +424,11 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error?.message ?? error);
|
||||
process.exit(1);
|
||||
});
|
||||
if (require.main === module) {
|
||||
main().catch((error) => {
|
||||
console.error(error?.message ?? error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { validateContractImportStatus };
|
||||
|
||||
在新工单中引用
屏蔽一个用户