Merge branch 'develop' into adiDev

This commit is contained in:
AdisakKanthawilang 2025-03-04 18:07:23 +07:00
commit 4647120172
6 changed files with 359 additions and 112 deletions

View file

@ -52,7 +52,7 @@ import { EducationLevel } from "../entities/EducationLevel";
import { HR_FUND_COURSE_CODE } from "../entities/HR_FUND_COURSE_CODE";
import { HR_MAJOR_CODE } from "../entities/HR_MAJOR_CODE";
// import { uuidv7 } from "uuidv7";
// import { ProfileSalaries } from "../entities/ProfileSalaries";
import { ProfileSalaries } from "../entities/ProfileSalaries";
@Route("api/v1/org/upload")
@Tags("UPLOAD")
@Security("bearerAuth")
@ -67,7 +67,7 @@ export class ImportDataController extends Controller {
private posLevelRepo = AppDataSource.getRepository(PosLevel);
private posTypeRepo = AppDataSource.getRepository(PosType);
private positionOfficerRepo = AppDataSource.getRepository(positionOfficer);
// private ProfileSalariesRepo = AppDataSource.getRepository(ProfileSalaries);
private ProfileSalariesRepo = AppDataSource.getRepository(ProfileSalaries);
private HR_PERSONAL_OFFICER_FAMILYRepo = AppDataSource.getRepository(HR_PERSONAL_OFFICER_FAMILY);
private HR_EDUCATIONRepo = AppDataSource.getRepository(HR_EDUCATION);
private HR_PERSONAL_OFFICER_ADDRESSRepo = AppDataSource.getRepository(
@ -2347,109 +2347,113 @@ export class ImportDataController extends Controller {
return new HttpSuccess();
}
// /**
// * @summary เงินเดือน ข้าราชการ
// */
// @Post("uploadProfileSalary-OfficerEntry")
// async UploadFileSQLSalaryEntry(@Request() request: { user: Record<string, any> }) {
// let rowCount = 0;
// let null_: any = null;
// let sqlStatements: string[] = [];
/**
* @summary
*/
@Post("uploadProfileSalary-OfficerEntry")
async UploadFileSQLSalaryEntry(@Request() request: { user: Record<string, any> }) {
let rowCount = 0;
let null_: any = null;
let sqlStatements: string[] = [];
// const [profiles, total] = await AppDataSource.getRepository(Profile)
// .createQueryBuilder("profile")
// .select(["profile.citizenId", "profile.id"])
// .orderBy("profile.citizenId", "ASC")
// // .where("profile.citizenId = '3101702379675'")
// .skip(10000)
// .take(20000)
// .getManyAndCount();
// var _profiles: ProfileSalary[] = [];
// const filePath = path.join(__dirname, "salaryProfile1.csv");
// // CSV Header
// let csvData = `"id","createdAt","createdUserId","lastUpdatedAt","lastUpdateUserId","createdFullName","lastUpdateFullName","profileId","profileEmployeeId","order","commandNo","commandYear","commandDateSign","commandDateAffect","commandCode","commandName","posNoAbb","posNo","positionName","positionType","positionLevel","positionCee","orgRoot","orgChild1","orgChild2","orgChild3","orgChild4","positionExecutive","amount","amountSpecial","positionSalaryAmount","mouthSalaryAmount","remark","dateGovernment","isGovernment","commandId","refId"\n`;
const [profiles, total] = await AppDataSource.getRepository(Profile)
.createQueryBuilder("profile")
.select(["profile.citizenId", "profile.id"])
.orderBy("profile.citizenId", "ASC")
.where("profile.citizenId = '3101501190150'")
// .skip(0)
// .take(1000)
.getManyAndCount();
const filePath = path.join(__dirname, "salaryProfile1.csv");
// CSV Header
let csvData = `"id","createdAt","createdUserId","lastUpdatedAt","lastUpdateUserId","createdFullName","lastUpdateFullName","profileId","profileEmployeeId","order","commandNo","commandYear","commandDateSign","commandDateAffect","commandCode","commandName","posNoAbb","posNo","positionName","positionType","positionLevel","positionCee","orgRoot","orgChild1","orgChild2","orgChild3","orgChild4","positionExecutive","amount","amountSpecial","positionSalaryAmount","mouthSalaryAmount","remark","dateGovernment","isGovernment","commandId","refId","isEntry"\n`;
// fs.appendFile(filePath, csvData, (err) => {
// if (err) {
// console.error("Error writing CSV file:", err);
// } else {
// console.log("Salary profiles successfully written to salaryProfile.csv");
// }
// });
// await Promise.all(
// profiles.map(async (_item) => {
// const existingProfile = await this.ProfileSalariesRepo.find({
// where: { ProfileId: _item.citizenId },
// order: {
// Order: "ASC",
// },
// });
// let order = 1;
// await Promise.all(
// existingProfile.map(async (item) => {
// rowCount++;
// const profileSalary: any = new ProfileSalary();
// profileSalary.profileId = _item.id;
// profileSalary.order = item.Order;
fs.appendFile(filePath, csvData, (err) => {
if (err) {
console.error("Error writing CSV file:", err);
} else {
console.log("Salary profiles successfully written to salaryProfile.csv");
}
});
// await Promise.all(
// profiles.map(async (_item) => {
console.log("XXXXXXXXXXXXXXX");
for await (const _item of profiles) {
console.log("zzzzzzzzzzzzz");
const existingProfile = await this.ProfileSalariesRepo.find({
where: { posNo: _item.citizenId },
order: {
Order: "ASC",
},
});
let order = 1;
// await Promise.all(
// existingProfile.map(async (item) => {
for await (const item of existingProfile) {
console.log("zzzzzzz4zzzzzz");
rowCount++;
const profileSalary: any = new ProfileSalary();
profileSalary.profileId = _item.id;
profileSalary.order = item.Order;
// profileSalary.commandDateAffect =
// item.Date == null
// ? null_
// : new Date(item.Date.setDate(item.Date.getDate() + 1))
// .toISOString()
// .replace("T", " ")
// .substring(0, 19);
// profileSalary.remark = item.SalaryRef + item.PositionName;
// profileSalary.amount = item.Amount;
// profileSalary.positionSalaryAmount = item.PositionSalaryAmount;
// const str = item.PosNoName;
// const parts = str.split(" ");
// if (parts.length > 1) {
// const posNo = parts.at(-1);
// const posNoAbb = parts.slice(0, -1).join(" ");
// profileSalary.posNoAbb = posNoAbb;
// profileSalary.posNo = posNo;
// }
// profileSalary.posLevel = this.canConvertToInt(item.PositionLevelName)
// ? null_
// : item.PositionLevelName;
// profileSalary.posCee = this.canConvertToInt(item.PositionLevelName)
// ? item.PositionLevelName
// : null_;
// //xxxxxxxxxxxxxxxxx
// profileSalary.posType = item.PositionTypeName;
// profileSalary.isEntry = true;
profileSalary.commandDateAffect =
item.Date == null
? null_
: new Date(item.Date.setDate(item.Date.getDate() + 1))
.toISOString()
.replace("T", " ")
.substring(0, 19);
profileSalary.remark = item.SalaryRef + item.PositionName;
profileSalary.amount = item.Amount;
profileSalary.positionSalaryAmount = item.PositionSalaryAmount;
// const str = item.PosNoName;
// const parts = str.split(" ");
// if (parts.length > 1) {
// const posNo = parts.at(-1);
// const posNoAbb = parts.slice(0, -1).join(" ");
// profileSalary.posNoAbb = posNoAbb;
// profileSalary.posNo = posNo;
// }
profileSalary.posNo = item.PosNoName;
profileSalary.positionLevel = item.PositionLevelName;
profileSalary.positionCee = this.canConvertToInt(item.PositionLevelName)
? item.PositionLevelName
: null_;
//xxxxxxxxxxxxxxxxx
profileSalary.positionType = item.PositionTypeName;
profileSalary.isEntry = true;
// profileSalary.createdUserId = request.user.sub;
// profileSalary.createdFullName = request.user.name;
// profileSalary.lastUpdateUserId = request.user.sub;
// profileSalary.lastUpdateFullName = request.user.name;
// profileSalary.createdAt = new Date().toISOString().split("T")[0];
// profileSalary.lastUpdatedAt = new Date().toISOString().split("T")[0];
// // const result = uuidv7();
// // profileSalary.id = result;
profileSalary.createdUserId = request.user.sub;
profileSalary.createdFullName = request.user.name;
profileSalary.lastUpdateUserId = request.user.sub;
profileSalary.lastUpdateFullName = request.user.name;
profileSalary.createdAt = new Date().toISOString().split("T")[0];
profileSalary.lastUpdatedAt = new Date().toISOString().split("T")[0];
// const result = uuidv7();
// profileSalary.id = result;
// console.log(profileSalary.commandDateSign);
// csvData = `"${profileSalary.id || "NULL"}","${profileSalary.createdAt || "NULL"}","${profileSalary.createdUserId || "NULL"}","${profileSalary.lastUpdatedAt || "NULL"}","${profileSalary.lastUpdateUserId || "NULL"}","${profileSalary.createdFullName || "NULL"}","${profileSalary.lastUpdateFullName || "NULL"}","${profileSalary.profileId || "NULL"}","${profileSalary.profileEmployeeId || "NULL"}","${profileSalary.order || "NULL"}","${profileSalary.commandNo || "NULL"}","${profileSalary.commandYear || "NULL"}","${profileSalary.commandDateSign || "NULL"}","${profileSalary.commandDateAffect || "NULL"}","${profileSalary.commandCode || "NULL"}","${profileSalary.commandName || "NULL"}","${profileSalary.posNoAbb || "NULL"}","${profileSalary.posNo || "NULL"}","${profileSalary.positionName || "NULL"}","${profileSalary.positionType || "NULL"}","${profileSalary.positionLevel || "NULL"}","${profileSalary.positionCee || "NULL"}","${profileSalary.orgRoot || "NULL"}","${profileSalary.orgChild1 || "NULL"}","${profileSalary.orgChild2 || "NULL"}","${profileSalary.orgChild3 || "NULL"}","${profileSalary.orgChild4 || "NULL"}","${profileSalary.positionExecutive || "NULL"}","${profileSalary.amount || 0}","${profileSalary.amountSpecial || 0}","${profileSalary.positionSalaryAmount || 0}","${profileSalary.mouthSalaryAmount || 0}","${profileSalary.remark || "NULL"}","${profileSalary.dateGovernment || "NULL"}","${profileSalary.isGovernment || "NULL"}","${profileSalary.commandId || "NULL"}","${profileSalary.refId || "NULL"}"\n`;
await this.salaryRepo.save(profileSalary);
// console.log(profileSalary.commandDateSign);
// csvData = `"${profileSalary.id || "NULL"}","${profileSalary.createdAt || "NULL"}","${profileSalary.createdUserId || "NULL"}","${profileSalary.lastUpdatedAt || "NULL"}","${profileSalary.lastUpdateUserId || "NULL"}","${profileSalary.createdFullName || "NULL"}","${profileSalary.lastUpdateFullName || "NULL"}","${profileSalary.profileId || "NULL"}","${profileSalary.profileEmployeeId || "NULL"}","${profileSalary.order || "NULL"}","${profileSalary.commandNo || "NULL"}","${profileSalary.commandYear || "NULL"}","${profileSalary.commandDateSign || "NULL"}","${profileSalary.commandDateAffect || "NULL"}","${profileSalary.commandCode || "NULL"}","${profileSalary.commandName || "NULL"}","${profileSalary.posNoAbb || "NULL"}","${profileSalary.posNo || "NULL"}","${profileSalary.positionName || "NULL"}","${profileSalary.positionType || "NULL"}","${profileSalary.positionLevel || "NULL"}","${profileSalary.positionCee || "NULL"}","${profileSalary.orgRoot || "NULL"}","${profileSalary.orgChild1 || "NULL"}","${profileSalary.orgChild2 || "NULL"}","${profileSalary.orgChild3 || "NULL"}","${profileSalary.orgChild4 || "NULL"}","${profileSalary.positionExecutive || "NULL"}","${profileSalary.amount || 0}","${profileSalary.amountSpecial || 0}","${profileSalary.positionSalaryAmount || 0}","${profileSalary.mouthSalaryAmount || 0}","${profileSalary.remark || "NULL"}","${profileSalary.dateGovernment || "NULL"}","${profileSalary.isGovernment || "NULL"}","${profileSalary.commandId || "NULL"}","${profileSalary.refId || "NULL"}","${profileSalary.isEntry || "NULL"}"\n`;
// fs.appendFile(filePath, csvData.replace('"NULL"', "NULL"), (err) => {
// if (err) {
// console.error("Error writing CSV file:", err);
// } else {
// console.log(
// "Salary profiles successfully written to salaryProfile.csv: " + rowCount,
// );
// }
// });
// }),
// );
// order = 1;
// }),
// );
// return new HttpSuccess();
// }
// canConvertToInt(str: string) {
// const num = Number(str);
// return Number.isInteger(num);
// }
// fs.appendFile(filePath, csvData.replace('"NULL"', "NULL"), (err) => {
// if (err) {
// console.error("Error writing CSV file:", err);
// } else {
console.log("Salary profiles successfully written to salaryProfile.csv: " + rowCount);
// }
// });
}
order = 1;
}
return new HttpSuccess();
}
canConvertToInt(str: string) {
try {
const num = Number(str);
return Number.isInteger(num);
} catch (error) {
return null;
}
}
}

View file

@ -19,7 +19,7 @@ import HttpError from "../interfaces/http-error";
import { ProfileSalaryHistory } from "../entities/ProfileSalaryHistory";
import { RequestWithUser } from "../middlewares/user";
import { Profile } from "../entities/Profile";
import { LessThan, MoreThan } from "typeorm";
import { In, LessThan, MoreThan } from "typeorm";
import permission from "../interfaces/permission";
import { setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/org/profile/salary")
@ -62,7 +62,7 @@ export class ProfileSalaryController extends Controller {
if (_workflow == false)
await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId);
const record = await this.salaryRepo.find({
where: { profileId: profileId },
where: { profileId: profileId, commandCode: In(["5", "6", "7"]) },
order: { order: "ASC" },
});
return new HttpSuccess(record);
@ -74,7 +74,25 @@ export class ProfileSalaryController extends Controller {
if (_workflow == false)
await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId);
const record = await this.salaryRepo.find({
where: { profileId: profileId },
where: {
profileId: profileId,
commandCode: In([
"0",
"9",
"1",
"2",
"3",
"4",
"8",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
]),
},
order: { order: "ASC" },
});
return new HttpSuccess(record);

View file

@ -259,7 +259,7 @@ export class ReportController extends Controller {
if (tenureType != "" && tenureType == "position") {
tenureTypeCondition = "registryOfficer.Years BETWEEN :tenureMin AND :tenureMax";
} else if (tenureType != "" && tenureType == "level") {
tenureTypeCondition = "registryOfficer.Years BETWEEN :tenureMin AND :tenureMax"; //xxxxxxxxxxxx
tenureTypeCondition = "registryOfficer.levelYears BETWEEN :tenureMin AND :tenureMax"; //xxxxxxxxxxxx
}
const [lists, total] = await AppDataSource.getRepository(viewRegistryOfficer)
@ -385,12 +385,9 @@ export class ReportController extends Controller {
Days: x.posExecutiveDays,
},
posLevelDate: {
// Years: x.levelYears,
// Months: x.levelMonths,
// Days: x.levelDays,
Years: 0,
Months: 0,
Days: 0,
Years: x.levelYears,
Months: x.levelMonths,
Days: x.levelDays,
},
}));
return new HttpSuccess({

View file

@ -15,6 +15,12 @@ export class ProfileSalaries extends EntityBase {
})
Date: Date;
@Column({
nullable: true,
default: null,
})
posNo: string;
@Column({
nullable: true,
default: null,

View file

@ -0,0 +1,199 @@
import { ViewColumn, ViewEntity } from "typeorm";
@ViewEntity({
expression: `
WITH resultData AS (
SELECT
commandDateAffect,
positionName,
positionCee,
TIMESTAMPDIFF(
DAY,
LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) AS days_diff,
TIMESTAMPDIFF(
DAY,
LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) / 365.2524 AS 'Years',
TIMESTAMPDIFF(
DAY,
LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) / 30.4375 % 12 AS 'Months',
TIMESTAMPDIFF(
DAY,
LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) % 30.4375 AS 'Days',
posNo,
positionExecutive,
positionType,
positionLevel,
orgRoot,
orgChild1,
orgChild2,
orgChild3,
orgChild4,
commandCode,
commandName,
commandNo,
commandYear,
remark,
profileId,
ROW_NUMBER() OVER (PARTITION BY profileId ORDER BY commandDateAffect ASC) AS orderNumber
FROM (
SELECT
commandDateAffect,
commandDateSign,
positionName,
positionCee,
posNo,
positionExecutive,
positionType,
positionLevel,
orgRoot,
orgChild1,
orgChild2,
orgChild3,
orgChild4,
commandCode,
commandName,
commandNo,
commandYear,
remark,
profileId/*,
LAG(commandDateSign) OVER (ORDER BY commandDateAffect ASC, commandDateSign ASC) AS prevCommandDateSign,
@group := IF(@prevPosition = positionName, @group, @group + 1) AS groupedId,
@prevPosition := positionName*/
FROM
profileSalary/*,
(SELECT @group := 0, @prevPosition := NULL) AS vars*/
WHERE
commandCode IN (1, 2, 3, 4, 8, 10, 11, 12, 15, 16)
ORDER BY
commandDateAffect ASC, commandDateSign ASC
) AS groupedPosition
/*WHERE
prevCommandDateSign IS NULL OR commandDateSign >= prevCommandDateSign*/
GROUP BY
profileId, /*groupedId,*/ positionName, positionCee, positionType, positionLevel
)
SELECT
commandDateAffect,
positionName,
positionCee,
days_diff,
Years,
Months,
Days,
posNo,
positionExecutive,
positionType,
positionLevel,
orgRoot,
orgChild1,
orgChild2,
orgChild3,
orgChild4,
commandCode,
commandName,
commandNo,
commandYear,
remark,
profileId,
orderNumber
FROM resultData
UNION ALL
SELECT
CURDATE() AS commandDateAffect,
NULL AS positionName,
NULL AS positionCee,
TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) AS days_diff,
TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) / 365.2524 AS 'Years',
TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) / 30.4375 % 12 AS 'Months',
TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) % 30.4375 AS 'Days',
NULL AS posNo,
NULL AS positionExecutive,
NULL AS positionType,
NULL AS positionLevel,
NULL AS orgRoot,
NULL AS orgChild1,
NULL AS orgChild2,
NULL AS orgChild3,
NULL AS orgChild4,
NULL AS commandCode,
NULL AS commandName,
NULL AS commandNo,
NULL AS commandYear,
NULL AS remark,
profileId,
NULL AS orderNumber
FROM resultData
`,
})
export class viewCurrentTenureLevelOfficer {
@ViewColumn()
commandDateAffect: Date;
@ViewColumn()
days_diff: number;
@ViewColumn()
Years: number;
@ViewColumn()
Months: number;
@ViewColumn()
Days: number;
@ViewColumn()
positionName: string;
@ViewColumn()
positionCee: string;
@ViewColumn()
posNo: string;
@ViewColumn()
positionExecutive: string;
@ViewColumn()
positionType: string;
@ViewColumn()
positionLevel: string;
@ViewColumn()
orgRoot: string;
@ViewColumn()
orgChild1: string;
@ViewColumn()
orgChild2: string;
@ViewColumn()
orgChild3: string;
@ViewColumn()
orgChild4: string;
@ViewColumn()
commandCode: number;
@ViewColumn()
commandName: string;
@ViewColumn()
commandNo: string;
@ViewColumn()
commandYear: number;
@ViewColumn()
remark: string;
@ViewColumn()
profileId: string;
@ViewColumn()
orderNumber: number;
}

View file

@ -75,6 +75,16 @@ import { ViewColumn, ViewEntity } from "typeorm";
ROW_NUMBER() OVER (PARTITION BY vctoExc.profileId) AS vctoExc_number
FROM view_current_tenure_exc_officer vctoExc
WHERE vctoExc.orderNumber Is Null
),
PositionLevelDate AS (
SELECT
vctlo.Years,
vctlo.Months,
vctlo.Days,
vctlo.profileId,
ROW_NUMBER() OVER (PARTITION BY vctlo.profileId) AS vctlo_number
FROM view_current_tenure_level_officer vctlo
WHERE vctlo.orderNumber Is Null
)
SELECT
p.id as profileId,
@ -123,7 +133,10 @@ import { ViewColumn, ViewEntity } from "typeorm";
vcto.Days,
vctoExc.Years AS posExecutiveYears,
vctoExc.Months AS posExecutiveMonths,
vctoExc.Days AS posExecutiveDays
vctoExc.Days AS posExecutiveDays,
vctlo.Years AS levelYears,
vctlo.Months AS levelMonths,
vctlo.Days AS levelDays
FROM profile p
LEFT JOIN posLevel ON p.posLevelId = posLevel.id
LEFT JOIN posType ON p.posTypeId = posType.id
@ -131,6 +144,7 @@ import { ViewColumn, ViewEntity } from "typeorm";
LEFT JOIN Education ed ON p.id = ed.profileId AND ed.ed_number = 1
LEFT JOIN PositionDate vcto ON p.id = vcto.profileId AND vcto.vcto_number = 1
LEFT JOIN PositionExcDate vctoExc ON p.id = vctoExc.profileId AND vctoExc.vctoExc_number = 1
LEFT JOIN PositionLevelDate vctlo ON p.id = vctlo.profileId AND vctlo.vctlo_number = 1
`,
})
export class viewRegistryOfficer {
@ -253,4 +267,13 @@ export class viewRegistryOfficer {
@ViewColumn()
posExecutiveDays: number;
@ViewColumn()
levelYears: number;
@ViewColumn()
levelMonths: number;
@ViewColumn()
levelDays: number;
}