Fix [Bug] คำนวนระยะเวลาดำรงตำแหน่งในสายงาน, ระยะเวลาดำรงตำแหน่งตามระดับ และทางการบริหารของคนที่พ้นจากราชการ #137

This commit is contained in:
Bright 2025-07-18 13:41:52 +07:00
parent ea74db7005
commit 42cc69cbbe
5 changed files with 131 additions and 22 deletions

View file

@ -5244,6 +5244,8 @@ export class OrganizationDotnetController extends Controller {
*/ */
@Get("profile-leave/keycloak/{keycloakId}") @Get("profile-leave/keycloak/{keycloakId}")
async GetProfileLeaveByKeycloakIdAsync(@Path() keycloakId: string) { async GetProfileLeaveByKeycloakIdAsync(@Path() keycloakId: string) {
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
const profile = await this.profileRepo.findOne({ const profile = await this.profileRepo.findOne({
relations: [ relations: [
"posLevel", "posLevel",
@ -5317,8 +5319,9 @@ export class OrganizationDotnetController extends Controller {
oc = `${_profileCurrent.orgChild4?.orgChild4Name}`; oc = `${_profileCurrent.orgChild4?.orgChild4Name}`;
} }
} }
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?)", [ const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?, ?)", [
profile.id, profile.id,
_currentDate
]); ]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
@ -5429,7 +5432,12 @@ export class OrganizationDotnetController extends Controller {
oc = `${_profileCurrent.orgChild4?.orgChild4Name}`; oc = `${_profileCurrent.orgChild4?.orgChild4Name}`;
} }
} }
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?)", [profile.id]); if (profile && profile?.isLeave) {
_currentDate = profile && profile.leaveDate
? Extension.toDateOnlyString(profile.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [profile.id, _currentDate]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapProfile = { const mapProfile = {

View file

@ -5050,10 +5050,19 @@ export class PositionController extends Controller {
: `CASE WHEN posMaster.orgChild1 is null THEN ${searchShortName0} WHEN posMaster.orgChild2 is null THEN ${searchShortName1} WHEN posMaster.orgChild3 is null THEN ${searchShortName2} WHEN posMaster.orgChild4 is null THEN ${searchShortName3} ELSE ${searchShortName4} END LIKE '%${body.keyword}%'` : `CASE WHEN posMaster.orgChild1 is null THEN ${searchShortName0} WHEN posMaster.orgChild2 is null THEN ${searchShortName1} WHEN posMaster.orgChild3 is null THEN ${searchShortName2} WHEN posMaster.orgChild4 is null THEN ${searchShortName3} ELSE ${searchShortName4} END LIKE '%${body.keyword}%'`
: "1=1", : "1=1",
) )
.andWhere(checkChildConditions) .andWhere(checkChildConditions)
.andWhere(typeCondition) .andWhere(typeCondition)
.andWhere(revisionCondition) .andWhere(revisionCondition)
.andWhere({ current_holderId: IsNull() }); .andWhere({ current_holderId: IsNull() });
}),
)
.orWhere(
new Brackets((qb) => {
qb.andWhere(`posMaster.conditionReason LIKE '%${body.keyword}%' AND posMaster.conditionReason IS NOT NULL`)
.andWhere(checkChildConditions)
.andWhere(typeCondition)
.andWhere(revisionCondition)
.andWhere({ current_holderId: IsNull() });
}), }),
) )
.orderBy("orgRoot.orgRootOrder", "ASC") .orderBy("orgRoot.orgRootOrder", "ASC")

View file

