Merge branch 'develop' into feat/org-move-draf-current

* develop:
  fix: ช่วยรายการและรักษาการ endDate null
  fix salaryId set null
  fix script move positionSalaryTemp to positionSalary
This commit is contained in:
Warunee Tamkoo 2026-02-09 09:55:30 +07:00
commit 22fc43fe17
3 changed files with 83 additions and 49 deletions

View file

@ -38,6 +38,17 @@ import {
import { ProfileSalaryBackup } from "../entities/ProfileSalaryBackup"; import { ProfileSalaryBackup } from "../entities/ProfileSalaryBackup";
import { ProfileActposition } from "../entities/ProfileActposition"; import { ProfileActposition } from "../entities/ProfileActposition";
import { ProfileAssistance } from "../entities/ProfileAssistance"; import { ProfileAssistance } from "../entities/ProfileAssistance";
const SALARY_COMMAND_CODES = {
ACT_POSITION: "17", // รักษาการ
ASSISTANCE: "18", // ช่วยราชการ
} as const;
class ConfirmDoneSalaryDto {
profileId: string;
type: "OFFICER" | "EMPLOYEE";
}
@Route("api/v1/org/profile/salaryTemp") @Route("api/v1/org/profile/salaryTemp")
@Tags("ProfileSalaryTemp") @Tags("ProfileSalaryTemp")
@Security("bearerAuth") @Security("bearerAuth")
@ -1013,7 +1024,10 @@ export class ProfileSalaryTempController extends Controller {
if (!salary) { if (!salary) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
return new HttpSuccess({ salaryNew: salary, salaryOld: salary.profileSalary }); return new HttpSuccess({
salaryNew: salary,
salaryOld: salary.profileSalary,
});
} }
/** /**
@ -1242,7 +1256,9 @@ export class ProfileSalaryTempController extends Controller {
profile.statusCheckEdit = "PENDING"; profile.statusCheckEdit = "PENDING";
await this.profileRepo.save(profile); await this.profileRepo.save(profile);
} else { } else {
const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileId }); const profile = await this.profileEmployeeRepo.findOneBy({
id: body.profileId,
});
if (!profile) { if (!profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
@ -1271,7 +1287,9 @@ export class ProfileSalaryTempController extends Controller {
profile.statusCheckEdit = "EDITED"; profile.statusCheckEdit = "EDITED";
await this.profileRepo.save(profile); await this.profileRepo.save(profile);
} else { } else {
const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileId }); const profile = await this.profileEmployeeRepo.findOneBy({
id: body.profileId,
});
if (!profile) { if (!profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
@ -1290,7 +1308,7 @@ export class ProfileSalaryTempController extends Controller {
@Post("confirm-done") @Post("confirm-done")
public async confirmDoneSalary( public async confirmDoneSalary(
@Request() req: RequestWithUser, @Request() req: RequestWithUser,
@Body() body: { profileId: string; type: string }, @Body() body: ConfirmDoneSalaryDto,
) { ) {
const queryRunner = AppDataSource.createQueryRunner(); const queryRunner = AppDataSource.createQueryRunner();
await queryRunner.connect(); await queryRunner.connect();
@ -1303,8 +1321,12 @@ export class ProfileSalaryTempController extends Controller {
* 1. Load Profile * 1. Load Profile
* ========================= */ * ========================= */
const profile = isOfficer const profile = isOfficer
? await queryRunner.manager.findOne(Profile, { where: { id: body.profileId } }) ? await queryRunner.manager.findOne(Profile, {
: await queryRunner.manager.findOne(ProfileEmployee, { where: { id: body.profileId } }); where: { id: body.profileId },
})
: await queryRunner.manager.findOne(ProfileEmployee, {
where: { id: body.profileId },
});
if (!profile) { if (!profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบข้อมูล profile"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบข้อมูล profile");
@ -1325,24 +1347,26 @@ export class ProfileSalaryTempController extends Controller {
} }
/* ========================= /* =========================
* 3. Split Update / Insert * 3. Temp restore
* ========================= */ * ========================= */
// const toUpdate = salaryTemps.filter((t) => t.salaryId && t.isEdit && !t.isDelete); const originalTempRows = salaryTemps; // เก็บไว้ restore หลัง insert ProfileSalary เสร็จ
const backupTemp = salaryTemps;
const toInsert = salaryTemps.filter((t) => !t.isDelete); const toInsert = salaryTemps.filter((t) => !t.isDelete);
// delete profile salary temp /* =========================
* 4. ProfileSalaryTemp ProfileSalary
* ========================= */
await queryRunner.manager.delete(ProfileSalaryTemp, { await queryRunner.manager.delete(ProfileSalaryTemp, {
...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }), ...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }),
}); });
// add insert to profile salary backup // backup profile salary before delete
const profileSalaryBeforeDelete = await queryRunner.manager.find(ProfileSalary, { const profileSalaryBeforeDelete = await queryRunner.manager.find(ProfileSalary, {
where: { where: {
...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }), ...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }),
}, },
}); });
// insert ProfileSalary backup to ProfileSalaryBackup
if (profileSalaryBeforeDelete.length > 0) { if (profileSalaryBeforeDelete.length > 0) {
const backupRows = profileSalaryBeforeDelete.map(({ id, ...salary }) => const backupRows = profileSalaryBeforeDelete.map(({ id, ...salary }) =>
queryRunner.manager.create(ProfileSalaryBackup, { queryRunner.manager.create(ProfileSalaryBackup, {
@ -1358,21 +1382,6 @@ export class ProfileSalaryTempController extends Controller {
...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }), ...(isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }),
}); });
/* =========================
* 4. UPDATE
* ========================= */
// for (const temp of toUpdate) {
// const { id, salaryId, isDelete, isEdit, ...data } = temp;
// await queryRunner.manager.update(
// ProfileSalary,
// { id: salaryId },
// {
// ...data,
// ...metaUpdate,
// },
// );
// }
/* ========================= /* =========================
* 5. INSERT (bulk) * 5. INSERT (bulk)
* ========================= */ * ========================= */
@ -1387,12 +1396,22 @@ export class ProfileSalaryTempController extends Controller {
lastUpdatedAt: dateNow, lastUpdatedAt: dateNow,
}; };
const salaryRows = toInsert.filter((x) => !["17", "18"].includes(x.commandCode)); // แยกข้อมูลตามประเภทการ insert
// ส่งไปรักษาการ const { salaryRows, actPositionRows, assistanceRows } = toInsert.reduce<{
const actPositionRows = toInsert.filter((x) => x.commandCode === "17"); salaryRows: ProfileSalaryTemp[];
// ส่งไปช่วยราชการ actPositionRows: ProfileSalaryTemp[];
const assistanceRows = toInsert.filter((x) => x.commandCode === "18"); assistanceRows: ProfileSalaryTemp[];
}>(
(acc, x) => {
if (x.commandCode === SALARY_COMMAND_CODES.ACT_POSITION) acc.actPositionRows.push(x);
else if (x.commandCode === SALARY_COMMAND_CODES.ASSISTANCE) acc.assistanceRows.push(x);
else acc.salaryRows.push(x);
return acc;
},
{ salaryRows: [], actPositionRows: [], assistanceRows: [] },
);
// Insert ProfileSalary
if (salaryRows.length) { if (salaryRows.length) {
await queryRunner.manager.insert( await queryRunner.manager.insert(
ProfileSalary, ProfileSalary,
@ -1403,14 +1422,15 @@ export class ProfileSalaryTempController extends Controller {
); );
} }
if (actPositionRows.length > 0) { // Insert ProfileActposition
if (actPositionRows.length) {
await queryRunner.manager.insert( await queryRunner.manager.insert(
ProfileActposition, ProfileActposition,
actPositionRows.map((x) => ({ actPositionRows.map((x) => ({
profileId: x.profileId, profileId: x.profileId,
profileEmployeeId: x.profileEmployeeId, profileEmployeeId: x.profileEmployeeId,
dateStart: x.commandDateAffect, dateStart: x.commandDateAffect,
dateEnd: x.commandDateAffect, dateEnd: null,
posNo: x.posNo, posNo: x.posNo,
position: x.positionName, position: x.positionName,
commandId: x.commandId, commandId: x.commandId,
@ -1423,7 +1443,8 @@ export class ProfileSalaryTempController extends Controller {
); );
} }
if (assistanceRows.length > 0) { // Insert ProfileAssistance
if (assistanceRows.length) {
await queryRunner.manager.insert( await queryRunner.manager.insert(
ProfileAssistance, ProfileAssistance,
assistanceRows.map((x) => ({ assistanceRows.map((x) => ({
@ -1431,7 +1452,7 @@ export class ProfileSalaryTempController extends Controller {
profileEmployeeId: x.profileEmployeeId, profileEmployeeId: x.profileEmployeeId,
agency: x.orgRoot, agency: x.orgRoot,
dateStart: x.commandDateAffect, dateStart: x.commandDateAffect,
dateEnd: x.commandDateAffect, dateEnd: null,
commandId: x.commandId, commandId: x.commandId,
commandNo: x.commandNo, commandNo: x.commandNo,
commandName: x.commandName, commandName: x.commandName,
@ -1445,14 +1466,17 @@ export class ProfileSalaryTempController extends Controller {
} }
} }
// insert profile salary temp new /* =========================
if (backupTemp.length > 0) { * Restore ProfileSalaryTemp ( ProfileSalary insert )
const insertBackupTemp = toInsert.map(({ id, ...data }) => ({ * ========================= */
...data, if (originalTempRows.length > 0) {
salaryId: null, await queryRunner.manager.insert(
})); ProfileSalaryTemp,
originalTempRows.map(({ id, ...data }) => ({
await queryRunner.manager.insert(ProfileSalaryTemp, insertBackupTemp); ...data,
salaryId: null,
})),
);
} }
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
@ -1547,7 +1571,9 @@ export class ProfileSalaryTempController extends Controller {
salaryId: string, salaryId: string,
@Request() req: RequestWithUser, @Request() req: RequestWithUser,
) { ) {
const source_item = await this.salaryRepo.findOne({ where: { id: salaryId } }); const source_item = await this.salaryRepo.findOne({
where: { id: salaryId },
});
// if (source_item) { // if (source_item) {
//await new permission().PermissionOrgUserGet(req,"SYS_REGISTRY_OFFICER",source_item.profileId,); //ไม่แน่ใจOFFปิดไว้ก่อน //await new permission().PermissionOrgUserGet(req,"SYS_REGISTRY_OFFICER",source_item.profileId,); //ไม่แน่ใจOFFปิดไว้ก่อน
// } // }
@ -1555,7 +1581,10 @@ export class ProfileSalaryTempController extends Controller {
const sourceOrder = source_item.order; const sourceOrder = source_item.order;
if (direction.trim().toUpperCase() == "UP") { if (direction.trim().toUpperCase() == "UP") {
const dest_item = await this.salaryRepo.findOne({ const dest_item = await this.salaryRepo.findOne({
where: { profileId: source_item.profileId, order: LessThan(sourceOrder) }, where: {
profileId: source_item.profileId,
order: LessThan(sourceOrder),
},
order: { order: "DESC" }, order: { order: "DESC" },
}); });
if (dest_item == null) return new HttpSuccess(); if (dest_item == null) return new HttpSuccess();
@ -1567,7 +1596,10 @@ export class ProfileSalaryTempController extends Controller {
await Promise.all([this.salaryRepo.save(source_item), this.salaryRepo.save(dest_item)]); await Promise.all([this.salaryRepo.save(source_item), this.salaryRepo.save(dest_item)]);
} else { } else {
const dest_item = await this.salaryRepo.findOne({ const dest_item = await this.salaryRepo.findOne({
where: { profileId: source_item.profileId, order: MoreThan(sourceOrder) }, where: {
profileId: source_item.profileId,
order: MoreThan(sourceOrder),
},
order: { order: "ASC" }, order: { order: "ASC" },
}); });
if (dest_item == null) return new HttpSuccess(); if (dest_item == null) return new HttpSuccess();
@ -1598,7 +1630,9 @@ export class ProfileSalaryTempController extends Controller {
profile = await this.profileRepo.findOneBy({ id: profileId }); profile = await this.profileRepo.findOneBy({ id: profileId });
if (!profile) { if (!profile) {
profileEmployee = await this.profileEmployeeRepo.findOneBy({ id: profileId }); profileEmployee = await this.profileEmployeeRepo.findOneBy({
id: profileId,
});
if (!profileEmployee) { if (!profileEmployee) {
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
} }

View file

@ -29,7 +29,7 @@ export class ProfileActposition extends EntityBase {
comment: "วันที่สิ้นสุด", comment: "วันที่สิ้นสุด",
default: null, default: null,
}) })
dateEnd: Date; dateEnd: Date | null;
@Column({ @Column({
nullable: true, nullable: true,

View file

@ -43,7 +43,7 @@ export class ProfileAssistance extends EntityBase {
comment: "วันสิ้นสุดการช่วยราชการ", comment: "วันสิ้นสุดการช่วยราชการ",
default: null, default: null,
}) })
dateEnd: Date; dateEnd: Date | null;
@Column({ @Column({
nullable: true, nullable: true,