1729 lines
64 KiB
TypeScript
1729 lines
64 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 } 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 CallAPI from "../interfaces/call-api";
|
|
import { SalaryOrgEmployee } from "../entities/SalaryOrgEmployee";
|
|
import { EmployeePosType } from "../entities/EmployeePosType";
|
|
import {
|
|
SalaryProfileEmployee,
|
|
CreateSalaryProfileEmployee,
|
|
} from "../entities/SalaryProfileEmployee";
|
|
import { EmployeePosLevel } from "../entities/EmployeePosLevel";
|
|
import { SalaryEmployee } from "../entities/SalaryEmployee";
|
|
import { SalaryRankEmployee } from "../entities/SalaryRankEmployee";
|
|
import { SalaryFormulaEmployee } from "../entities/SalaryFormulaEmployee";
|
|
|
|
@Route("api/v1/salary/period-employee")
|
|
@Tags("SalaryEmployee")
|
|
@Security("bearerAuth")
|
|
export class SalaryPeriodEmployeeController extends Controller {
|
|
private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod);
|
|
private salaryOrgRepository = AppDataSource.getRepository(SalaryOrgEmployee);
|
|
private salaryProfileRepository = AppDataSource.getRepository(SalaryProfileEmployee);
|
|
private posTypeRepository = AppDataSource.getRepository(EmployeePosType);
|
|
private posLevelRepository = AppDataSource.getRepository(EmployeePosLevel);
|
|
private salaryRepository = AppDataSource.getRepository(SalaryEmployee);
|
|
private salaryRankRepository = AppDataSource.getRepository(SalaryRankEmployee);
|
|
private salaryFormulaEmployeeRepository = AppDataSource.getRepository(SalaryFormulaEmployee);
|
|
|
|
/**
|
|
* 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: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
}
|
|
|
|
const data = {
|
|
group1id:
|
|
salaryPeriod.salaryOrgEmployees.find(
|
|
(x) =>
|
|
x.group == "GROUP1" &&
|
|
x.rootId == body.rootId &&
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
) == null
|
|
? null
|
|
: salaryPeriod.salaryOrgEmployees.find(
|
|
(x) =>
|
|
x.group == "GROUP1" &&
|
|
x.rootId == body.rootId &&
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
)?.id,
|
|
group2id:
|
|
salaryPeriod.salaryOrgEmployees.find(
|
|
(x) =>
|
|
x.group == "GROUP2" &&
|
|
x.rootId == body.rootId &&
|
|
x.snapshot == body.snapshot.toLocaleUpperCase(),
|
|
) == null
|
|
? null
|
|
: salaryPeriod.salaryOrgEmployees.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 sum = item.salaryProfiles.reduce((accumulator, object) => {
|
|
return accumulator + object.amountSpecial;
|
|
}, 0);
|
|
const data = {
|
|
org: item.root,
|
|
total: item.total,
|
|
fifteenPercent: item.fifteenPercent + item.fifteenPoint / 100,
|
|
chosen: item.quantityUsed,
|
|
remaining: item.remainQuota,
|
|
currentAmount: item.currentAmount,
|
|
sixPercentAmount: item.sixPercentAmount,
|
|
spentAmount: item.spentAmount,
|
|
sixPercentSpentAmount: item.sixPercentAmount - item.spentAmount,
|
|
useAmount: item.useAmount,
|
|
remainingAmount: item.remainingAmount,
|
|
totalAmountSpecial: sum,
|
|
totalBackup: item.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) {
|
|
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);
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
if (salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
where: {
|
|
salaryOrgId: salaryProfile?.salaryOrg.id,
|
|
type: "FULL",
|
|
},
|
|
});
|
|
const calRemainQuota = salaryProfile?.salaryOrg.fifteenPercent - amountFullType;
|
|
salaryProfile.salaryOrg.quantityUsed = amountFullType;
|
|
salaryProfile.salaryOrg.remainQuota = calRemainQuota;
|
|
await this.salaryOrgRepository.save(salaryProfile?.salaryOrg);
|
|
} else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.createQueryBuilder("salaryProfile")
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
.where({
|
|
salaryOrgId: salaryProfile?.salaryOrg.id,
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
})
|
|
.getRawOne();
|
|
const calRemainAmount =
|
|
salaryProfile.salaryOrg.sixPercentAmount -
|
|
sumAmountUse.totalAmount -
|
|
salaryProfile.salaryOrg.spentAmount;
|
|
salaryProfile.salaryOrg.useAmount =
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null ? 0 : sumAmountUse.totalAmount;
|
|
salaryProfile.salaryOrg.remainingAmount = calRemainAmount;
|
|
await this.salaryOrgRepository.save(salaryProfile?.salaryOrg);
|
|
}
|
|
}
|
|
|
|
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 }) {
|
|
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, "ไม่พบระดับตำแหน่ง");
|
|
}
|
|
let type = salaryProfile.type;
|
|
const salaryFormula = await this.salaryFormulaEmployeeRepository.findOne({
|
|
where: {
|
|
position: salaryProfile.position,
|
|
posType: { posTypeName: salaryProfile.posType },
|
|
posLevel: { posLevelName: salaryProfile.posLevel },
|
|
},
|
|
relations: ["salaryEmployeeMins", "salaryEmployee"],
|
|
});
|
|
let group = salaryProfile.group;
|
|
let step = salaryProfile.salaryLevel == null ? 0 : salaryProfile.salaryLevel;
|
|
if (group == null || group == 0) {
|
|
if (salaryFormula != null) {
|
|
group = salaryFormula.salaryEmployeeMins.sort((a, b) => a.group - b.group)[0].group;
|
|
} else {
|
|
group = 1;
|
|
}
|
|
}
|
|
if (salaryProfile.amount == null || salaryProfile.amount == 0) {
|
|
if (salaryFormula != null) {
|
|
const salaryRankMin = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMin == null ? 0 : salaryFormula.salaryMin,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
if (salaryRankMin == null) {
|
|
step = 1;
|
|
} else {
|
|
step = salaryRankMin.step - 0.5;
|
|
}
|
|
} else {
|
|
step = 1;
|
|
}
|
|
}
|
|
|
|
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" || type == "FULL" || type == "FULLHAFT") {
|
|
if (type == "HAFT") {
|
|
step = step + 0.5;
|
|
} else if (type == "FULL") {
|
|
step = step + 1;
|
|
} else if (type == "FULLHAFT") {
|
|
step = step + 1.5;
|
|
}
|
|
let salaryRankMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
order: { step: "DESC" },
|
|
});
|
|
if (salaryRankMax != null && step > salaryRankMax.step) {
|
|
let salaryRankAmount = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: MoreThan(salaryProfile.amount),
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group + 1,
|
|
},
|
|
},
|
|
order: { salaryMonth: "ASC" },
|
|
});
|
|
group = group + 1;
|
|
step =
|
|
(salaryRankAmount == null ? 1 : salaryRankAmount.step) +
|
|
(step - (salaryRankMax == null ? 0 : salaryRankMax.step) - 0.5);
|
|
}
|
|
let salaryRanks = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
step: step,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (salaryRanks != null && salaryRanks.salaryMonth != null) {
|
|
if (
|
|
salaryFormula != null &&
|
|
salaryFormula.salaryMax != null &&
|
|
salaryRanks.salaryMonth > salaryFormula.salaryMax
|
|
) {
|
|
let salaryRankAmountMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMax,
|
|
salaryEmployee_: {
|
|
id: salaryFormula.salaryEmployee.id,
|
|
},
|
|
},
|
|
});
|
|
salaryProfile.isNext = true;
|
|
salaryProfile.amountUse = salaryFormula.salaryMax - salaryProfile.amount;
|
|
salaryProfile.positionSalaryAmount =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount =
|
|
salaryRankAmountMax == null ? 0 : salaryRankAmountMax.salaryDay;
|
|
salaryProfile.groupNew = salaryFormula.salaryEmployee.group;
|
|
salaryProfile.salaryLevelNew = salaryRankAmountMax == null ? 0 : salaryRankAmountMax.step;
|
|
salaryRankAmountMax == null ? 0 : salaryRankAmountMax.step;
|
|
if (salaryRankAmountMax != null) {
|
|
if (step - salaryRankAmountMax.step <= 0.5) {
|
|
salaryProfile.positionSalaryAmountPer = 0.02;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.02;
|
|
} else if (step - salaryRankAmountMax.step <= 1) {
|
|
salaryProfile.positionSalaryAmountPer = 0.04;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.04;
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0.06;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.06;
|
|
}
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse = salaryRanks.salaryMonth - salaryProfile.amount;
|
|
salaryProfile.positionSalaryAmount = salaryRanks.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount = salaryRanks.salaryDay;
|
|
salaryProfile.groupNew = group;
|
|
salaryProfile.salaryLevelNew = step;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse = 0;
|
|
salaryProfile.positionSalaryAmount = salaryProfile.amount;
|
|
salaryProfile.positionSalaryDayAmount = 0;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
|
}
|
|
|
|
await this.salaryProfileRepository.save(salaryProfile);
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
if (salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
if (salaryProfile.isReserve == false) {
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
where: {
|
|
salaryOrgId: salaryProfile?.salaryOrg.id,
|
|
type: "FULL",
|
|
},
|
|
});
|
|
const calRemainQuota = salaryProfile?.salaryOrg.fifteenPercent - amountFullType;
|
|
salaryProfile.salaryOrg.quantityUsed = amountFullType;
|
|
salaryProfile.salaryOrg.remainQuota = calRemainQuota;
|
|
await this.salaryOrgRepository.save(salaryProfile?.salaryOrg);
|
|
}
|
|
} else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.createQueryBuilder("salaryProfile")
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
.where({
|
|
salaryOrgId: salaryProfile?.salaryOrg.id,
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
})
|
|
.getRawOne();
|
|
const calRemainAmount =
|
|
salaryProfile.salaryOrg.sixPercentAmount -
|
|
sumAmountUse.totalAmount -
|
|
salaryProfile.salaryOrg.spentAmount;
|
|
salaryProfile.salaryOrg.useAmount =
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null ? 0 : sumAmountUse.totalAmount;
|
|
salaryProfile.salaryOrg.remainingAmount = calRemainAmount;
|
|
await this.salaryOrgRepository.save(salaryProfile?.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 }) {
|
|
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, "ไม่พบข้อมูลกลุ่มการขอเลื่อนเงินเดือน");
|
|
}
|
|
|
|
salaryProfile.salaryOrgId = salaryOrg.id;
|
|
await this.salaryProfileRepository.save(salaryProfile);
|
|
if (salaryOrg) {
|
|
// หาจำนวน Quota คงเหลือ
|
|
if (salaryOrg.snapshot == "SNAP1") {
|
|
if (salaryOrg.salaryPeriod.period == "APR") {
|
|
if (salaryProfile.isReserve == false) {
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
where: {
|
|
salaryOrgId: salaryOrg.id,
|
|
type: "FULL",
|
|
},
|
|
});
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
salaryOrg.quantityUsed = amountFullType;
|
|
salaryOrg.remainQuota = calRemainQuota;
|
|
await this.salaryOrgRepository.save(salaryOrg);
|
|
}
|
|
} else if (salaryOrg.salaryPeriod.period == "OCT") {
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.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;
|
|
await this.salaryOrgRepository.save(salaryOrg);
|
|
}
|
|
}
|
|
}
|
|
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 }) {
|
|
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 ขั้นต่อปีได้",
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//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, "ไม่พบระดับตำแหน่ง");
|
|
}
|
|
salaryProfile.type = body.type;
|
|
salaryProfile.isReserve = body.isReserve;
|
|
let type = salaryProfile.type;
|
|
const salaryFormula = await this.salaryFormulaEmployeeRepository.findOne({
|
|
where: {
|
|
position: salaryProfile.position,
|
|
posType: { posTypeName: salaryProfile.posType },
|
|
posLevel: { posLevelName: salaryProfile.posLevel },
|
|
},
|
|
relations: ["salaryEmployeeMins", "salaryEmployee"],
|
|
});
|
|
let group = salaryProfile.group;
|
|
let step = salaryProfile.salaryLevel == null ? 0 : salaryProfile.salaryLevel;
|
|
if (group == null || group == 0) {
|
|
if (salaryFormula != null) {
|
|
group = salaryFormula.salaryEmployeeMins.sort((a, b) => a.group - b.group)[0].group;
|
|
} else {
|
|
group = 1;
|
|
}
|
|
}
|
|
if (salaryProfile.amount == null || salaryProfile.amount == 0) {
|
|
if (salaryFormula != null) {
|
|
const salaryRankMin = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMin == null ? 0 : salaryFormula.salaryMin,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
if (salaryRankMin == null) {
|
|
step = 1;
|
|
} else {
|
|
step = salaryRankMin.step - 0.5;
|
|
}
|
|
} else {
|
|
step = 1;
|
|
}
|
|
}
|
|
|
|
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" || type == "FULL" || type == "FULLHAFT") {
|
|
if (type == "HAFT") {
|
|
step = step + 0.5;
|
|
} else if (type == "FULL") {
|
|
step = step + 1;
|
|
} else if (type == "FULLHAFT") {
|
|
step = step + 1.5;
|
|
}
|
|
let salaryRankMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
order: { step: "DESC" },
|
|
});
|
|
if (salaryRankMax != null && step > salaryRankMax.step) {
|
|
let salaryRankAmount = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: MoreThan(salaryProfile.amount == null ? 0 : salaryProfile.amount),
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group + 1,
|
|
},
|
|
},
|
|
order: { salaryMonth: "ASC" },
|
|
});
|
|
group = group + 1;
|
|
step =
|
|
(salaryRankAmount == null ? 1 : salaryRankAmount.step) +
|
|
(step - (salaryRankMax == null ? 0 : salaryRankMax.step) - 0.5);
|
|
}
|
|
let salaryRanks = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
step: step,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (salaryRanks != null && salaryRanks.salaryMonth != null) {
|
|
if (
|
|
salaryFormula != null &&
|
|
salaryFormula.salaryMax != null &&
|
|
salaryRanks.salaryMonth > salaryFormula.salaryMax
|
|
) {
|
|
let salaryRankAmountMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMax,
|
|
salaryEmployee_: {
|
|
id: salaryFormula.salaryEmployee.id,
|
|
},
|
|
},
|
|
});
|
|
salaryProfile.isNext = true;
|
|
salaryProfile.amountUse =
|
|
salaryFormula.salaryMax - (salaryProfile.amount == null ? 0 : salaryProfile.amount);
|
|
salaryProfile.positionSalaryAmount =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount =
|
|
salaryRankAmountMax == null ? 0 : salaryRankAmountMax.salaryDay;
|
|
salaryProfile.groupNew = salaryFormula.salaryEmployee.group;
|
|
salaryProfile.salaryLevelNew = salaryRankAmountMax == null ? 0 : salaryRankAmountMax.step;
|
|
if (salaryRankAmountMax != null) {
|
|
if (step - salaryRankAmountMax.step <= 0.5) {
|
|
salaryProfile.positionSalaryAmountPer = 0.02;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.02;
|
|
} else if (step - salaryRankAmountMax.step <= 1) {
|
|
salaryProfile.positionSalaryAmountPer = 0.04;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.04;
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0.06;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.06;
|
|
}
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse =
|
|
salaryRanks.salaryMonth - (salaryProfile.amount == null ? 0 : salaryProfile.amount);
|
|
salaryProfile.positionSalaryAmount = salaryRanks.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount = salaryRanks.salaryDay;
|
|
salaryProfile.groupNew = group;
|
|
salaryProfile.salaryLevelNew = step;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse = 0;
|
|
salaryProfile.positionSalaryAmount =
|
|
salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
|
salaryProfile.positionSalaryDayAmount = 0;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
|
}
|
|
await this.salaryProfileRepository.save(salaryProfile);
|
|
|
|
if (salaryProfile.salaryOrg) {
|
|
// หาจำนวน Quota คงเหลือ
|
|
if (salaryProfile.salaryOrg.snapshot == "SNAP1") {
|
|
if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
|
|
if (body.isReserve == false) {
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
where: {
|
|
salaryOrgId: salaryProfile.salaryOrg.id,
|
|
type: "FULL",
|
|
},
|
|
});
|
|
const calRemainQuota = salaryProfile.salaryOrg.fifteenPercent - amountFullType;
|
|
salaryProfile.salaryOrg.quantityUsed = amountFullType;
|
|
salaryProfile.salaryOrg.remainQuota = calRemainQuota;
|
|
await this.salaryOrgRepository.save(salaryProfile.salaryOrg);
|
|
}
|
|
} else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.createQueryBuilder("salaryProfile")
|
|
.select("SUM(salaryProfile.amountUse)", "totalAmount")
|
|
.where({
|
|
salaryOrgId: salaryProfile.salaryOrg.id,
|
|
type: In(["HAFT", "FULL", "FULLHAFT"]),
|
|
})
|
|
.getRawOne();
|
|
const calRemainAmount =
|
|
salaryProfile.salaryOrg.sixPercentAmount -
|
|
sumAmountUse.totalAmount -
|
|
salaryProfile.salaryOrg.spentAmount;
|
|
salaryProfile.salaryOrg.useAmount =
|
|
sumAmountUse == null || sumAmountUse.totalAmount == null ? 0 : sumAmountUse.totalAmount;
|
|
salaryProfile.salaryOrg.remainingAmount = calRemainAmount;
|
|
await this.salaryOrgRepository.save(salaryProfile.salaryOrg);
|
|
}
|
|
}
|
|
}
|
|
return new HttpSuccess();
|
|
}
|
|
|
|
/**
|
|
* API รายการอัตราเงินเดือน
|
|
*
|
|
* @summary SLR_023 - รายการอัตราเงินเดือน #22
|
|
*
|
|
*/
|
|
@Put("org/{id}")
|
|
async GetListsSalaryProfile(
|
|
@Path() id: string,
|
|
@Body()
|
|
body: {
|
|
page: number;
|
|
pageSize: number;
|
|
keyword?: string;
|
|
type?: any;
|
|
isRetire?: string | null;
|
|
},
|
|
) {
|
|
const salaryOrg = await this.salaryOrgRepository.findOne({
|
|
where: {
|
|
id: id,
|
|
},
|
|
});
|
|
if (!salaryOrg) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
}
|
|
const [salaryProfile, total] = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.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("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: { user: Record<string, any> },
|
|
) {
|
|
const salaryProfile = await this.salaryProfileRepository.findOne({
|
|
where: {
|
|
id: id,
|
|
},
|
|
});
|
|
if (!salaryProfile) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเพิ่มเงินเดือนของบุคคลนี้");
|
|
}
|
|
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);
|
|
return new HttpSuccess();
|
|
}
|
|
|
|
/**
|
|
* API เพิ่มคนเลื่อนเงินเดือนตามรอบ
|
|
*
|
|
* @summary SLR_028 - เพิ่มคนเลื่อนเงินเดือนตามรอบ #27
|
|
*
|
|
*/
|
|
@Post("org/profile")
|
|
async addSalaryProfile(
|
|
@Body() requestBody: CreateSalaryProfileEmployee,
|
|
@Request() request: { user: Record<string, any> },
|
|
) {
|
|
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 SalaryProfileEmployee(), 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, "ไม่พบระดับตำแหน่ง");
|
|
}
|
|
let type = salaryProfile.type;
|
|
const salaryFormula = await this.salaryFormulaEmployeeRepository.findOne({
|
|
where: {
|
|
position: salaryProfile.position,
|
|
posType: { posTypeName: salaryProfile.posType },
|
|
posLevel: { posLevelName: salaryProfile.posLevel },
|
|
},
|
|
relations: ["salaryEmployeeMins", "salaryEmployee"],
|
|
});
|
|
let group = salaryProfile.group;
|
|
let step = salaryProfile.salaryLevel == null ? 0 : salaryProfile.salaryLevel;
|
|
if (group == null || group == 0) {
|
|
if (salaryFormula != null) {
|
|
group = salaryFormula.salaryEmployeeMins.sort((a, b) => a.group - b.group)[0].group;
|
|
} else {
|
|
group = 1;
|
|
}
|
|
}
|
|
if (salaryProfile.amount == null || salaryProfile.amount == 0) {
|
|
if (salaryFormula != null) {
|
|
const salaryRankMin = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMin == null ? 0 : salaryFormula.salaryMin,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
if (salaryRankMin == null) {
|
|
step = 1;
|
|
} else {
|
|
step = salaryRankMin.step - 0.5;
|
|
}
|
|
} else {
|
|
step = 1;
|
|
}
|
|
}
|
|
|
|
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" || type == "FULL" || type == "FULLHAFT") {
|
|
if (type == "HAFT") {
|
|
step = step + 0.5;
|
|
} else if (type == "FULL") {
|
|
step = step + 1;
|
|
} else if (type == "FULLHAFT") {
|
|
step = step + 1.5;
|
|
}
|
|
let salaryRankMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
order: { step: "DESC" },
|
|
});
|
|
if (salaryRankMax != null && step > salaryRankMax.step) {
|
|
let salaryRankAmount = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: MoreThan(salaryProfile.amount == null ? 0 : salaryProfile.amount),
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group + 1,
|
|
},
|
|
},
|
|
order: { salaryMonth: "ASC" },
|
|
});
|
|
group = group + 1;
|
|
step =
|
|
(salaryRankAmount == null ? 1 : salaryRankAmount.step) +
|
|
(step - (salaryRankMax == null ? 0 : salaryRankMax.step) - 0.5);
|
|
}
|
|
let salaryRanks = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
step: step,
|
|
salaryEmployee_: {
|
|
isActive: true,
|
|
group: group,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (salaryRanks != null && salaryRanks.salaryMonth != null) {
|
|
if (
|
|
salaryFormula != null &&
|
|
salaryFormula.salaryMax != null &&
|
|
salaryRanks.salaryMonth > salaryFormula.salaryMax
|
|
) {
|
|
let salaryRankAmountMax = await this.salaryRankRepository.findOne({
|
|
where: {
|
|
salaryMonth: salaryFormula.salaryMax,
|
|
salaryEmployee_: {
|
|
id: salaryFormula.salaryEmployee.id,
|
|
},
|
|
},
|
|
});
|
|
salaryProfile.isNext = true;
|
|
salaryProfile.amountUse =
|
|
salaryFormula.salaryMax - (salaryProfile.amount == null ? 0 : salaryProfile.amount);
|
|
salaryProfile.positionSalaryAmount =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount =
|
|
salaryRankAmountMax == null ? 0 : salaryRankAmountMax.salaryDay;
|
|
salaryProfile.groupNew = salaryFormula.salaryEmployee.group;
|
|
salaryProfile.salaryLevelNew = salaryRankAmountMax == null ? 0 : salaryRankAmountMax.step;
|
|
if (salaryRankAmountMax != null) {
|
|
if (step - salaryRankAmountMax.step <= 0.5) {
|
|
salaryProfile.positionSalaryAmountPer = 0.02;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.02;
|
|
} else if (step - salaryRankAmountMax.step <= 1) {
|
|
salaryProfile.positionSalaryAmountPer = 0.04;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.04;
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0.06;
|
|
salaryProfile.amountSpecial =
|
|
salaryRankAmountMax == null || salaryRankAmountMax.salaryMonth == null
|
|
? 0
|
|
: salaryRankAmountMax.salaryMonth * 0.06;
|
|
}
|
|
} else {
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse =
|
|
salaryRanks.salaryMonth - (salaryProfile.amount == null ? 0 : salaryProfile.amount);
|
|
salaryProfile.positionSalaryAmount = salaryRanks.salaryMonth;
|
|
salaryProfile.positionSalaryDayAmount = salaryRanks.salaryDay;
|
|
salaryProfile.groupNew = group;
|
|
salaryProfile.salaryLevelNew = step;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
salaryProfile.isNext = false;
|
|
salaryProfile.amountUse = 0;
|
|
salaryProfile.positionSalaryAmount =
|
|
salaryProfile.amount == null ? 0 : salaryProfile.amount;
|
|
salaryProfile.positionSalaryDayAmount = 0;
|
|
salaryProfile.positionSalaryAmountPer = 0;
|
|
salaryProfile.amountSpecial = 0;
|
|
}
|
|
} else {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
|
|
}
|
|
|
|
salaryProfile.salaryOrgId = salaryOrg.id;
|
|
salaryProfile.createdUserId = request.user.sub;
|
|
salaryProfile.createdFullName = request.user.name;
|
|
salaryProfile.lastUpdateUserId = request.user.sub;
|
|
salaryProfile.lastUpdateFullName = request.user.name;
|
|
await this.salaryProfileRepository.save(salaryProfile);
|
|
|
|
// หาจำนวน Quota คงเหลือ
|
|
if (salaryOrg.snapshot == "SNAP1") {
|
|
const _salaryOrg = await this.salaryOrgRepository.findOne({
|
|
where: {
|
|
id: salaryOrg.id,
|
|
},
|
|
});
|
|
if (!_salaryOrg) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน");
|
|
}
|
|
if (salaryOrg.salaryPeriod.period == "APR") {
|
|
_salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
_salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
|
|
_salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
|
|
|
|
const amountFullType = await this.salaryProfileRepository.count({
|
|
where: {
|
|
salaryOrgId: salaryOrg.id,
|
|
type: "FULL",
|
|
},
|
|
});
|
|
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
|
|
_salaryOrg.quantityUsed = amountFullType;
|
|
_salaryOrg.remainQuota = calRemainQuota;
|
|
await this.salaryOrgRepository.save(_salaryOrg);
|
|
} else if (salaryOrg.salaryPeriod.period == "OCT") {
|
|
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
|
|
_salaryOrg.currentAmount = totalProfile;
|
|
_salaryOrg.total = salaryOrg.salaryProfiles.length;
|
|
_salaryOrg.sixPercentAmount = totalProfile * 0.06;
|
|
|
|
const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee)
|
|
.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;
|
|
await this.salaryOrgRepository.save(_salaryOrg);
|
|
}
|
|
}
|
|
|
|
return new HttpSuccess(salaryProfile.id);
|
|
}
|
|
|
|
/**
|
|
* API ปิดรอบเงินเดือน
|
|
*
|
|
* @summary SLR_032 - ปิดรอบเงินเดือน #31
|
|
*
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
*/
|
|
@Get("close/{id}")
|
|
async closeSalaryPeriod_ById(@Path() id: string) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: id },
|
|
});
|
|
if (!salaryPeriod) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
}
|
|
salaryPeriod.isClose = !salaryPeriod.isClose;
|
|
await this.salaryPeriodRepository.save(salaryPeriod);
|
|
return new HttpSuccess();
|
|
}
|
|
|
|
/**
|
|
* API สร้างรอบเงินเดือน
|
|
*
|
|
* @summary SLR_016 - สร้างรอบเงินเดือน #16
|
|
*
|
|
*/
|
|
@Post()
|
|
async create_salary_period(
|
|
@Body() requestBody: CreateSalaryPeriod,
|
|
@Request() request: { user: Record<string, any> },
|
|
) {
|
|
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) + " ซ้ำ",
|
|
);
|
|
}
|
|
|
|
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;
|
|
await this.salaryPeriodRepository.save(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);
|
|
await this.salaryProfileRepository.remove(salaryProfile);
|
|
|
|
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;
|
|
await this.salaryPeriodRepository.save(salaryPeriod);
|
|
|
|
await Promise.all(
|
|
orgs.map(async (rootId: string) => {
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
|
salaryOrgNew.salaryPeriodId = salaryPeriod.id;
|
|
salaryOrgNew.status = "PENDING";
|
|
salaryOrgNew.rootId = rootId;
|
|
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";
|
|
await this.salaryOrgRepository.save(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: { user: Record<string, any> },
|
|
) {
|
|
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) + " ซ้ำ",
|
|
);
|
|
}
|
|
|
|
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);
|
|
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);
|
|
await this.salaryProfileRepository.remove(salaryProfile);
|
|
|
|
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;
|
|
await this.salaryPeriodRepository.save(chk_SalaryPeriod);
|
|
|
|
await Promise.all(
|
|
orgs.map(async (rootId: string) => {
|
|
let salaryOrgNew = Object.assign(new SalaryOrgEmployee());
|
|
salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id;
|
|
salaryOrgNew.status = "PENDING";
|
|
salaryOrgNew.rootId = rootId;
|
|
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";
|
|
await this.salaryOrgRepository.save(salaryOrgNew);
|
|
}),
|
|
);
|
|
}
|
|
return new HttpSuccess(id);
|
|
}
|
|
|
|
/**
|
|
* API ลบรอบเงินเดือน
|
|
*
|
|
* @summary SLR_018 - ลบรอบเงินเดือน #18
|
|
*
|
|
* @param {string} id Guid, *Id รอบเงินเดือน
|
|
*/
|
|
@Delete("{id}")
|
|
async delete_salary_period(@Path() id: string) {
|
|
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"],
|
|
});
|
|
const salaryProfile = SalaryOrg.find((x) => x.salaryProfiles.length > 0);
|
|
if (salaryProfile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้");
|
|
|
|
await this.salaryOrgRepository.remove(SalaryOrg);
|
|
await this.salaryPeriodRepository.remove(SalaryPeriod);
|
|
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);
|
|
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 รายการรอบเงินเดือน
|
|
*
|
|
* @summary SLR_020 - รายการรอบเงินเดือน #20
|
|
*
|
|
*/
|
|
@Get()
|
|
async GetListsSalaryPeriod(
|
|
@Query("page") page: number = 1,
|
|
@Query("pageSize") pageSize: number = 10,
|
|
@Query("keyword") keyword?: string,
|
|
@Query("year") year: number = 2024,
|
|
) {
|
|
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.effectiveDate", "DESC")
|
|
.skip((page - 1) * pageSize)
|
|
.take(pageSize)
|
|
.getManyAndCount();
|
|
|
|
return new HttpSuccess({ data: salaryPeriod, total });
|
|
}
|
|
|
|
/**
|
|
* API เจ้าหน้าที่ส่ง ผอ
|
|
*
|
|
*
|
|
* @param {string} periodId Guid, *Id รอบเงินเดือน
|
|
* @param {string} rootId Guid, *Id สำนัก
|
|
*/
|
|
@Get("officer/approve/{periodId}/{rootId}")
|
|
async OfficerApprove(@Path() periodId: string, rootId: string) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: periodId },
|
|
relations: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod)
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
await Promise.all(
|
|
salaryPeriod.salaryOrgEmployees
|
|
.filter((x) => x.rootId == rootId)
|
|
.map(async (x: any) => {
|
|
x.status = "WAITHEAD1";
|
|
await this.salaryOrgRepository.save(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) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: periodId },
|
|
relations: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod)
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
await Promise.all(
|
|
salaryPeriod.salaryOrgEmployees
|
|
.filter((x) => x.rootId == rootId)
|
|
.map(async (x: any) => {
|
|
x.status = "WAITOWNER1";
|
|
await this.salaryOrgRepository.save(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) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: periodId },
|
|
relations: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod)
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
await Promise.all(
|
|
salaryPeriod.salaryOrgEmployees
|
|
.filter((x) => x.rootId == rootId)
|
|
.map(async (x: any) => {
|
|
x.status = "REPORT";
|
|
await this.salaryOrgRepository.save(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;
|
|
},
|
|
) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: periodId },
|
|
relations: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod)
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
await Promise.all(
|
|
salaryPeriod.salaryOrgEmployees
|
|
.filter((x) => x.rootId == rootId)
|
|
.map(async (x: any) => {
|
|
x.status = "WAITHEAD2";
|
|
x.ownerRecommend = body.titleRecommend;
|
|
await this.salaryOrgRepository.save(x);
|
|
}),
|
|
);
|
|
return new HttpSuccess();
|
|
}
|
|
|
|
/**
|
|
* API ผอ ส่ง เจ้าหน้าที่
|
|
*
|
|
*
|
|
* @param {string} orgId Guid, *Id รอบเงินเดือน
|
|
* @param {string} rootId Guid, *Id สำนัก
|
|
*/
|
|
@Put("head/comment/{periodId}/{rootId}")
|
|
async WaitHeadApprove(
|
|
@Path() periodId: string,
|
|
rootId: string,
|
|
@Body()
|
|
body: {
|
|
titleRecommend: string;
|
|
},
|
|
) {
|
|
const salaryPeriod = await this.salaryPeriodRepository.findOne({
|
|
where: { id: periodId },
|
|
relations: ["salaryOrgEmployees"],
|
|
});
|
|
if (!salaryPeriod)
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้");
|
|
|
|
await Promise.all(
|
|
salaryPeriod.salaryOrgEmployees
|
|
.filter((x) => x.rootId == rootId)
|
|
.map(async (x: any) => {
|
|
x.status = "REPORT";
|
|
x.ownerRecommend = body.titleRecommend;
|
|
await this.salaryOrgRepository.save(x);
|
|
}),
|
|
);
|
|
return new HttpSuccess();
|
|
}
|
|
}
|