2024-02-22 15:32:42 +07:00
|
|
|
import {
|
|
|
|
|
Controller,
|
|
|
|
|
Get,
|
|
|
|
|
Post,
|
|
|
|
|
Put,
|
|
|
|
|
Delete,
|
|
|
|
|
Route,
|
|
|
|
|
Security,
|
|
|
|
|
Tags,
|
|
|
|
|
Body,
|
|
|
|
|
Path,
|
|
|
|
|
Request,
|
|
|
|
|
Query,
|
|
|
|
|
} from "tsoa";
|
|
|
|
|
import { AppDataSource } from "../database/data-source";
|
2024-06-27 12:02:32 +07:00
|
|
|
import { In, Not, MoreThan, Brackets, Like, MoreThanOrEqual, IsNull } from "typeorm";
|
2024-02-22 15:32:42 +07:00
|
|
|
import HttpSuccess from "../interfaces/http-success";
|
|
|
|
|
import HttpError from "../interfaces/http-error";
|
|
|
|
|
import HttpStatusCode from "../interfaces/http-status";
|
2024-02-22 16:49:23 +07:00
|
|
|
import { CreateSalaryPeriod, SalaryPeriod, UpdateSalaryPeriod } from "../entities/SalaryPeriod";
|
2024-02-27 08:58:22 +07:00
|
|
|
import Extension from "../interfaces/extension";
|
|
|
|
|
import { SalaryOrg } from "../entities/SalaryOrg";
|
|
|
|
|
import { CreateSalaryProfile, SalaryProfile } from "../entities/SalaryProfile";
|
2024-02-27 13:03:34 +07:00
|
|
|
import { PosType } from "../entities/PosType";
|
|
|
|
|
import { PosLevel } from "../entities/PosLevel";
|
|
|
|
|
import { Salarys } from "../entities/Salarys";
|
|
|
|
|
import { SalaryRanks } from "../entities/SalaryRanks";
|
2024-02-28 11:27:52 +07:00
|
|
|
import CallAPI from "../interfaces/call-api";
|
2024-03-16 12:05:54 +07:00
|
|
|
import { SalaryOrgEmployee } from "../entities/SalaryOrgEmployee";
|
|
|
|
|
import { SalaryProfileEmployee } from "../entities/SalaryProfileEmployee";
|
2024-08-09 14:17:24 +07:00
|
|
|
import { RequestWithUser } from "../middlewares/user";
|
|
|
|
|
import permission from "../interfaces/permission";
|
2024-09-03 15:18:23 +07:00
|
|
|
import { setLogDataDiff } from "../interfaces/utils";
|
2024-02-22 15:32:42 +07:00
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
@Route("api/v1/salary/period")
|
2024-02-22 15:32:42 +07:00
|
|
|
@Tags("Salary")
|
|
|
|
|
@Security("bearerAuth")
|
|
|
|
|
export class SalaryPeriodController extends Controller {
|
|
|
|
|
private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod);
|
2024-02-27 08:58:22 +07:00
|
|
|
private salaryOrgRepository = AppDataSource.getRepository(SalaryOrg);
|
2024-03-16 12:05:54 +07:00
|
|
|
private salaryOrgEmployeeRepository = AppDataSource.getRepository(SalaryOrgEmployee);
|
2024-02-27 08:58:22 +07:00
|
|
|
private salaryProfileRepository = AppDataSource.getRepository(SalaryProfile);
|
2024-03-16 12:05:54 +07:00
|
|
|
private salaryProfileEmployeeRepository = AppDataSource.getRepository(SalaryProfileEmployee);
|
2024-02-27 13:03:34 +07:00
|
|
|
private posTypeRepository = AppDataSource.getRepository(PosType);
|
|
|
|
|
private posLevelRepository = AppDataSource.getRepository(PosLevel);
|
|
|
|
|
private salaryRepository = AppDataSource.getRepository(Salarys);
|
|
|
|
|
private salaryRankRepository = AppDataSource.getRepository(SalaryRanks);
|
2024-02-22 15:32:42 +07:00
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
/**
|
|
|
|
|
* API รอบล่าสุด
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_030 - รอบล่าสุด #29
|
|
|
|
|
*
|
|
|
|
|
*/
|
2024-02-28 10:34:55 +07:00
|
|
|
@Post("latest")
|
|
|
|
|
async GetGroupSalaryPeriodLatest(
|
|
|
|
|
@Body() body: { rootId: string; salaryPeriodId: string; snapshot: string },
|
|
|
|
|
) {
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
2024-02-28 10:34:55 +07:00
|
|
|
id: body.salaryPeriodId,
|
2024-02-27 08:58:22 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
|
|
|
|
order: { effectiveDate: "DESC" },
|
|
|
|
|
relations: ["salaryOrgs"],
|
|
|
|
|
});
|
|
|
|
|
if (!salaryPeriod) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
|
|
|
}
|
|
|
|
|
const data = {
|
2024-02-27 16:19:18 +07:00
|
|
|
group1id:
|
2025-04-21 16:04:50 +07:00
|
|
|
salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2024-02-28 10:34:55 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP1" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
) == null
|
2024-02-27 16:19:18 +07:00
|
|
|
? null
|
2025-04-21 16:04:50 +07:00
|
|
|
: salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2024-02-28 10:34:55 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP1" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
)?.id,
|
2025-04-05 18:12:02 +07:00
|
|
|
group1IsClose:
|
2025-04-21 16:04:50 +07:00
|
|
|
salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2025-04-05 18:12:02 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP1" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
) == null
|
|
|
|
|
? null
|
2025-04-21 16:04:50 +07:00
|
|
|
: salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2025-04-05 18:12:02 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP1" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
)?.isClose,
|
2024-02-27 16:19:18 +07:00
|
|
|
group2id:
|
2025-04-21 16:04:50 +07:00
|
|
|
salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2024-02-28 10:34:55 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP2" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
) == null
|
2024-02-27 16:19:18 +07:00
|
|
|
? null
|
2025-04-21 16:04:50 +07:00
|
|
|
: salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2024-02-28 10:34:55 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP2" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
)?.id,
|
2025-04-05 18:12:02 +07:00
|
|
|
group2IsClose:
|
2025-04-21 16:04:50 +07:00
|
|
|
salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2025-04-05 18:12:02 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP2" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
) == null
|
|
|
|
|
? null
|
2025-04-21 16:04:50 +07:00
|
|
|
: salaryPeriod.salaryOrgs &&
|
|
|
|
|
salaryPeriod.salaryOrgs.find(
|
2025-04-05 18:12:02 +07:00
|
|
|
(x) =>
|
|
|
|
|
x.group == "GROUP2" &&
|
|
|
|
|
x.rootId == body.rootId &&
|
|
|
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
|
|
|
)?.isClose,
|
2024-02-27 08:58:22 +07:00
|
|
|
effectiveDate: salaryPeriod.effectiveDate,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
};
|
|
|
|
|
return new HttpSuccess(data);
|
2024-02-22 16:49:23 +07:00
|
|
|
}
|
2024-02-22 15:32:42 +07:00
|
|
|
|
2024-03-27 17:08:28 +07:00
|
|
|
/**
|
|
|
|
|
* API ยอดใช้งานทั้งหมด
|
|
|
|
|
*
|
|
|
|
|
* @summary ยอดใช้งานทั้งหมด
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id
|
|
|
|
|
* @param {string} group
|
|
|
|
|
* @param {string} period
|
|
|
|
|
* @param {string} snapshot
|
|
|
|
|
*/
|
|
|
|
|
@Post("summary/all")
|
|
|
|
|
async summaryUseSalary(
|
|
|
|
|
@Body()
|
|
|
|
|
body: {
|
|
|
|
|
year: number;
|
|
|
|
|
group: string;
|
|
|
|
|
period: string;
|
|
|
|
|
snapshot: string;
|
|
|
|
|
},
|
|
|
|
|
) {
|
|
|
|
|
const _salaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
relations: ["salaryPeriod", "salaryProfiles"],
|
|
|
|
|
where: {
|
2024-03-28 16:57:13 +07:00
|
|
|
group: Like(
|
|
|
|
|
`%${body.group.trim().toUpperCase() == "GROUP1" ? "GROUP1" : body.group.trim().toUpperCase() == "GROUP2" ? "GROUP2" : "GROUP1"}%`,
|
|
|
|
|
),
|
2024-03-27 17:08:28 +07:00
|
|
|
snapshot: body.snapshot.trim().toUpperCase(),
|
2024-03-28 16:57:13 +07:00
|
|
|
salaryPeriod: { id: body.period },
|
2024-03-27 17:08:28 +07:00
|
|
|
},
|
|
|
|
|
});
|
2024-03-28 16:57:13 +07:00
|
|
|
|
2024-03-27 17:08:28 +07:00
|
|
|
const salaryOrg: any[] = [];
|
|
|
|
|
await Promise.all(
|
|
|
|
|
_salaryOrg.map(async (item) => {
|
2024-03-28 16:57:13 +07:00
|
|
|
const _salaryOrgGROUP2 = await this.salaryOrgRepository.findOne({
|
|
|
|
|
relations: ["salaryPeriod", "salaryProfiles"],
|
|
|
|
|
where: {
|
|
|
|
|
group: Like(
|
|
|
|
|
`%${body.group.trim().toUpperCase() != "GROUP1" && body.group.trim().toUpperCase() != "GROUP2" ? "GROUP2" : "ZXCASD"}%`,
|
|
|
|
|
),
|
|
|
|
|
rootId: item.rootId,
|
|
|
|
|
snapshot: body.snapshot.trim().toUpperCase(),
|
|
|
|
|
salaryPeriod: { id: body.period },
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-03-27 17:08:28 +07:00
|
|
|
const sum = item.salaryProfiles.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.amountSpecial;
|
|
|
|
|
}, 0);
|
2024-03-28 16:57:13 +07:00
|
|
|
const sumGROUP2 =
|
|
|
|
|
_salaryOrgGROUP2 == null
|
|
|
|
|
? 0
|
|
|
|
|
: _salaryOrgGROUP2.salaryProfiles.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.amountSpecial;
|
|
|
|
|
}, 0);
|
2024-03-27 17:08:28 +07:00
|
|
|
const data = {
|
2024-03-28 16:57:13 +07:00
|
|
|
org: item.root,
|
|
|
|
|
total: item.total + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.total),
|
|
|
|
|
fifteenPercent:
|
2024-03-29 12:00:41 +07:00
|
|
|
item.fifteenPercent +
|
2024-03-29 14:02:07 +07:00
|
|
|
item.fifteenPoint / 100 +
|
2024-03-29 12:00:41 +07:00
|
|
|
(_salaryOrgGROUP2 == null
|
|
|
|
|
? 0
|
2024-03-29 14:02:07 +07:00
|
|
|
: _salaryOrgGROUP2.fifteenPercent + _salaryOrgGROUP2.fifteenPoint / 100),
|
2024-03-28 16:57:13 +07:00
|
|
|
chosen:
|
|
|
|
|
item.quantityUsed + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.quantityUsed),
|
|
|
|
|
remaining:
|
|
|
|
|
item.remainQuota + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.remainQuota),
|
|
|
|
|
currentAmount:
|
|
|
|
|
item.currentAmount + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.currentAmount),
|
|
|
|
|
sixPercentAmount:
|
|
|
|
|
item.sixPercentAmount +
|
|
|
|
|
(_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.sixPercentAmount),
|
|
|
|
|
spentAmount:
|
|
|
|
|
item.spentAmount + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.spentAmount),
|
|
|
|
|
sixPercentSpentAmount:
|
|
|
|
|
item.sixPercentAmount -
|
|
|
|
|
item.spentAmount +
|
|
|
|
|
(_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.sixPercentAmount) -
|
|
|
|
|
(_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.spentAmount),
|
|
|
|
|
useAmount: item.useAmount + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.useAmount),
|
|
|
|
|
remainingAmount:
|
|
|
|
|
item.remainingAmount +
|
|
|
|
|
(_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.remainingAmount),
|
|
|
|
|
totalAmountSpecial: sum + sumGROUP2,
|
|
|
|
|
totalBackup:
|
|
|
|
|
item.salaryProfiles.filter((x) => x.isReserve == true).length +
|
|
|
|
|
(_salaryOrgGROUP2 == null
|
|
|
|
|
? 0
|
|
|
|
|
: _salaryOrgGROUP2.salaryProfiles.filter((x) => x.isReserve == true).length),
|
2024-03-27 17:08:28 +07:00
|
|
|
};
|
|
|
|
|
salaryOrg.push(data);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
return new HttpSuccess({
|
|
|
|
|
salaryOrg,
|
|
|
|
|
dashboard: {
|
|
|
|
|
total: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.total;
|
|
|
|
|
}, 0),
|
|
|
|
|
fifteenPercent: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.fifteenPercent;
|
|
|
|
|
}, 0),
|
|
|
|
|
chosen: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.chosen;
|
|
|
|
|
}, 0),
|
|
|
|
|
remaining: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.remaining;
|
|
|
|
|
}, 0),
|
|
|
|
|
currentAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.currentAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
sixPercentAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.sixPercentAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
spentAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.spentAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
sixPercentSpentAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.sixPercentSpentAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
useAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.useAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
remainingAmount: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.remainingAmount;
|
|
|
|
|
}, 0),
|
|
|
|
|
totalAmountSpecial: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.totalAmountSpecial;
|
|
|
|
|
}, 0),
|
|
|
|
|
totalBackup: salaryOrg.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.totalBackup;
|
|
|
|
|
}, 0),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
/**
|
|
|
|
|
* API จำนวนโควตา
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_029 - จำนวนโควตา #28
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id Guid, *Id กลุ่ม(salaryOrgId/groupId)
|
|
|
|
|
*/
|
|
|
|
|
@Get("quota/{id}")
|
|
|
|
|
async GetSalaryquotaLatest(@Path() id: string) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: id,
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
if (!salaryOrg) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-07 14:25:14 +07:00
|
|
|
const sum = salaryOrg.salaryProfiles.reduce((accumulator, object) => {
|
|
|
|
|
return accumulator + object.amountSpecial;
|
|
|
|
|
}, 0);
|
2024-02-27 08:58:22 +07:00
|
|
|
const data = {
|
|
|
|
|
total: salaryOrg.total,
|
2025-04-05 18:12:02 +07:00
|
|
|
fifteenPercent: salaryOrg.fifteenPercent + salaryOrg.fifteenPoint / 100,
|
2024-02-29 11:29:05 +07:00
|
|
|
chosen: salaryOrg.quantityUsed,
|
|
|
|
|
remaining: salaryOrg.remainQuota,
|
|
|
|
|
currentAmount: salaryOrg.currentAmount,
|
|
|
|
|
sixPercentAmount: salaryOrg.sixPercentAmount,
|
|
|
|
|
spentAmount: salaryOrg.spentAmount,
|
|
|
|
|
sixPercentSpentAmount: salaryOrg.sixPercentAmount - salaryOrg.spentAmount,
|
|
|
|
|
useAmount: salaryOrg.useAmount,
|
|
|
|
|
remainingAmount: salaryOrg.remainingAmount,
|
2024-03-07 14:25:14 +07:00
|
|
|
totalAmountSpecial: sum,
|
2024-03-07 15:28:23 +07:00
|
|
|
totalBackup: salaryOrg.salaryProfiles.filter((x) => x.isReserve == true).length,
|
2024-03-14 21:52:48 +07:00
|
|
|
status: salaryOrg.status,
|
2024-02-27 08:58:22 +07:00
|
|
|
};
|
|
|
|
|
return new HttpSuccess(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API ลบคนเลื่อนเงินเดือนในรอบ
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_024 - ลบคนเลื่อนเงินเดือนในรอบ #23
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id profile Id
|
|
|
|
|
*/
|
|
|
|
|
@Delete("profile/{id}")
|
2024-08-09 14:17:24 +07:00
|
|
|
async deleteSalaryProfile(@Path() id: string, @Request() req: RequestWithUser) {
|
|
|
|
|
await new permission().PermissionDelete(req, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
2024-03-04 13:40:33 +07:00
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: { id: id },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
|
|
|
|
|
}
|
2024-02-29 11:01:35 +07:00
|
|
|
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.remove(salaryProfile, { data: req });
|
2024-03-04 13:40:33 +07:00
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
|
|
|
|
|
2024-02-29 11:01:35 +07:00
|
|
|
// หาจำนวน Quota คงเหลือ
|
2024-04-04 17:08:18 +07:00
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-04-04 18:57:18 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-04 14:00:40 +07:00
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
return new HttpSuccess();
|
2024-02-28 18:03:36 +07:00
|
|
|
}
|
2024-02-29 10:29:51 +07:00
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API แก้ไขเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_025 - แก้ไขเงินเดือน #24
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id profile Id
|
|
|
|
|
* @param {string} amount ฐานเงินเดือน
|
|
|
|
|
*/
|
|
|
|
|
@Post("change/amount")
|
2024-08-22 17:23:48 +07:00
|
|
|
async changeAmount(
|
|
|
|
|
@Body() body: { profileId: string; amount: number },
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
) {
|
|
|
|
|
await new permission().PermissionCreate(request, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
2024-03-04 14:09:54 +07:00
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: { id: body.profileId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
salaryProfile.amount = body.amount;
|
2024-02-27 16:12:32 +07:00
|
|
|
//Type & Level
|
|
|
|
|
const Type = await this.posTypeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeName: salaryProfile.posType,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Type) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
const Level = await this.posLevelRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeId: Type.id,
|
|
|
|
|
posLevelName: salaryProfile.posLevel,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Level) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
//Salary
|
|
|
|
|
const salarys = await this.salaryRepository.findOne({
|
2024-02-28 10:34:55 +07:00
|
|
|
where: {
|
|
|
|
|
posTypeId: Level.posTypeId,
|
|
|
|
|
posLevelId: Level.id,
|
2024-04-02 14:53:36 +07:00
|
|
|
isSpecial: salaryProfile.isSpecial == true ? true : false,
|
2024-02-28 10:34:55 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-27 16:12:32 +07:00
|
|
|
});
|
2024-02-28 10:34:55 +07:00
|
|
|
if (!salarys) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
let type = salaryProfile.type;
|
2024-02-27 16:12:32 +07:00
|
|
|
//SalaryRank
|
2024-02-28 10:34:55 +07:00
|
|
|
let salaryRanks: any = null;
|
|
|
|
|
if (salaryProfile.amount != null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
2024-04-02 13:33:08 +07:00
|
|
|
salary: MoreThanOrEqual(salaryProfile.amount),
|
2024-03-07 17:37:00 +07:00
|
|
|
isNext: false,
|
2024-02-28 10:34:55 +07:00
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-02-28 10:34:55 +07:00
|
|
|
});
|
2024-03-07 18:43:10 +07:00
|
|
|
if (salaryRanks != null) {
|
|
|
|
|
if (salaryProfile.type == "HAFT") {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) {
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULL") {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFull,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULLHAFT") {
|
|
|
|
|
if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
} else if (
|
2024-03-07 18:43:10 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == null ||
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == 0
|
|
|
|
|
) {
|
|
|
|
|
type = "FULL";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFullHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryProfile.amount,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryRanks == null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: MoreThan(salaryProfile.amount),
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-03-07 18:43:10 +07:00
|
|
|
});
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-02-27 16:12:32 +07:00
|
|
|
}
|
|
|
|
|
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = false;
|
|
|
|
|
if (type == "NONE") {
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "PENDING") {
|
2024-02-29 10:29:51 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
|
|
|
|
salaryProfile.positionSalaryAmount = 0;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "HAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULL") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFull == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFull - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULLHAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFullHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFullHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
2024-02-28 10:34:55 +07:00
|
|
|
} else {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
2024-02-27 16:12:32 +07:00
|
|
|
}
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfile.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
const before = structuredClone(salaryProfile);
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryProfile });
|
2024-03-04 13:40:33 +07:00
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
|
|
|
|
|
2024-02-29 11:01:35 +07:00
|
|
|
// หาจำนวน Quota คงเหลือ
|
2024-04-04 17:08:18 +07:00
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-04-04 18:57:18 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-07 15:28:23 +07:00
|
|
|
}
|
2024-03-04 14:00:40 +07:00
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
return new HttpSuccess();
|
2024-02-28 18:03:36 +07:00
|
|
|
}
|
2024-02-27 08:58:22 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API ย้ายกลุ่ม
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_026 - ย้ายกลุ่ม #25
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id profile Id
|
|
|
|
|
* @param {string} groupId groupId
|
|
|
|
|
*/
|
|
|
|
|
@Post("change/group")
|
2024-08-22 17:23:48 +07:00
|
|
|
async changeGroup(
|
|
|
|
|
@Body() body: { profileId: string; groupId: string },
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
) {
|
|
|
|
|
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
2024-04-01 09:40:44 +07:00
|
|
|
// relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: { id: body.profileId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
2024-03-04 14:09:54 +07:00
|
|
|
relations: ["salaryPeriod"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: { id: body.groupId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryOrg) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มการขอเลื่อนเงินเดือน");
|
|
|
|
|
}
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = null;
|
2024-02-28 18:03:36 +07:00
|
|
|
|
2024-02-29 10:29:51 +07:00
|
|
|
salaryProfile.salaryOrgId = salaryOrg.id;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfile.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryProfile });
|
|
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
2024-03-07 15:28:23 +07:00
|
|
|
where: {
|
2024-04-04 17:08:18 +07:00
|
|
|
id: _salaryProfile.salaryOrg.id,
|
2024-03-07 15:28:23 +07:00
|
|
|
},
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-03-07 15:28:23 +07:00
|
|
|
});
|
2024-04-04 17:08:18 +07:00
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-04-04 18:57:18 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
2024-03-07 15:28:23 +07:00
|
|
|
}
|
2024-03-04 14:00:40 +07:00
|
|
|
}
|
2024-03-04 13:44:06 +07:00
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
return new HttpSuccess();
|
2024-02-28 18:03:36 +07:00
|
|
|
}
|
2024-02-27 08:58:22 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-02-28 16:27:36 +07:00
|
|
|
* API แก้ไขขั้น
|
2024-02-27 08:58:22 +07:00
|
|
|
*
|
2024-02-28 16:27:36 +07:00
|
|
|
* @summary SLR_025 - แก้ไขขั้น #24
|
2024-02-27 08:58:22 +07:00
|
|
|
*
|
|
|
|
|
* @param {string} id profile Id
|
|
|
|
|
* @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น
|
|
|
|
|
*/
|
|
|
|
|
@Post("change/type")
|
2024-07-08 11:05:57 +07:00
|
|
|
async changeType(
|
|
|
|
|
@Body() body: { profileId: string; type: string; isReserve: boolean; remark?: string | null },
|
2024-08-22 17:23:48 +07:00
|
|
|
@Request() req: RequestWithUser,
|
2024-07-08 11:05:57 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
2024-03-05 09:38:05 +07:00
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: { id: body.profileId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
body.type = body.type.toUpperCase();
|
2024-03-05 09:38:05 +07:00
|
|
|
|
|
|
|
|
//ตรวจสอบงวดเมษาว่าเลื่อนกี่ขั้น
|
2024-03-05 10:43:08 +07:00
|
|
|
if (body.type == "FULLHAFT") {
|
2024-03-05 09:38:05 +07:00
|
|
|
if (salaryProfile?.salaryOrg?.salaryPeriod?.period === "OCT") {
|
|
|
|
|
const checkPreviousType = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: {
|
2024-03-05 10:22:40 +07:00
|
|
|
citizenId: salaryProfile?.citizenId,
|
2024-03-05 09:38:05 +07:00
|
|
|
salaryOrg: {
|
|
|
|
|
salaryPeriod: {
|
|
|
|
|
period: "APR",
|
2024-03-05 10:43:08 +07:00
|
|
|
year: salaryProfile?.salaryOrg?.salaryPeriod?.year, //ปีที่ตรงกันด้วย
|
2024-03-05 09:38:05 +07:00
|
|
|
},
|
2024-03-05 10:43:08 +07:00
|
|
|
snapshot: "SNAP2",
|
2024-03-05 09:38:05 +07:00
|
|
|
},
|
2024-03-05 10:43:08 +07:00
|
|
|
type: "FULL",
|
2024-03-05 09:38:05 +07:00
|
|
|
},
|
|
|
|
|
});
|
2024-03-05 10:43:08 +07:00
|
|
|
if (checkPreviousType) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.NOT_FOUND,
|
|
|
|
|
"ไม่สามารถเลื่อนขั้นบุคลากรเกิน 2 ขั้นต่อปีได้",
|
|
|
|
|
);
|
2024-03-05 09:38:05 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
2024-04-03 16:34:36 +07:00
|
|
|
if (body.type == "FULL") {
|
|
|
|
|
salaryProfile.isReserve = body.isReserve;
|
|
|
|
|
} else {
|
|
|
|
|
salaryProfile.isReserve = false;
|
2024-03-05 09:38:05 +07:00
|
|
|
}
|
|
|
|
|
|
2024-02-27 16:12:32 +07:00
|
|
|
//Type & Level
|
|
|
|
|
const Type = await this.posTypeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeName: salaryProfile.posType,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Type) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
const Level = await this.posLevelRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeId: Type.id,
|
|
|
|
|
posLevelName: salaryProfile.posLevel,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Level) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
//Salary
|
|
|
|
|
const salarys = await this.salaryRepository.findOne({
|
2024-02-28 10:34:55 +07:00
|
|
|
where: {
|
|
|
|
|
posTypeId: Level.posTypeId,
|
|
|
|
|
posLevelId: Level.id,
|
2024-04-02 14:53:36 +07:00
|
|
|
isSpecial: salaryProfile.isSpecial == true ? true : false,
|
2024-02-28 10:34:55 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-27 16:12:32 +07:00
|
|
|
});
|
2024-02-28 10:34:55 +07:00
|
|
|
if (!salarys) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.type = body.type;
|
2024-07-08 11:05:57 +07:00
|
|
|
let _null: any = null;
|
|
|
|
|
salaryProfile.remark = body.remark == null ? _null : body.remark;
|
2024-03-07 17:37:00 +07:00
|
|
|
let type = salaryProfile.type;
|
2024-02-27 16:12:32 +07:00
|
|
|
//SalaryRank
|
2024-02-28 10:34:55 +07:00
|
|
|
let salaryRanks: any = null;
|
|
|
|
|
if (salaryProfile.amount != null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
2024-04-02 13:33:08 +07:00
|
|
|
salary: MoreThanOrEqual(salaryProfile.amount),
|
2024-03-07 17:37:00 +07:00
|
|
|
isNext: false,
|
2024-02-28 10:34:55 +07:00
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-02-28 10:34:55 +07:00
|
|
|
});
|
2024-03-07 18:43:10 +07:00
|
|
|
if (salaryRanks != null) {
|
|
|
|
|
if (salaryProfile.type == "HAFT") {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) {
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULL") {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFull,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULLHAFT") {
|
|
|
|
|
if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
} else if (
|
2024-03-07 18:43:10 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == null ||
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == 0
|
|
|
|
|
) {
|
|
|
|
|
type = "FULL";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFullHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryProfile.amount,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryRanks == null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: MoreThan(salaryProfile.amount),
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-03-07 18:43:10 +07:00
|
|
|
});
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
|
|
|
|
|
salaryProfile.isNext = false;
|
|
|
|
|
if (type == "NONE") {
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "PENDING") {
|
2024-02-29 10:29:51 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
|
|
|
|
salaryProfile.positionSalaryAmount = 0;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "HAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULL") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFull == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFull - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULLHAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFullHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFullHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
2024-02-27 08:58:22 +07:00
|
|
|
} else {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
|
|
|
|
}
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfile.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
const before = structuredClone(salaryProfile);
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryProfile });
|
2024-03-05 09:38:05 +07:00
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
2024-03-07 15:28:23 +07:00
|
|
|
where: {
|
2024-04-04 17:08:18 +07:00
|
|
|
id: _salaryProfile.salaryOrg.id,
|
2024-03-07 15:28:23 +07:00
|
|
|
},
|
2024-04-04 18:57:18 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-03-07 15:28:23 +07:00
|
|
|
});
|
2024-04-04 17:08:18 +07:00
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
2024-03-07 15:28:23 +07:00
|
|
|
}
|
2024-03-05 09:38:05 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
return new HttpSuccess();
|
2024-03-05 09:38:05 +07:00
|
|
|
}
|
2024-02-27 08:58:22 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-05 18:12:02 +07:00
|
|
|
/**
|
|
|
|
|
* API แก้ไขขั้น
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_025 - แก้ไขขั้น #24
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id profile Id
|
|
|
|
|
* @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น
|
|
|
|
|
*/
|
|
|
|
|
@Post("change/type-multi")
|
|
|
|
|
async changeTypeMulti(
|
|
|
|
|
@Body() body: { profileId: string[]; type: string; isReserve: boolean; remark?: string | null },
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
) {
|
|
|
|
|
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
|
|
|
|
|
|
|
|
|
|
for await (const profile of body.profileId) {
|
|
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: profile },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.NOT_FOUND,
|
|
|
|
|
"ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
body.type = body.type.toUpperCase();
|
|
|
|
|
|
|
|
|
|
//ตรวจสอบงวดเมษาว่าเลื่อนกี่ขั้น
|
|
|
|
|
if (body.type == "FULLHAFT") {
|
|
|
|
|
if (salaryProfile?.salaryOrg?.salaryPeriod?.period === "OCT") {
|
|
|
|
|
const checkPreviousType = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: {
|
|
|
|
|
citizenId: salaryProfile?.citizenId,
|
|
|
|
|
salaryOrg: {
|
|
|
|
|
salaryPeriod: {
|
|
|
|
|
period: "APR",
|
|
|
|
|
year: salaryProfile?.salaryOrg?.salaryPeriod?.year, //ปีที่ตรงกันด้วย
|
|
|
|
|
},
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (checkPreviousType) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.NOT_FOUND,
|
|
|
|
|
"ไม่สามารถเลื่อนขั้นบุคลากรเกิน 2 ขั้นต่อปีได้",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (body.type == "FULL") {
|
|
|
|
|
salaryProfile.isReserve = body.isReserve;
|
|
|
|
|
} else {
|
|
|
|
|
salaryProfile.isReserve = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Type & Level
|
|
|
|
|
const Type = await this.posTypeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeName: salaryProfile.posType,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Type) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
const Level = await this.posLevelRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeId: Type.id,
|
|
|
|
|
posLevelName: salaryProfile.posLevel,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!Level) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
//Salary
|
|
|
|
|
const salarys = await this.salaryRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
posTypeId: Level.posTypeId,
|
|
|
|
|
posLevelId: Level.id,
|
|
|
|
|
isSpecial: salaryProfile.isSpecial == true ? true : false,
|
|
|
|
|
isActive: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!salarys) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
salaryProfile.type = body.type;
|
|
|
|
|
let _null: any = null;
|
|
|
|
|
salaryProfile.remark = body.remark == null ? _null : body.remark;
|
|
|
|
|
let type = salaryProfile.type;
|
|
|
|
|
//SalaryRank
|
|
|
|
|
let salaryRanks: any = null;
|
|
|
|
|
if (salaryProfile.amount != null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: MoreThanOrEqual(salaryProfile.amount),
|
|
|
|
|
isNext: false,
|
|
|
|
|
},
|
|
|
|
|
order: { salary: "ASC" },
|
|
|
|
|
});
|
|
|
|
|
if (salaryRanks != null) {
|
|
|
|
|
if (salaryProfile.type == "HAFT") {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) {
|
|
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
|
|
|
|
}
|
|
|
|
|
} else if (salaryProfile.type == "FULL") {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
|
|
|
|
|
type = "HAFT";
|
|
|
|
|
}
|
|
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFull,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
|
|
|
|
}
|
|
|
|
|
} else if (salaryProfile.type == "FULLHAFT") {
|
|
|
|
|
if (
|
|
|
|
|
salaryRanks.salaryFullHalfSpecial != null &&
|
|
|
|
|
salaryRanks.salaryFullHalfSpecial > 0
|
|
|
|
|
) {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) {
|
|
|
|
|
type = "HAFT";
|
|
|
|
|
} else if (
|
|
|
|
|
salaryRanks.salaryHalfSpecial == null ||
|
|
|
|
|
salaryRanks.salaryHalfSpecial == 0
|
|
|
|
|
) {
|
|
|
|
|
type = "FULL";
|
|
|
|
|
}
|
|
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFullHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryProfile.amount,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryRanks == null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: MoreThan(salaryProfile.amount),
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
order: { salary: "ASC" },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
salaryProfile.isNext = false;
|
|
|
|
|
if (type == "NONE") {
|
|
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
|
|
|
|
salaryProfile.positionSalaryAmount =
|
|
|
|
|
salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
|
|
|
|
} else if (type == "PENDING") {
|
|
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
|
|
|
|
salaryProfile.positionSalaryAmount = 0;
|
|
|
|
|
} else if (type == "HAFT") {
|
|
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryHalfSpecial;
|
|
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryHalf - salaryProfile.amount;
|
|
|
|
|
salaryProfile.positionSalaryAmount =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf;
|
|
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULL") {
|
|
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullSpecial;
|
|
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFull == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFull - salaryProfile.amount;
|
|
|
|
|
salaryProfile.positionSalaryAmount =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull;
|
|
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULLHAFT") {
|
|
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalfSpecial;
|
|
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFullHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalf - salaryProfile.amount;
|
|
|
|
|
salaryProfile.positionSalaryAmount =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalf == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalf;
|
|
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
salaryProfile.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
|
|
|
|
const before = structuredClone(salaryProfile);
|
|
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryProfile });
|
|
|
|
|
|
|
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
|
|
|
|
relations: { salaryProfiles: true },
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
|
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
|
|
|
|
relations: { salaryProfiles: true },
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
|
|
|
|
salaryOrg.lastUpdateUserId = req.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = req.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: req });
|
|
|
|
|
setLogDataDiff(req, { before, after: salaryOrg });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
/**
|
|
|
|
|
* API รายการอัตราเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_023 - รายการอัตราเงินเดือน #22
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Put("org/{id}")
|
|
|
|
|
async GetListsSalaryProfile(
|
2024-08-22 17:23:48 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-27 08:58:22 +07:00
|
|
|
@Path() id: string,
|
2024-02-29 12:08:11 +07:00
|
|
|
@Body()
|
2024-02-29 13:40:49 +07:00
|
|
|
body: {
|
|
|
|
|
page: number;
|
|
|
|
|
pageSize: number;
|
|
|
|
|
keyword?: string;
|
|
|
|
|
type?: any;
|
2024-03-19 09:46:52 +07:00
|
|
|
isRetire?: string | null;
|
2024-02-29 13:40:49 +07:00
|
|
|
},
|
2024-02-27 08:58:22 +07:00
|
|
|
) {
|
2024-08-22 17:23:48 +07:00
|
|
|
await new permission().PermissionList(request, "SYS_SALARY_OFFICER");
|
2025-04-28 10:48:58 +07:00
|
|
|
const _data = await new permission().PermissionOrgList(request, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!salaryOrg) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
|
|
|
}
|
|
|
|
|
const [salaryProfile, total] = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("profile")
|
2024-02-29 12:08:11 +07:00
|
|
|
.andWhere(
|
2024-02-28 10:34:55 +07:00
|
|
|
new Brackets((qb) => {
|
2024-02-29 13:40:49 +07:00
|
|
|
qb.andWhere(body.type != null && body.type != "" ? `profile.type LIKE :type` : "1=1", {
|
2024-03-04 13:40:33 +07:00
|
|
|
type: body.type == null ? "" : `${body.type.toUpperCase()}`,
|
2024-02-28 10:34:55 +07:00
|
|
|
})
|
2024-03-19 09:46:52 +07:00
|
|
|
.andWhere(
|
2025-04-11 12:29:59 +07:00
|
|
|
// body.isRetire != null
|
|
|
|
|
// ? body.isRetire == "1"
|
|
|
|
|
// ? `profile.isRetired = true`
|
|
|
|
|
// : `profile.isRetired = false`
|
|
|
|
|
// : "1=1",
|
|
|
|
|
body.isRetire == null
|
2025-04-30 13:35:39 +07:00
|
|
|
? "1=1"
|
2025-04-21 16:04:50 +07:00
|
|
|
: body.isRetire == "1"
|
|
|
|
|
? `profile.isRetired = true`
|
|
|
|
|
: body.isRetire == "0"
|
|
|
|
|
? `profile.isRetired = false`
|
|
|
|
|
: "1=1",
|
2024-03-19 09:46:52 +07:00
|
|
|
)
|
2024-02-28 10:34:55 +07:00
|
|
|
.andWhere({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
})
|
|
|
|
|
.andWhere(
|
|
|
|
|
new Brackets((qb) => {
|
|
|
|
|
qb.orWhere("profile.posMasterNoPrefix LIKE :keyword", {
|
|
|
|
|
keyword: `%${body.keyword}%`,
|
|
|
|
|
})
|
|
|
|
|
.orWhere("profile.posMasterNo LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.posMasterNoSuffix LIKE :keyword", {
|
|
|
|
|
keyword: `%${body.keyword}%`,
|
|
|
|
|
})
|
|
|
|
|
.orWhere("profile.orgShortName LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.prefix LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.firstName LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.lastName LIKE :keyword", { keyword: `%${body.keyword}%` })
|
2025-02-04 10:13:40 +07:00
|
|
|
.orWhere(
|
|
|
|
|
"CONCAT(profile.prefix,profile.firstName,' ',profile.lastName) LIKE :keyword",
|
|
|
|
|
{ keyword: `%${body.keyword}%` },
|
|
|
|
|
)
|
2025-08-08 16:21:07 +07:00
|
|
|
.orWhere("CONCAT(profile.orgShortName,' ',profile.posMasterNo) LIKE :keyword", {
|
2025-02-04 10:13:40 +07:00
|
|
|
keyword: `%${body.keyword}%`,
|
|
|
|
|
})
|
2024-02-28 10:34:55 +07:00
|
|
|
// .orWhere("profile.citizenId LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` })
|
2025-03-29 16:59:26 +07:00
|
|
|
.orWhere("profile.posType LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.posLevel LIKE :keyword", { keyword: `%${body.keyword}%` })
|
2025-06-17 18:17:49 +07:00
|
|
|
.orWhere("profile.posExecutive LIKE :keyword", { keyword: `%${body.keyword}%` })
|
2024-02-28 10:34:55 +07:00
|
|
|
.orWhere("profile.amount LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.amountSpecial LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.amountUse LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.positionSalaryAmount LIKE :keyword", {
|
|
|
|
|
keyword: `%${body.keyword}%`,
|
2025-04-03 18:01:04 +07:00
|
|
|
})
|
|
|
|
|
.orWhere("profile.root LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.child1 LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.child2 LIKE :keyword", { keyword: `%${body.keyword}%` })
|
|
|
|
|
.orWhere("profile.child3 LIKE :keyword", { keyword: `%${body.keyword}%` })
|
2025-04-05 18:12:02 +07:00
|
|
|
.orWhere("profile.child4 LIKE :keyword", { keyword: `%${body.keyword}%` });
|
2024-02-28 10:34:55 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
)
|
2025-04-28 10:48:58 +07:00
|
|
|
.andWhere(
|
|
|
|
|
_data.root != undefined && _data.root != null
|
|
|
|
|
? _data.root[0] != null
|
|
|
|
|
? `rootId IN (:...root)`
|
|
|
|
|
: `rootId is null`
|
|
|
|
|
: "1=1",
|
|
|
|
|
{
|
2025-04-28 11:05:13 +07:00
|
|
|
root: _data.root,
|
2025-04-28 10:48:58 +07:00
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.andWhere(
|
|
|
|
|
_data.child1 != undefined && _data.child1 != null
|
|
|
|
|
? _data.child1[0] != null
|
|
|
|
|
? `child1Id IN (:...child1)`
|
|
|
|
|
: `child1Id is null`
|
|
|
|
|
: "1=1",
|
|
|
|
|
{
|
|
|
|
|
child1: _data.child1,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.andWhere(
|
|
|
|
|
_data.child2 != undefined && _data.child2 != null
|
|
|
|
|
? _data.child2[0] != null
|
|
|
|
|
? `child2Id IN (:...child2)`
|
|
|
|
|
: `child2Id is null`
|
|
|
|
|
: "1=1",
|
|
|
|
|
{
|
|
|
|
|
child2: _data.child2,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.andWhere(
|
|
|
|
|
_data.child3 != undefined && _data.child3 != null
|
|
|
|
|
? _data.child3[0] != null
|
|
|
|
|
? `child3Id IN (:...child3)`
|
|
|
|
|
: `child3Id is null`
|
|
|
|
|
: "1=1",
|
|
|
|
|
{
|
|
|
|
|
child3: _data.child3,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.andWhere(
|
|
|
|
|
_data.child4 != undefined && _data.child4 != null
|
|
|
|
|
? _data.child4[0] != null
|
|
|
|
|
? `child4Id IN (:...child4)`
|
|
|
|
|
: `child4Id is null`
|
|
|
|
|
: "1=1",
|
|
|
|
|
{
|
|
|
|
|
child4: _data.child4,
|
|
|
|
|
},
|
|
|
|
|
)
|
2025-04-05 18:12:02 +07:00
|
|
|
.orderBy("profile.rootOrder", "ASC")
|
|
|
|
|
.addOrderBy("profile.child1Order", "ASC")
|
|
|
|
|
.addOrderBy("profile.child2Order", "ASC")
|
|
|
|
|
.addOrderBy("profile.child3Order", "ASC")
|
|
|
|
|
.addOrderBy("profile.child4Order", "ASC")
|
|
|
|
|
.addOrderBy("profile.posMasterNo", "ASC")
|
2024-02-27 08:58:22 +07:00
|
|
|
.skip((body.page - 1) * body.pageSize)
|
|
|
|
|
.take(body.pageSize)
|
|
|
|
|
.getManyAndCount();
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const result = salaryProfile.map((profile) => ({
|
|
|
|
|
...profile,
|
|
|
|
|
posExecutive: profile.positionExecutiveField
|
|
|
|
|
? `${profile.posExecutive}(${profile.positionExecutiveField})`
|
|
|
|
|
: profile.posExecutive ?? null,
|
|
|
|
|
}));
|
2025-06-17 18:17:49 +07:00
|
|
|
|
|
|
|
|
return new HttpSuccess({ data: result, total });
|
2024-02-27 08:58:22 +07:00
|
|
|
}
|
|
|
|
|
|
2024-03-07 15:28:23 +07:00
|
|
|
/**
|
|
|
|
|
* API แก้คุณสมบัติ
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_031 - แก้คุณสมบัติ #30
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Put("org/property/{id}")
|
|
|
|
|
async editProperty(
|
|
|
|
|
@Path() id: string,
|
|
|
|
|
@Body()
|
|
|
|
|
body: {
|
2024-03-07 16:17:33 +07:00
|
|
|
isPunish: any;
|
|
|
|
|
isSuspension: any;
|
|
|
|
|
isAbsent: any;
|
|
|
|
|
isLeave: any;
|
2024-03-07 15:28:23 +07:00
|
|
|
},
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-03-07 15:28:23 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_OFFICER");
|
2024-03-07 15:28:23 +07:00
|
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!salaryProfile) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเพิ่มเงินเดือนของบุคคลนี้");
|
|
|
|
|
}
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(salaryProfile);
|
2024-03-07 15:28:23 +07:00
|
|
|
salaryProfile.isPunish = body.isPunish;
|
|
|
|
|
salaryProfile.isSuspension = body.isSuspension;
|
|
|
|
|
salaryProfile.isAbsent = body.isAbsent;
|
|
|
|
|
salaryProfile.isLeave = body.isLeave;
|
|
|
|
|
salaryProfile.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryProfile });
|
|
|
|
|
|
2024-03-07 15:28:23 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
/**
|
|
|
|
|
* API เพิ่มคนเลื่อนเงินเดือนตามรอบ
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_028 - เพิ่มคนเลื่อนเงินเดือนตามรอบ #27
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Post("org/profile")
|
|
|
|
|
async addSalaryProfile(
|
|
|
|
|
@Body() requestBody: CreateSalaryProfile,
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-27 08:58:22 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionCreate(request, "SYS_SALARY_OFFICER");
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
2024-03-07 15:28:23 +07:00
|
|
|
relations: ["salaryPeriod", "salaryProfiles"],
|
2024-02-27 08:58:22 +07:00
|
|
|
where: {
|
|
|
|
|
id: requestBody.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!salaryOrg) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
|
|
|
}
|
2024-02-28 18:03:36 +07:00
|
|
|
|
2024-02-27 08:58:22 +07:00
|
|
|
const salaryOrgAll = await this.salaryOrgRepository.find({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryOrg.salaryPeriodId,
|
2024-02-29 14:41:44 +07:00
|
|
|
snapshot: salaryOrg.snapshot,
|
2024-02-27 08:58:22 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!salaryOrgAll) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
|
|
|
}
|
|
|
|
|
const salaryProfileAll = await this.salaryProfileRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: In(salaryOrgAll.map((x) => x.id)),
|
|
|
|
|
citizenId: requestBody.citizenId,
|
|
|
|
|
// prefix: requestBody.prefix,
|
|
|
|
|
// firstName: requestBody.firstName,
|
|
|
|
|
// lastName: requestBody.lastName,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryProfileAll != null) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
2024-03-05 10:29:24 +07:00
|
|
|
"ไม่สามารถเพิ่มรายชื่อนี้ได้ เนื่องจากมีการยื่นขอเลื่อนเงินเดือนแล้ว",
|
2024-02-27 08:58:22 +07:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-28 16:04:09 +07:00
|
|
|
let salaryProfile: any = Object.assign(new SalaryProfile(), requestBody);
|
|
|
|
|
delete salaryProfile.id;
|
2024-02-27 08:58:22 +07:00
|
|
|
salaryProfile.type = salaryProfile.type.toUpperCase();
|
2024-02-27 13:03:34 +07:00
|
|
|
//Type & Level
|
2024-03-07 17:37:00 +07:00
|
|
|
const posType = await this.posTypeRepository.findOne({
|
2024-02-27 13:03:34 +07:00
|
|
|
where: {
|
|
|
|
|
posTypeName: salaryProfile.posType,
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-03-07 17:37:00 +07:00
|
|
|
if (!posType) {
|
2024-02-27 13:03:34 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
const posLevel = await this.posLevelRepository.findOne({
|
2024-02-27 13:03:34 +07:00
|
|
|
where: {
|
2024-03-07 17:37:00 +07:00
|
|
|
posTypeId: posType.id,
|
2024-02-27 13:03:34 +07:00
|
|
|
posLevelName: salaryProfile.posLevel,
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-03-07 17:37:00 +07:00
|
|
|
if (!posLevel) {
|
2024-02-27 13:03:34 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
|
|
|
|
//Salary
|
|
|
|
|
const salarys = await this.salaryRepository.findOne({
|
2024-02-28 10:34:55 +07:00
|
|
|
where: {
|
2024-03-07 17:37:00 +07:00
|
|
|
posTypeId: posLevel.posTypeId,
|
|
|
|
|
posLevelId: posLevel.id,
|
2024-04-02 14:53:36 +07:00
|
|
|
isSpecial: salaryProfile.isSpecial == true ? true : false,
|
2024-02-28 10:34:55 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-27 13:03:34 +07:00
|
|
|
});
|
2024-02-28 10:34:55 +07:00
|
|
|
if (!salarys) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
let type = salaryProfile.type;
|
2024-02-27 13:03:34 +07:00
|
|
|
//SalaryRank
|
2024-02-28 10:34:55 +07:00
|
|
|
let salaryRanks: any = null;
|
|
|
|
|
if (salaryProfile.amount != null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
2024-04-02 13:33:08 +07:00
|
|
|
salary: MoreThanOrEqual(salaryProfile.amount),
|
2024-03-07 17:37:00 +07:00
|
|
|
isNext: false,
|
2024-02-28 10:34:55 +07:00
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-02-28 10:34:55 +07:00
|
|
|
});
|
2024-03-07 18:43:10 +07:00
|
|
|
if (salaryRanks != null) {
|
|
|
|
|
if (salaryProfile.type == "HAFT") {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) {
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULL") {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFull,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else if (salaryProfile.type == "FULLHAFT") {
|
|
|
|
|
if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) {
|
|
|
|
|
if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) {
|
2024-03-07 17:37:00 +07:00
|
|
|
type = "HAFT";
|
|
|
|
|
} else if (
|
2024-03-07 18:43:10 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == null ||
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryRanks.salaryHalfSpecial == 0
|
|
|
|
|
) {
|
|
|
|
|
type = "FULL";
|
|
|
|
|
}
|
2025-03-31 15:17:35 +07:00
|
|
|
const _salaryRanks = await this.salaryRankRepository.findOne({
|
2024-03-07 18:43:10 +07:00
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryRanks.salaryFullHalf,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-03-31 15:17:35 +07:00
|
|
|
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-07 18:43:10 +07:00
|
|
|
} else {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: salaryProfile.amount,
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryRanks == null) {
|
|
|
|
|
salaryRanks = await this.salaryRankRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryId: salarys.id,
|
|
|
|
|
salary: MoreThan(salaryProfile.amount),
|
|
|
|
|
isNext: true,
|
|
|
|
|
},
|
2024-04-02 13:33:08 +07:00
|
|
|
order: { salary: "ASC" },
|
2024-03-07 18:43:10 +07:00
|
|
|
});
|
|
|
|
|
}
|
2024-03-07 17:37:00 +07:00
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
}
|
2024-02-27 13:03:34 +07:00
|
|
|
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = false;
|
|
|
|
|
if (type == "NONE") {
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "PENDING") {
|
2024-02-29 10:29:51 +07:00
|
|
|
salaryProfile.amountSpecial = 0;
|
|
|
|
|
salaryProfile.amountUse = 0;
|
|
|
|
|
salaryProfile.positionSalaryAmount = 0;
|
2024-03-07 17:37:00 +07:00
|
|
|
} else if (type == "HAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULL") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFull == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFull - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
|
|
|
|
} else if (type == "FULLHAFT") {
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.amountSpecial =
|
|
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null
|
|
|
|
|
? 0
|
|
|
|
|
: salaryRanks.salaryFullHalfSpecial;
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryProfile.amountUse =
|
|
|
|
|
salaryRanks == null ||
|
|
|
|
|
salaryProfile == null ||
|
|
|
|
|
salaryRanks.salaryFullHalf == null ||
|
|
|
|
|
salaryProfile.amount == null
|
|
|
|
|
? 0
|
2024-03-07 14:25:14 +07:00
|
|
|
: salaryRanks.salaryFullHalf - salaryProfile.amount;
|
2024-03-04 14:09:54 +07:00
|
|
|
salaryProfile.positionSalaryAmount =
|
2024-03-06 17:24:27 +07:00
|
|
|
salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
|
2024-02-27 08:58:22 +07:00
|
|
|
} else {
|
2024-03-07 17:37:00 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
2024-02-27 08:58:22 +07:00
|
|
|
}
|
|
|
|
|
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = null;
|
2024-02-27 08:58:22 +07:00
|
|
|
salaryProfile.salaryOrgId = salaryOrg.id;
|
|
|
|
|
salaryProfile.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfile.createdFullName = request.user.name;
|
|
|
|
|
salaryProfile.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfile.lastUpdateFullName = request.user.name;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfile.createdAt = new Date();
|
|
|
|
|
salaryProfile.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfile, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryProfile });
|
2024-02-29 10:29:51 +07:00
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
const _salaryProfile = await this.salaryProfileRepository.findOne({
|
|
|
|
|
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
|
|
|
|
|
where: { id: salaryProfile.id },
|
|
|
|
|
});
|
2024-03-06 18:28:05 +07:00
|
|
|
|
2024-04-04 17:08:18 +07:00
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
|
|
|
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
|
|
|
where: {
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: "FULL",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
|
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
|
|
|
salaryOrg.remainQuota = calRemainQuota;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
|
|
|
if (_salaryProfile != null) {
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
id: _salaryProfile.salaryOrg.id,
|
|
|
|
|
},
|
2024-04-04 18:57:18 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-04-04 17:08:18 +07:00
|
|
|
});
|
|
|
|
|
if (salaryOrg != null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
|
|
|
salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: _salaryProfile.salaryOrg.salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: salaryOrg.rootId,
|
|
|
|
|
group: salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
|
|
|
|
|
.createQueryBuilder("salaryProfile")
|
|
|
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
|
|
|
.where({
|
|
|
|
|
salaryOrgId: salaryOrg.id,
|
|
|
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
|
|
|
})
|
|
|
|
|
.getRawOne();
|
|
|
|
|
const calRemainAmount =
|
|
|
|
|
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
|
|
|
|
|
salaryOrg.useAmount =
|
|
|
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null
|
|
|
|
|
? 0
|
|
|
|
|
: sumAmountUse.totalAmount;
|
|
|
|
|
salaryOrg.remainingAmount = calRemainAmount;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrg, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrg });
|
2024-04-04 17:08:18 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-04 14:00:40 +07:00
|
|
|
}
|
2024-04-04 17:08:18 +07:00
|
|
|
return new HttpSuccess();
|
2024-02-29 10:29:51 +07:00
|
|
|
}
|
2024-02-27 08:58:22 +07:00
|
|
|
return new HttpSuccess(salaryProfile.id);
|
|
|
|
|
}
|
2024-02-27 10:39:37 +07:00
|
|
|
|
2024-03-07 15:51:45 +07:00
|
|
|
/**
|
|
|
|
|
* API ปิดรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_032 - ปิดรอบเงินเดือน #31
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
|
|
|
*/
|
|
|
|
|
@Get("close/{id}")
|
2024-09-04 17:42:31 +07:00
|
|
|
async closeSalaryPeriod_ById(@Path() id: string, @Request() request: RequestWithUser) {
|
|
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
|
2024-03-07 15:51:45 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: id },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryPeriod) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
|
}
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(salaryPeriod);
|
2024-03-07 15:51:45 +07:00
|
|
|
salaryPeriod.isClose = !salaryPeriod.isClose;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryPeriod.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryPeriod });
|
|
|
|
|
|
2024-03-07 15:51:45 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:39:37 +07:00
|
|
|
/**
|
|
|
|
|
* API สร้างรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_016 - สร้างรอบเงินเดือน #16
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Post()
|
|
|
|
|
async create_salary_period(
|
|
|
|
|
@Body() requestBody: CreateSalaryPeriod,
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-27 10:39:37 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionCreate(request, "SYS_SALARY_ROUND");
|
2024-02-27 10:39:37 +07:00
|
|
|
const salaryPeriod = Object.assign(new SalaryPeriod(), requestBody);
|
2024-02-27 11:27:12 +07:00
|
|
|
|
2024-02-27 10:39:37 +07:00
|
|
|
const chk_toUpper = ["SPECIAL", "APR", "OCT"];
|
|
|
|
|
if (!chk_toUpper.includes(salaryPeriod.period.toUpperCase())) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const chk_period = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
period: salaryPeriod.period,
|
2024-02-27 11:27:12 +07:00
|
|
|
year: requestBody.year,
|
2024-02-27 10:39:37 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (chk_period) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.NOT_FOUND,
|
2024-03-15 09:55:07 +07:00
|
|
|
"ประเภทผังปี " + Extension.ToThaiYear(salaryPeriod.year) + " ซ้ำ",
|
2024-02-27 10:39:37 +07:00
|
|
|
);
|
|
|
|
|
}
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = null;
|
2024-02-27 10:39:37 +07:00
|
|
|
salaryPeriod.period = salaryPeriod.period.toUpperCase();
|
|
|
|
|
salaryPeriod.createdUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.createdFullName = request.user.name;
|
|
|
|
|
salaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.lastUpdateFullName = request.user.name;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryPeriod.createdAt = new Date();
|
|
|
|
|
salaryPeriod.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryPeriod });
|
2024-03-08 12:25:35 +07:00
|
|
|
|
|
|
|
|
if (salaryPeriod.period == "SPECIAL") {
|
|
|
|
|
const snapshot = "SNAP1";
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfile = await this.salaryProfileRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
|
|
|
|
|
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
|
2024-03-08 12:25:35 +07:00
|
|
|
|
2024-03-27 16:39:45 +07:00
|
|
|
const salaryOrgEmployee = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfileEmployee = await this.salaryProfileEmployeeRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrgEmployee.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileEmployeeRepository.remove(salaryProfileEmployee, { data: request });
|
|
|
|
|
await this.salaryOrgEmployeeRepository.remove(salaryOrgEmployee, { data: request });
|
2024-03-27 16:39:45 +07:00
|
|
|
|
2024-07-10 10:44:37 +07:00
|
|
|
let orgs = await new CallAPI().GetData(request, "/org/unauthorize/active/root/id");
|
|
|
|
|
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
|
2024-03-08 12:25:35 +07:00
|
|
|
|
|
|
|
|
salaryPeriod.revisionId = revisionId;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.lastUpdateFullName = request.user.name;
|
2024-09-03 15:18:23 +07:00
|
|
|
salaryPeriod.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryPeriod });
|
2025-03-29 16:59:26 +07:00
|
|
|
let _null: any = null;
|
2024-03-08 12:25:35 +07:00
|
|
|
await Promise.all(
|
2024-03-27 16:39:45 +07:00
|
|
|
orgs.map(async (root: any) => {
|
2024-03-08 12:25:35 +07:00
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrg());
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
|
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-03-27 16:39:45 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
await Promise.all(
|
|
|
|
|
orgs.map(async (root: any) => {
|
|
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
|
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
2024-03-08 12:25:35 +07:00
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-03-08 12:25:35 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-27 10:39:37 +07:00
|
|
|
return new HttpSuccess(salaryPeriod.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API แก้ไขรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_017 - แก้ไขรอบเงินเดือน #17
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
|
|
|
*/
|
|
|
|
|
@Put("{id}")
|
|
|
|
|
async update_salary_period(
|
|
|
|
|
@Path() id: string,
|
|
|
|
|
@Body() requestBody: UpdateSalaryPeriod,
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-27 10:39:37 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
|
2024-02-27 10:39:37 +07:00
|
|
|
const chk_SalaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: id },
|
|
|
|
|
});
|
|
|
|
|
if (!chk_SalaryPeriod) {
|
2024-02-28 13:35:08 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-02-27 10:39:37 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const chk_toUpper = ["SPECIAL", "APR", "OCT"];
|
|
|
|
|
if (!chk_toUpper.includes(requestBody.period.toUpperCase())) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
const chk_period = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
period: requestBody.period,
|
|
|
|
|
id: Not(id),
|
2024-02-27 11:27:12 +07:00
|
|
|
year: requestBody.year,
|
2024-02-27 10:39:37 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (chk_period) {
|
|
|
|
|
throw new HttpError(
|
|
|
|
|
HttpStatusCode.NOT_FOUND,
|
2024-03-04 13:40:33 +07:00
|
|
|
"ประเภทผังปี " + (requestBody.effectiveDate.getFullYear() + 543) + " ซ้ำ",
|
2024-02-27 10:39:37 +07:00
|
|
|
);
|
|
|
|
|
}
|
2024-08-23 14:10:34 +07:00
|
|
|
const beforeChk_SalaryPeriod = structuredClone(chk_SalaryPeriod);
|
2024-02-27 10:39:37 +07:00
|
|
|
chk_SalaryPeriod.period = requestBody.period.toUpperCase();
|
|
|
|
|
chk_SalaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
chk_SalaryPeriod.lastUpdateFullName = request.user.name;
|
|
|
|
|
chk_SalaryPeriod.lastUpdatedAt = new Date();
|
|
|
|
|
this.salaryPeriodRepository.merge(chk_SalaryPeriod, requestBody);
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(chk_SalaryPeriod, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before: beforeChk_SalaryPeriod, after: chk_SalaryPeriod });
|
|
|
|
|
|
2024-03-08 12:25:35 +07:00
|
|
|
if (chk_SalaryPeriod.period == "SPECIAL") {
|
|
|
|
|
const snapshot = "SNAP1";
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: chk_SalaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfile = await this.salaryProfileRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
|
|
|
|
|
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
|
2024-03-08 12:25:35 +07:00
|
|
|
|
2024-03-27 16:39:45 +07:00
|
|
|
const salaryOrgEmployee = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: chk_SalaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfileEmployee = await this.salaryProfileEmployeeRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrgEmployee.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileEmployeeRepository.remove(salaryProfileEmployee, { data: request });
|
|
|
|
|
await this.salaryOrgEmployeeRepository.remove(salaryOrgEmployee, { data: request });
|
2024-03-27 16:39:45 +07:00
|
|
|
|
2024-07-10 10:44:37 +07:00
|
|
|
let orgs = await new CallAPI().GetData(request, "/org/unauthorize/active/root/id");
|
|
|
|
|
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
|
2024-03-08 12:25:35 +07:00
|
|
|
|
|
|
|
|
chk_SalaryPeriod.revisionId = revisionId;
|
2024-09-03 14:48:19 +07:00
|
|
|
chk_SalaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
chk_SalaryPeriod.lastUpdateFullName = request.user.name;
|
|
|
|
|
chk_SalaryPeriod.lastUpdatedAt = new Date();
|
2024-09-03 15:18:23 +07:00
|
|
|
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(chk_SalaryPeriod, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before: beforeChk_SalaryPeriod, after: chk_SalaryPeriod });
|
2025-03-29 16:59:26 +07:00
|
|
|
let _null: any = null;
|
2024-03-08 12:25:35 +07:00
|
|
|
await Promise.all(
|
2024-03-27 16:39:45 +07:00
|
|
|
orgs.map(async (root: any) => {
|
2024-03-08 12:25:35 +07:00
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrg());
|
2024-08-23 14:10:34 +07:00
|
|
|
const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
|
|
|
|
|
|
2024-03-08 12:25:35 +07:00
|
|
|
salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
|
|
|
|
salaryOrgNew.revisionId = chk_SalaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
2024-03-27 16:39:45 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await Promise.all(
|
|
|
|
|
orgs.map(async (root: any) => {
|
|
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
2024-08-23 14:10:34 +07:00
|
|
|
const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
|
|
|
|
|
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
|
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
2024-03-08 12:25:35 +07:00
|
|
|
salaryOrgNew.revisionId = chk_SalaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
2024-03-08 12:25:35 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-27 10:39:37 +07:00
|
|
|
return new HttpSuccess(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API ลบรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_018 - ลบรอบเงินเดือน #18
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
|
|
|
*/
|
|
|
|
|
@Delete("{id}")
|
2024-08-09 14:17:24 +07:00
|
|
|
async delete_salary_period(@Path() id: string, @Request() request: RequestWithUser) {
|
|
|
|
|
await new permission().PermissionDelete(request, "SYS_SALARY_ROUND");
|
2024-02-27 10:39:37 +07:00
|
|
|
const SalaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: id },
|
|
|
|
|
});
|
2024-03-14 21:52:48 +07:00
|
|
|
if (!SalaryPeriod)
|
2024-02-28 13:35:08 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-03-14 21:52:48 +07:00
|
|
|
|
|
|
|
|
if (SalaryPeriod?.period == "SPECIAL") {
|
|
|
|
|
const SalaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: SalaryPeriod.id },
|
2024-05-21 13:06:48 +07:00
|
|
|
relations: { salaryProfiles: true },
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
|
|
|
|
const salaryProfile = SalaryOrg.find((x) => x.salaryProfiles.length > 0);
|
|
|
|
|
if (salaryProfile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้");
|
|
|
|
|
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.remove(SalaryOrg, { data: request });
|
|
|
|
|
await this.salaryPeriodRepository.remove(SalaryPeriod, { data: request });
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
} else {
|
|
|
|
|
const SalaryOrg = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: { salaryPeriodId: SalaryPeriod.id },
|
|
|
|
|
});
|
|
|
|
|
if (SalaryOrg) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้");
|
|
|
|
|
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.remove(SalaryPeriod, { data: request });
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
2024-02-27 17:14:22 +07:00
|
|
|
}
|
2024-03-14 21:52:48 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API รายการรอบเงินเดือน(active)
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Get("active")
|
2024-03-15 10:15:10 +07:00
|
|
|
async GetListsSalaryPeriodActive(
|
|
|
|
|
@Query("page") page: number = 1,
|
|
|
|
|
@Query("pageSize") pageSize: number = 10,
|
|
|
|
|
@Query("keyword") keyword?: string,
|
|
|
|
|
) {
|
|
|
|
|
const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod)
|
2024-03-14 21:52:48 +07:00
|
|
|
.createQueryBuilder("salaryPeriod")
|
|
|
|
|
.where({ isActive: true })
|
|
|
|
|
.select([
|
|
|
|
|
"salaryPeriod.id",
|
|
|
|
|
"salaryPeriod.period",
|
|
|
|
|
"salaryPeriod.isActive",
|
|
|
|
|
"salaryPeriod.isClose",
|
|
|
|
|
"salaryPeriod.effectiveDate",
|
|
|
|
|
"salaryPeriod.status",
|
|
|
|
|
"salaryPeriod.year",
|
|
|
|
|
"salaryPeriod.revisionId",
|
|
|
|
|
])
|
|
|
|
|
.orderBy("salaryPeriod.effectiveDate", "DESC")
|
2024-03-15 10:15:10 +07:00
|
|
|
.skip((page - 1) * pageSize)
|
|
|
|
|
.take(pageSize)
|
|
|
|
|
.getManyAndCount();
|
2024-03-14 21:52:48 +07:00
|
|
|
|
2024-03-15 10:15:10 +07:00
|
|
|
return new HttpSuccess({ data: salaryPeriod, total });
|
2024-02-27 10:39:37 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API รายละเอียดรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_019 - รายละเอียดรอบเงินเดือน #19
|
|
|
|
|
*
|
|
|
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
|
|
|
*/
|
|
|
|
|
@Get("{id}")
|
|
|
|
|
async GetSalaryPeriod_ById(@Path() id: string) {
|
|
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: id },
|
2024-02-28 10:34:55 +07:00
|
|
|
select: [
|
|
|
|
|
"id",
|
|
|
|
|
"period",
|
|
|
|
|
"isActive",
|
|
|
|
|
"effectiveDate",
|
2024-03-07 15:51:45 +07:00
|
|
|
"isClose",
|
2024-02-28 10:34:55 +07:00
|
|
|
"status",
|
|
|
|
|
"year",
|
|
|
|
|
"revisionId",
|
|
|
|
|
],
|
2024-02-27 10:39:37 +07:00
|
|
|
});
|
|
|
|
|
if (!salaryPeriod) {
|
2024-02-28 13:35:08 +07:00
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-02-27 10:39:37 +07:00
|
|
|
}
|
|
|
|
|
return new HttpSuccess(salaryPeriod);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 10:28:40 +07:00
|
|
|
/**
|
|
|
|
|
* API รายการรอบเงินเดือน by year
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_020 - รายการรอบเงินเดือน by year
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Get("active/{year}")
|
|
|
|
|
async GetListsSalaryPeriodByYear(
|
|
|
|
|
@Path() year: number,
|
|
|
|
|
@Query("page") page: number = 1,
|
|
|
|
|
@Query("pageSize") pageSize: number = 10,
|
|
|
|
|
@Query("keyword") keyword?: string,
|
|
|
|
|
) {
|
|
|
|
|
const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod)
|
|
|
|
|
.createQueryBuilder("salaryPeriod")
|
|
|
|
|
.andWhere(year != 0 ? "salaryPeriod.year LIKE :year" : "1=1", { year: `${year}` })
|
2024-03-26 10:30:02 +07:00
|
|
|
.andWhere({ isActive: true })
|
2024-06-27 12:02:32 +07:00
|
|
|
.andWhere({ revisionId: Not(IsNull()) })
|
2024-03-26 10:28:40 +07:00
|
|
|
.select([
|
|
|
|
|
"salaryPeriod.id",
|
|
|
|
|
"salaryPeriod.period",
|
|
|
|
|
"salaryPeriod.isActive",
|
|
|
|
|
"salaryPeriod.isClose",
|
|
|
|
|
"salaryPeriod.effectiveDate",
|
|
|
|
|
"salaryPeriod.status",
|
|
|
|
|
"salaryPeriod.year",
|
|
|
|
|
"salaryPeriod.revisionId",
|
|
|
|
|
])
|
|
|
|
|
.orderBy("salaryPeriod.effectiveDate", "DESC")
|
|
|
|
|
.skip((page - 1) * pageSize)
|
|
|
|
|
.take(pageSize)
|
|
|
|
|
.getManyAndCount();
|
|
|
|
|
|
|
|
|
|
return new HttpSuccess({ data: salaryPeriod, total });
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:39:37 +07:00
|
|
|
/**
|
|
|
|
|
* API รายการรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
* @summary SLR_020 - รายการรอบเงินเดือน #20
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Get()
|
|
|
|
|
async GetListsSalaryPeriod(
|
2024-09-04 17:42:31 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-27 10:39:37 +07:00
|
|
|
@Query("page") page: number = 1,
|
|
|
|
|
@Query("pageSize") pageSize: number = 10,
|
|
|
|
|
@Query("keyword") keyword?: string,
|
|
|
|
|
@Query("year") year: number = 2024,
|
|
|
|
|
) {
|
2024-09-04 17:42:31 +07:00
|
|
|
await new permission().PermissionList(request, "SYS_SALARY_ROUND");
|
2024-02-27 10:39:37 +07:00
|
|
|
const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod)
|
2024-02-28 10:34:55 +07:00
|
|
|
.createQueryBuilder("salaryPeriod")
|
2024-03-04 13:40:33 +07:00
|
|
|
.andWhere(year != 0 ? "salaryPeriod.year LIKE :year" : "1=1", { year: `${year}` })
|
|
|
|
|
.orWhere("salaryPeriod.period LIKE :keyword", { keyword: `${keyword}` })
|
|
|
|
|
// .orWhere("salaryPeriod.isActive LIKE :keyword", { keyword: `${keyword}` })
|
2024-02-27 10:39:37 +07:00
|
|
|
.select([
|
2024-02-28 10:34:55 +07:00
|
|
|
"salaryPeriod.id",
|
|
|
|
|
"salaryPeriod.period",
|
|
|
|
|
"salaryPeriod.isActive",
|
2024-03-07 15:51:45 +07:00
|
|
|
"salaryPeriod.isClose",
|
2024-02-28 10:34:55 +07:00
|
|
|
"salaryPeriod.effectiveDate",
|
|
|
|
|
"salaryPeriod.status",
|
|
|
|
|
"salaryPeriod.year",
|
|
|
|
|
"salaryPeriod.revisionId",
|
2024-02-27 10:39:37 +07:00
|
|
|
])
|
2024-11-29 16:49:05 +07:00
|
|
|
.orderBy("salaryPeriod.year", "DESC")
|
|
|
|
|
.addOrderBy("salaryPeriod.effectiveDate", "DESC")
|
2024-02-27 10:39:37 +07:00
|
|
|
.skip((page - 1) * pageSize)
|
|
|
|
|
.take(pageSize)
|
|
|
|
|
.getManyAndCount();
|
|
|
|
|
|
|
|
|
|
return new HttpSuccess({ data: salaryPeriod, total });
|
|
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
|
|
|
|
|
/**
|
2024-02-28 16:27:36 +07:00
|
|
|
* API snapshot salary
|
2024-02-28 10:34:55 +07:00
|
|
|
*
|
2024-02-28 16:27:36 +07:00
|
|
|
* @summary snapshot salary
|
2024-02-28 10:34:55 +07:00
|
|
|
*
|
|
|
|
|
*/
|
2024-02-28 11:22:42 +07:00
|
|
|
@Get("snapshot/{snapshot}/{salaryPeriodId}")
|
2024-02-28 10:34:55 +07:00
|
|
|
async SnapshotSalary(
|
2024-02-28 11:22:42 +07:00
|
|
|
@Path() snapshot: string,
|
2024-02-28 10:34:55 +07:00
|
|
|
salaryPeriodId: string,
|
2024-08-23 14:10:34 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-02-28 10:34:55 +07:00
|
|
|
) {
|
2025-05-01 13:22:51 +07:00
|
|
|
try {
|
2025-07-15 22:40:02 +07:00
|
|
|
snapshot = snapshot.toLocaleUpperCase();
|
|
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: salaryPeriodId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryPeriod) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการสร้างเงินเดือน");
|
|
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfile = await this.salaryProfileRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) },
|
|
|
|
|
});
|
|
|
|
|
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
|
|
|
|
|
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
|
2024-03-16 12:05:54 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryOrgEmployee = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfileEmployee = await this.salaryProfileEmployeeRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrgEmployee.map((x) => x.id)) },
|
|
|
|
|
});
|
|
|
|
|
await this.salaryProfileEmployeeRepository.remove(salaryProfileEmployee, { data: request });
|
|
|
|
|
await this.salaryOrgEmployeeRepository.remove(salaryOrgEmployee, { data: request });
|
|
|
|
|
let orgs = await new CallAPI().GetData(request, "/org/unauthorize/active/root/id");
|
|
|
|
|
|
|
|
|
|
//snap บางสำนัก
|
|
|
|
|
//.chin
|
|
|
|
|
// const targetRootIds = [
|
|
|
|
|
// "d7e98989-b5ce-47d6-93c3-ab63ed486348",
|
|
|
|
|
// "e0545eca-5d0a-4a1c-8bbd-e3e25c2521db",
|
|
|
|
|
// "26989ffa-d5ab-4bbd-ac97-130646cd1da6",
|
|
|
|
|
// "6f9b30e1-757a-40d5-b053-61eb1b91c0f0",
|
|
|
|
|
// "eaf65f33-25e9-4956-9dba-5d909f5eb595",
|
|
|
|
|
// "a3efed2c-3f4b-476d-95e6-9f7e0585ae25",
|
|
|
|
|
// ];
|
|
|
|
|
//.me
|
|
|
|
|
// const targetRootIds = [
|
|
|
|
|
// "b89a4467-7ee3-4706-8db7-f366555f826c",
|
|
|
|
|
// "585648a9-e634-43fc-9360-5fd4189136ab",
|
|
|
|
|
// "d6e3daa0-284a-428f-aa43-0750fa74e974",
|
|
|
|
|
// "ed3ddcfb-f882-4499-817b-aff73e5be87c",
|
|
|
|
|
// "f8ce98ca-a691-4c89-abde-875f559afb3a",
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
// orgs = orgs.filter((x: any) => targetRootIds.includes(x.rootId));
|
|
|
|
|
let total = 1000;
|
|
|
|
|
// let _orgProfiles = await new CallAPI().PostData(request, "/org/unauthorize/salary/gen", {
|
|
|
|
|
let _orgProfiles = await new CallAPI().PostData(request, "/org/unauthorize/new-salary/gen", {
|
2024-03-16 12:05:54 +07:00
|
|
|
page: 1,
|
2025-04-18 11:15:53 +07:00
|
|
|
pageSize: 1000,
|
2024-03-16 12:05:54 +07:00
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
2025-07-15 22:40:02 +07:00
|
|
|
});
|
|
|
|
|
let orgProfiles = _orgProfiles.data;
|
|
|
|
|
total = _orgProfiles.total;
|
|
|
|
|
console.log(`total: ${total}`);
|
|
|
|
|
|
|
|
|
|
if (total > 1000) {
|
|
|
|
|
const page = Math.ceil(total / 1000);
|
|
|
|
|
for (let index = 2; index <= page; index++) {
|
|
|
|
|
await new CallAPI()
|
|
|
|
|
// .PostData(request, "/org/unauthorize/salary/gen", {
|
|
|
|
|
.PostData(request, "/org/unauthorize/new-salary/gen", {
|
|
|
|
|
page: index,
|
|
|
|
|
pageSize: 1000,
|
|
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
})
|
|
|
|
|
.then((x) => {
|
|
|
|
|
Array.prototype.push.apply(orgProfiles, x.data);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
total = 1000;
|
|
|
|
|
let orgProfileEmployees: any;
|
|
|
|
|
let _orgProfileEmployees = await new CallAPI().PostData(
|
|
|
|
|
request,
|
|
|
|
|
// "/org/unauthorize/salary/employee/gen",
|
|
|
|
|
"/org/unauthorize/new-salary/employee/gen",
|
|
|
|
|
{
|
|
|
|
|
page: 1,
|
|
|
|
|
pageSize: 1000,
|
|
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
orgProfileEmployees = _orgProfileEmployees.data;
|
|
|
|
|
total = _orgProfileEmployees.total;
|
|
|
|
|
console.log(`totalEmp: ${total}`);
|
|
|
|
|
if (total > 1000) {
|
|
|
|
|
const page = Math.ceil(total / 1000);
|
|
|
|
|
for (let index = 2; index <= page; index++) {
|
|
|
|
|
await new CallAPI()
|
|
|
|
|
// .PostData(request, "/org/unauthorize/salary/employee/gen", {
|
|
|
|
|
.PostData(request, "/org/unauthorize/new-salary/employee/gen", {
|
|
|
|
|
page: index,
|
|
|
|
|
pageSize: 1000,
|
|
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
})
|
|
|
|
|
.then((x) => {
|
|
|
|
|
Array.prototype.push.apply(orgProfileEmployees, x.data);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
2025-05-01 13:22:51 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
|
|
|
|
|
let _null: any = null;
|
|
|
|
|
// const beforeSalaryPeriod = structuredClone(salaryPeriod);
|
|
|
|
|
salaryPeriod.revisionId = revisionId;
|
|
|
|
|
salaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryPeriod.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: beforeSalaryPeriod, after: salaryPeriod });
|
2024-02-28 10:34:55 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
orgs.map(async (root: any) => {
|
|
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrg());
|
2024-03-08 11:38:27 +07:00
|
|
|
delete salaryOrgNew.id;
|
2025-07-15 22:40:02 +07:00
|
|
|
// const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
|
|
|
|
|
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
|
|
|
|
salaryOrgNew.rootId = root.rootId;
|
|
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
|
|
|
|
salaryOrgNew.root = root.root;
|
|
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
|
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
2025-07-15 22:40:02 +07:00
|
|
|
// setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
|
|
|
|
console.log(`✅ [SNAP: ${snapshot}] บันทึก salaryOrgNew: ${salaryOrgNew.id}`);
|
|
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
delete salaryOrgNew.id;
|
|
|
|
|
salaryOrgNew.group = "GROUP2";
|
|
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
);
|
2024-03-16 12:05:54 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
orgs.map(async (root: any) => {
|
|
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
|
|
|
|
// const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
|
|
|
|
|
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
|
|
|
|
salaryOrgNew.rootId = root.rootId;
|
|
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
|
|
|
|
salaryOrgNew.root = root.root;
|
|
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.group = "GROUP1";
|
|
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
|
2025-07-15 22:40:02 +07:00
|
|
|
// setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
|
|
|
|
console.log(`✅ [SNAP: ${snapshot}] บันทึก salaryOrgEmployeeNew: ${salaryOrgNew.id}`);
|
|
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
delete salaryOrgNew.id;
|
|
|
|
|
salaryOrgNew.group = "GROUP2";
|
|
|
|
|
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
|
|
|
|
|
}
|
|
|
|
|
}),
|
2024-03-07 15:38:21 +07:00
|
|
|
);
|
2025-07-15 22:40:02 +07:00
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
//console.log(`step1`);
|
|
|
|
|
console.time("⏱ Step1: Load SalaryOrg (New)");
|
|
|
|
|
const salaryOrgList = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryOrgMap = new Map(
|
|
|
|
|
salaryOrgList.map((org) => [`${org.rootId}-${org.group}`, org]),
|
2025-07-11 17:06:12 +07:00
|
|
|
);
|
2025-07-15 22:40:02 +07:00
|
|
|
console.timeEnd("⏱ Step1: Load SalaryOrg (New)");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
console.time("⏱ Step2: Load SalaryProfileOld (SNAP1)");
|
|
|
|
|
let salaryOldMap = new Map();
|
|
|
|
|
if (snapshot === "SNAP2") {
|
|
|
|
|
const salaryOldList = await this.salaryProfileRepository
|
|
|
|
|
.createQueryBuilder("profile")
|
|
|
|
|
.innerJoin("profile.salaryOrg", "org")
|
|
|
|
|
.where("org.salaryPeriodId = :periodId", { periodId: salaryPeriod.id })
|
|
|
|
|
.andWhere("org.snapshot = :snapshot", { snapshot: "SNAP1" })
|
|
|
|
|
.getMany();
|
|
|
|
|
|
|
|
|
|
salaryOldMap = new Map(salaryOldList.map((item) => [item.citizenId, item]));
|
|
|
|
|
}
|
|
|
|
|
console.timeEnd("⏱ Step2: Load SalaryProfileOld (SNAP1)");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
console.time("⏱ Step3: Process Profiles");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const allProfilesToSave: SalaryProfile[] = [];
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
for (const profile of orgProfiles) {
|
|
|
|
|
let group = "GROUP1";
|
|
|
|
|
const { posType, posLevel } = profile;
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
if (
|
|
|
|
|
(posType === "ทั่วไป" && posLevel === "ทักษะพิเศษ") ||
|
|
|
|
|
(posType === "วิชาการ" && ["เชี่ยวชาญ", "ทรงคุณวุฒิ"].includes(posLevel)) ||
|
|
|
|
|
(posType === "อำนวยการ" && posLevel === "สูง") ||
|
|
|
|
|
(posType === "บริหาร" && ["ต้น", "สูง"].includes(posLevel))
|
|
|
|
|
) {
|
|
|
|
|
group = "GROUP2";
|
|
|
|
|
}
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryOrgNew = salaryOrgMap.get(`${profile.rootId}-${group}`);
|
|
|
|
|
if (!salaryOrgNew) {
|
|
|
|
|
console.warn(`⚠️ [SNAP: ${snapshot}] ไม่พบ salaryOrg สำหรับ rootId: ${profile.rootId}`);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryProfileNew = Object.assign(new SalaryProfile(), profile);
|
|
|
|
|
delete salaryProfileNew.id;
|
|
|
|
|
|
|
|
|
|
salaryProfileNew.salaryOrgId = salaryOrgNew.id;
|
|
|
|
|
salaryProfileNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.createdAt = new Date();
|
|
|
|
|
salaryProfileNew.lastUpdatedAt = new Date();
|
|
|
|
|
|
|
|
|
|
if (snapshot === "SNAP2") {
|
|
|
|
|
const salaryOld = salaryOldMap.get(salaryProfileNew.citizenId);
|
|
|
|
|
salaryProfileNew.type = salaryOld?.type ?? "PENDING";
|
|
|
|
|
salaryProfileNew.amount = salaryOld?.amount ?? 0;
|
|
|
|
|
salaryProfileNew.amountSpecial = salaryOld?.amountSpecial ?? 0;
|
|
|
|
|
salaryProfileNew.amountUse = salaryOld?.amountUse ?? 0;
|
|
|
|
|
salaryProfileNew.positionSalaryAmount = salaryOld?.positionSalaryAmount ?? 0;
|
|
|
|
|
salaryProfileNew.remark = salaryOld?.remark ?? null;
|
|
|
|
|
salaryProfileNew.isNext = salaryOld?.isNext ?? false;
|
|
|
|
|
salaryProfileNew.isSpecial = salaryOld?.isSpecial ?? false;
|
|
|
|
|
salaryProfileNew.isReserve = salaryOld?.isReserve ?? false;
|
|
|
|
|
salaryProfileNew.isRetired = salaryOld?.isRetired ?? false;
|
|
|
|
|
salaryProfileNew.isGood = salaryOld?.isGood ?? false;
|
|
|
|
|
}
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
// const beforeSalaryProfileNew = structuredClone(salaryProfileNew);
|
|
|
|
|
// setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew });
|
|
|
|
|
allProfilesToSave.push(salaryProfileNew);
|
2025-07-11 17:06:12 +07:00
|
|
|
}
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
console.timeEnd("⏱ Step3: Process Profiles");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
console.time("⏱ Step4: Save All Profiles");
|
|
|
|
|
// await this.salaryProfileRepository.save(allProfilesToSave, { chunk: 500, data: request });
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
await this.salaryProfileRepository
|
|
|
|
|
.createQueryBuilder()
|
|
|
|
|
.insert()
|
|
|
|
|
.into(SalaryProfile)
|
|
|
|
|
.values(allProfilesToSave)
|
|
|
|
|
.orIgnore()
|
|
|
|
|
.execute();
|
|
|
|
|
console.timeEnd("⏱ Step4: Save All Profiles");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
console.timeEnd("⏱ TOTAL SalaryProfile Process");
|
2025-07-11 17:06:12 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
//**********************/
|
|
|
|
|
console.log("mlength", orgProfileEmployees.length);
|
2025-08-08 16:32:11 +07:00
|
|
|
const profilesEmpToSave: SalaryProfileEmployee[] = [];
|
2025-07-15 22:40:02 +07:00
|
|
|
console.time("⏱ SalaryProfileEmployee - Total Time");
|
2025-07-15 23:52:51 +07:00
|
|
|
// await Promise.all(
|
|
|
|
|
// orgProfileEmployees.map(async (profile: any) => {
|
|
|
|
|
|
|
|
|
|
const batchSize = 1000;
|
|
|
|
|
for (let i = 0; i < orgProfileEmployees.length; i += batchSize) {
|
|
|
|
|
const profile = orgProfileEmployees.slice(i, i + batchSize);
|
|
|
|
|
const salaryOrgNew = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: profile.rootId,
|
|
|
|
|
snapshot: snapshot,
|
|
|
|
|
group: "GROUP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
//console.log(`step7`);
|
|
|
|
|
if (salaryOrgNew != null) {
|
|
|
|
|
//console.log(`step8`);
|
|
|
|
|
let salaryProfileNew = Object.assign(new SalaryProfileEmployee(), profile);
|
|
|
|
|
delete salaryProfileNew.id;
|
|
|
|
|
// const beforeSalaryProfileNew = structuredClone(salaryProfileNew);
|
|
|
|
|
|
|
|
|
|
salaryProfileNew.salaryOrgId = salaryOrgNew.id;
|
|
|
|
|
salaryProfileNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.createdAt = new Date();
|
|
|
|
|
salaryProfileNew.lastUpdatedAt = new Date();
|
|
|
|
|
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
//console.log(`step9`);
|
|
|
|
|
const salaryOrgOld = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" },
|
|
|
|
|
});
|
|
|
|
|
const salaryOld = await this.salaryProfileEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
citizenId: salaryProfileNew.citizenId,
|
|
|
|
|
salaryOrgId: In(salaryOrgOld.map((x) => x.id)),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryProfileNew.type = salaryOld == null ? 0 : salaryOld.type;
|
|
|
|
|
// salaryProfileNew.salaryLevel = salaryOld && salaryOld.salaryLevelNew ? salaryOld.salaryLevelNew : salaryOld?.salaryLevel;
|
|
|
|
|
// salaryProfileNew.group = salaryOld && salaryOld.groupNew ? salaryOld.groupNew : salaryOld?.group;
|
|
|
|
|
salaryProfileNew.salaryLevelNew =
|
|
|
|
|
salaryOld && salaryOld.salaryLevelNew ? salaryOld.salaryLevelNew : null;
|
|
|
|
|
salaryProfileNew.groupNew =
|
|
|
|
|
salaryOld && salaryOld.groupNew ? salaryOld.groupNew : null;
|
|
|
|
|
salaryProfileNew.amount = salaryOld == null ? 0 : salaryOld.amount;
|
|
|
|
|
salaryProfileNew.amountSpecial = salaryOld == null ? 0 : salaryOld.amountSpecial;
|
|
|
|
|
salaryProfileNew.amountUse = salaryOld == null ? 0 : salaryOld.amountUse;
|
|
|
|
|
salaryProfileNew.positionSalaryAmount =
|
|
|
|
|
salaryOld == null ? 0 : salaryOld.positionSalaryAmount;
|
|
|
|
|
salaryProfileNew.positionSalaryDayAmount =
|
|
|
|
|
salaryOld == null ? 0 : salaryOld.positionSalaryDayAmount;
|
|
|
|
|
salaryProfileNew.positionSalaryAmountPer =
|
|
|
|
|
salaryOld == null ? 0 : salaryOld.positionSalaryAmountPer;
|
|
|
|
|
salaryProfileNew.remark = salaryOld == null ? null : salaryOld.remark;
|
|
|
|
|
salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext;
|
|
|
|
|
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
|
|
|
|
|
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
|
|
|
|
|
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
|
|
|
|
|
salaryProfileNew.isGood = salaryOld == null ? false : salaryOld.isGood;
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
2025-07-15 23:52:51 +07:00
|
|
|
// profilesEmpToSave.push(salaryProfileNew);
|
|
|
|
|
//console.log(`step10`);
|
|
|
|
|
// console.log(
|
|
|
|
|
// `✅ [SNAP: ${snapshot}] Push SalaryProfileEmployee: ${salaryProfileNew.citizenId} (${salaryProfileNew.fullName ?? "-"})`,
|
|
|
|
|
// );
|
|
|
|
|
await this.salaryProfileEmployeeRepository.save(salaryProfileNew, { data: request });
|
|
|
|
|
// await this.salaryProfileEmployeeRepository.save(profilesEmpToSave, { chunk: 100, data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew });
|
|
|
|
|
} else {
|
|
|
|
|
console.warn(
|
|
|
|
|
`⚠️ [SNAP: ${snapshot}] ไม่พบ salaryOrgEmployee สำหรับ rootId: ${profile.rootId}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// );
|
2025-07-15 22:40:02 +07:00
|
|
|
console.timeEnd("⏱ SalaryProfileEmployee - Total Time");
|
|
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryOrgNew = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
relations: ["salaryProfiles"],
|
2024-02-29 11:01:35 +07:00
|
|
|
});
|
2025-07-15 22:40:02 +07:00
|
|
|
const salaryOrgEmployeeNew = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
if (salaryPeriod.period == "OCT") {
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => {
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
2024-02-29 11:01:35 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
const before_salaryOrg = structuredClone(_salaryOrg);
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
|
|
|
|
|
|
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor(
|
|
|
|
|
(_salaryOrg.salaryProfiles.length * 15) / 100,
|
|
|
|
|
);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.currentAmount = salaryOrgSnap1.currentAmount;
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount;
|
|
|
|
|
_salaryOrg.spentAmount = salaryOrgSnap1.spentAmount;
|
|
|
|
|
_salaryOrg.useAmount = salaryOrgSnap1.useAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount;
|
|
|
|
|
|
|
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-02-29 11:01:35 +07:00
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
2025-07-15 22:40:02 +07:00
|
|
|
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
2025-07-15 22:40:02 +07:00
|
|
|
|
2025-05-15 10:32:10 +07:00
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2024-02-29 11:01:35 +07:00
|
|
|
}
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before: before_salaryOrg, after: _salaryOrg });
|
2025-07-15 22:40:02 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => {
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
const before_salaryOrg = structuredClone(_salaryOrg);
|
2024-08-23 14:10:34 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
2024-03-16 12:05:54 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
|
|
|
|
|
|
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor(
|
|
|
|
|
(_salaryOrg.salaryProfiles.length * 15) / 100,
|
|
|
|
|
);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.currentAmount = salaryOrgSnap1.currentAmount;
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount;
|
|
|
|
|
_salaryOrg.spentAmount = salaryOrgSnap1.spentAmount;
|
|
|
|
|
_salaryOrg.useAmount = salaryOrgSnap1.useAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount;
|
|
|
|
|
|
|
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-03-16 12:05:54 +07:00
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-03-16 12:05:54 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
2025-05-15 10:32:10 +07:00
|
|
|
|
|
|
|
|
//เพิ่มคำนวน 15%
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgEmployeeRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before: before_salaryOrg, after: _salaryOrg });
|
2025-07-15 22:40:02 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
} else if (salaryPeriod.period == "APR") {
|
|
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => {
|
|
|
|
|
// const before_salaryOrg = structuredClone(_salaryOrg);
|
2024-08-23 14:10:34 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor(
|
|
|
|
|
(_salaryOrg.salaryProfiles.length * 15) / 100,
|
|
|
|
|
);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2024-02-29 11:01:35 +07:00
|
|
|
}
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgRepository.save(_salaryOrg, { data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: before_salaryOrg, after: _salaryOrg });
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => {
|
|
|
|
|
// const before_salaryOrg = structuredClone(_salaryOrg);
|
2024-08-23 14:10:34 +07:00
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootDnaId: _salaryOrg.rootDnaId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor(
|
|
|
|
|
(_salaryOrg.salaryProfiles.length * 15) / 100,
|
|
|
|
|
);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
// console.log("fifteenAPR: case 1");
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
// console.log("fifteenAPR: case 2");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-03-16 12:05:54 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2025-07-15 22:40:02 +07:00
|
|
|
// console.log("fifteenAPR: case 3");
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
|
|
|
|
|
2025-07-15 22:40:02 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
|
|
|
|
await this.salaryOrgEmployeeRepository.save(_salaryOrg, { data: request });
|
|
|
|
|
// setLogDataDiff(request, { before: before_salaryOrg, after: _salaryOrg });
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
console.log(`✅✅✅ [SNAPSHOT:${snapshot} เสร็จสิ้น]) ✅✅✅`);
|
|
|
|
|
return new HttpSuccess();
|
2025-05-01 13:22:51 +07:00
|
|
|
} catch (err) {
|
|
|
|
|
console.error(`❌ error processing employee:`, err);
|
|
|
|
|
}
|
2024-02-28 10:34:55 +07:00
|
|
|
}
|
2024-02-28 13:16:01 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cronjob SalaryPeriod
|
|
|
|
|
*/
|
|
|
|
|
async CronjobSalaryPeriod() {
|
|
|
|
|
const current = new Date();
|
2024-02-28 14:18:07 +07:00
|
|
|
let salaryPeriod: any;
|
2024-02-29 11:01:35 +07:00
|
|
|
let request: any;
|
2024-02-28 14:18:07 +07:00
|
|
|
if (current.getDate() == 1 && current.getMonth() == 2) {
|
|
|
|
|
salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
2024-02-28 13:16:01 +07:00
|
|
|
year: current.getFullYear(),
|
2024-02-29 11:01:35 +07:00
|
|
|
period: "APR",
|
2024-02-28 14:18:07 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-28 13:16:01 +07:00
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
if (salaryPeriod) {
|
|
|
|
|
this.SnapshotSalarys("SNAP1", salaryPeriod.id, request);
|
|
|
|
|
}
|
2024-02-28 14:18:07 +07:00
|
|
|
} else if (current.getDate() == 1 && current.getMonth() == 3) {
|
|
|
|
|
salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
2024-02-28 13:16:01 +07:00
|
|
|
year: current.getFullYear(),
|
|
|
|
|
period: "APR",
|
2024-02-28 14:18:07 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-28 13:16:01 +07:00
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
if (salaryPeriod) {
|
|
|
|
|
this.SnapshotSalarys("SNAP2", salaryPeriod.id, request);
|
|
|
|
|
}
|
2024-02-28 14:18:07 +07:00
|
|
|
} else if (current.getDate() == 1 && current.getMonth() == 8) {
|
|
|
|
|
salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
2024-02-28 13:16:01 +07:00
|
|
|
year: current.getFullYear(),
|
2024-02-29 11:01:35 +07:00
|
|
|
period: "OCT",
|
2024-02-28 14:18:07 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-28 13:16:01 +07:00
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
if (salaryPeriod) {
|
|
|
|
|
this.SnapshotSalarys("SNAP1", salaryPeriod.id, request);
|
|
|
|
|
}
|
2024-02-28 14:18:07 +07:00
|
|
|
} else if (current.getDate() == 1 && current.getMonth() == 9) {
|
|
|
|
|
salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
2024-02-28 13:16:01 +07:00
|
|
|
year: current.getFullYear(),
|
|
|
|
|
period: "OCT",
|
2024-02-28 14:18:07 +07:00
|
|
|
isActive: true,
|
|
|
|
|
},
|
2024-02-28 13:16:01 +07:00
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
if (salaryPeriod) {
|
|
|
|
|
this.SnapshotSalarys("SNAP2", salaryPeriod.id, request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async SnapshotSalarys(snapshot: string, salaryPeriodId: string, request: any) {
|
|
|
|
|
snapshot = snapshot.toLocaleUpperCase();
|
|
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: salaryPeriodId },
|
|
|
|
|
});
|
|
|
|
|
if (!salaryPeriod) {
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการสร้างเงินเดือน");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const salaryOrg = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfile = await this.salaryProfileRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
|
|
|
|
|
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
|
2024-02-29 11:01:35 +07:00
|
|
|
|
2024-03-27 16:39:45 +07:00
|
|
|
const salaryOrgEmployee = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
});
|
|
|
|
|
const salaryProfileEmployee = await this.salaryProfileEmployeeRepository.find({
|
|
|
|
|
where: { salaryOrgId: In(salaryOrgEmployee.map((x) => x.id)) },
|
|
|
|
|
});
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileEmployeeRepository.remove(salaryProfileEmployee, { data: request });
|
|
|
|
|
await this.salaryOrgEmployeeRepository.remove(salaryOrgEmployee, { data: request });
|
2024-03-27 16:39:45 +07:00
|
|
|
|
2024-07-10 10:44:37 +07:00
|
|
|
let orgs = await new CallAPI().GetData(request, "/org/unauthorize/active/root/id");
|
2025-03-26 10:12:56 +07:00
|
|
|
let total = 100;
|
2024-07-10 10:44:37 +07:00
|
|
|
let _orgProfiles = await new CallAPI().PostData(request, "/org/unauthorize/salary/gen", {
|
2024-03-16 12:05:54 +07:00
|
|
|
page: 1,
|
2025-03-26 10:12:56 +07:00
|
|
|
pageSize: 100,
|
2024-03-16 12:05:54 +07:00
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
});
|
|
|
|
|
let orgProfiles = _orgProfiles.data;
|
|
|
|
|
total = _orgProfiles.total;
|
2025-03-26 10:12:56 +07:00
|
|
|
if (total > 100) {
|
|
|
|
|
const page = Math.ceil(total / 100);
|
2024-03-16 12:05:54 +07:00
|
|
|
for (let index = 2; index <= page; index++) {
|
|
|
|
|
await new CallAPI()
|
2024-07-10 10:44:37 +07:00
|
|
|
.PostData(request, "/org/unauthorize/profile/salary/gen", {
|
2024-03-16 12:05:54 +07:00
|
|
|
page: index,
|
2025-03-26 10:12:56 +07:00
|
|
|
pageSize: 100,
|
2024-03-16 12:05:54 +07:00
|
|
|
keyword: "",
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
|
|
|
|
})
|
|
|
|
|
.then((x) => {
|
|
|
|
|
Array.prototype.push.apply(orgProfiles, x.data);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-26 10:12:56 +07:00
|
|
|
total = 100;
|
2024-03-16 12:05:54 +07:00
|
|
|
let _orgProfileEmployees = await new CallAPI().PostData(
|
|
|
|
|
request,
|
2024-07-10 10:44:37 +07:00
|
|
|
"/org/unauthorize/profile/salary/employee/gen",
|
2024-03-16 12:05:54 +07:00
|
|
|
{
|
2024-02-29 11:01:35 +07:00
|
|
|
page: 1,
|
2025-03-26 10:12:56 +07:00
|
|
|
pageSize: 100,
|
2024-02-29 11:01:35 +07:00
|
|
|
keyword: "",
|
2024-03-11 14:19:42 +07:00
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
2024-03-16 12:05:54 +07:00
|
|
|
},
|
|
|
|
|
);
|
2024-03-18 13:50:53 +07:00
|
|
|
let orgProfileEmployees = _orgProfileEmployees.data;
|
2024-03-16 12:05:54 +07:00
|
|
|
total = _orgProfileEmployees.total;
|
2025-03-26 10:12:56 +07:00
|
|
|
if (total > 100) {
|
|
|
|
|
const page = Math.ceil(total / 100);
|
2024-02-29 11:01:35 +07:00
|
|
|
for (let index = 2; index <= page; index++) {
|
|
|
|
|
await new CallAPI()
|
2024-07-10 10:44:37 +07:00
|
|
|
.PostData(request, "/org/unauthorize/profile/salary/employee/gen", {
|
2024-02-29 11:01:35 +07:00
|
|
|
page: index,
|
2025-03-26 10:12:56 +07:00
|
|
|
pageSize: 100,
|
2024-02-29 11:01:35 +07:00
|
|
|
keyword: "",
|
2024-03-11 14:19:42 +07:00
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: salaryPeriod.period,
|
2024-02-29 11:01:35 +07:00
|
|
|
})
|
|
|
|
|
.then((x) => {
|
2024-03-16 12:05:54 +07:00
|
|
|
Array.prototype.push.apply(orgProfileEmployees, x.data);
|
2024-02-29 11:01:35 +07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-10 10:44:37 +07:00
|
|
|
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = null;
|
2024-02-29 11:01:35 +07:00
|
|
|
salaryPeriod.revisionId = revisionId;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryPeriod.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryPeriod.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryPeriod.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryPeriod });
|
2025-03-29 16:59:26 +07:00
|
|
|
let _null: any = null;
|
2024-02-29 11:01:35 +07:00
|
|
|
await Promise.all(
|
2024-03-27 16:39:45 +07:00
|
|
|
orgs.map(async (root: any) => {
|
2024-02-29 11:01:35 +07:00
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrg());
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
2024-02-29 11:01:35 +07:00
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-03-08 11:38:27 +07:00
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-08-23 14:10:34 +07:00
|
|
|
|
2024-03-08 11:38:27 +07:00
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
delete salaryOrgNew.id;
|
|
|
|
|
salaryOrgNew.group = "GROUP2";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-03-08 11:38:27 +07:00
|
|
|
}
|
2024-02-29 11:01:35 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
2024-03-16 12:05:54 +07:00
|
|
|
await Promise.all(
|
2024-03-27 16:39:45 +07:00
|
|
|
orgs.map(async (root: any) => {
|
2024-03-16 12:05:54 +07:00
|
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
|
|
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
|
|
|
salaryOrgNew.status = "PENDING";
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.rootId = root.rootId;
|
2025-03-29 16:59:26 +07:00
|
|
|
salaryOrgNew.rootDnaId = root.rootDnaId ?? _null;
|
2024-03-27 16:39:45 +07:00
|
|
|
salaryOrgNew.root = root.root;
|
2024-03-16 12:05:54 +07:00
|
|
|
salaryOrgNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryOrgNew.snapshot = snapshot;
|
|
|
|
|
salaryOrgNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.createdFullName = request.user.name;
|
|
|
|
|
salaryOrgNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryOrgNew.lastUpdateFullName = request.user.name;
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryOrgNew.createdAt = new Date();
|
|
|
|
|
salaryOrgNew.lastUpdatedAt = new Date();
|
2024-03-16 12:05:54 +07:00
|
|
|
salaryOrgNew.group = "GROUP1";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-08-23 14:10:34 +07:00
|
|
|
|
2024-07-17 17:15:21 +07:00
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
delete salaryOrgNew.id;
|
|
|
|
|
salaryOrgNew.group = "GROUP2";
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryOrgNew });
|
2024-07-17 17:15:21 +07:00
|
|
|
}
|
2024-03-16 12:05:54 +07:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
2024-03-07 15:38:21 +07:00
|
|
|
if (salaryPeriod.period != "SPECIAL") {
|
|
|
|
|
await Promise.all(
|
|
|
|
|
orgProfiles.map(async (profile: any) => {
|
|
|
|
|
let group = "GROUP1";
|
|
|
|
|
if (
|
|
|
|
|
(profile.posType == "ทั่วไป" && profile.posLevel == "ทักษะพิเศษ") ||
|
|
|
|
|
(profile.posType == "วิชาการ" && profile.posLevel == "เชี่ยวชาญ") ||
|
|
|
|
|
(profile.posType == "วิชาการ" && profile.posLevel == "ทรงคุณวุฒิ") ||
|
|
|
|
|
(profile.posType == "อำนวยการ" && profile.posLevel == "สูง") ||
|
|
|
|
|
(profile.posType == "บริหาร" && profile.posLevel == "ต้น") ||
|
|
|
|
|
(profile.posType == "บริหาร" && profile.posLevel == "สูง")
|
|
|
|
|
) {
|
|
|
|
|
group = "GROUP2";
|
|
|
|
|
}
|
|
|
|
|
const salaryOrgNew = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: profile.rootId,
|
|
|
|
|
snapshot: snapshot,
|
|
|
|
|
group: group,
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
|
2024-03-07 15:38:21 +07:00
|
|
|
if (salaryOrgNew != null) {
|
|
|
|
|
let salaryProfileNew = Object.assign(new SalaryProfile(), profile);
|
2024-04-04 18:57:18 +07:00
|
|
|
delete salaryProfileNew.id;
|
2024-03-07 15:38:21 +07:00
|
|
|
salaryProfileNew.salaryOrgId = salaryOrgNew.id;
|
|
|
|
|
salaryProfileNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgOld = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" },
|
|
|
|
|
});
|
|
|
|
|
const salaryOld = await this.salaryProfileRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
citizenId: salaryProfileNew.citizenId,
|
|
|
|
|
salaryOrgId: In(salaryOrgOld.map((x) => x.id)),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryProfileNew.type = salaryOld == null ? 0 : salaryOld.type;
|
|
|
|
|
salaryProfileNew.amount = salaryOld == null ? 0 : salaryOld.amount;
|
|
|
|
|
salaryProfileNew.amountSpecial = salaryOld == null ? 0 : salaryOld.amountSpecial;
|
|
|
|
|
salaryProfileNew.amountUse = salaryOld == null ? 0 : salaryOld.amountUse;
|
|
|
|
|
salaryProfileNew.positionSalaryAmount =
|
|
|
|
|
salaryOld == null ? 0 : salaryOld.positionSalaryAmount;
|
2024-03-07 17:37:00 +07:00
|
|
|
salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext;
|
2024-04-09 09:25:55 +07:00
|
|
|
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
|
2024-04-04 17:08:18 +07:00
|
|
|
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
|
2024-04-09 09:25:55 +07:00
|
|
|
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
|
2024-03-07 15:38:21 +07:00
|
|
|
}
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.createdAt = new Date();
|
|
|
|
|
salaryProfileNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileRepository.save(salaryProfileNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryProfileNew });
|
2024-02-29 11:01:35 +07:00
|
|
|
}
|
2024-03-07 15:38:21 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-16 12:05:54 +07:00
|
|
|
await Promise.all(
|
2024-03-18 13:50:53 +07:00
|
|
|
orgProfileEmployees.map(async (profile: any) => {
|
2024-03-16 12:05:54 +07:00
|
|
|
const salaryOrgNew = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: profile.rootId,
|
|
|
|
|
snapshot: snapshot,
|
|
|
|
|
group: "GROUP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (salaryOrgNew != null) {
|
|
|
|
|
let salaryProfileNew = Object.assign(new SalaryProfileEmployee(), profile);
|
2024-04-04 18:57:18 +07:00
|
|
|
delete salaryProfileNew.id;
|
2024-03-16 12:05:54 +07:00
|
|
|
salaryProfileNew.salaryOrgId = salaryOrgNew.id;
|
|
|
|
|
salaryProfileNew.revisionId = salaryPeriod.revisionId;
|
|
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgOld = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" },
|
|
|
|
|
});
|
|
|
|
|
const salaryOld = await this.salaryProfileEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
citizenId: salaryProfileNew.citizenId,
|
|
|
|
|
salaryOrgId: In(salaryOrgOld.map((x) => x.id)),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
salaryProfileNew.type = salaryOld == null ? 0 : salaryOld.type;
|
|
|
|
|
salaryProfileNew.amount = salaryOld == null ? 0 : salaryOld.amount;
|
|
|
|
|
salaryProfileNew.amountSpecial = salaryOld == null ? 0 : salaryOld.amountSpecial;
|
|
|
|
|
salaryProfileNew.amountUse = salaryOld == null ? 0 : salaryOld.amountUse;
|
|
|
|
|
salaryProfileNew.positionSalaryAmount =
|
|
|
|
|
salaryOld == null ? 0 : salaryOld.positionSalaryAmount;
|
|
|
|
|
salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext;
|
2024-04-09 09:25:55 +07:00
|
|
|
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
|
2024-04-04 17:08:18 +07:00
|
|
|
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
|
2024-04-09 09:25:55 +07:00
|
|
|
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
2024-09-03 14:48:19 +07:00
|
|
|
salaryProfileNew.createdUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.createdFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.lastUpdateUserId = request.user.sub;
|
|
|
|
|
salaryProfileNew.lastUpdateFullName = request.user.name;
|
|
|
|
|
salaryProfileNew.createdAt = new Date();
|
|
|
|
|
salaryProfileNew.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryProfileEmployeeRepository.save(salaryProfileNew, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: salaryProfileNew });
|
2024-03-16 12:05:54 +07:00
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
);
|
2024-03-07 15:38:21 +07:00
|
|
|
}
|
2024-02-29 11:01:35 +07:00
|
|
|
|
|
|
|
|
const salaryOrgNew = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
2024-03-16 12:05:54 +07:00
|
|
|
const salaryOrgEmployeeNew = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
2024-02-29 11:01:35 +07:00
|
|
|
if (salaryPeriod.period == "OCT") {
|
|
|
|
|
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
year: salaryPeriod.year,
|
|
|
|
|
period: "APR",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => {
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
2024-02-29 11:01:35 +07:00
|
|
|
} else {
|
|
|
|
|
_salaryOrg.currentAmount = salaryOrgSnap1.currentAmount;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount;
|
|
|
|
|
_salaryOrg.spentAmount = salaryOrgSnap1.spentAmount;
|
|
|
|
|
_salaryOrg.useAmount = salaryOrgSnap1.useAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-02-29 11:01:35 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
2024-02-29 11:01:35 +07:00
|
|
|
}
|
|
|
|
|
|
2024-09-03 14:48:19 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: _salaryOrg });
|
2024-02-29 11:01:35 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-16 12:05:54 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => {
|
|
|
|
|
let totalAmount = 0;
|
|
|
|
|
if (salaryPeriodAPROld != null) {
|
|
|
|
|
const salaryOrgSnap2Old: any = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriodAPROld.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP2",
|
|
|
|
|
},
|
|
|
|
|
relations: ["salaryProfiles"],
|
|
|
|
|
});
|
|
|
|
|
totalAmount =
|
|
|
|
|
salaryOrgSnap2Old == null
|
|
|
|
|
? 0
|
|
|
|
|
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-03-16 12:05:54 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.currentAmount = salaryOrgSnap1.currentAmount;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
2024-03-16 12:05:54 +07:00
|
|
|
_salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount;
|
|
|
|
|
_salaryOrg.spentAmount = salaryOrgSnap1.spentAmount;
|
|
|
|
|
_salaryOrg.useAmount = salaryOrgSnap1.useAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount");
|
|
|
|
|
_salaryOrg.currentAmount = totalProfile;
|
2024-03-20 19:30:13 +07:00
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
2024-03-16 12:05:54 +07:00
|
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
|
_salaryOrg.spentAmount = totalAmount;
|
|
|
|
|
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-03 14:48:19 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: _salaryOrg });
|
2024-03-16 12:05:54 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-07 15:38:21 +07:00
|
|
|
} else if (salaryPeriod.period == "APR") {
|
2024-02-29 11:01:35 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => {
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2024-02-29 11:01:35 +07:00
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
2024-03-06 17:24:27 +07:00
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
2024-02-29 11:01:35 +07:00
|
|
|
}
|
|
|
|
|
|
2024-09-03 14:48:19 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: _salaryOrg });
|
2024-02-29 11:01:35 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-16 12:05:54 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => {
|
|
|
|
|
if (snapshot == "SNAP2") {
|
|
|
|
|
const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
salaryPeriodId: salaryPeriod.id,
|
|
|
|
|
rootId: _salaryOrg.rootId,
|
|
|
|
|
group: _salaryOrg.group,
|
|
|
|
|
snapshot: "SNAP1",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (salaryOrgSnap1 == null) {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = salaryOrgSnap1.total;
|
|
|
|
|
_salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent;
|
|
|
|
|
_salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint;
|
|
|
|
|
_salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed;
|
|
|
|
|
_salaryOrg.remainQuota = salaryOrgSnap1.remainQuota;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
|
|
|
|
|
_salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
_salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
|
_salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-03 14:48:19 +07:00
|
|
|
_salaryOrg.createdUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.createdFullName = request.user.name;
|
|
|
|
|
_salaryOrg.lastUpdateUserId = request.user.sub;
|
|
|
|
|
_salaryOrg.lastUpdateFullName = request.user.name;
|
|
|
|
|
_salaryOrg.createdAt = new Date();
|
|
|
|
|
_salaryOrg.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgEmployeeRepository.save(_salaryOrg, { data: request });
|
2025-08-13 13:38:56 +07:00
|
|
|
// setLogDataDiff(request, { before, after: _salaryOrg });
|
2024-03-16 12:05:54 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-02-28 13:16:01 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-14 21:52:48 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API เจ้าหน้าที่ส่ง ผอ
|
|
|
|
|
*
|
|
|
|
|
*
|
2024-03-15 09:21:56 +07:00
|
|
|
* @param {string} periodId Guid, *Id รอบเงินเดือน
|
|
|
|
|
* @param {string} rootId Guid, *Id สำนัก
|
2024-03-14 21:52:48 +07:00
|
|
|
*/
|
2024-03-15 09:21:56 +07:00
|
|
|
@Get("officer/approve/{periodId}/{rootId}")
|
2024-08-23 14:10:34 +07:00
|
|
|
async OfficerApprove(
|
|
|
|
|
@Path() periodId: string,
|
|
|
|
|
rootId: string,
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
) {
|
2024-03-15 09:21:56 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: periodId },
|
|
|
|
|
relations: ["salaryOrgs"],
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
2024-03-15 09:21:56 +07:00
|
|
|
if (!salaryPeriod)
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
|
await Promise.all(
|
2024-03-18 16:17:05 +07:00
|
|
|
salaryPeriod.salaryOrgs
|
|
|
|
|
.filter((x) => x.rootId == rootId)
|
|
|
|
|
.map(async (x) => {
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(x);
|
2024-03-18 16:17:05 +07:00
|
|
|
x.status = "WAITHEAD1";
|
2024-09-03 14:48:19 +07:00
|
|
|
x.lastUpdateUserId = request.user.sub;
|
|
|
|
|
x.lastUpdateFullName = request.user.name;
|
|
|
|
|
x.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(x, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: x });
|
2024-03-18 16:17:05 +07:00
|
|
|
}),
|
2024-03-15 09:21:56 +07:00
|
|
|
);
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API ผอ ส่ง สกจ
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param {string} orgId Guid, *Id รอบเงินเดือน
|
2024-03-15 09:21:56 +07:00
|
|
|
* @param {string} rootId Guid, *Id สำนัก
|
2024-03-14 21:52:48 +07:00
|
|
|
*/
|
2024-03-15 09:21:56 +07:00
|
|
|
@Get("head/approve/{periodId}/{rootId}")
|
2024-08-23 14:10:34 +07:00
|
|
|
async HeadApprove(@Path() periodId: string, rootId: string, @Request() request: RequestWithUser) {
|
2024-03-15 09:21:56 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: periodId },
|
|
|
|
|
relations: ["salaryOrgs"],
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
2024-03-15 09:21:56 +07:00
|
|
|
if (!salaryPeriod)
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-03-14 21:52:48 +07:00
|
|
|
|
2024-03-15 09:21:56 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryPeriod.salaryOrgs
|
|
|
|
|
.filter((x) => x.rootId == rootId)
|
|
|
|
|
.map(async (x) => {
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(x);
|
2024-03-15 09:21:56 +07:00
|
|
|
x.status = "WAITOWNER1";
|
2024-09-03 14:48:19 +07:00
|
|
|
x.lastUpdateUserId = request.user.sub;
|
|
|
|
|
x.lastUpdateFullName = request.user.name;
|
|
|
|
|
x.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(x, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: x });
|
2024-03-15 09:21:56 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API สกจ อนุมัติ
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param {string} orgId Guid, *Id รอบเงินเดือน
|
2024-03-15 09:21:56 +07:00
|
|
|
* @param {string} rootId Guid, *Id สำนัก
|
2024-03-14 21:52:48 +07:00
|
|
|
*/
|
2024-03-15 09:21:56 +07:00
|
|
|
@Get("owner/approve/{periodId}/{rootId}")
|
2024-08-23 14:10:34 +07:00
|
|
|
async OwnerApprove(
|
|
|
|
|
@Path() periodId: string,
|
|
|
|
|
rootId: string,
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
) {
|
2024-03-15 09:21:56 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: periodId },
|
|
|
|
|
relations: ["salaryOrgs"],
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
2024-03-15 09:21:56 +07:00
|
|
|
if (!salaryPeriod)
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-03-14 21:52:48 +07:00
|
|
|
|
2024-03-15 09:21:56 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryPeriod.salaryOrgs
|
|
|
|
|
.filter((x) => x.rootId == rootId)
|
|
|
|
|
.map(async (x) => {
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(x);
|
2024-03-15 09:21:56 +07:00
|
|
|
x.status = "REPORT";
|
2024-09-03 14:48:19 +07:00
|
|
|
x.lastUpdateUserId = request.user.sub;
|
|
|
|
|
x.lastUpdateFullName = request.user.name;
|
|
|
|
|
x.lastUpdatedAt = new Date();
|
2024-08-23 14:10:34 +07:00
|
|
|
await this.salaryOrgRepository.save(x, { data: request });
|
|
|
|
|
setLogDataDiff(request, { before, after: x });
|
2024-03-15 09:21:56 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API สกจ ส่ง ผอ
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param {string} orgId Guid, *Id รอบเงินเดือน
|
2024-03-15 09:21:56 +07:00
|
|
|
* @param {string} rootId Guid, *Id สำนัก
|
2024-03-14 21:52:48 +07:00
|
|
|
*/
|
2024-03-15 09:21:56 +07:00
|
|
|
@Put("owner/comment/{periodId}/{rootId}")
|
2024-03-14 21:52:48 +07:00
|
|
|
async WaitOwnerApprove(
|
2024-03-15 09:21:56 +07:00
|
|
|
@Path() periodId: string,
|
|
|
|
|
rootId: string,
|
2024-03-14 21:52:48 +07:00
|
|
|
@Body()
|
|
|
|
|
body: {
|
|
|
|
|
titleRecommend: string;
|
|
|
|
|
},
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-03-14 21:52:48 +07:00
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_OFFICER");
|
2024-03-15 09:21:56 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: periodId },
|
|
|
|
|
relations: ["salaryOrgs"],
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
2024-03-15 09:21:56 +07:00
|
|
|
if (!salaryPeriod)
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-03-14 21:52:48 +07:00
|
|
|
|
2024-03-15 09:21:56 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryPeriod.salaryOrgs
|
|
|
|
|
.filter((x) => x.rootId == rootId)
|
|
|
|
|
.map(async (x) => {
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(x);
|
2024-03-15 09:21:56 +07:00
|
|
|
x.status = "WAITHEAD2";
|
|
|
|
|
x.ownerRecommend = body.titleRecommend;
|
2024-09-03 14:48:19 +07:00
|
|
|
x.lastUpdateUserId = request.user.sub;
|
|
|
|
|
x.lastUpdateFullName = request.user.name;
|
|
|
|
|
x.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
await this.salaryOrgRepository.save(x, { data: request });
|
2024-08-23 14:10:34 +07:00
|
|
|
setLogDataDiff(request, { before, after: x });
|
2024-03-15 09:21:56 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API ผอ ส่ง เจ้าหน้าที่
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param {string} orgId Guid, *Id รอบเงินเดือน
|
2024-03-15 09:21:56 +07:00
|
|
|
* @param {string} rootId Guid, *Id สำนัก
|
2024-03-14 21:52:48 +07:00
|
|
|
*/
|
2024-03-15 09:21:56 +07:00
|
|
|
@Put("head/comment/{periodId}/{rootId}")
|
2024-03-14 21:52:48 +07:00
|
|
|
async WaitHeadApprove(
|
2024-08-09 14:17:24 +07:00
|
|
|
@Request() request: RequestWithUser,
|
2024-03-15 09:21:56 +07:00
|
|
|
@Path() periodId: string,
|
|
|
|
|
rootId: string,
|
2024-03-14 21:52:48 +07:00
|
|
|
@Body()
|
|
|
|
|
body: {
|
|
|
|
|
titleRecommend: string;
|
|
|
|
|
},
|
|
|
|
|
) {
|
2024-08-09 14:17:24 +07:00
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
|
2024-03-15 09:21:56 +07:00
|
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
|
|
|
where: { id: periodId },
|
|
|
|
|
relations: ["salaryOrgs"],
|
2024-03-14 21:52:48 +07:00
|
|
|
});
|
2024-03-15 09:21:56 +07:00
|
|
|
if (!salaryPeriod)
|
|
|
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
2024-03-14 21:52:48 +07:00
|
|
|
|
2024-03-15 09:21:56 +07:00
|
|
|
await Promise.all(
|
|
|
|
|
salaryPeriod.salaryOrgs
|
|
|
|
|
.filter((x) => x.rootId == rootId)
|
|
|
|
|
.map(async (x) => {
|
2024-08-23 14:10:34 +07:00
|
|
|
const before = structuredClone(x);
|
2024-03-15 09:21:56 +07:00
|
|
|
x.status = "REPORT";
|
|
|
|
|
x.ownerRecommend = body.titleRecommend;
|
2024-09-03 14:48:19 +07:00
|
|
|
x.lastUpdateUserId = request.user.sub;
|
|
|
|
|
x.lastUpdateFullName = request.user.name;
|
|
|
|
|
x.lastUpdatedAt = new Date();
|
2024-08-27 13:36:10 +07:00
|
|
|
await this.salaryOrgRepository.save(x, { data: request });
|
2024-08-23 14:10:34 +07:00
|
|
|
setLogDataDiff(request, { before, after: x });
|
2024-03-15 09:21:56 +07:00
|
|
|
}),
|
|
|
|
|
);
|
2024-03-14 21:52:48 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
2025-04-05 18:12:02 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API แก้ไขรอบเงินเดือน
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
@Put("change/isclose/{snapShot}/{salaryPeriodId}")
|
|
|
|
|
async ChangeIsClose(
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
@Path() snapShot: string,
|
|
|
|
|
salaryPeriodId: string,
|
|
|
|
|
@Body()
|
|
|
|
|
body: {
|
|
|
|
|
isClose: boolean;
|
|
|
|
|
},
|
|
|
|
|
) {
|
|
|
|
|
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
|
|
|
|
|
const salaryPeriod = await this.salaryOrgRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriodId, snapshot: snapShot },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for await (const item of salaryPeriod) {
|
|
|
|
|
item.isClose = body.isClose;
|
|
|
|
|
await this.salaryOrgRepository.save(item);
|
|
|
|
|
}
|
2025-04-21 16:04:50 +07:00
|
|
|
const salaryPeriodEmp = await this.salaryOrgEmployeeRepository.find({
|
|
|
|
|
where: { salaryPeriodId: salaryPeriodId, snapshot: snapShot },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for await (const item of salaryPeriodEmp) {
|
|
|
|
|
item.isClose = body.isClose;
|
|
|
|
|
await this.salaryOrgEmployeeRepository.save(item);
|
|
|
|
|
}
|
2025-04-05 18:12:02 +07:00
|
|
|
return new HttpSuccess();
|
|
|
|
|
}
|
2024-02-22 15:32:42 +07:00
|
|
|
}
|