From 5b726e69c8fe41ba890520f13776949f3a2d2690 Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 6 Feb 2026 14:47:13 +0700 Subject: [PATCH] =?UTF-8?q?Migrate=20add=20table=20profileSalaryBackup=20&?= =?UTF-8?q?=20=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88=E0=B8=A1=20insert=20?= =?UTF-8?q?=E0=B8=A3=E0=B8=B1=E0=B8=81=E0=B8=A9=E0=B8=B2=E0=B8=81=E0=B8=B2?= =?UTF-8?q?=E0=B8=A3=20=E0=B9=81=E0=B8=A5=E0=B8=B0=E0=B8=8A=E0=B9=88?= =?UTF-8?q?=E0=B8=A7=E0=B8=A2=E0=B8=A3=E0=B8=B2=E0=B8=8A=E0=B8=81=E0=B8=B2?= =?UTF-8?q?=E0=B8=A3=20=20#2292?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/ProfileSalaryController.ts | 9 +- .../ProfileSalaryEmployeeController.ts | 8 +- .../ProfileSalaryTempController.ts | 101 +++++- src/entities/ProfileSalaryBackup.ts | 295 ++++++++++++++++++ ...291424-create_table_profileSalaryBackup.ts | 14 + 5 files changed, 406 insertions(+), 21 deletions(-) create mode 100644 src/entities/ProfileSalaryBackup.ts create mode 100644 src/migration/1770349291424-create_table_profileSalaryBackup.ts diff --git a/src/controllers/ProfileSalaryController.ts b/src/controllers/ProfileSalaryController.ts index 78975593..4736337a 100644 --- a/src/controllers/ProfileSalaryController.ts +++ b/src/controllers/ProfileSalaryController.ts @@ -397,8 +397,7 @@ export class ProfileSalaryController extends Controller { const record = await this.salaryRepo.find({ where: { profileId: profile.id, - // commandCode: In(["5", "6", "7"]) - commandCode: In(["5", "6", "7"]), + commandCode: In(["5", "6", "7", "19"]), }, order: { order: "ASC" }, }); @@ -477,7 +476,7 @@ export class ProfileSalaryController extends Controller { if (_workflow == false) await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId); const record = await this.salaryRepo.find({ - where: { profileId: profileId, commandCode: In(["5", "6", "7"]) }, + where: { profileId: profileId, commandCode: In(["5", "6", "7", "19"]) }, order: { order: "ASC" }, }); // const result = record.map((r) => ({ @@ -842,7 +841,7 @@ export class ProfileSalaryController extends Controller { let _workflow = await new permission().Workflow(req, profileId, "SYS_SALARY_OFFICER"); if (_workflow == false) await new permission().PermissionGet(req, "SYS_SALARY_OFFICER"); const record = await this.salaryRepo.find({ - where: { profileId: profileId, commandCode: In(["5", "6", "7"]) }, + where: { profileId: profileId, commandCode: In(["5", "6", "7", "19"]) }, order: { order: "ASC" }, }); return new HttpSuccess(record); @@ -909,6 +908,7 @@ export class ProfileSalaryController extends Controller { if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ"; else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ"; else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ"; + else if (body.commandCode == "19") body.commandName = "ไม่ได้เลื่อนเงินเดือน/ค่าจ้าง"; } Object.assign(data, { ...body, ...meta }); const history = new ProfileSalaryHistory(); @@ -1032,6 +1032,7 @@ export class ProfileSalaryController extends Controller { if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ"; else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ"; else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ"; + else if (body.commandCode == "19") body.commandName = "ไม่ได้เลื่อนเงินเดือน/ค่าจ้าง"; } Object.assign(record, body); Object.assign(history, { ...record, id: undefined }); diff --git a/src/controllers/ProfileSalaryEmployeeController.ts b/src/controllers/ProfileSalaryEmployeeController.ts index 36576788..f113a2ba 100644 --- a/src/controllers/ProfileSalaryEmployeeController.ts +++ b/src/controllers/ProfileSalaryEmployeeController.ts @@ -49,7 +49,7 @@ export class ProfileSalaryEmployeeController extends Controller { throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); } const record = await this.salaryRepo.find({ - where: { profileEmployeeId: profile.id, commandCode: In(["5", "6", "7"]) }, + where: { profileEmployeeId: profile.id, commandCode: In(["5", "6", "7", "19"]) }, order: { order: "ASC" }, }); return new HttpSuccess(record); @@ -96,7 +96,7 @@ export class ProfileSalaryEmployeeController extends Controller { if (_workflow == false) await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileId); const record = await this.salaryRepo.find({ - where: { profileEmployeeId: profileId, commandCode: In(["5", "6", "7"]) }, + where: { profileEmployeeId: profileId, commandCode: In(["5", "6", "7", "19"]) }, order: { order: "ASC" }, }); return new HttpSuccess(record); @@ -322,7 +322,7 @@ export class ProfileSalaryEmployeeController extends Controller { let _workflow = await new permission().Workflow(req, profileId, "SYS_WAGE"); if (_workflow == false) await new permission().PermissionGet(req, "SYS_WAGE"); const record = await this.salaryRepo.find({ - where: { profileEmployeeId: profileId, commandCode: In(["5", "6", "7"]) }, + where: { profileEmployeeId: profileId, commandCode: In(["5", "6", "7", "19"]) }, order: { order: "ASC" }, }); return new HttpSuccess(record); @@ -395,6 +395,7 @@ export class ProfileSalaryEmployeeController extends Controller { if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ"; else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ"; else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ"; + else if (body.commandCode == "19") body.commandName = "ไม่ได้เลื่อนเงินเดือน/ค่าจ้าง"; } Object.assign(data, { ...body, ...meta }); const history = new ProfileSalaryHistory(); @@ -528,6 +529,7 @@ export class ProfileSalaryEmployeeController extends Controller { if (body.commandCode == "7") body.commandName = "เงินพิเศษอื่น ๆ"; else if (body.commandCode == "6") body.commandName = "เลื่อนเงินเดือนกรณีอื่น ๆ"; else if (body.commandCode == "5") body.commandName = "เลื่อนเงินเดือนตามปกติ"; + else if (body.commandCode == "19") body.commandName = "ไม่ได้เลื่อนเงินเดือน/ค่าจ้าง"; } Object.assign(record, body); Object.assign(history, { ...record, id: undefined }); diff --git a/src/controllers/ProfileSalaryTempController.ts b/src/controllers/ProfileSalaryTempController.ts index 95713278..b85bc85b 100644 --- a/src/controllers/ProfileSalaryTempController.ts +++ b/src/controllers/ProfileSalaryTempController.ts @@ -35,7 +35,9 @@ import { CreatePositionSalaryEditHistory, PositionSalaryEditHistory, } from "../entities/PositionSalaryEditHistory"; - +import { ProfileSalaryBackup } from "../entities/ProfileSalaryBackup"; +import { ProfileActposition } from "../entities/ProfileActposition"; +import { ProfileAssistance } from "../entities/ProfileAssistance"; @Route("api/v1/org/profile/salaryTemp") @Tags("ProfileSalaryTemp") @Security("bearerAuth") @@ -1328,12 +1330,6 @@ export class ProfileSalaryTempController extends Controller { // const toUpdate = salaryTemps.filter((t) => t.salaryId && t.isEdit && !t.isDelete); const backupTemp = salaryTemps; const toInsert = salaryTemps.filter((t) => !t.isDelete); - const dateNow = new Date(); - const metaUpdate = { - lastUpdateUserId: req.user.sub, - lastUpdateFullName: req.user.name, - lastUpdatedAt: dateNow, - }; // delete profile salary temp await queryRunner.manager.delete(ProfileSalaryTemp, { @@ -1341,6 +1337,23 @@ export class ProfileSalaryTempController extends Controller { }); // add insert to profile salary backup + const profileSalaryBeforeDelete = await queryRunner.manager.find(ProfileSalary, { + where: { + ...(isOfficer + ? { profileId: body.profileId } + : { profileEmployeeId: body.profileId }), + }, + }); + + if (profileSalaryBeforeDelete.length > 0) { + const backupRows = profileSalaryBeforeDelete.map(({ id, ...salary }) => + queryRunner.manager.create(ProfileSalaryBackup, { + ...salary, + profileSalaryId: id, + }) + ); + await queryRunner.manager.insert(ProfileSalaryBackup, backupRows); + } // delete profile salary await queryRunner.manager.delete(ProfileSalary, { @@ -1366,18 +1379,78 @@ export class ProfileSalaryTempController extends Controller { * 5. INSERT (bulk) * ========================= */ if (toInsert.length > 0) { - const metaCreate = { + const dateNow = new Date(); + const metaCreated = { createdUserId: req.user.sub, createdFullName: req.user.name, createdAt: dateNow, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + lastUpdatedAt: dateNow, }; - const insertData = toInsert.map(({ id, ...data }) => ({ - ...data, - ...metaCreate, - ...metaUpdate, - })); - await queryRunner.manager.insert(ProfileSalary, insertData); + const salaryRows = toInsert.filter( + x => !["17", "18"].includes(x.commandCode) + ); + // ส่งไปรักษาการ + const actPositionRows = toInsert.filter( + x => x.commandCode === "17" + ); + // ส่งไปช่วยราชการ + const assistanceRows = toInsert.filter( + x => x.commandCode === "18" + ); + + if (salaryRows.length) { + await queryRunner.manager.insert( + ProfileSalary, + salaryRows.map(({ id, ...data }) => ({ + ...data, + ...metaCreated, + })) + ); + } + + if (actPositionRows.length) { + await queryRunner.manager.insert( + ProfileActposition, + actPositionRows.map(x => ({ + profileId: x.profileId, + profileEmployeeId: x.profileEmployeeId, + dateStart: x.commandDateAffect, + dateEnd: x.commandDateAffect, + posNo: x.posNo, + position: x.positionName, + commandId: x.commandId, + refCommandNo: x.commandNo, + refCommandDate: x.commandDateAffect, + status: false, + isDeleted: false, + ...metaCreated, + })) + ); + } + + if (assistanceRows.length) { + await queryRunner.manager.insert( + ProfileAssistance, + assistanceRows.map(x => ({ + profileId: x.profileId, + profileEmployeeId: x.profileEmployeeId, + agency: x.orgRoot, + dateStart: x.commandDateAffect, + dateEnd: x.commandDateAffect, + commandId: x.commandId, + commandNo: x.commandNo, + commandName: x.commandName, + refCommandDate: x.commandDateSign, + refId: x.refId, + status: "DONE", + isUpload: false, + ...metaCreated, + })) + ); + } } // insert profile salary temp new diff --git a/src/entities/ProfileSalaryBackup.ts b/src/entities/ProfileSalaryBackup.ts new file mode 100644 index 00000000..29cdd325 --- /dev/null +++ b/src/entities/ProfileSalaryBackup.ts @@ -0,0 +1,295 @@ +import { Entity, Column, Double } from "typeorm"; +import { EntityBase } from "./base/Base"; + +@Entity("profileSalaryBackup") +export class ProfileSalaryBackup extends EntityBase { + + @Column({ + nullable: true, + length: 40, + comment: "อ้างอิง profileSalary (no FK constraint)", + type: "uuid", + default: null, + }) + profileSalaryId: string; + + @Column({ + nullable: true, + length: 40, + comment: "อ้างอิง profile (no FK constraint)", + type: "uuid", + default: null, + }) + profileId: string; + + @Column({ + nullable: true, + length: 40, + comment: "อ้างอิง ProfileEmployee (no FK constraint)", + default: null, + }) + profileEmployeeId: string; + + @Column({ + nullable: true, + comment: "เรียงลำดับใหมาตามการนำเข้า", + default: null, + }) + order: number; + + @Column({ + nullable: true, + comment: "เลขที่คำสั่ง", + default: null, + }) + commandNo: string; + + @Column({ + nullable: true, + comment: "ปีที่ออกคำสั่ง", + default: null, + }) + commandYear: number; + + @Column({ + comment: "คำสั่งวันที่", + type: "datetime", + nullable: true, + }) + commandDateSign: Date; + + @Column({ + comment: "คำสั่งมีผลวันที่", + type: "datetime", + nullable: true, + }) + commandDateAffect: Date; + + @Column({ + nullable: true, + comment: "รหัสประเภทของคำสั่ง", + default: null, + }) + commandCode: string; + + @Column({ + nullable: true, + comment: "ชื่อประเภทคำสั่ง", + default: null, + }) + commandName: string; + + @Column({ + nullable: true, + length: 40, + comment: "ตัวย่อเลขที่ตำแหน่ง", + default: null, + }) + posNoAbb: string; + + @Column({ + nullable: true, + length: 40, + comment: "เลขที่ตำแหน่ง", + default: null, + }) + posNo: string; + + @Column({ + nullable: true, + length: 255, + comment: "ตำแหน่ง", + default: null, + }) + positionName: string; + + @Column({ + nullable: true, + length: 255, + comment: "ประเภทตำแหน่ง", + default: null, + }) + positionType: string; + + @Column({ + nullable: true, + length: 255, + comment: "ระดับตำแหน่ง", + default: null, + }) + positionLevel: string; + + @Column({ + nullable: true, + comment: "ระดับของเก่าที่ยังไม่เทียบเท่าแบบแท่ง", + default: null, + }) + positionCee: string; + + @Column({ + nullable: true, + comment: "root name", + default: null, + }) + orgRoot: string; + + @Column({ + nullable: true, + comment: "child1 name", + default: null, + }) + orgChild1: string; + + @Column({ + nullable: true, + comment: "child2 name", + default: null, + }) + orgChild2: string; + + @Column({ + nullable: true, + comment: "child3 name", + default: null, + }) + orgChild3: string; + + @Column({ + nullable: true, + comment: "child4 name", + default: null, + }) + orgChild4: string; + + @Column({ + nullable: true, + length: 255, + comment: "ตำแหน่งทางการบริหาร", + default: null, + }) + positionExecutive: string; + + @Column({ + comment: "เงินเดือนฐาน", + default: 0, + nullable: true, + type: "double", + }) + amount: Double; + + @Column({ + comment: "เงินพิเศษ", + default: 0, + nullable: true, + type: "double", + }) + amountSpecial: Double; + + @Column({ + comment: "เงินประจำตำแหน่ง", + default: 0, + nullable: true, + type: "double", + }) + positionSalaryAmount: Double; + + @Column({ + comment: "เงินค่าตอบแทนรายเดือน", + default: 0, + nullable: true, + type: "double", + }) + mouthSalaryAmount: Double; + + @Column({ + nullable: true, + type: "text", + comment: "หมายเหตุ", + default: null, + }) + remark: string; + + @Column({ + nullable: true, + comment: "refId", + default: null, + }) + refId: string; + + @Column({ + comment: "วันที่", + type: "datetime", + nullable: true, + }) + dateGovernment: Date; + + @Column({ + nullable: true, + comment: "เข้ารับราชการ", + default: null, + }) + isGovernment: boolean; + + @Column({ + comment: "ข้อมูลจาก Entry", + default: false, + }) + isEntry: boolean; + + @Column({ + nullable: true, + length: 255, + comment: "ด้านของตำแหน่ง", + default: null, + }) + positionPathSide: string; + + @Column({ + nullable: true, + length: 255, + comment: "ตำแหน่งในสายงาน", + default: null, + }) + positionLine: string; + + @Column({ + nullable: true, + length: 40, + comment: "อ้างอิง command (no FK constraint)", + default: null, + }) + commandId: string; + + @Column({ + nullable: true, + length: 255, + comment: "หน่วยงานที่ออกคำสั่ง", + default: null, + }) + posNumCodeSit: string; + + @Column({ + nullable: true, + length: 255, + comment: "หน่วยงานที่ออกคำสั่ง(ตัวย่อ)", + default: null, + }) + posNumCodeSitAbb: string; + + @Column({ + nullable: true, + length: 255, + comment: "ด้านทางการบริหาร", + default: null, + }) + positionExecutiveField: string; + + @Column({ + nullable: true, + length: 255, + comment: "ด้าน/สาขา", + default: null, + }) + positionArea: string; + +} \ No newline at end of file diff --git a/src/migration/1770349291424-create_table_profileSalaryBackup.ts b/src/migration/1770349291424-create_table_profileSalaryBackup.ts new file mode 100644 index 00000000..2f5c5b8d --- /dev/null +++ b/src/migration/1770349291424-create_table_profileSalaryBackup.ts @@ -0,0 +1,14 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateTableProfileSalaryBackup1770349291424 implements MigrationInterface { + name = 'CreateTableProfileSalaryBackup1770349291424' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`profileSalaryBackup\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'System Administrator', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'System Administrator', \`profileSalaryId\` varchar(40) NULL COMMENT 'อ้างอิง profileSalary (no FK constraint)', \`profileId\` varchar(40) NULL COMMENT 'อ้างอิง profile (no FK constraint)', \`profileEmployeeId\` varchar(40) NULL COMMENT 'อ้างอิง ProfileEmployee (no FK constraint)', \`order\` int NULL COMMENT 'เรียงลำดับใหมาตามการนำเข้า', \`commandNo\` varchar(255) NULL COMMENT 'เลขที่คำสั่ง', \`commandYear\` int NULL COMMENT 'ปีที่ออกคำสั่ง', \`commandDateSign\` datetime NULL COMMENT 'คำสั่งวันที่', \`commandDateAffect\` datetime NULL COMMENT 'คำสั่งมีผลวันที่', \`commandCode\` varchar(255) NULL COMMENT 'รหัสประเภทของคำสั่ง', \`commandName\` varchar(255) NULL COMMENT 'ชื่อประเภทคำสั่ง', \`posNoAbb\` varchar(40) NULL COMMENT 'ตัวย่อเลขที่ตำแหน่ง', \`posNo\` varchar(40) NULL COMMENT 'เลขที่ตำแหน่ง', \`positionName\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`positionType\` varchar(255) NULL COMMENT 'ประเภทตำแหน่ง', \`positionLevel\` varchar(255) NULL COMMENT 'ระดับตำแหน่ง', \`positionCee\` varchar(255) NULL COMMENT 'ระดับของเก่าที่ยังไม่เทียบเท่าแบบแท่ง', \`orgRoot\` varchar(255) NULL COMMENT 'root name', \`orgChild1\` varchar(255) NULL COMMENT 'child1 name', \`orgChild2\` varchar(255) NULL COMMENT 'child2 name', \`orgChild3\` varchar(255) NULL COMMENT 'child3 name', \`orgChild4\` varchar(255) NULL COMMENT 'child4 name', \`positionExecutive\` varchar(255) NULL COMMENT 'ตำแหน่งทางการบริหาร', \`amount\` double NULL COMMENT 'เงินเดือนฐาน' DEFAULT '0', \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ' DEFAULT '0', \`positionSalaryAmount\` double NULL COMMENT 'เงินประจำตำแหน่ง' DEFAULT '0', \`mouthSalaryAmount\` double NULL COMMENT 'เงินค่าตอบแทนรายเดือน' DEFAULT '0', \`remark\` text NULL COMMENT 'หมายเหตุ', \`refId\` varchar(255) NULL COMMENT 'refId', \`dateGovernment\` datetime NULL COMMENT 'วันที่', \`isGovernment\` tinyint NULL COMMENT 'เข้ารับราชการ', \`isEntry\` tinyint NOT NULL COMMENT 'ข้อมูลจาก Entry' DEFAULT 0, \`positionPathSide\` varchar(255) NULL COMMENT 'ด้านของตำแหน่ง', \`positionLine\` varchar(255) NULL COMMENT 'ตำแหน่งในสายงาน', \`commandId\` varchar(40) NULL COMMENT 'อ้างอิง command (no FK constraint)', \`posNumCodeSit\` varchar(255) NULL COMMENT 'หน่วยงานที่ออกคำสั่ง', \`posNumCodeSitAbb\` varchar(255) NULL COMMENT 'หน่วยงานที่ออกคำสั่ง(ตัวย่อ)', \`positionExecutiveField\` varchar(255) NULL COMMENT 'ด้านทางการบริหาร', \`positionArea\` varchar(255) NULL COMMENT 'ด้าน/สาขา', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE \`profileSalaryBackup\``); + } + +}