@ -32,6 +32,8 @@ import { Command } from "../entities/Command";
import { OrgRoot } from "../entities/OrgRoot"; import { OrgRoot } from "../entities/OrgRoot";
import { OrgRevision } from "../entities/OrgRevision"; import { OrgRevision } from "../entities/OrgRevision";
import { Position } from "../entities/Position"; import { Position } from "../entities/Position";
import Extension from "../interfaces/extension";
@Route("api/v1/org/profile/salary") @Route("api/v1/org/profile/salary")
@Tags("ProfileSalary") @Tags("ProfileSalary")
@Security("bearerAuth") @Security("bearerAuth")
@ -55,8 +57,15 @@ export class ProfileSalaryController extends Controller {
let data: any = []; let data: any = [];
await this.positionOfficerRepo.clear(); await this.positionOfficerRepo.clear();
const profile = await this.profileRepo.find(); const profile = await this.profileRepo.find();
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
for await (const x of profile) { for await (const x of profile) {
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?)", [x.id]); if (x.isLeave) {
_currentDate = x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [x.id, _currentDate]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
_position.length > 1 _position.length > 1
@ -94,10 +103,18 @@ export class ProfileSalaryController extends Controller {
public async cronjobTenurePositionEmployee() { public async cronjobTenurePositionEmployee() {
let data: any = []; let data: any = [];
await this.positionEmployeeRepo.clear(); await this.positionEmployeeRepo.clear();
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
const profile = await this.profileEmployeeRepo.find(); const profile = await this.profileEmployeeRepo.find();
for await (const x of profile) { for await (const x of profile) {
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?)", [ if (x?.isLeave) {
_currentDate = x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?, ?)", [
x.id, x.id,
_currentDate
]); ]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
@ -137,8 +154,15 @@ export class ProfileSalaryController extends Controller {
let data: any = []; let data: any = [];
await this.levelOfficerRepo.clear(); await this.levelOfficerRepo.clear();
const profile = await this.profileRepo.find({ relations: ["posLevel", "posType"] }); const profile = await this.profileRepo.find({ relations: ["posLevel", "posType"] });
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
for await (const x of profile) { for await (const x of profile) {
const positionLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?)", [x.id]); if (x?.isLeave) {
_currentDate = x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: _currentDate
}
const positionLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [x.id, _currentDate]);
const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : []; const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : [];
const mapPositionLevel = const mapPositionLevel =
_positionLevel.length > 1 _positionLevel.length > 1
@ -187,9 +211,17 @@ export class ProfileSalaryController extends Controller {
let data: any = []; let data: any = [];
await this.levelEmployeeRepo.clear(); await this.levelEmployeeRepo.clear();
const profile = await this.profileEmployeeRepo.find({ relations: ["posLevel", "posType"] }); const profile = await this.profileEmployeeRepo.find({ relations: ["posLevel", "posType"] });
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
for await (const x of profile) { for await (const x of profile) {
const positionLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [ if (x?.isLeave) {
_currentDate = x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: _currentDate
}
const positionLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?, ?)", [
x.id, x.id,
_currentDate
]); ]);
const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : []; const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : [];
const mapPositionLevel = const mapPositionLevel =
@ -246,7 +278,14 @@ export class ProfileSalaryController extends Controller {
orgRevisionIsCurrent: true, orgRevisionIsCurrent: true,
}, },
}); });
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
for await (const x of profile) { for await (const x of profile) {
if (x?.isLeave) {
_currentDate = x.leaveDate
? Extension.toDateOnlyString(x.leaveDate)
: _currentDate
}
const position = await this.positionRepo.findOne({ const position = await this.positionRepo.findOne({
where: { where: {
positionIsSelected: true, positionIsSelected: true,
@ -260,7 +299,7 @@ export class ProfileSalaryController extends Controller {
posExecutive: true, posExecutive: true,
}, },
}); });
const positionExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?)", [x.id]); const positionExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [x.id, _currentDate]);
const _position = positionExecutive.length > 0 ? positionExecutive[0] : []; const _position = positionExecutive.length > 0 ? positionExecutive[0] : [];
const mapPosition = const mapPosition =
_position.length > 1 _position.length > 1
@ -475,7 +514,14 @@ export class ProfileSalaryController extends Controller {
if (!profile) { if (!profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?)", [profile.id]); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
if (profile && profile?.isLeave) {
_currentDate = profile && profile.leaveDate
? Extension.toDateOnlyString(profile.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [profile.id, _currentDate]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
@ -506,8 +552,7 @@ export class ProfileSalaryController extends Controller {
}, },
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [profile.id, _currentDate]);
const posLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?)", [profile.id]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =
_posLevel.length > 1 _posLevel.length > 1
@ -544,8 +589,9 @@ export class ProfileSalaryController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?)", [ const posExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [
profile.id, profile.id,
_currentDate
]); ]);
const _posExecutive = posExecutive.length > 0 ? posExecutive[0] : []; const _posExecutive = posExecutive.length > 0 ? posExecutive[0] : [];
const mapPosExecutive = const mapPosExecutive =
@ -589,7 +635,20 @@ export class ProfileSalaryController extends Controller {
// const sql_mode = await AppDataSource.query( // const sql_mode = await AppDataSource.query(
// "SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));", // "SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));",
// ); // );
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?)", [profileId]); const _profile = await this.profileRepo.findOne({
where: { id: profileId }
})
if (!_profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
}
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
if (_profile && _profile?.isLeave) {
_currentDate = _profile && _profile.leaveDate
? Extension.toDateOnlyString(_profile.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [profileId, _currentDate]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
@ -624,7 +683,7 @@ export class ProfileSalaryController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?)", [profileId]); const posLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [profileId, _currentDate]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =
_posLevel.length > 1 _posLevel.length > 1
@ -664,8 +723,9 @@ export class ProfileSalaryController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?)", [ const posExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [
profileId, profileId,
_currentDate
]); ]);
const _posExecutive = posExecutive.length > 0 ? posExecutive[0] : []; const _posExecutive = posExecutive.length > 0 ? posExecutive[0] : [];
const mapPosExecutive = const mapPosExecutive =

