sort order

This commit is contained in:
moss 2025-04-05 18:12:02 +07:00
parent bf85af7e0d
commit 230b552f6d
15 changed files with 951 additions and 145 deletions

View file

@ -83,6 +83,20 @@ export class SalaryPeriodController extends Controller {
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
)?.id,
group1IsClose:
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(),
)?.isClose,
group2id:
salaryPeriod.salaryOrgs.find(
(x) =>
@ -97,6 +111,20 @@ export class SalaryPeriodController extends Controller {
x.rootId == body.rootId &&
x.snapshot == body.snapshot.toLocaleUpperCase(),
)?.id,
group2IsClose:
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(),
)?.isClose,
effectiveDate: salaryPeriod.effectiveDate,
period: salaryPeriod.period,
};
@ -263,7 +291,7 @@ export class SalaryPeriodController extends Controller {
}, 0);
const data = {
total: salaryOrg.total,
fifteenPercent: salaryOrg.fifteenPercent + (salaryOrg.fifteenPoint / 100),
fifteenPercent: salaryOrg.fifteenPercent + salaryOrg.fifteenPoint / 100,
chosen: salaryOrg.quantityUsed,
remaining: salaryOrg.remainQuota,
currentAmount: salaryOrg.currentAmount,
@ -1163,6 +1191,349 @@ export class SalaryPeriodController extends Controller {
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-multi")
async changeTypeMulti(
@Body() body: { profileId: string[]; type: string; isReserve: boolean; remark?: string | null },
@Request() req: RequestWithUser,
) {
await new permission().PermissionCreate(req, "SYS_SALARY_OFFICER");
for await (const profile of body.profileId) {
const salaryProfile = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: profile },
});
if (!salaryProfile) {
throw new HttpError(
HttpStatusCode.NOT_FOUND,
"ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ",
);
}
body.type = body.type.toUpperCase();
//ตรวจสอบงวดเมษาว่าเลื่อนกี่ขั้น
if (body.type == "FULLHAFT") {
if (salaryProfile?.salaryOrg?.salaryPeriod?.period === "OCT") {
const checkPreviousType = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: {
citizenId: salaryProfile?.citizenId,
salaryOrg: {
salaryPeriod: {
period: "APR",
year: salaryProfile?.salaryOrg?.salaryPeriod?.year, //ปีที่ตรงกันด้วย
},
snapshot: "SNAP2",
},
type: "FULL",
},
});
if (checkPreviousType) {
throw new HttpError(
HttpStatusCode.NOT_FOUND,
"ไม่สามารถเลื่อนขั้นบุคลากรเกิน 2 ขั้นต่อปีได้",
);
}
}
}
if (body.type == "FULL") {
salaryProfile.isReserve = body.isReserve;
} else {
salaryProfile.isReserve = false;
}
//Type & Level
const Type = await this.posTypeRepository.findOne({
where: {
posTypeName: salaryProfile.posType,
},
});
if (!Type) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง");
}
const Level = await this.posLevelRepository.findOne({
where: {
posTypeId: Type.id,
posLevelName: salaryProfile.posLevel,
},
});
if (!Level) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
}
//Salary
const salarys = await this.salaryRepository.findOne({
where: {
posTypeId: Level.posTypeId,
posLevelId: Level.id,
isSpecial: salaryProfile.isSpecial == true ? true : false,
isActive: true,
},
});
if (!salarys) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง");
}
salaryProfile.type = body.type;
let _null: any = null;
salaryProfile.remark = body.remark == null ? _null : body.remark;
let type = salaryProfile.type;
//SalaryRank
let salaryRanks: any = null;
if (salaryProfile.amount != null) {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: MoreThanOrEqual(salaryProfile.amount),
isNext: false,
},
order: { salary: "ASC" },
});
if (salaryRanks != null) {
if (salaryProfile.type == "HAFT") {
if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) {
const _salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryHalf,
isNext: true,
},
});
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
}
} else if (salaryProfile.type == "FULL") {
if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) {
if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) {
type = "HAFT";
}
const _salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFull,
isNext: true,
},
});
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
}
} else if (salaryProfile.type == "FULLHAFT") {
if (
salaryRanks.salaryFullHalfSpecial != null &&
salaryRanks.salaryFullHalfSpecial > 0
) {
if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) {
type = "HAFT";
} else if (
salaryRanks.salaryHalfSpecial == null ||
salaryRanks.salaryHalfSpecial == 0
) {
type = "FULL";
}
const _salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryRanks.salaryFullHalf,
isNext: true,
},
});
salaryRanks = _salaryRanks == null ? salaryRanks : _salaryRanks;
}
}
} else {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: salaryProfile.amount,
isNext: true,
},
});
if (salaryRanks == null) {
salaryRanks = await this.salaryRankRepository.findOne({
where: {
salaryId: salarys.id,
salary: MoreThan(salaryProfile.amount),
isNext: true,
},
order: { salary: "ASC" },
});
}
}
}
salaryProfile.isNext = false;
if (type == "NONE") {
salaryProfile.amountSpecial = 0;
salaryProfile.amountUse = 0;
salaryProfile.positionSalaryAmount =
salaryProfile.amount == null ? 0 : salaryProfile.amount;
} else if (type == "PENDING") {
salaryProfile.amountSpecial = 0;
salaryProfile.amountUse = 0;
salaryProfile.positionSalaryAmount = 0;
} else if (type == "HAFT") {
salaryProfile.amountSpecial =
salaryRanks == null || salaryRanks.salaryHalfSpecial == null
? 0
: salaryRanks.salaryHalfSpecial;
salaryProfile.amountUse =
salaryRanks == null ||
salaryProfile == null ||
salaryRanks.salaryHalf == null ||
salaryProfile.amount == null
? 0
: salaryRanks.salaryHalf - salaryProfile.amount;
salaryProfile.positionSalaryAmount =
salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf;
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
} else if (type == "FULL") {
salaryProfile.amountSpecial =
salaryRanks == null || salaryRanks.salaryFullSpecial == null
? 0
: salaryRanks.salaryFullSpecial;
salaryProfile.amountUse =
salaryRanks == null ||
salaryProfile == null ||
salaryRanks.salaryFull == null ||
salaryProfile.amount == null
? 0
: salaryRanks.salaryFull - salaryProfile.amount;
salaryProfile.positionSalaryAmount =
salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull;
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
} else if (type == "FULLHAFT") {
salaryProfile.amountSpecial =
salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null
? 0
: salaryRanks.salaryFullHalfSpecial;
salaryProfile.amountUse =
salaryRanks == null ||
salaryProfile == null ||
salaryRanks.salaryFullHalf == null ||
salaryProfile.amount == null
? 0
: salaryRanks.salaryFullHalf - salaryProfile.amount;
salaryProfile.positionSalaryAmount =
salaryRanks == null || salaryRanks.salaryFullHalf == null
? 0
: salaryRanks.salaryFullHalf;
salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext;
} else {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง");
}
salaryProfile.lastUpdateUserId = req.user.sub;
salaryProfile.lastUpdateFullName = req.user.name;
salaryProfile.lastUpdatedAt = new Date();
const before = structuredClone(salaryProfile);
await this.salaryProfileRepository.save(salaryProfile, { data: req });
setLogDataDiff(req, { before, after: salaryProfile });
const _salaryProfile = await this.salaryProfileRepository.findOne({
relations: ["salaryOrg", "salaryOrg.salaryPeriod"],
where: { id: salaryProfile.id },
});
// หาจำนวน Quota คงเหลือ
if (_salaryProfile != null) {
if (_salaryProfile.salaryOrg.snapshot == "SNAP1") {
if (_salaryProfile.salaryOrg.salaryPeriod.period == "APR") {
if (_salaryProfile != null) {
const salaryOrg = await this.salaryOrgRepository.findOne({
where: {
id: _salaryProfile.salaryOrg.id,
},
relations: { salaryProfiles: true },
});
if (salaryOrg != null) {
const amountFullType = await this.salaryProfileRepository.count({
where: {
salaryOrgId: salaryOrg.id,
type: "FULL",
},
});
salaryOrg.total = salaryOrg.salaryProfiles.length;
salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100);
salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100;
salaryOrg.quantityUsed = amountFullType;
const calRemainQuota = salaryOrg.fifteenPercent - amountFullType;
salaryOrg.remainQuota = calRemainQuota;
salaryOrg.lastUpdateUserId = req.user.sub;
salaryOrg.lastUpdateFullName = req.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: req });
setLogDataDiff(req, { before, after: salaryOrg });
}
}
} else if (_salaryProfile.salaryOrg.salaryPeriod.period == "OCT") {
if (_salaryProfile != null) {
const salaryOrg = await this.salaryOrgRepository.findOne({
where: {
id: _salaryProfile.salaryOrg.id,
},
relations: { salaryProfiles: true },
});
if (salaryOrg != null) {
const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount");
salaryOrg.currentAmount = totalProfile;
salaryOrg.total = salaryOrg.salaryProfiles.length;
salaryOrg.sixPercentAmount = totalProfile * 0.06;
let totalAmount = 0;
const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({
where: {
year: _salaryProfile.salaryOrg.salaryPeriod.year,
period: "APR",
},
});
if (salaryPeriodAPROld != null) {
const salaryOrgSnap2Old: any = await this.salaryOrgRepository.findOne({
where: {
salaryPeriodId: salaryPeriodAPROld.id,
rootId: salaryOrg.rootId,
group: salaryOrg.group,
snapshot: "SNAP2",
},
relations: ["salaryProfiles"],
});
totalAmount =
salaryOrgSnap2Old == null
? 0
: Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse");
}
salaryOrg.spentAmount = totalAmount;
const sumAmountUse = await AppDataSource.getRepository(SalaryProfile)
.createQueryBuilder("salaryProfile")
.select("SUM(salaryProfile.amountUse)", "totalAmount")
.where({
salaryOrgId: salaryOrg.id,
type: In(["HAFT", "FULL", "FULLHAFT"]),
})
.getRawOne();
const calRemainAmount =
salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount;
salaryOrg.useAmount =
sumAmountUse == null || sumAmountUse.totalAmount == null
? 0
: sumAmountUse.totalAmount;
salaryOrg.remainingAmount = calRemainAmount;
salaryOrg.lastUpdateUserId = req.user.sub;
salaryOrg.lastUpdateFullName = req.user.name;
salaryOrg.lastUpdatedAt = new Date();
await this.salaryOrgRepository.save(salaryOrg, { data: req });
setLogDataDiff(req, { before, after: salaryOrg });
}
}
}
}
// return new HttpSuccess();
}
}
return new HttpSuccess();
}
/**
* API
*
@ -1243,13 +1614,17 @@ export class SalaryPeriodController extends Controller {
.orWhere("profile.child1 LIKE :keyword", { keyword: `%${body.keyword}%` })
.orWhere("profile.child2 LIKE :keyword", { keyword: `%${body.keyword}%` })
.orWhere("profile.child3 LIKE :keyword", { keyword: `%${body.keyword}%` })
.orWhere("profile.child4 LIKE :keyword", { keyword: `%${body.keyword}%` })
.orWhere("profile.child4 LIKE :keyword", { keyword: `%${body.keyword}%` });
}),
);
}),
)
.orderBy("profile.citizenId", "ASC")
.addOrderBy("profile.isReserve", "ASC")
.orderBy("profile.rootOrder", "ASC")
.addOrderBy("profile.child1Order", "ASC")
.addOrderBy("profile.child2Order", "ASC")
.addOrderBy("profile.child3Order", "ASC")
.addOrderBy("profile.child4Order", "ASC")
.addOrderBy("profile.posMasterNo", "ASC")
.skip((body.page - 1) * body.pageSize)
.take(body.pageSize)
.getManyAndCount();
@ -3327,4 +3702,31 @@ export class SalaryPeriodController extends Controller {
);
return new HttpSuccess();
}
/**
* API
*
*
*/
@Put("change/isclose/{snapShot}/{salaryPeriodId}")
async ChangeIsClose(
@Request() request: RequestWithUser,
@Path() snapShot: string,
salaryPeriodId: string,
@Body()
body: {
isClose: boolean;
},
) {
await new permission().PermissionUpdate(request, "SYS_SALARY_ROUND");
const salaryPeriod = await this.salaryOrgRepository.find({
where: { salaryPeriodId: salaryPeriodId, snapshot: snapShot },
});
for await (const item of salaryPeriod) {
item.isClose = body.isClose;
await this.salaryOrgRepository.save(item);
}
return new HttpSuccess();
}
}