690513:0920 Refactor Workflow module: Lint error #01
This commit is contained in:
@@ -56,6 +56,9 @@ export class ResponseCode extends UuidBaseEntity {
|
||||
createdAt!: Date;
|
||||
|
||||
// Relations
|
||||
@OneToMany(() => ResponseCodeRule, (rule: ResponseCodeRule) => rule.responseCode)
|
||||
@OneToMany(
|
||||
() => ResponseCodeRule,
|
||||
(rule: ResponseCodeRule) => rule.responseCode
|
||||
)
|
||||
rules?: ResponseCodeRule[];
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ export class ResponseCodeController {
|
||||
@Get('document-type/:documentTypeId')
|
||||
findByDocumentType(
|
||||
@Param('documentTypeId') documentTypeId: string,
|
||||
@Query('projectId') projectId?: string,
|
||||
@Query('projectId') projectId?: string
|
||||
) {
|
||||
return this.responseCodeService.findByDocumentType(
|
||||
Number(documentTypeId),
|
||||
projectId ? Number(projectId) : undefined,
|
||||
projectId ? Number(projectId) : undefined
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export class ResponseCodeService {
|
||||
@InjectRepository(ResponseCode)
|
||||
private readonly responseCodeRepo: Repository<ResponseCode>,
|
||||
@InjectRepository(ResponseCodeRule)
|
||||
private readonly responseCodeRuleRepo: Repository<ResponseCodeRule>,
|
||||
private readonly responseCodeRuleRepo: Repository<ResponseCodeRule>
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,9 @@ export class ResponseCodeService {
|
||||
* ดึง Response Codes ตาม Category (FR-006)
|
||||
* ใช้สำหรับแสดงผลใน Review page ตามประเภทเอกสาร
|
||||
*/
|
||||
async findByCategory(category: ResponseCodeCategory): Promise<ResponseCode[]> {
|
||||
async findByCategory(
|
||||
category: ResponseCodeCategory
|
||||
): Promise<ResponseCode[]> {
|
||||
return this.responseCodeRepo.find({
|
||||
where: { category, isActive: true },
|
||||
order: { code: 'ASC' },
|
||||
@@ -44,7 +46,7 @@ export class ResponseCodeService {
|
||||
*/
|
||||
async findByDocumentType(
|
||||
documentTypeId: number,
|
||||
projectId?: number,
|
||||
projectId?: number
|
||||
): Promise<ResponseCode[]> {
|
||||
// ดึง Rules ระดับ Project (ถ้ามี) หรือ Global default
|
||||
const rules = await this.responseCodeRuleRepo.find({
|
||||
@@ -64,7 +66,7 @@ export class ResponseCodeService {
|
||||
}
|
||||
|
||||
return Array.from(codeMap.values()).sort((a, b) =>
|
||||
a.code.localeCompare(b.code),
|
||||
a.code.localeCompare(b.code)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติเพื่อก่อสร้าง',
|
||||
descriptionEn: 'Approved for Construction',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -21,8 +25,13 @@ export const responseCodeSeedData = [
|
||||
code: '1B',
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติเพื่อก่อสร้าง พร้อมความเห็น (แก้ไขไม่ต้องส่งกลับ)',
|
||||
descriptionEn: 'Approved for Construction with Comments (No Resubmission Required)',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
descriptionEn:
|
||||
'Approved for Construction with Comments (No Resubmission Required)',
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -31,7 +40,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติ — มีผลต่อสัญญา/Change Order',
|
||||
descriptionEn: 'Approved — Contract Implications / Change Order Required',
|
||||
implications: { affectsSchedule: true, affectsCost: true, requiresContractReview: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: true,
|
||||
requiresContractReview: true,
|
||||
},
|
||||
notifyRoles: ['CONTRACT_MANAGER', 'QS_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -40,7 +53,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติทางเลือก — แตกต่างจากแบบสัญญา',
|
||||
descriptionEn: 'Approved Alternative — Differs from Contract Drawing',
|
||||
implications: { affectsSchedule: false, affectsCost: true, requiresContractReview: true },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: true,
|
||||
requiresContractReview: true,
|
||||
},
|
||||
notifyRoles: ['CONTRACT_MANAGER', 'DESIGN_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -49,7 +66,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติเพื่อวัตถุประสงค์การออกแบบเท่านั้น',
|
||||
descriptionEn: 'Approved for Design Purpose Only',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -58,7 +79,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติเพื่ออ้างอิงเท่านั้น',
|
||||
descriptionEn: 'Approved for Reference Only',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -67,7 +92,12 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติพร้อมเงื่อนไข ESG',
|
||||
descriptionEn: 'Approved with ESG Conditions',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false, requiresEiaAmendment: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
requiresEiaAmendment: true,
|
||||
},
|
||||
notifyRoles: ['EIA_OFFICER', 'HSE_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -76,7 +106,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'อนุมัติตามหมายเหตุ — ต้องแก้ไขและส่งกลับเพื่อตรวจสอบ',
|
||||
descriptionEn: 'Approved as Noted — Revise and Resubmit for Review',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -85,7 +119,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'ปฏิเสธ — ต้องแก้ไขและส่งใหม่',
|
||||
descriptionEn: 'Rejected — Revise and Resubmit',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: ['PROJECT_MANAGER', 'DESIGN_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -94,7 +132,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ENGINEERING,
|
||||
descriptionTh: 'ไม่เกี่ยวข้อง / ถอนคืน',
|
||||
descriptionEn: 'Not Applicable / Withdrawn',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -105,7 +147,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'อนุมัติวัสดุ/อุปกรณ์เพื่อจัดซื้อ',
|
||||
descriptionEn: 'Approved for Procurement',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -114,7 +160,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'อนุมัติวัสดุ/อุปกรณ์ พร้อมความเห็น',
|
||||
descriptionEn: 'Approved for Procurement with Comments',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -123,7 +173,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'อนุมัติ — มีผลต่อค่าใช้จ่าย',
|
||||
descriptionEn: 'Approved — Cost Implications',
|
||||
implications: { affectsSchedule: false, affectsCost: true, requiresContractReview: true },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: true,
|
||||
requiresContractReview: true,
|
||||
},
|
||||
notifyRoles: ['QS_MANAGER', 'PROCUREMENT_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -132,7 +186,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'ส่งข้อมูลเพิ่มเติม',
|
||||
descriptionEn: 'Provide Additional Information',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -141,7 +199,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'ปฏิเสธ — ไม่เป็นไปตามสัญญา',
|
||||
descriptionEn: 'Rejected — Non-Compliant with Contract',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: ['PROJECT_MANAGER', 'PROCUREMENT_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -150,7 +212,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.MATERIAL,
|
||||
descriptionTh: 'ไม่เกี่ยวข้อง / ถอนคืน',
|
||||
descriptionEn: 'Not Applicable / Withdrawn',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -161,7 +227,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.CONTRACT,
|
||||
descriptionTh: 'อนุมัติ — ไม่มีผลต่อสัญญา',
|
||||
descriptionEn: 'Approved — No Contract Implication',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -170,7 +240,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.CONTRACT,
|
||||
descriptionTh: 'อนุมัติ — ต้องออก Change Order',
|
||||
descriptionEn: 'Approved — Change Order Required',
|
||||
implications: { affectsSchedule: true, affectsCost: true, requiresContractReview: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: true,
|
||||
requiresContractReview: true,
|
||||
},
|
||||
notifyRoles: ['CONTRACT_MANAGER', 'QS_MANAGER', 'PROJECT_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -179,7 +253,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.CONTRACT,
|
||||
descriptionTh: 'อยู่ระหว่างการพิจารณา — ต้องการข้อมูลเพิ่มเติม',
|
||||
descriptionEn: 'Under Review — Additional Information Required',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -188,7 +266,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.CONTRACT,
|
||||
descriptionTh: 'ปฏิเสธ — ขัดต่อเงื่อนไขสัญญา',
|
||||
descriptionEn: 'Rejected — Contradicts Contract Terms',
|
||||
implications: { affectsSchedule: true, affectsCost: true, requiresContractReview: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: true,
|
||||
requiresContractReview: true,
|
||||
},
|
||||
notifyRoles: ['CONTRACT_MANAGER', 'LEGAL_TEAM', 'PROJECT_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -199,7 +281,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.TESTING,
|
||||
descriptionTh: 'อนุมัติผลการทดสอบ / ส่งมอบ',
|
||||
descriptionEn: 'Approved — Test Results / Handover Accepted',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -208,7 +294,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.TESTING,
|
||||
descriptionTh: 'ผ่านพร้อมข้อบกพร่องเล็กน้อย — ต้องแก้ไขและรายงาน',
|
||||
descriptionEn: 'Passed with Minor Defects — Rectify and Report',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: ['QA_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -217,7 +307,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.TESTING,
|
||||
descriptionTh: 'ไม่ผ่าน — ต้องทดสอบซ้ำ',
|
||||
descriptionEn: 'Failed — Retest Required',
|
||||
implications: { affectsSchedule: true, affectsCost: true, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: true,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: ['PROJECT_MANAGER', 'QA_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -228,7 +322,11 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ESG,
|
||||
descriptionTh: 'อนุมัติ — เป็นไปตามมาตรฐาน ESG',
|
||||
descriptionEn: 'Approved — ESG Compliant',
|
||||
implications: { affectsSchedule: false, affectsCost: false, requiresContractReview: false },
|
||||
implications: {
|
||||
affectsSchedule: false,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
},
|
||||
notifyRoles: [],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -237,7 +335,12 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ESG,
|
||||
descriptionTh: 'อนุมัติพร้อมเงื่อนไขด้านสิ่งแวดล้อม',
|
||||
descriptionEn: 'Approved with Environmental Conditions',
|
||||
implications: { affectsSchedule: true, affectsCost: false, requiresContractReview: false, requiresEiaAmendment: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: false,
|
||||
requiresContractReview: false,
|
||||
requiresEiaAmendment: true,
|
||||
},
|
||||
notifyRoles: ['EIA_OFFICER', 'HSE_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -246,7 +349,12 @@ export const responseCodeSeedData = [
|
||||
category: ResponseCodeCategory.ESG,
|
||||
descriptionTh: 'ปฏิเสธ — ไม่เป็นไปตามข้อกำหนด EIA/ESG',
|
||||
descriptionEn: 'Rejected — Non-Compliant with EIA/ESG Requirements',
|
||||
implications: { affectsSchedule: true, affectsCost: true, requiresContractReview: false, requiresEiaAmendment: true },
|
||||
implications: {
|
||||
affectsSchedule: true,
|
||||
affectsCost: true,
|
||||
requiresContractReview: false,
|
||||
requiresEiaAmendment: true,
|
||||
},
|
||||
notifyRoles: ['EIA_OFFICER', 'HSE_MANAGER', 'PROJECT_MANAGER'],
|
||||
isSystem: true,
|
||||
},
|
||||
@@ -261,13 +369,16 @@ export async function seedResponseCodes(dataSource: DataSource): Promise<void> {
|
||||
|
||||
for (const data of responseCodeSeedData) {
|
||||
const exists = await repo.findOne({
|
||||
where: { code: data.code, category: data.category as ResponseCodeCategory },
|
||||
where: {
|
||||
code: data.code,
|
||||
category: data.category,
|
||||
},
|
||||
});
|
||||
|
||||
if (!exists) {
|
||||
const entity = repo.create({
|
||||
code: data.code,
|
||||
category: data.category as ResponseCodeCategory,
|
||||
category: data.category,
|
||||
descriptionTh: data.descriptionTh,
|
||||
descriptionEn: data.descriptionEn,
|
||||
implications: data.implications,
|
||||
|
||||
@@ -35,14 +35,14 @@ export class ImplicationsService {
|
||||
responseCode.code,
|
||||
affectsSchedule,
|
||||
affectsCost,
|
||||
requiresContractReview,
|
||||
requiresContractReview
|
||||
);
|
||||
|
||||
const actionRequired = this.buildActionList(
|
||||
responseCode.code,
|
||||
requiresContractReview,
|
||||
requiresEiaAmendment,
|
||||
affectsCost,
|
||||
affectsCost
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -60,7 +60,7 @@ export class ImplicationsService {
|
||||
code: string,
|
||||
affectsSchedule: boolean,
|
||||
affectsCost: boolean,
|
||||
requiresContractReview: boolean,
|
||||
requiresContractReview: boolean
|
||||
): CodeImplicationResult['severity'] {
|
||||
// Code 3 (Rejected) = CRITICAL เสมอ
|
||||
if (code === '3') return 'CRITICAL';
|
||||
@@ -72,7 +72,8 @@ export class ImplicationsService {
|
||||
if (affectsSchedule && affectsCost) return 'HIGH';
|
||||
|
||||
// มีผลต่ออย่างใดอย่างหนึ่ง
|
||||
if (requiresContractReview || affectsSchedule || affectsCost) return 'MEDIUM';
|
||||
if (requiresContractReview || affectsSchedule || affectsCost)
|
||||
return 'MEDIUM';
|
||||
|
||||
return 'LOW';
|
||||
}
|
||||
@@ -81,7 +82,7 @@ export class ImplicationsService {
|
||||
code: string,
|
||||
requiresContractReview: boolean,
|
||||
requiresEiaAmendment: boolean,
|
||||
affectsCost: boolean,
|
||||
affectsCost: boolean
|
||||
): string[] {
|
||||
const actions: string[] = [];
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ export class InheritanceService {
|
||||
|
||||
constructor(
|
||||
@InjectRepository(ResponseCodeRule)
|
||||
private readonly ruleRepo: Repository<ResponseCodeRule>,
|
||||
private readonly ruleRepo: Repository<ResponseCodeRule>
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ export class InheritanceService {
|
||||
*/
|
||||
async resolveMatrix(
|
||||
documentTypeId: number,
|
||||
projectId?: number,
|
||||
projectId?: number
|
||||
): Promise<ResolvedMatrix[]> {
|
||||
// ดึง global rules (projectId IS NULL)
|
||||
const globalRules = await this.ruleRepo.find({
|
||||
@@ -63,7 +63,7 @@ export class InheritanceService {
|
||||
|
||||
// Build map: responseCodeId → project rule
|
||||
const projectRuleMap = new Map(
|
||||
projectRules.map((r) => [r.responseCodeId, r]),
|
||||
projectRules.map((r) => [r.responseCodeId, r])
|
||||
);
|
||||
|
||||
// Merge: project overrides global
|
||||
@@ -96,7 +96,7 @@ export class InheritanceService {
|
||||
// เพิ่ม project-only rules (ไม่มี global parent)
|
||||
for (const projectRule of projectRules) {
|
||||
const alreadyMerged = globalRules.some(
|
||||
(g) => g.responseCodeId === projectRule.responseCodeId,
|
||||
(g) => g.responseCodeId === projectRule.responseCodeId
|
||||
);
|
||||
if (!alreadyMerged) {
|
||||
merged.push({
|
||||
@@ -113,7 +113,7 @@ export class InheritanceService {
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`Resolved ${merged.length} rules for docType=${documentTypeId}, project=${projectId}`,
|
||||
`Resolved ${merged.length} rules for docType=${documentTypeId}, project=${projectId}`
|
||||
);
|
||||
|
||||
return merged;
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// File: src/modules/response-code/services/matrix-management.service.ts
|
||||
// CRUD สำหรับ ResponseCodeRule (global + project overrides) (T061, FR-022)
|
||||
import { Injectable, Logger, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import {
|
||||
Injectable,
|
||||
Logger,
|
||||
NotFoundException,
|
||||
BadRequestException,
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { ResponseCodeRule } from '../entities/response-code-rule.entity';
|
||||
@@ -23,7 +28,7 @@ export class MatrixManagementService {
|
||||
@InjectRepository(ResponseCodeRule)
|
||||
private readonly ruleRepo: Repository<ResponseCodeRule>,
|
||||
@InjectRepository(ResponseCode)
|
||||
private readonly codeRepo: Repository<ResponseCode>,
|
||||
private readonly codeRepo: Repository<ResponseCode>
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -35,7 +40,9 @@ export class MatrixManagementService {
|
||||
});
|
||||
|
||||
if (!code) {
|
||||
throw new NotFoundException(`ResponseCode not found: ${dto.responseCodePublicId}`);
|
||||
throw new NotFoundException(
|
||||
`ResponseCode not found: ${dto.responseCodePublicId}`
|
||||
);
|
||||
}
|
||||
|
||||
if (code.isSystem && !dto.isEnabled) {
|
||||
@@ -52,8 +59,10 @@ export class MatrixManagementService {
|
||||
|
||||
if (existing) {
|
||||
existing.isEnabled = dto.isEnabled;
|
||||
existing.requiresComments = dto.requiresComments ?? existing.requiresComments;
|
||||
existing.triggersNotification = dto.triggersNotification ?? existing.triggersNotification;
|
||||
existing.requiresComments =
|
||||
dto.requiresComments ?? existing.requiresComments;
|
||||
existing.triggersNotification =
|
||||
dto.triggersNotification ?? existing.triggersNotification;
|
||||
return this.ruleRepo.save(existing);
|
||||
}
|
||||
|
||||
@@ -74,7 +83,7 @@ export class MatrixManagementService {
|
||||
*/
|
||||
async getRulesByDocType(
|
||||
documentTypeId: number,
|
||||
projectId?: number,
|
||||
projectId?: number
|
||||
): Promise<ResponseCodeRule[]> {
|
||||
const where: Record<string, unknown> = { documentTypeId };
|
||||
if (projectId !== undefined) {
|
||||
@@ -93,10 +102,14 @@ export class MatrixManagementService {
|
||||
* ลบ project override (หวนกลับใช้ global default)
|
||||
*/
|
||||
async deleteProjectOverride(rulePublicId: string): Promise<void> {
|
||||
const rule = await this.ruleRepo.findOne({ where: { publicId: rulePublicId } });
|
||||
const rule = await this.ruleRepo.findOne({
|
||||
where: { publicId: rulePublicId },
|
||||
});
|
||||
if (!rule) throw new NotFoundException(rulePublicId);
|
||||
if (!rule.projectId) {
|
||||
throw new BadRequestException('Cannot delete a global rule — disable it instead');
|
||||
throw new BadRequestException(
|
||||
'Cannot delete a global rule — disable it instead'
|
||||
);
|
||||
}
|
||||
await this.ruleRepo.remove(rule);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export class NotificationTriggerService {
|
||||
@InjectRepository(User)
|
||||
private readonly userRepo: Repository<User>,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly implicationsService: ImplicationsService,
|
||||
private readonly implicationsService: ImplicationsService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -30,14 +30,16 @@ export class NotificationTriggerService {
|
||||
responseCodePublicId: string,
|
||||
rfaPublicId: string,
|
||||
documentNumber: string,
|
||||
reviewerUserId: number,
|
||||
_reviewerUserId: number
|
||||
): Promise<void> {
|
||||
const responseCode = await this.responseCodeRepo.findOne({
|
||||
where: { publicId: responseCodePublicId },
|
||||
});
|
||||
|
||||
if (!responseCode) {
|
||||
this.logger.warn(`Response code not found for notification trigger: ${responseCodePublicId}`);
|
||||
this.logger.warn(
|
||||
`Response code not found for notification trigger: ${responseCodePublicId}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,12 +77,12 @@ export class NotificationTriggerService {
|
||||
type: 'SYSTEM',
|
||||
entityType: 'rfa',
|
||||
entityId: rfaPublicId as unknown as number,
|
||||
}),
|
||||
),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
`Triggered ${notifyRoles.length} role notifications for code ${codeLabel} on document ${documentNumber}`,
|
||||
`Triggered ${notifyRoles.length} role notifications for code ${codeLabel} on document ${documentNumber}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user