View file

@ -29,6 +29,8 @@ import permission from "../interfaces/permission";
import { setLogDataDiff } from "../interfaces/utils"; import { setLogDataDiff } from "../interfaces/utils";
import { Command } from "../entities/Command"; import { Command } from "../entities/Command";
import { OrgRoot } from "../entities/OrgRoot"; import { OrgRoot } from "../entities/OrgRoot";
import Extension from "../interfaces/extension";
@Route("api/v1/org/profile-employee/salary") @Route("api/v1/org/profile-employee/salary")
@Tags("ProfileSalary") @Tags("ProfileSalary")
@Security("bearerAuth") @Security("bearerAuth")
@ -141,8 +143,16 @@ export class ProfileSalaryEmployeeController extends Controller {
if (!profile) { if (!profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
} }
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?)", [ const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
if (profile && profile?.isLeave) {
_currentDate = profile && profile.leaveDate
? Extension.toDateOnlyString(profile.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?, ?)", [
profile.id, profile.id,
_currentDate
]); ]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
@ -173,8 +183,9 @@ export class ProfileSalaryEmployeeController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [ const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?, ?)", [
profile.id, profile.id,
_currentDate
]); ]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =
@ -216,8 +227,22 @@ export class ProfileSalaryEmployeeController extends Controller {
@Get("tenure/{profileId}") @Get("tenure/{profileId}")
public async getPositionTenure(@Path() profileId: string, @Request() req: RequestWithUser) { public async getPositionTenure(@Path() profileId: string, @Request() req: RequestWithUser) {
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?)", [ const _profile = await this.profileRepo.findOne({
where: { id: profileId }
})
if (!_profile) {
throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว");
}
const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today");
let _currentDate = CURRENT_DATE[0].today;
if (_profile && _profile?.isLeave) {
_currentDate = _profile && _profile.leaveDate
? Extension.toDateOnlyString(_profile.leaveDate)
: _currentDate
}
const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?, ?)", [
profileId, profileId,
_currentDate
]); ]);
const _position = position.length > 0 ? position[0] : []; const _position = position.length > 0 ? position[0] : [];
const mapPosition = const mapPosition =
@ -248,8 +273,9 @@ export class ProfileSalaryEmployeeController extends Controller {
[] as { name: string; days: number; year: number; month: number; day: number }[], [] as { name: string; days: number; year: number; month: number; day: number }[],
); );
const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?)", [ const posLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?, ?)", [
profileId, profileId,
_currentDate
]); ]);
const _posLevel = posLevel.length > 0 ? posLevel[0] : []; const _posLevel = posLevel.length > 0 ? posLevel[0] : [];
const mapPosLevel = const mapPosLevel =

View file

@ -381,6 +381,12 @@ class Extension {
if (val >= 90 && val <= 100) return "ดีเด่น"; if (val >= 90 && val <= 100) return "ดีเด่น";
else return "-"; else return "-";
} }
public static toDateOnlyString(date: Date): string {
return date.getFullYear() + "-" +
String(date.getMonth() + 1).padStart(2, "0") + "-" +
String(date.getDate()).padStart(2, "0");
}
} }
export default Extension; export default Extension;