hrms-api-salary/src/controllers/SalaryPeriodController.ts
DESKTOP-2S5P7D1\Windows 10 fdf27655e1 add dna
2025-02-04 10:13:40 +07:00

3310 lines
135 KiB
TypeScript

import {
Controller,
Get,
Post,
Put,
Delete,
Route,
Security,
Tags,
Body,
Path,
Request,
Query,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import { In, Not, MoreThan, Brackets, Like, MoreThanOrEqual, IsNull } from "typeorm";
import HttpSuccess from "../interfaces/http-success";
import HttpError from "../interfaces/http-error";
import HttpStatusCode from "../interfaces/http-status";
import { CreateSalaryPeriod, SalaryPeriod, UpdateSalaryPeriod } from "../entities/SalaryPeriod";
import Extension from "../interfaces/extension";
import { SalaryOrg } from "../entities/SalaryOrg";
import { CreateSalaryProfile, SalaryProfile } from "../entities/SalaryProfile";
import { PosType } from "../entities/PosType";
import { PosLevel } from "../entities/PosLevel";
import { Salarys } from "../entities/Salarys";
import { SalaryRanks } from "../entities/SalaryRanks";
import CallAPI from "../interfaces/call-api";
import { SalaryOrgEmployee } from "../entities/SalaryOrgEmployee";
import { SalaryProfileEmployee } from "../entities/SalaryProfileEmployee";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/salary/period")
@Tags("Salary")
@Security("bearerAuth")
export class SalaryPeriodController extends Controller {
private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod);
private salaryOrgRepository = AppDataSource.getRepository(SalaryOrg);
private salaryOrgEmployeeRepository = AppDataSource.getRepository(SalaryOrgEmployee);
private salaryProfileRepository = AppDataSource.getRepository(SalaryProfile);
private salaryProfileEmployeeRepository = AppDataSource.getRepository(SalaryProfileEmployee);
private posTypeRepository = AppDataSource.getRepository(PosType);
private posLevelRepository = AppDataSource.getRepository(PosLevel);
private salaryRepository = AppDataSource.getRepository(Salarys);
private salaryRankRepository = AppDataSource.getRepository(SalaryRanks);
/**
* API รอบล่าสุด
*
* @summary SLR_030 - รอบล่าสุด #29
*
*/
@Post("latest")
async GetGroupSalaryPeriodLatest(
@Body() body: { rootId: string; salaryPeriodId: string; snapshot: string },
) {
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: {
id: body.salaryPeriodId,
isActive: true,
},
order: { effectiveDate: "DESC" },
relations: ["salaryOrgs"],
});
if (!salaryPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
}
const data = {
group1id:
salaryPeriod.salaryOrgs.find(
(x) =>
x.group == "GROUP1" &&
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
) == null
? null
: salaryPeriod.salaryOrgs.find(
(x) =>
x.group == "GROUP1" &&
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
)?.id,
group2id:
salaryPeriod.salaryOrgs.find(
(x) =>
x.group == "GROUP2" &&
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
) == null
? null
: salaryPeriod.salaryOrgs.find(
(x) =>
x.group == "GROUP2" &&
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
)?.id,
effectiveDate: salaryPeriod.effectiveDate,
period: salaryPeriod.period,
};
return new HttpSuccess(data);
}
/**
* 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: {
group: Like(
`%${body.group.trim().toUpperCase() == "GROUP1" ? "GROUP1" : body.group.trim().toUpperCase() == "GROUP2" ? "GROUP2" : "GROUP1"}%`,
),
snapshot: body.snapshot.trim().toUpperCase(),
salaryPeriod: { id: body.period },
},
});
const salaryOrg: any[] = [];
await Promise.all(
_salaryOrg.map(async (item) => {
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 },
},
});
const sum = item.salaryProfiles.reduce((accumulator, object) => {
return accumulator + object.amountSpecial;
}, 0);
const sumGROUP2 =
_salaryOrgGROUP2 == null
? 0
: _salaryOrgGROUP2.salaryProfiles.reduce((accumulator, object) => {
return accumulator + object.amountSpecial;
}, 0);
const data = {
org: item.root,
total: item.total + (_salaryOrgGROUP2 == null ? 0 : _salaryOrgGROUP2.total),
fifteenPercent:
item.fifteenPercent +
item.fifteenPoint / 100 +
(_salaryOrgGROUP2 == null
? 0
: _salaryOrgGROUP2.fifteenPercent + _salaryOrgGROUP2.fifteenPoint / 100),
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),
};
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),
},
});
}
/**
* 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, "ไม่พบรอบการขึ้นเงินเดือน");
}
const sum = salaryOrg.salaryProfiles.reduce((accumulator, object) => {
return accumulator + object.amountSpecial;
}, 0);
const data = {
total: salaryOrg.total,
fifteenPercent: salaryOrg.fifteenPercent,
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,
totalAmountSpecial: sum,
totalBackup: salaryOrg.salaryProfiles.filter((x) => x.isReserve == true).length,
status: salaryOrg.status,
};
return new HttpSuccess(data);
}
/**
* API ลบคนเลื่อนเงินเดือนในรอบ
*
* @summary SLR_024 - ลบคนเลื่อนเงินเดือนในรอบ #23
*
* @param {string} id profile Id
*/
@Delete("profile/{id}")
async deleteSalaryProfile(@Path() id: string, @Request() req: RequestWithUser) {
await new permission().PermissionDelete(req, "SYS_SALARY_OFFICER");
const salaryProfile = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: id },
});
if (!salaryProfile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
}
await this.salaryProfileRepository.remove(salaryProfile, { data: req });
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 });
}
}
} 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 });
}
}
}
}
return new HttpSuccess();
}
return new HttpSuccess();
}
/**
* API แก้ไขเงินเดือน
*
* @summary SLR_025 - แก้ไขเงินเดือน #24
*
* @param {string} id profile Id
* @param {string} amount ฐานเงินเดือน
*/
@Post("change/amount")
async changeAmount(
@Body() body: { profileId: string; amount: number },
@Request() request: RequestWithUser,
) {
await new permission().PermissionCreate(request, "SYS_SALARY_OFFICER");
const salaryProfile = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: body.profileId },
});
if (!salaryProfile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
}
salaryProfile.amount = body.amount;
//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, "ไม่พบระดับตำแหน่ง");
}
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) {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryHalf,
isNext: true,
},
});
}
} else if (salaryProfile.type == "FULL") {
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
type = "HAFT";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFull,
isNext: true,
},
});
}
} 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";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFullHalf,
isNext: true,
},
});
}
}
} 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 = request.user.sub;
salaryProfile.lastUpdateFullName = request.user.name;
salaryProfile.lastUpdatedAt = new Date();
const before = structuredClone(salaryProfile);
await this.salaryProfileRepository.save(salaryProfile, { data: request });
setLogDataDiff(request, { 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 = request.user.sub;
salaryOrg.lastUpdateFullName = request.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: request });
setLogDataDiff(request, { 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 = request.user.sub;
salaryOrg.lastUpdateFullName = request.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: request });
setLogDataDiff(request, { before, after: salaryOrg });
}
}
}
}
return new HttpSuccess();
}
}
/**
* API ย้ายกลุ่ม
*
* @summary SLR_026 - ย้ายกลุ่ม #25
*
* @param {string} id profile Id
* @param {string} groupId groupId
*/
@Post("change/group")
async changeGroup(
@Body() body: { profileId: string; groupId: string },
@Request() req: RequestWithUser,
) {
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
const salaryProfile = await this.salaryProfileRepository.findOne({
// relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: body.profileId },
});
if (!salaryProfile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ");
}
const salaryOrg = await this.salaryOrgRepository.findOne({
relations: ["salaryPeriod"],
where: { id: body.groupId },
});
if (!salaryOrg) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มการขอเลื่อนเงินเดือน");
}
const before = null;
salaryProfile.salaryOrgId = salaryOrg.id;
salaryProfile.lastUpdateUserId = req.user.sub;
salaryProfile.lastUpdateFullName = req.user.name;
salaryProfile.lastUpdatedAt = new Date();
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();
}
/**
* API แก้ไขขั้น
*
* @summary SLR_025 - แก้ไขขั้น #24
*
* @param {string} id profile Id
* @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น
*/
@Post("change/type")
async changeType(
@Body() body: { profileId: string; type: string; isReserve: boolean; remark?: string | null },
@Request() req: RequestWithUser,
) {
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
const salaryProfile = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: body.profileId },
});
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) {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryHalf,
isNext: true,
},
});
}
} else if (salaryProfile.type == "FULL") {
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
type = "HAFT";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFull,
isNext: true,
},
});
}
} 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";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFullHalf,
isNext: true,
},
});
}
}
} 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();
}
/**
* API รายการอัตราเงินเดือน
*
* @summary SLR_023 - รายการอัตราเงินเดือน #22
*
*/
@Put("org/{id}")
async GetListsSalaryProfile(
@Request() request: RequestWithUser,
@Path() id: string,
@Body()
body: {
page: number;
pageSize: number;
keyword?: string;
type?: any;
isRetire?: string | null;
},
) {
await new permission().PermissionList(request, "SYS_SALARY_OFFICER");
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")
.andWhere(
new Brackets((qb) => {
qb.andWhere(body.type != null && body.type != "" ? `profile.type LIKE :type` : "1=1", {
type: body.type == null ? "" : `${body.type.toUpperCase()}`,
})
.andWhere(
body.isRetire != null
? body.isRetire == "1"
? `profile.isRetired = true`
: `profile.isRetired = false`
: "1=1",
)
.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}%` })
.orWhere(
"CONCAT(profile.prefix,profile.firstName,' ',profile.lastName) LIKE :keyword",
{ keyword: `%${body.keyword}%` },
)
.orWhere("CONCAT(profile.orgShortName,profile.posMasterNo) LIKE :keyword", {
keyword: `%${body.keyword}%`,
})
// .orWhere("profile.citizenId LIKE :keyword", { keyword: `%${body.keyword}%` })
.orWhere("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` })
// .orWhere("profile.posType LIKE :keyword", { keyword: `%${body.keyword}%` })
// .orWhere("profile.posLevel LIKE :keyword", { keyword: `%${body.keyword}%` })
// .orWhere("profile.posExecutive LIKE :keyword", { keyword: `%${body.keyword}%` })
.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}%`,
});
}),
);
}),
)
.orderBy("profile.citizenId", "ASC")
.addOrderBy("profile.isReserve", "ASC")
.skip((body.page - 1) * body.pageSize)
.take(body.pageSize)
.getManyAndCount();
return new HttpSuccess({ data: salaryProfile, total });
}
/**
* API แก้คุณสมบัติ
*
* @summary SLR_031 - แก้คุณสมบัติ #30
*
*/
@Put("org/property/{id}")
async editProperty(
@Path() id: string,
@Body()
body: {
isPunish: any;
isSuspension: any;
isAbsent: any;
isLeave: any;
},
@Request() request: RequestWithUser,
) {
await new permission().PermissionUpdate(request, "SYS_SALARY_OFFICER");
const salaryProfile = await this.salaryProfileRepository.findOne({
where: {
id: id,
},
});
if (!salaryProfile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเพิ่มเงินเดือนของบุคคลนี้");
}
const before = structuredClone(salaryProfile);
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();
await this.salaryProfileRepository.save(salaryProfile, { data: request });
setLogDataDiff(request, { before, after: salaryProfile });
return new HttpSuccess();
}
/**
* API เพิ่มคนเลื่อนเงินเดือนตามรอบ
*
* @summary SLR_028 - เพิ่มคนเลื่อนเงินเดือนตามรอบ #27
*
*/
@Post("org/profile")
async addSalaryProfile(
@Body() requestBody: CreateSalaryProfile,
@Request() request: RequestWithUser,
) {
await new permission().PermissionCreate(request, "SYS_SALARY_OFFICER");
const salaryOrg = await this.salaryOrgRepository.findOne({
relations: ["salaryPeriod", "salaryProfiles"],
where: {
id: requestBody.id,
},
});
if (!salaryOrg) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
}
const salaryOrgAll = await this.salaryOrgRepository.find({
where: {
salaryPeriodId: salaryOrg.salaryPeriodId,
snapshot: salaryOrg.snapshot,
},
});
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,
"ไม่สามารถเพิ่มรายชื่อนี้ได้ เนื่องจากมีการยื่นขอเลื่อนเงินเดือนแล้ว",
);
}
let salaryProfile: any = Object.assign(new SalaryProfile(), requestBody);
delete salaryProfile.id;
salaryProfile.type = salaryProfile.type.toUpperCase();
//Type & Level
const posType = await this.posTypeRepository.findOne({
where: {
posTypeName: salaryProfile.posType,
},
});
if (!posType) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
}
const posLevel = await this.posLevelRepository.findOne({
where: {
posTypeId: posType.id,
posLevelName: salaryProfile.posLevel,
},
});
if (!posLevel) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
}
//Salary
const salarys = await this.salaryRepository.findOne({
where: {
posTypeId: posLevel.posTypeId,
posLevelId: posLevel.id,
isSpecial: salaryProfile.isSpecial == true ? true : false,
isActive: true,
},
});
if (!salarys) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
}
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) {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryHalf,
isNext: true,
},
});
}
} else if (salaryProfile.type == "FULL") {
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
type = "HAFT";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFull,
isNext: true,
},
});
}
} 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";
}
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFullHalf,
isNext: true,
},
});
}
}
} 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, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
}
const before = null;
salaryProfile.salaryOrgId = salaryOrg.id;
salaryProfile.createdUserId = request.user.sub;
salaryProfile.createdFullName = request.user.name;
salaryProfile.lastUpdateUserId = request.user.sub;
salaryProfile.lastUpdateFullName = request.user.name;
salaryProfile.createdAt = new Date();
salaryProfile.lastUpdatedAt = new Date();
await this.salaryProfileRepository.save(salaryProfile, { data: request });
setLogDataDiff(request, { 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 = request.user.sub;
salaryOrg.lastUpdateFullName = request.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: request });
setLogDataDiff(request, { 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 = request.user.sub;
salaryOrg.lastUpdateFullName = request.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: request });
setLogDataDiff(request, { before, after: salaryOrg });
}
}
}
}
return new HttpSuccess();
}
return new HttpSuccess(salaryProfile.id);
}
/**
* API ปิดรอบเงินเดือน
*
* @summary SLR_032 - ปิดรอบเงินเดือน #31
*
* @param {string} id Guid, *Id รอบเงินเดือน
*/
@Get("close/{id}")
async closeSalaryPeriod_ById(@Path() id: string, @Request() request: RequestWithUser) {
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: id },
});
if (!salaryPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
}
const before = structuredClone(salaryPeriod);
salaryPeriod.isClose = !salaryPeriod.isClose;
salaryPeriod.lastUpdateUserId = request.user.sub;
salaryPeriod.lastUpdateFullName = request.user.name;
salaryPeriod.lastUpdatedAt = new Date();
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
setLogDataDiff(request, { before, after: salaryPeriod });
return new HttpSuccess();
}
/**
* API สร้างรอบเงินเดือน
*
* @summary SLR_016 - สร้างรอบเงินเดือน #16
*
*/
@Post()
async create_salary_period(
@Body() requestBody: CreateSalaryPeriod,
@Request() request: RequestWithUser,
) {
await new permission().PermissionCreate(request, "SYS_SALARY_ROUND");
const salaryPeriod = Object.assign(new SalaryPeriod(), requestBody);
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,
year: requestBody.year,
},
});
if (chk_period) {
throw new HttpError(
HttpStatusCode.NOT_FOUND,
"ประเภทผังปี " + Extension.ToThaiYear(salaryPeriod.year) + " ซ้ำ",
);
}
const before = null;
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;
salaryPeriod.createdAt = new Date();
salaryPeriod.lastUpdatedAt = new Date();
await this.salaryPeriodRepository.save(salaryPeriod, { data: request });
setLogDataDiff(request, { before, after: salaryPeriod });
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)) },
});
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
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");
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
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, after: salaryPeriod });
await Promise.all(
orgs.map(async (root: any) => {
let salaryOrgNew = Object.assign(new SalaryOrg());
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
salaryOrgNew.status = "PENDING";
salaryOrgNew.rootId = root.rootId;
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";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
}),
);
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;
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();
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
}),
);
}
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,
@Request() request: RequestWithUser,
) {
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
const chk_SalaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: id },
});
if (!chk_SalaryPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
}
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),
year: requestBody.year,
},
});
if (chk_period) {
throw new HttpError(
HttpStatusCode.NOT_FOUND,
"ประเภทผังปี " + (requestBody.effectiveDate.getFullYear() + 543) + " ซ้ำ",
);
}
const beforeChk_SalaryPeriod = structuredClone(chk_SalaryPeriod);
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);
await this.salaryPeriodRepository.save(chk_SalaryPeriod, { data: request });
setLogDataDiff(request, { before: beforeChk_SalaryPeriod, after: chk_SalaryPeriod });
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)) },
});
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
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)) },
});
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");
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
chk_SalaryPeriod.revisionId = revisionId;
chk_SalaryPeriod.lastUpdateUserId = request.user.sub;
chk_SalaryPeriod.lastUpdateFullName = request.user.name;
chk_SalaryPeriod.lastUpdatedAt = new Date();
await this.salaryPeriodRepository.save(chk_SalaryPeriod, { data: request });
setLogDataDiff(request, { before: beforeChk_SalaryPeriod, after: chk_SalaryPeriod });
await Promise.all(
orgs.map(async (root: any) => {
let salaryOrgNew = Object.assign(new SalaryOrg());
const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id;
salaryOrgNew.status = "PENDING";
salaryOrgNew.rootId = root.rootId;
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";
salaryOrgNew.createdAt = new Date();
salaryOrgNew.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
}),
);
await Promise.all(
orgs.map(async (root: any) => {
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id;
salaryOrgNew.status = "PENDING";
salaryOrgNew.rootId = root.rootId;
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";
salaryOrgNew.createdAt = new Date();
salaryOrgNew.lastUpdatedAt = new Date();
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
}),
);
}
return new HttpSuccess(id);
}
/**
* API ลบรอบเงินเดือน
*
* @summary SLR_018 - ลบรอบเงินเดือน #18
*
* @param {string} id Guid, *Id รอบเงินเดือน
*/
@Delete("{id}")
async delete_salary_period(@Path() id: string, @Request() request: RequestWithUser) {
await new permission().PermissionDelete(request, "SYS_SALARY_ROUND");
const SalaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: id },
});
if (!SalaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
if (SalaryPeriod?.period == "SPECIAL") {
const SalaryOrg = await this.salaryOrgRepository.find({
where: { salaryPeriodId: SalaryPeriod.id },
relations: { salaryProfiles: true },
});
const salaryProfile = SalaryOrg.find((x) => x.salaryProfiles.length > 0);
if (salaryProfile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้");
await this.salaryOrgRepository.remove(SalaryOrg, { data: request });
await this.salaryPeriodRepository.remove(SalaryPeriod, { data: request });
return new HttpSuccess();
} else {
const SalaryOrg = await this.salaryOrgRepository.findOne({
where: { salaryPeriodId: SalaryPeriod.id },
});
if (SalaryOrg) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้");
await this.salaryPeriodRepository.remove(SalaryPeriod, { data: request });
return new HttpSuccess();
}
}
/**
* API รายการรอบเงินเดือน(active)
*
*
*/
@Get("active")
async GetListsSalaryPeriodActive(
@Query("page") page: number = 1,
@Query("pageSize") pageSize: number = 10,
@Query("keyword") keyword?: string,
) {
const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod)
.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")
.skip((page - 1) * pageSize)
.take(pageSize)
.getManyAndCount();
return new HttpSuccess({ data: salaryPeriod, total });
}
/**
* 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 },
select: [
"id",
"period",
"isActive",
"effectiveDate",
"isClose",
"status",
"year",
"revisionId",
],
});
if (!salaryPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
}
return new HttpSuccess(salaryPeriod);
}
/**
* 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}` })
.andWhere({ isActive: true })
.andWhere({ revisionId: Not(IsNull()) })
.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 });
}
/**
* API รายการรอบเงินเดือน
*
* @summary SLR_020 - รายการรอบเงินเดือน #20
*
*/
@Get()
async GetListsSalaryPeriod(
@Request() request: RequestWithUser,
@Query("page") page: number = 1,
@Query("pageSize") pageSize: number = 10,
@Query("keyword") keyword?: string,
@Query("year") year: number = 2024,
) {
await new permission().PermissionList(request, "SYS_SALARY_ROUND");
const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod)
.createQueryBuilder("salaryPeriod")
.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}` })
.select([
"salaryPeriod.id",
"salaryPeriod.period",
"salaryPeriod.isActive",
"salaryPeriod.isClose",
"salaryPeriod.effectiveDate",
"salaryPeriod.status",
"salaryPeriod.year",
"salaryPeriod.revisionId",
])
.orderBy("salaryPeriod.year", "DESC")
.addOrderBy("salaryPeriod.effectiveDate", "DESC")
.skip((page - 1) * pageSize)
.take(pageSize)
.getManyAndCount();
return new HttpSuccess({ data: salaryPeriod, total });
}
/**
* API snapshot salary
*
* @summary snapshot salary
*
*/
@Get("snapshot/{snapshot}/{salaryPeriodId}")
async SnapshotSalary(
@Path() snapshot: string,
salaryPeriodId: string,
@Request() request: RequestWithUser,
) {
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)) },
});
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
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");
let total = 1000;
let _orgProfiles = await new CallAPI().PostData(request, "/org/unauthorize/salary/gen", {
page: 1,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
});
let orgProfiles = _orgProfiles.data;
total = _orgProfiles.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", {
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",
{
page: 1,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
},
);
orgProfileEmployees = _orgProfileEmployees.data;
total = _orgProfileEmployees.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", {
page: index,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
})
.then((x) => {
Array.prototype.push.apply(orgProfileEmployees, x.data);
});
}
}
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
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 });
await Promise.all(
orgs.map(async (root: any) => {
let salaryOrgNew = Object.assign(new SalaryOrg());
delete salaryOrgNew.id;
const beforeSalaryOrgNew = structuredClone(salaryOrgNew);
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
salaryOrgNew.status = "PENDING";
salaryOrgNew.rootId = root.rootId;
salaryOrgNew.rootDnaId = root.rootDnaId;
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";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
if (salaryPeriod.period != "SPECIAL") {
delete salaryOrgNew.id;
salaryOrgNew.group = "GROUP2";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
}
}),
);
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;
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();
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
if (salaryPeriod.period != "SPECIAL") {
delete salaryOrgNew.id;
salaryOrgNew.group = "GROUP2";
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryOrgNew, after: salaryOrgNew });
}
}),
);
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,
},
});
if (salaryOrgNew != null) {
let salaryProfileNew = Object.assign(new SalaryProfile(), 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") {
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 ? "PENDING" : 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;
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
}
await this.salaryProfileRepository.save(salaryProfileNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew });
}
}),
);
await Promise.all(
orgProfileEmployees.map(async (profile: any) => {
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);
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") {
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;
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
}
await this.salaryProfileEmployeeRepository.save(salaryProfileNew, { data: request });
setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew });
}
}),
);
}
const salaryOrgNew = await this.salaryOrgRepository.find({
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
relations: ["salaryProfiles"],
});
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");
}
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;
} 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;
}
} else {
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;
}
_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) => {
let totalAmount = 0;
const before_salaryOrg = structuredClone(_salaryOrg);
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");
}
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;
} 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;
}
} else {
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;
}
_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 });
}),
);
} else if (salaryPeriod.period == "APR") {
await Promise.all(
salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => {
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) {
_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);
}
_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);
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);
} 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);
}
_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 });
}),
);
}
return new HttpSuccess();
}
/**
* Cronjob SalaryPeriod
*/
async CronjobSalaryPeriod() {
const current = new Date();
let salaryPeriod: any;
let request: any;
if (current.getDate() == 1 && current.getMonth() == 2) {
salaryPeriod = await this.salaryPeriodRepository.findOne({
where: {
year: current.getFullYear(),
period: "APR",
isActive: true,
},
});
if (salaryPeriod) {
this.SnapshotSalarys("SNAP1", salaryPeriod.id, request);
}
} else if (current.getDate() == 1 && current.getMonth() == 3) {
salaryPeriod = await this.salaryPeriodRepository.findOne({
where: {
year: current.getFullYear(),
period: "APR",
isActive: true,
},
});
if (salaryPeriod) {
this.SnapshotSalarys("SNAP2", salaryPeriod.id, request);
}
} else if (current.getDate() == 1 && current.getMonth() == 8) {
salaryPeriod = await this.salaryPeriodRepository.findOne({
where: {
year: current.getFullYear(),
period: "OCT",
isActive: true,
},
});
if (salaryPeriod) {
this.SnapshotSalarys("SNAP1", salaryPeriod.id, request);
}
} else if (current.getDate() == 1 && current.getMonth() == 9) {
salaryPeriod = await this.salaryPeriodRepository.findOne({
where: {
year: current.getFullYear(),
period: "OCT",
isActive: true,
},
});
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)) },
});
await this.salaryOrgRepository.remove(salaryOrg, { data: request });
await this.salaryProfileRepository.remove(salaryProfile, { data: request });
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");
let total = 1000;
let _orgProfiles = await new CallAPI().PostData(request, "/org/unauthorize/salary/gen", {
page: 1,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
});
let orgProfiles = _orgProfiles.data;
total = _orgProfiles.total;
if (total > 1000) {
const page = Math.ceil(total / 1000);
for (let index = 2; index <= page; index++) {
await new CallAPI()
.PostData(request, "/org/unauthorize/profile/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 = await new CallAPI().PostData(
request,
"/org/unauthorize/profile/salary/employee/gen",
{
page: 1,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
},
);
let orgProfileEmployees = _orgProfileEmployees.data;
total = _orgProfileEmployees.total;
if (total > 1000) {
const page = Math.ceil(total / 1000);
for (let index = 2; index <= page; index++) {
await new CallAPI()
.PostData(request, "/org/unauthorize/profile/salary/employee/gen", {
page: index,
pageSize: 1000,
keyword: "",
year: salaryPeriod.year,
period: salaryPeriod.period,
})
.then((x) => {
Array.prototype.push.apply(orgProfileEmployees, x.data);
});
}
}
let revisionId = await new CallAPI().GetData(request, "/org/unauthorize/revision/latest");
const before = null;
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, after: salaryPeriod });
await Promise.all(
orgs.map(async (root: any) => {
let salaryOrgNew = Object.assign(new SalaryOrg());
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
salaryOrgNew.status = "PENDING";
salaryOrgNew.rootId = root.rootId;
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";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
if (salaryPeriod.period != "SPECIAL") {
delete salaryOrgNew.id;
salaryOrgNew.group = "GROUP2";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
}
}),
);
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;
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";
await this.salaryOrgRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
if (salaryPeriod.period != "SPECIAL") {
delete salaryOrgNew.id;
salaryOrgNew.group = "GROUP2";
await this.salaryOrgEmployeeRepository.save(salaryOrgNew, { data: request });
setLogDataDiff(request, { before, after: salaryOrgNew });
}
}),
);
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,
},
});
if (salaryOrgNew != null) {
let 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;
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;
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.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();
await this.salaryProfileRepository.save(salaryProfileNew, { data: request });
setLogDataDiff(request, { before, after: salaryProfileNew });
}
}),
);
await Promise.all(
orgProfileEmployees.map(async (profile: any) => {
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);
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;
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;
salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial;
salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve;
salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired;
}
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();
await this.salaryProfileEmployeeRepository.save(salaryProfileNew, { data: request });
setLogDataDiff(request, { before, after: salaryProfileNew });
}
}),
);
}
const salaryOrgNew = await this.salaryOrgRepository.find({
where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot },
relations: ["salaryProfiles"],
});
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,
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;
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
_salaryOrg.spentAmount = totalAmount;
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
} 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;
}
} else {
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;
}
_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, after: _salaryOrg });
}),
);
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;
_salaryOrg.total = _salaryOrg.salaryProfiles.length;
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
_salaryOrg.spentAmount = totalAmount;
_salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount;
} 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;
}
} else {
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;
}
_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, after: _salaryOrg });
}),
);
} else if (salaryPeriod.period == "APR") {
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;
_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);
}
_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, after: _salaryOrg });
}),
);
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);
}
_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, after: _salaryOrg });
}),
);
}
}
/**
* API เจ้าหน้าที่ส่ง ผอ
*
*
* @param {string} periodId Guid, *Id รอบเงินเดือน
* @param {string} rootId Guid, *Id สำนัก
*/
@Get("officer/approve/{periodId}/{rootId}")
async OfficerApprove(
@Path() periodId: string,
rootId: string,
@Request() request: RequestWithUser,
) {
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: periodId },
relations: ["salaryOrgs"],
});
if (!salaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
await Promise.all(
salaryPeriod.salaryOrgs
.filter((x) => x.rootId == rootId)
.map(async (x) => {
const before = structuredClone(x);
x.status = "WAITHEAD1";
x.lastUpdateUserId = request.user.sub;
x.lastUpdateFullName = request.user.name;
x.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(x, { data: request });
setLogDataDiff(request, { before, after: x });
}),
);
return new HttpSuccess();
}
/**
* API ผอ ส่ง สกจ
*
*
* @param {string} orgId Guid, *Id รอบเงินเดือน
* @param {string} rootId Guid, *Id สำนัก
*/
@Get("head/approve/{periodId}/{rootId}")
async HeadApprove(@Path() periodId: string, rootId: string, @Request() request: RequestWithUser) {
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: periodId },
relations: ["salaryOrgs"],
});
if (!salaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
await Promise.all(
salaryPeriod.salaryOrgs
.filter((x) => x.rootId == rootId)
.map(async (x) => {
const before = structuredClone(x);
x.status = "WAITOWNER1";
x.lastUpdateUserId = request.user.sub;
x.lastUpdateFullName = request.user.name;
x.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(x, { data: request });
setLogDataDiff(request, { before, after: x });
}),
);
return new HttpSuccess();
}
/**
* API สกจ อนุมัติ
*
*
* @param {string} orgId Guid, *Id รอบเงินเดือน
* @param {string} rootId Guid, *Id สำนัก
*/
@Get("owner/approve/{periodId}/{rootId}")
async OwnerApprove(
@Path() periodId: string,
rootId: string,
@Request() request: RequestWithUser,
) {
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: periodId },
relations: ["salaryOrgs"],
});
if (!salaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
await Promise.all(
salaryPeriod.salaryOrgs
.filter((x) => x.rootId == rootId)
.map(async (x) => {
const before = structuredClone(x);
x.status = "REPORT";
x.lastUpdateUserId = request.user.sub;
x.lastUpdateFullName = request.user.name;
x.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(x, { data: request });
setLogDataDiff(request, { before, after: x });
}),
);
return new HttpSuccess();
}
/**
* API สกจ ส่ง ผอ
*
*
* @param {string} orgId Guid, *Id รอบเงินเดือน
* @param {string} rootId Guid, *Id สำนัก
*/
@Put("owner/comment/{periodId}/{rootId}")
async WaitOwnerApprove(
@Path() periodId: string,
rootId: string,
@Body()
body: {
titleRecommend: string;
},
@Request() request: RequestWithUser,
) {
await new permission().PermissionUpdate(request, "SYS_SALARY_OFFICER");
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: periodId },
relations: ["salaryOrgs"],
});
if (!salaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
await Promise.all(
salaryPeriod.salaryOrgs
.filter((x) => x.rootId == rootId)
.map(async (x) => {
const before = structuredClone(x);
x.status = "WAITHEAD2";
x.ownerRecommend = body.titleRecommend;
x.lastUpdateUserId = request.user.sub;
x.lastUpdateFullName = request.user.name;
x.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(x, { data: request });
setLogDataDiff(request, { before, after: x });
}),
);
return new HttpSuccess();
}
/**
* API ผอ ส่ง เจ้าหน้าที่
*
*
* @param {string} orgId Guid, *Id รอบเงินเดือน
* @param {string} rootId Guid, *Id สำนัก
*/
@Put("head/comment/{periodId}/{rootId}")
async WaitHeadApprove(
@Request() request: RequestWithUser,
@Path() periodId: string,
rootId: string,
@Body()
body: {
titleRecommend: string;
},
) {
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
const salaryPeriod = await this.salaryPeriodRepository.findOne({
where: { id: periodId },
relations: ["salaryOrgs"],
});
if (!salaryPeriod)
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
await Promise.all(
salaryPeriod.salaryOrgs
.filter((x) => x.rootId == rootId)
.map(async (x) => {
const before = structuredClone(x);
x.status = "REPORT";
x.ownerRecommend = body.titleRecommend;
x.lastUpdateUserId = request.user.sub;
x.lastUpdateFullName = request.user.name;
x.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(x, { data: request });
setLogDataDiff(request, { before, after: x });
}),
);
return new HttpSuccess();
}
}