Merge branch 'develop' into working
This commit is contained in:
commit
f770b9214a
43 changed files with 3757 additions and 157 deletions
109
package-lock.json
generated
109
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
|||
"@elastic/elasticsearch": "^8.14.0",
|
||||
"@nestjs/platform-express": "^10.3.9",
|
||||
"@tsoa/runtime": "^6.0.0",
|
||||
"amqplib": "^0.10.4",
|
||||
"axios": "^1.7.2",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.0.0",
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
"xlsx": "^0.20.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/amqplib": "^0.10.5",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.11.5",
|
||||
|
|
@ -43,6 +45,45 @@
|
|||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@acuminous/bitsyntax": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz",
|
||||
"integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==",
|
||||
"dependencies": {
|
||||
"buffer-more-ints": "~1.0.0",
|
||||
"debug": "^4.3.4",
|
||||
"safe-buffer": "~5.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@acuminous/bitsyntax/node_modules/debug": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@acuminous/bitsyntax/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/@acuminous/bitsyntax/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
|
|
@ -392,6 +433,15 @@
|
|||
"yarn": ">=1.9.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/amqplib": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.10.5.tgz",
|
||||
"integrity": "sha512-/cSykxROY7BWwDoi4Y4/jLAuZTshZxd8Ey1QYa/VaXriMotBDoou7V/twJiOSHzU6t1Kp1AHAUXGCgqq+6DNeg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
|
|
@ -568,6 +618,41 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/amqplib": {
|
||||
"version": "0.10.4",
|
||||
"resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.4.tgz",
|
||||
"integrity": "sha512-DMZ4eCEjAVdX1II2TfIUpJhfKAuoCeDIo/YyETbfAqehHTXxxs7WOOd+N1Xxr4cKhx12y23zk8/os98FxlZHrw==",
|
||||
"dependencies": {
|
||||
"@acuminous/bitsyntax": "^0.1.2",
|
||||
"buffer-more-ints": "~1.0.0",
|
||||
"readable-stream": "1.x >=1.1.9",
|
||||
"url-parse": "~1.5.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/amqplib/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
||||
},
|
||||
"node_modules/amqplib/node_modules/readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/amqplib/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
||||
},
|
||||
"node_modules/ansi-escapes": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
|
||||
|
|
@ -860,6 +945,11 @@
|
|||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"node_modules/buffer-more-ints": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
|
||||
"integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg=="
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||
|
|
@ -3508,6 +3598,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
|
|
@ -3653,6 +3748,11 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
|
||||
|
|
@ -4967,6 +5067,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/amqplib": "^0.10.5",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.11.5",
|
||||
|
|
@ -30,6 +31,7 @@
|
|||
"@elastic/elasticsearch": "^8.14.0",
|
||||
"@nestjs/platform-express": "^10.3.9",
|
||||
"@tsoa/runtime": "^6.0.0",
|
||||
"amqplib": "^0.10.4",
|
||||
"axios": "^1.7.2",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.0.0",
|
||||
|
|
|
|||
26
src/app.ts
26
src/app.ts
|
|
@ -5,11 +5,14 @@ import express from "express";
|
|||
import swaggerUi from "swagger-ui-express";
|
||||
import swaggerDocument from "./swagger.json";
|
||||
import * as cron from "node-cron";
|
||||
import { init as rabbitmqInit } from "./services/rabbitmq";
|
||||
import error from "./middlewares/error";
|
||||
import { AppDataSource } from "./database/data-source";
|
||||
import { RegisterRoutes } from "./routes";
|
||||
import { OrganizationController } from "./controllers/OrganizationController";
|
||||
import logMiddleware from "./middlewares/logs";
|
||||
import { run } from "node:test";
|
||||
import { CommandController } from "./controllers/CommandController";
|
||||
|
||||
async function main() {
|
||||
await AppDataSource.initialize();
|
||||
|
|
@ -23,7 +26,7 @@ async function main() {
|
|||
);
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(logMiddleware);
|
||||
// app.use(logMiddleware);
|
||||
app.use("/", express.static("static"));
|
||||
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));
|
||||
|
||||
|
|
@ -43,6 +46,17 @@ async function main() {
|
|||
}
|
||||
});
|
||||
|
||||
const cronTime_command = "0 2 * * * *";
|
||||
// const cronTime_command = "*/10 * * * * *";
|
||||
cron.schedule(cronTime_command, async () => {
|
||||
try {
|
||||
const commandController = new CommandController();
|
||||
await commandController.cronjobCommand();
|
||||
} catch (error) {
|
||||
console.error("Error executing function from controller:", error);
|
||||
}
|
||||
});
|
||||
|
||||
// app.listen(APP_PORT, APP_HOST, () => console.log(`Listening on: http://localhost:${APP_PORT}`));
|
||||
app.listen(
|
||||
APP_PORT,
|
||||
|
|
@ -52,6 +66,16 @@ async function main() {
|
|||
console.log(`[APP] Swagger on: http://localhost:${APP_PORT}/api-docs`)
|
||||
),
|
||||
);
|
||||
async function runMessageQueue() {
|
||||
try {
|
||||
await rabbitmqInit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
setTimeout(runMessageQueue, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
runMessageQueue();
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ import HttpSuccess from "../interfaces/http-success";
|
|||
import HttpStatusCode from "../interfaces/http-status";
|
||||
import HttpError from "../interfaces/http-error";
|
||||
import { Command } from "../entities/Command";
|
||||
import { Brackets, LessThan, MoreThan, Double, In } from "typeorm";
|
||||
import { Brackets, LessThan, MoreThan, Double, In, Not, Between } from "typeorm";
|
||||
import { CommandType } from "../entities/CommandType";
|
||||
import { CommandSend } from "../entities/CommandSend";
|
||||
import { Profile } from "../entities/Profile";
|
||||
import { Profile, CreateProfileAllFields } from "../entities/Profile";
|
||||
import { RequestWithUser } from "../middlewares/user";
|
||||
import { OrgRevision } from "../entities/OrgRevision";
|
||||
import { CommandSendCC } from "../entities/CommandSendCC";
|
||||
|
|
@ -32,9 +32,14 @@ import HttpStatus from "../interfaces/http-status";
|
|||
import Extension from "../interfaces/extension";
|
||||
import { ProfileEmployee } from "../entities/ProfileEmployee";
|
||||
import CallAPI from "../interfaces/call-api";
|
||||
import { ProfileSalary } from "../entities/ProfileSalary";
|
||||
import { ProfileSalary, CreateProfileSalary } from "../entities/ProfileSalary";
|
||||
import { ProfileSalaryHistory } from "../entities/ProfileSalaryHistory";
|
||||
import { removeProfileInOrganize, setLogDataDiff } from "../interfaces/utils";
|
||||
import {
|
||||
calculateRetireDate,
|
||||
calculateRetireLaw,
|
||||
removeProfileInOrganize,
|
||||
setLogDataDiff,
|
||||
} from "../interfaces/utils";
|
||||
import { Position } from "../entities/Position";
|
||||
import { PosMaster } from "../entities/PosMaster";
|
||||
import { EmployeePosition } from "../entities/EmployeePosition";
|
||||
|
|
@ -42,6 +47,15 @@ import { EmployeePosMaster } from "../entities/EmployeePosMaster";
|
|||
import { ProfileDiscipline } from "../entities/ProfileDiscipline";
|
||||
import { ProfileDisciplineHistory } from "../entities/ProfileDisciplineHistory";
|
||||
import { PosMasterAct } from "../entities/PosMasterAct";
|
||||
import { sendToQueue } from "../services/rabbitmq";
|
||||
import { PosLevel } from "../entities/PosLevel";
|
||||
import { PosType } from "../entities/PosType";
|
||||
import { addUserRoles, createUser, getRoles } from "../keycloak";
|
||||
import { ProfileEducation, CreateProfileEducation } from "../entities/ProfileEducation";
|
||||
import { ProfileEducationHistory } from "../entities/ProfileEducationHistory";
|
||||
import { CreateProfileCertificate, ProfileCertificate } from "../entities/ProfileCertificate";
|
||||
import { ProfileCertificateHistory } from "../entities/ProfileCertificateHistory";
|
||||
import permission from "../interfaces/permission";
|
||||
|
||||
@Route("api/v1/org/command")
|
||||
@Tags("Command")
|
||||
|
|
@ -70,6 +84,13 @@ export class CommandController extends Controller {
|
|||
private disciplineRepository = AppDataSource.getRepository(ProfileDiscipline);
|
||||
private disciplineHistoryRepository = AppDataSource.getRepository(ProfileDisciplineHistory);
|
||||
private posMasterActRepository = AppDataSource.getRepository(PosMasterAct);
|
||||
private posLevelRepo = AppDataSource.getRepository(PosLevel);
|
||||
private posTypeRepo = AppDataSource.getRepository(PosType);
|
||||
private profileEducationRepo = AppDataSource.getRepository(ProfileEducation);
|
||||
private profileEducationHistoryRepo = AppDataSource.getRepository(ProfileEducationHistory);
|
||||
private certificateRepo = AppDataSource.getRepository(ProfileCertificate);
|
||||
private certificateHistoryRepo = AppDataSource.getRepository(ProfileCertificateHistory);
|
||||
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
||||
|
||||
/**
|
||||
* API list รายการคำสั่ง
|
||||
|
|
@ -79,6 +100,7 @@ export class CommandController extends Controller {
|
|||
*/
|
||||
@Get("list")
|
||||
async GetResult(
|
||||
@Request() request: RequestWithUser,
|
||||
@Query("page") page: number = 1,
|
||||
@Query("pageSize") pageSize: number = 10,
|
||||
@Query() keyword: string = "",
|
||||
|
|
@ -86,8 +108,107 @@ export class CommandController extends Controller {
|
|||
@Query() year?: number,
|
||||
@Query() status?: string | null,
|
||||
) {
|
||||
let profilekArray: any = [];
|
||||
|
||||
let _profile = await this.profileRepository.findOne({
|
||||
where: { keycloak: request.user.sub },
|
||||
relations: ["current_holders", "current_holders.orgRevision"],
|
||||
});
|
||||
let isDirector =
|
||||
_profile?.current_holders?.filter(
|
||||
(x) =>
|
||||
x.orgRevision?.orgRevisionIsCurrent == true && x.orgRevision?.orgRevisionIsDraft == false,
|
||||
)[0]?.isDirector || false;
|
||||
if (isDirector) {
|
||||
let _data: any = {
|
||||
root: null,
|
||||
child1: null,
|
||||
child2: null,
|
||||
child3: null,
|
||||
child4: null,
|
||||
};
|
||||
if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
_data = await new permission().PermissionOrgList(request, "COMMAND");
|
||||
}
|
||||
const profiles = await this.profileRepository
|
||||
.createQueryBuilder("profile")
|
||||
.leftJoinAndSelect("profile.current_holders", "current_holders")
|
||||
.leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
|
||||
.leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
|
||||
.leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
|
||||
.leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
|
||||
.leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
|
||||
.andWhere(
|
||||
_data.root != undefined && _data.root != null
|
||||
? _data.root[0] != null
|
||||
? `current_holders.orgRootId IN (:...root)`
|
||||
: `current_holders.orgRootId is null`
|
||||
: "1=1",
|
||||
{
|
||||
root: _data.root,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child1 != undefined && _data.child1 != null
|
||||
? _data.child1[0] != null
|
||||
? `current_holders.orgChild1Id IN (:...child1)`
|
||||
: `current_holders.orgChild1Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child1: _data.child1,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child2 != undefined && _data.child2 != null
|
||||
? _data.child2[0] != null
|
||||
? `current_holders.orgChild2Id IN (:...child2)`
|
||||
: `current_holders.orgChild2Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child2: _data.child2,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child3 != undefined && _data.child3 != null
|
||||
? _data.child3[0] != null
|
||||
? `current_holders.orgChild3Id IN (:...child3)`
|
||||
: `current_holders.orgChild3Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child3: _data.child3,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child4 != undefined && _data.child4 != null
|
||||
? _data.child4[0] != null
|
||||
? `current_holders.orgChild4Id IN (:...child4)`
|
||||
: `current_holders.orgChild4Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child4: _data.child4,
|
||||
},
|
||||
)
|
||||
.select("profile.keycloak", "keycloak")
|
||||
.getRawMany();
|
||||
profilekArray = profiles.map((p) => p.keycloak);
|
||||
}
|
||||
|
||||
const [commands, total] = await this.commandRepository
|
||||
.createQueryBuilder("command")
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.orWhere(
|
||||
profilekArray.length > 0
|
||||
? "command.createdUserId IN (:...profilekArray)"
|
||||
: "command.createdUserId='1'",
|
||||
{
|
||||
profilekArray: profilekArray,
|
||||
},
|
||||
).orWhere("command.createdUserId = :createdUserId", {
|
||||
createdUserId: request.user.sub,
|
||||
});
|
||||
}),
|
||||
)
|
||||
.andWhere(
|
||||
status != null && status != undefined && status != ""
|
||||
? "command.status IN (:...status)"
|
||||
|
|
@ -125,12 +246,9 @@ export class CommandController extends Controller {
|
|||
new Brackets((qb) => {
|
||||
qb.where(keyword != null && keyword != "" ? "command.commandNo LIKE :keyword" : "1=1", {
|
||||
keyword: `%${keyword}%`,
|
||||
}).orWhere(
|
||||
keyword != null && keyword != "" ? "command.issue LIKE :keyword" : "1=1",
|
||||
{
|
||||
keyword: `%${keyword}%`,
|
||||
},
|
||||
);
|
||||
}).orWhere(keyword != null && keyword != "" ? "command.issue LIKE :keyword" : "1=1", {
|
||||
keyword: `%${keyword}%`,
|
||||
});
|
||||
}),
|
||||
)
|
||||
.orderBy("command.createdAt", "DESC")
|
||||
|
|
@ -250,8 +368,7 @@ export class CommandController extends Controller {
|
|||
detailFooter: string | null;
|
||||
commandAffectDate: Date | null;
|
||||
commandExcecuteDate: Date | null;
|
||||
isBangkok: boolean | null;
|
||||
isAttachment: boolean | null;
|
||||
isBangkok: string | null;
|
||||
},
|
||||
@Request() request: RequestWithUser,
|
||||
) {
|
||||
|
|
@ -896,19 +1013,20 @@ export class CommandController extends Controller {
|
|||
if (command.commandExcecuteDate == null)
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบวันที่คำสั่งมีผล");
|
||||
|
||||
let profiles = command.commandRecives
|
||||
.filter((x) => x.profileId != null)
|
||||
.map(async (x) => x.profileId);
|
||||
let profiles =
|
||||
command && command.commandRecives.length > 0
|
||||
? command.commandRecives.filter((x) => x.profileId != null).map((x) => x.profileId)
|
||||
: [];
|
||||
|
||||
await new CallAPI()
|
||||
await new CallAPI()
|
||||
.PostData(request, "/placement/noti/profiles", {
|
||||
subject: `${command.issue}`,
|
||||
body: `${command.issue}`,
|
||||
receiverUserId: profiles,
|
||||
payload: "",//แนบไฟล์
|
||||
receiverUserIds: profiles,
|
||||
payload: "", //แนบไฟล์
|
||||
isSendMail: true,
|
||||
isSendInbox: true,
|
||||
receiveDate: command.commandExcecuteDate,
|
||||
isSendNotification: true,
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error calling API:", error);
|
||||
|
|
@ -922,34 +1040,86 @@ export class CommandController extends Controller {
|
|||
)
|
||||
) {
|
||||
command.status = "WAITING";
|
||||
command.lastUpdateUserId = request.user.sub;
|
||||
command.lastUpdateFullName = request.user.name;
|
||||
command.lastUpdatedAt = new Date();
|
||||
await this.commandRepository.save(command);
|
||||
} else {
|
||||
const path = this.commandTypePath(command.commandType.code);
|
||||
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||
|
||||
await new CallAPI()
|
||||
.PostData(request, path + "/excecute", {
|
||||
refIds: command.commandRecives
|
||||
.filter((x) => x.refId != null)
|
||||
.map((x) => ({
|
||||
refId: x.refId,
|
||||
commandAffectDate: command.commandAffectDate,
|
||||
commandNo: command.commandNo,
|
||||
commandYear: command.commandYear,
|
||||
templateDoc: command.positionDetail,
|
||||
amount: x.amount,
|
||||
positionSalaryAmount: x.positionSalaryAmount,
|
||||
mouthSalaryAmount: x.mouthSalaryAmount,
|
||||
})),
|
||||
})
|
||||
.then(async (res) => {
|
||||
command.status = "REPORTED";
|
||||
})
|
||||
.catch((e) => {});
|
||||
const msg = {
|
||||
data: {
|
||||
id: command.id,
|
||||
status: "REPORTED",
|
||||
lastUpdateUserId: request.user.sub,
|
||||
lastUpdateFullName: request.user.name,
|
||||
lastUpdatedAt: new Date(),
|
||||
},
|
||||
user: request.user,
|
||||
token: request.headers["authorization"],
|
||||
};
|
||||
sendToQueue(msg);
|
||||
}
|
||||
command.lastUpdateUserId = request.user.sub;
|
||||
command.lastUpdateFullName = request.user.name;
|
||||
command.lastUpdatedAt = new Date();
|
||||
await this.commandRepository.save(command);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
async cronjobCommand(@Request() request?: RequestWithUser) {
|
||||
console.log(request);
|
||||
const today = new Date();
|
||||
today.setHours(7, 0, 0, 0); //+7 เพื่อให้ตรง local time (อาจจะต้องใช้ moment)
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const command = await this.commandRepository.find({
|
||||
relations: ["commandType", "commandRecives"],
|
||||
where: {
|
||||
commandExcecuteDate: Between(today, tomorrow),
|
||||
status: "WAITING",
|
||||
},
|
||||
});
|
||||
|
||||
const data = {
|
||||
client_id: "gettoken",
|
||||
client_secret: process.env.AUTH_ACCOUNT_SECRET,
|
||||
grant_type: "password",
|
||||
requested_token_type: "urn:ietf:params:oauth:token-type:refresh_token",
|
||||
username: process.env.USERNAME_,
|
||||
password: process.env.PASSWORD_,
|
||||
};
|
||||
let _data: any = null;
|
||||
await Promise.all([
|
||||
await new CallAPI()
|
||||
.PostDataKeycloak("/realms/bma-ehr/protocol/openid-connect/token", data)
|
||||
.then(async (x) => {
|
||||
_data = x;
|
||||
})
|
||||
.catch(async (x) => {
|
||||
throw new HttpError(HttpStatus.UNAUTHORIZED, "ชื่อผู้ใช้งานหรือรหัสผ่านไม่ถูกต้อง");
|
||||
}),
|
||||
]);
|
||||
if (_data == null) {
|
||||
return new HttpError(HttpStatus.UNAUTHORIZED, "ชื่อผู้ใช้งานหรือรหัสผ่านไม่ถูกต้อง");
|
||||
}
|
||||
|
||||
command.forEach(async (x) => {
|
||||
const path = this.commandTypePath(x.commandType.code);
|
||||
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||
const msg = {
|
||||
data: {
|
||||
id: x.id,
|
||||
status: "REPORTED",
|
||||
lastUpdateUserId: "system",
|
||||
lastUpdateFullName: "system",
|
||||
// lastUpdateUserId: _data.user.sub,
|
||||
// lastUpdateFullName: _data.user.name,
|
||||
lastUpdatedAt: new Date(),
|
||||
},
|
||||
user: _data.user,
|
||||
token: _data.access_token,
|
||||
};
|
||||
sendToQueue(msg);
|
||||
});
|
||||
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
|
|
@ -969,11 +1139,38 @@ export class CommandController extends Controller {
|
|||
if (!command) {
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้");
|
||||
}
|
||||
|
||||
let issue =
|
||||
command.isBangkok == "OFFICE"
|
||||
? "สำนักปลัดกรุงเทพมหานคร"
|
||||
: command.isBangkok == "BANGKOK"
|
||||
? "กรุงเทพมหานคร"
|
||||
: null;
|
||||
if (issue == null) {
|
||||
const orgRevisionActive = await this.orgRevisionRepository.findOne({
|
||||
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||
relations: ["posMasters", "posMasters.orgRoot"],
|
||||
});
|
||||
if (orgRevisionActive != null) {
|
||||
const profile = await this.profileRepository.findOne({
|
||||
where: {
|
||||
keycloak: command.createdUserId.toString(),
|
||||
},
|
||||
});
|
||||
if (profile != null) {
|
||||
issue =
|
||||
orgRevisionActive?.posMasters?.filter((x) => x.current_holderId == profile.id)[0]
|
||||
?.orgRoot?.orgRootName || null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (issue == null) issue = "...................................";
|
||||
const _command = {
|
||||
issue: "...................................",
|
||||
commandNo: command.commandNo,
|
||||
commandYear: command.commandYear,
|
||||
issue: issue,
|
||||
commandNo: command.commandNo == null ? "" : Extension.ToThaiNumber(command.commandNo),
|
||||
commandYear:
|
||||
command.commandYear == null
|
||||
? ""
|
||||
: Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()),
|
||||
commandTitle: command.issue,
|
||||
detailHeader: command.detailHeader,
|
||||
detailBody: command.detailBody,
|
||||
|
|
@ -988,6 +1185,9 @@ export class CommandController extends Controller {
|
|||
: Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)),
|
||||
name: "...................................",
|
||||
position: "...................................",
|
||||
authorizedUserFullName: "...................................",
|
||||
authorizedPosition: "...................................",
|
||||
commandAffectDate: "...................................",
|
||||
};
|
||||
return new HttpSuccess({
|
||||
template: command.commandType.fileCover,
|
||||
|
|
@ -1016,7 +1216,6 @@ export class CommandController extends Controller {
|
|||
let _command: any = [];
|
||||
const path = this.commandTypePath(command.commandType.code);
|
||||
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||
|
||||
await new CallAPI()
|
||||
.PostData(request, path + "/attachment", {
|
||||
refIds: command.commandRecives
|
||||
|
|
@ -1037,15 +1236,51 @@ export class CommandController extends Controller {
|
|||
})),
|
||||
})
|
||||
.then(async (res) => {
|
||||
console.log(res);
|
||||
_command = res;
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
let issue =
|
||||
command.isBangkok == "OFFICE"
|
||||
? "สำนักปลัดกรุงเทพมหานคร"
|
||||
: command.isBangkok == "BANGKOK"
|
||||
? "กรุงเทพมหานคร"
|
||||
: null;
|
||||
if (issue == null) {
|
||||
const orgRevisionActive = await this.orgRevisionRepository.findOne({
|
||||
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||
relations: ["posMasters", "posMasters.orgRoot"],
|
||||
});
|
||||
if (orgRevisionActive != null) {
|
||||
const profile = await this.profileRepository.findOne({
|
||||
where: {
|
||||
keycloak: command.createdUserId.toString(),
|
||||
},
|
||||
});
|
||||
if (profile != null) {
|
||||
issue =
|
||||
orgRevisionActive?.posMasters?.filter((x) => x.current_holderId == profile.id)[0]
|
||||
?.orgRoot?.orgRootName || null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (issue == null) issue = "...................................";
|
||||
return new HttpSuccess({
|
||||
template: command.commandType.fileAttachment,
|
||||
reportName: "xlsx-report",
|
||||
data: _command,
|
||||
data: {
|
||||
data: _command,
|
||||
issuerOrganizationName: issue,
|
||||
commandNo: command.commandNo == null ? "" : Extension.ToThaiNumber(command.commandNo),
|
||||
commandYear:
|
||||
command.commandYear == null
|
||||
? ""
|
||||
: Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()),
|
||||
commandExcecuteDate:
|
||||
command.commandExcecuteDate == null
|
||||
? ""
|
||||
: Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1067,7 +1302,7 @@ export class CommandController extends Controller {
|
|||
commandExcecuteDate?: Date | null;
|
||||
persons: {
|
||||
refId: string;
|
||||
profileId?: string|null;
|
||||
profileId?: string | null;
|
||||
citizenId: string;
|
||||
prefix: string;
|
||||
firstName: string;
|
||||
|
|
@ -1990,6 +2225,207 @@ export class CommandController extends Controller {
|
|||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
@Post("excexute/create-officer-profile")
|
||||
public async CreateOfficeProfileExcecute(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
data: {
|
||||
bodyProfile: CreateProfileAllFields;
|
||||
bodyEducations?: CreateProfileEducation[];
|
||||
bodyCertificates?: CreateProfileCertificate[];
|
||||
bodySalarys?: CreateProfileSalary | null;
|
||||
bodyPosition?: {
|
||||
posmasterId: string;
|
||||
positionId: string;
|
||||
} | null;
|
||||
}[];
|
||||
},
|
||||
) {
|
||||
await Promise.all(
|
||||
body.data.map(async (item) => {
|
||||
const before = null;
|
||||
const meta = {
|
||||
createdUserId: req.user.sub,
|
||||
createdFullName: req.user.name,
|
||||
lastUpdateUserId: req.user.sub,
|
||||
lastUpdateFullName: req.user.name,
|
||||
createdAt: new Date(),
|
||||
lastUpdatedAt: new Date(),
|
||||
};
|
||||
const _null: any = null;
|
||||
if (item.bodyProfile.posLevelId === "") item.bodyProfile.posLevelId = null;
|
||||
if (item.bodyProfile.posTypeId === "") item.bodyProfile.posTypeId = null;
|
||||
if (
|
||||
item.bodyProfile.posLevelId &&
|
||||
!(await this.posLevelRepo.findOneBy({ id: item.bodyProfile.posLevelId }))
|
||||
) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้");
|
||||
}
|
||||
if (
|
||||
item.bodyProfile.posTypeId &&
|
||||
!(await this.posTypeRepo.findOneBy({ id: item.bodyProfile.posTypeId }))
|
||||
) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
|
||||
}
|
||||
|
||||
let profile: any = await this.profileRepository.findOneBy({
|
||||
citizenId: item.bodyProfile.citizenId,
|
||||
});
|
||||
if (!profile) {
|
||||
profile = Object.assign({ ...item.bodyProfile, ...meta });
|
||||
profile.dateRetire =
|
||||
item.bodyProfile.birthDate == null
|
||||
? _null
|
||||
: calculateRetireDate(item.bodyProfile.birthDate);
|
||||
profile.dateRetireLaw =
|
||||
item.bodyProfile.birthDate == null
|
||||
? _null
|
||||
: calculateRetireLaw(item.bodyProfile.birthDate);
|
||||
const userKeycloakId = await createUser(profile.citizenId, profile.citizenId, {
|
||||
firstName: profile.firstName,
|
||||
lastName: profile.lastName,
|
||||
// email: profile.email,
|
||||
});
|
||||
if (typeof userKeycloakId !== "string") {
|
||||
throw new Error(userKeycloakId.errorMessage);
|
||||
}
|
||||
const list = await getRoles();
|
||||
if (!Array.isArray(list))
|
||||
throw new Error("Failed. Cannot get role(s) data from the server.");
|
||||
const result = await addUserRoles(
|
||||
userKeycloakId,
|
||||
list
|
||||
.filter((v) => v.name === "USER")
|
||||
.map((x) => ({
|
||||
id: x.id,
|
||||
name: x.name,
|
||||
})),
|
||||
);
|
||||
if (!result) throw new Error("Failed. Cannot set user's role.");
|
||||
profile.keycloak = userKeycloakId;
|
||||
profile.email = item.bodyProfile.email;
|
||||
await this.profileRepository.save(profile);
|
||||
setLogDataDiff(req, { before, after: profile });
|
||||
}
|
||||
if (profile && profile.id) {
|
||||
//Educations
|
||||
if (item.bodyEducations && item.bodyEducations.length > 0) {
|
||||
await Promise.all(
|
||||
item.bodyEducations.map(async (education) => {
|
||||
const profileEdu = new ProfileEducation();
|
||||
Object.assign(profileEdu, { ...education, ...meta });
|
||||
const eduHistory = new ProfileEducationHistory();
|
||||
Object.assign(eduHistory, { ...profileEdu, id: undefined });
|
||||
profileEdu.profileId = profile.id;
|
||||
await this.profileEducationRepo.save(profileEdu, { data: req });
|
||||
setLogDataDiff(req, { before, after: profileEdu });
|
||||
eduHistory.profileEducationId = profileEdu.id;
|
||||
await this.profileEducationHistoryRepo.save(eduHistory, { data: req });
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
//Certificates
|
||||
if (item.bodyCertificates && item.bodyCertificates.length > 0) {
|
||||
await Promise.all(
|
||||
item.bodyCertificates.map(async (cer) => {
|
||||
const profileCer = new ProfileCertificate();
|
||||
Object.assign(profileCer, { ...cer, ...meta });
|
||||
const cerHistory = new ProfileCertificateHistory();
|
||||
Object.assign(cerHistory, { ...profileCer, id: undefined });
|
||||
profileCer.profileId = profile.id;
|
||||
await this.certificateRepo.save(profileCer, { data: req });
|
||||
setLogDataDiff(req, { before, after: profileCer });
|
||||
cerHistory.profileCertificateId = profileCer.id;
|
||||
await this.certificateHistoryRepo.save(cerHistory, { data: req });
|
||||
}),
|
||||
);
|
||||
}
|
||||
//Salary
|
||||
if (item.bodySalarys && item.bodySalarys != null) {
|
||||
const dest_item = await this.salaryRepo.findOne({
|
||||
where: { profileId: profile.id },
|
||||
order: { order: "DESC" },
|
||||
});
|
||||
const profileSal = new ProfileSalary();
|
||||
Object.assign(profileSal, { ...item.bodySalarys, ...meta });
|
||||
const salaryHistory = new ProfileSalaryHistory();
|
||||
Object.assign(salaryHistory, { ...profileSal, id: undefined });
|
||||
profileSal.order = dest_item == null ? 1 : dest_item.order + 1;
|
||||
profileSal.profileId = profile.id;
|
||||
await this.salaryRepo.save(profileSal, { data: req });
|
||||
setLogDataDiff(req, { before, after: profileSal });
|
||||
salaryHistory.profileSalaryId = profileSal.id;
|
||||
await this.salaryHistoryRepo.save(salaryHistory, { data: req });
|
||||
}
|
||||
//Position
|
||||
if (item.bodyPosition && item.bodyPosition != null) {
|
||||
const posMaster = await this.posMasterRepository.findOne({
|
||||
where: { id: item.bodyPosition.posmasterId },
|
||||
});
|
||||
if (posMaster == null)
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
|
||||
|
||||
const posMasterOld = await this.posMasterRepository.findOne({
|
||||
where: {
|
||||
current_holderId: profile.id,
|
||||
orgRevisionId: posMaster.orgRevisionId,
|
||||
},
|
||||
});
|
||||
if (posMasterOld != null) posMasterOld.current_holderId = null;
|
||||
|
||||
const positionOld = await this.positionRepository.findOne({
|
||||
where: {
|
||||
posMasterId: posMasterOld?.id,
|
||||
positionIsSelected: true,
|
||||
},
|
||||
});
|
||||
if (positionOld != null) {
|
||||
positionOld.positionIsSelected = false;
|
||||
await this.positionRepository.save(positionOld);
|
||||
}
|
||||
|
||||
const checkPosition = await this.positionRepository.find({
|
||||
where: {
|
||||
posMasterId: item.bodyPosition.posmasterId,
|
||||
positionIsSelected: true,
|
||||
},
|
||||
});
|
||||
if (checkPosition.length > 0) {
|
||||
const clearPosition = checkPosition.map((positions) => ({
|
||||
...positions,
|
||||
positionIsSelected: false,
|
||||
}));
|
||||
await this.positionRepository.save(clearPosition);
|
||||
}
|
||||
|
||||
posMaster.current_holderId = profile.id;
|
||||
if (posMasterOld != null) await this.posMasterRepository.save(posMasterOld);
|
||||
await this.posMasterRepository.save(posMaster);
|
||||
|
||||
const positionNew = await this.positionRepository.findOne({
|
||||
where: {
|
||||
id: item.bodyPosition.positionId,
|
||||
posMasterId: item.bodyPosition.posmasterId,
|
||||
},
|
||||
});
|
||||
if (positionNew != null) {
|
||||
positionNew.positionIsSelected = true;
|
||||
profile.posLevelId = positionNew.posLevelId;
|
||||
profile.posTypeId = positionNew.posTypeId;
|
||||
profile.position = positionNew.positionName;
|
||||
await this.profileRepository.save(profile, { data: req });
|
||||
setLogDataDiff(req, { before, after: profile });
|
||||
await this.positionRepository.save(positionNew, { data: req });
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
@Post("command21/employee/report/excecute")
|
||||
public async command21SalaryEmployeeExcecute(
|
||||
@Request() req: RequestWithUser,
|
||||
|
|
@ -2131,6 +2567,28 @@ export class CommandController extends Controller {
|
|||
refIds: string[];
|
||||
},
|
||||
) {
|
||||
const profile = await this.profileEmployeeRepository.find({ where: { id: In(body.refIds) } });
|
||||
const data = profile.map((_data) => ({
|
||||
..._data,
|
||||
statusTemp: "REPORT",
|
||||
}));
|
||||
await this.profileEmployeeRepository.save(data);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
@Post("command21/employee/delete")
|
||||
public async command21SalaryEmployeeDelete(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refIds: string[];
|
||||
},
|
||||
) {
|
||||
const profile = await this.profileEmployeeRepository.find({ where: { id: In(body.refIds) } });
|
||||
const data = profile.map((_data) => ({
|
||||
..._data,
|
||||
statusTemp: "WAITTING",
|
||||
}));
|
||||
await this.profileEmployeeRepository.save(data);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
|
|
@ -2161,6 +2619,28 @@ export class CommandController extends Controller {
|
|||
refIds: string[];
|
||||
},
|
||||
) {
|
||||
// const profile = await this.profileEmployeeRepository.find({ where: { id: In(body.refIds) } });
|
||||
// const data = profile.map((_data) => ({
|
||||
// ..._data,
|
||||
// statusTemp: "DONE",
|
||||
// }));
|
||||
// await this.profileEmployeeRepository.save(data);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
@Post("command40/officer/delete")
|
||||
public async command40SalaryOfficerDelete(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refIds: string[];
|
||||
},
|
||||
) {
|
||||
// const profile = await this.profileEmployeeRepository.find({ where: { id: In(body.refIds) } });
|
||||
// const data = profile.map((_data) => ({
|
||||
// ..._data,
|
||||
// statusTemp: "WAITTING",
|
||||
// }));
|
||||
// await this.profileEmployeeRepository.save(data);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
@Post("command40/officer/report/attachment")
|
||||
|
|
@ -2231,8 +2711,7 @@ export class CommandController extends Controller {
|
|||
"" + posMasterAct.posMasterChild?.current_holder?.firstName ??
|
||||
"" + " " + posMasterAct.posMasterChild?.current_holder?.lastName ??
|
||||
null,
|
||||
organization: _organization,
|
||||
position: posMasterAct.posMasterChild?.current_holder?.position ?? null,
|
||||
oc: (posMasterAct.posMasterChild?.current_holder?.position ?? null) + "/" + _organization,
|
||||
postype: posMasterAct.posMasterChild?.current_holder?.posType?.posTypeName ?? null,
|
||||
poslevel: posMasterAct.posMasterChild?.current_holder?.posLevel?.posLevelName ?? null,
|
||||
organizationNew: _organizationNew,
|
||||
|
|
@ -2280,6 +2759,7 @@ export class CommandController extends Controller {
|
|||
) {
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
commandTypePath(commandCode: string) {
|
||||
switch (commandCode) {
|
||||
case "C-PM-01":
|
||||
|
|
@ -2293,7 +2773,7 @@ export class CommandController extends Controller {
|
|||
case "C-PM-05":
|
||||
return "/placement/appointment/appoint/report";
|
||||
case "C-PM-06":
|
||||
return "/placement/appointment/slip/report";
|
||||
return "/placement/slip/report";
|
||||
case "C-PM-07":
|
||||
return "/placement/appointment/move/report";
|
||||
case "C-PM-08":
|
||||
|
|
@ -2301,7 +2781,7 @@ export class CommandController extends Controller {
|
|||
case "C-PM-09":
|
||||
return "/retirement/other/out/report";
|
||||
case "C-PM-10":
|
||||
return "/xxxxxx";
|
||||
return "/probation/report/command10/officer/report";
|
||||
case "C-PM-11":
|
||||
return "/probation/report/command11/officer/report";
|
||||
case "C-PM-12":
|
||||
|
|
@ -2309,7 +2789,7 @@ export class CommandController extends Controller {
|
|||
case "C-PM-13":
|
||||
return "/placement/transfer/command/report";
|
||||
case "C-PM-14":
|
||||
return "/placement/Receive/command/report";
|
||||
return "/placement/receive/command/report";
|
||||
case "C-PM-15":
|
||||
return "/placement/officer/command/report";
|
||||
case "C-PM-16":
|
||||
|
|
@ -2359,7 +2839,7 @@ export class CommandController extends Controller {
|
|||
case "C-PM-38":
|
||||
return "/org/command/command38/officer/report";
|
||||
case "C-PM-39":
|
||||
return "/placement/slip/report";
|
||||
return "/placement/appointment/slip/report";
|
||||
case "C-PM-40":
|
||||
return "/org/command/command40/officer/report";
|
||||
case "C-PM-41":
|
||||
|
|
|
|||
|
|
@ -301,17 +301,8 @@ export class DevelopmentRequestController extends Controller {
|
|||
});
|
||||
if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
|
||||
await new permission().PermissionUpdate(req, "SYS_REGISTRY_OFFICER");
|
||||
const before = structuredClone(record);
|
||||
requestBody.status = requestBody.status.trim().toUpperCase();
|
||||
Object.assign(record, requestBody);
|
||||
|
||||
record.lastUpdateUserId = req.user.sub;
|
||||
record.lastUpdateFullName = req.user.name;
|
||||
record.lastUpdatedAt = new Date();
|
||||
|
||||
await this.developmentRequestRepository.save(record, { data: req });
|
||||
setLogDataDiff(req, { before, after: record });
|
||||
if (requestBody.status == "APPROVE") {
|
||||
|
||||
if (requestBody.status == "APPROVE" && record.status == "PENDING") {
|
||||
let profileDevelopment = new ProfileDevelopment();
|
||||
const meta = {
|
||||
createdUserId: req.user.sub,
|
||||
|
|
@ -368,7 +359,16 @@ export class DevelopmentRequestController extends Controller {
|
|||
);
|
||||
}
|
||||
}
|
||||
const before = structuredClone(record);
|
||||
requestBody.status = requestBody.status.trim().toUpperCase();
|
||||
Object.assign(record, requestBody);
|
||||
|
||||
record.lastUpdateUserId = req.user.sub;
|
||||
record.lastUpdateFullName = req.user.name;
|
||||
record.lastUpdatedAt = new Date();
|
||||
|
||||
await this.developmentRequestRepository.save(record, { data: req });
|
||||
setLogDataDiff(req, { before, after: record });
|
||||
return new HttpSuccess(record.id);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -310,7 +310,6 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
|
||||
let privilege = await this.Permission(request, system, action);
|
||||
console.log(privilege);
|
||||
let reply = await getAsync("posMaster_" + profile.id);
|
||||
if (reply != null) {
|
||||
reply = JSON.parse(reply);
|
||||
|
|
@ -685,19 +684,6 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
|
||||
public async PermissionOrg(req: RequestWithUser, system: string, action: string) {
|
||||
// if (
|
||||
// req.headers.hasOwnProperty("api_key") &&
|
||||
// req.headers["api_key"] &&
|
||||
// req.headers["api_key"] == process.env.API_KEY
|
||||
// ) {
|
||||
// return {
|
||||
// root: null,
|
||||
// child1: null,
|
||||
// child2: null,
|
||||
// child3: null,
|
||||
// child4: null,
|
||||
// };
|
||||
// }
|
||||
let x: any = await this.listAuthSysOrgFunc(req, system, action);
|
||||
let privilege = x.privilege;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ import { RequestWithUser } from "../middlewares/user";
|
|||
import { PermissionOrg } from "../entities/PermissionOrg";
|
||||
import { Profile } from "../entities/Profile";
|
||||
import HttpStatus from "../interfaces/http-status";
|
||||
import permission from "../interfaces/permission";
|
||||
import { PosMaster } from "../entities/PosMaster";
|
||||
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
|
||||
import { ProfileEmployee } from "../entities/ProfileEmployee";
|
||||
|
||||
@Route("api/v1/org/permission-org")
|
||||
@Tags("PermissionOrg")
|
||||
|
|
@ -39,6 +43,10 @@ export class PermissionOrgController extends Controller {
|
|||
private profileRepository = AppDataSource.getRepository(Profile);
|
||||
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
||||
private permissionOrgRepository = AppDataSource.getRepository(PermissionOrg);
|
||||
private posMasterRepository = AppDataSource.getRepository(PosMaster);
|
||||
private posMasterEmpRepository = AppDataSource.getRepository(EmployeePosMaster);
|
||||
private profileRepo = AppDataSource.getRepository(Profile);
|
||||
private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee);
|
||||
|
||||
/**
|
||||
* API หาสำนักทั้งหมดแบบร่าง
|
||||
|
|
@ -48,22 +56,35 @@ export class PermissionOrgController extends Controller {
|
|||
*/
|
||||
@Get()
|
||||
async GetActiveRootIdAdmin(@Request() request: RequestWithUser) {
|
||||
// if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
// throw new HttpError(HttpStatus.FORBIDDEN, "ไม่มีสิทธิ์ใช้งานระบบนี้");
|
||||
// }
|
||||
const orgRevisionActive = await this.orgRevisionRepository.findOne({
|
||||
where: { orgRevisionIsCurrent: false, orgRevisionIsDraft: true },
|
||||
relations: ["posMasters"],
|
||||
});
|
||||
if (!orgRevisionActive) {
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างที่แบบร่างอยู่ตอนนี้");
|
||||
}
|
||||
if (!orgRevisionActive) return new HttpSuccess([]);
|
||||
let rootId: any = null;
|
||||
if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: {
|
||||
keycloak: request.user.sub,
|
||||
},
|
||||
});
|
||||
if (profile == null) return new HttpSuccess([]);
|
||||
|
||||
const data = await this.orgRootRepository.find({
|
||||
where: { orgRevisionId: orgRevisionActive.id },
|
||||
order: {
|
||||
orgRootOrder: "ASC",
|
||||
},
|
||||
});
|
||||
if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
rootId =
|
||||
orgRevisionActive?.posMasters?.filter((x) => x.next_holderId == profile.id)[0]
|
||||
?.orgRootId || null;
|
||||
if (!rootId) return new HttpSuccess([]);
|
||||
}
|
||||
}
|
||||
const data = await AppDataSource.getRepository(OrgRoot)
|
||||
.createQueryBuilder("orgRoot")
|
||||
.where("orgRoot.orgRevisionId = :id", { id: orgRevisionActive.id })
|
||||
.andWhere(rootId != null ? `orgRoot.id = :rootId` : "1=1", {
|
||||
rootId: rootId,
|
||||
})
|
||||
.orderBy("orgRoot.orgRootOrder", "ASC")
|
||||
.getMany();
|
||||
return new HttpSuccess(data);
|
||||
}
|
||||
|
||||
|
|
@ -500,4 +521,38 @@ export class PermissionOrgController extends Controller {
|
|||
await this.permissionOrgRepository.delete(_delPermissionOrg.id);
|
||||
return new HttpSuccess();
|
||||
}
|
||||
public async listAuthSysOrgFuncByRevisionId(
|
||||
request: RequestWithUser,
|
||||
system: string,
|
||||
revisionId: string,
|
||||
) {
|
||||
let profile = await this.profileRepo.findOne({
|
||||
where: {
|
||||
keycloak: request.user.sub,
|
||||
},
|
||||
relations: ["next_holders", "next_holders.authRole", "next_holders.authRole.authRoles"],
|
||||
});
|
||||
if (!profile) {
|
||||
return [null];
|
||||
}
|
||||
|
||||
let attrOwnership =
|
||||
profile?.next_holders
|
||||
.filter((x) => x.orgRevisionId == revisionId)[0]
|
||||
?.authRole?.authRoles?.filter((x) => x.authSysId == system)[0]?.attrOwnership || null;
|
||||
|
||||
const posMaster = await this.posMasterRepository.findOne({
|
||||
where: {
|
||||
next_holderId: profile.id,
|
||||
orgRevisionId: revisionId,
|
||||
},
|
||||
});
|
||||
if (!posMaster) {
|
||||
return [null];
|
||||
} else if (attrOwnership == "OWNER") {
|
||||
return null;
|
||||
} else {
|
||||
return [posMaster.orgRootId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import { updateName } from "../keycloak";
|
|||
import permission from "../interfaces/permission";
|
||||
import { PosMasterAct } from "../entities/PosMasterAct";
|
||||
import axios from "axios";
|
||||
import { OrgChild1 } from "../entities/OrgChild1";
|
||||
@Route("api/v1/org/profile")
|
||||
@Tags("Profile")
|
||||
@Security("bearerAuth")
|
||||
|
|
@ -101,6 +102,7 @@ export class ProfileController extends Controller {
|
|||
private disciplineHistoryRepository = AppDataSource.getRepository(ProfileDisciplineHistory);
|
||||
private profileLeaveRepository = AppDataSource.getRepository(ProfileLeave);
|
||||
private posMasterActRepository = AppDataSource.getRepository(PosMasterAct);
|
||||
private orgChild1Repository = AppDataSource.getRepository(OrgChild1);
|
||||
|
||||
/**
|
||||
* report ประวัติแบบย่อ ข้าราชการ
|
||||
|
|
@ -934,6 +936,91 @@ export class ProfileController extends Controller {
|
|||
|
||||
return new HttpSuccess({ caregiver, commander, chairman });
|
||||
}
|
||||
|
||||
/**
|
||||
* API
|
||||
*
|
||||
* @summary API
|
||||
*
|
||||
*/
|
||||
@Get("admin-keycloak")
|
||||
async listProfileIdByorg(@Request() request: RequestWithUser) {
|
||||
let _data: any = {
|
||||
root: null,
|
||||
child1: null,
|
||||
child2: null,
|
||||
child3: null,
|
||||
child4: null,
|
||||
};
|
||||
if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
_data = await new permission().PermissionOrgList(request, "SYS_ORG");
|
||||
}
|
||||
const profiles = await this.profileRepo
|
||||
.createQueryBuilder("profile")
|
||||
.leftJoinAndSelect("profile.current_holders", "current_holders")
|
||||
.leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
|
||||
.leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
|
||||
.leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
|
||||
.leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
|
||||
.leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
|
||||
.andWhere(
|
||||
_data.root != undefined && _data.root != null
|
||||
? _data.root[0] != null
|
||||
? `current_holders.orgRootId IN (:...root)`
|
||||
: `current_holders.orgRootId is null`
|
||||
: "1=1",
|
||||
{
|
||||
root: _data.root,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child1 != undefined && _data.child1 != null
|
||||
? _data.child1[0] != null
|
||||
? `current_holders.orgChild1Id IN (:...child1)`
|
||||
: `current_holders.orgChild1Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child1: _data.child1,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child2 != undefined && _data.child2 != null
|
||||
? _data.child2[0] != null
|
||||
? `current_holders.orgChild2Id IN (:...child2)`
|
||||
: `current_holders.orgChild2Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child2: _data.child2,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child3 != undefined && _data.child3 != null
|
||||
? _data.child3[0] != null
|
||||
? `current_holders.orgChild3Id IN (:...child3)`
|
||||
: `current_holders.orgChild3Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child3: _data.child3,
|
||||
},
|
||||
)
|
||||
.andWhere(
|
||||
_data.child4 != undefined && _data.child4 != null
|
||||
? _data.child4[0] != null
|
||||
? `current_holders.orgChild4Id IN (:...child4)`
|
||||
: `current_holders.orgChild4Id is null`
|
||||
: "1=1",
|
||||
{
|
||||
child4: _data.child4,
|
||||
},
|
||||
)
|
||||
.andWhere({ keycloak: Not(IsNull()) })
|
||||
.andWhere({ keycloak: Not("") })
|
||||
.select("profile.keycloak", "keycloak")
|
||||
.getRawMany();
|
||||
const keycloakArray = profiles.map((p) => p.keycloak);
|
||||
|
||||
return new HttpSuccess(keycloakArray);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
|
@ -3407,6 +3494,32 @@ export class ProfileController extends Controller {
|
|||
return new HttpSuccess(_profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* API เช็ค สกจ
|
||||
*
|
||||
* @summary เช็ค สกจ
|
||||
*
|
||||
*/
|
||||
@Get("keycloak/idofficer")
|
||||
async getIsOfficerByKeycloak(@Request() request: RequestWithUser) {
|
||||
const posMasters = await this.posMasterRepo.findOne({
|
||||
where: {
|
||||
current_holder: {
|
||||
keycloak: request.user.sub,
|
||||
},
|
||||
orgRevision: {
|
||||
orgRevisionIsCurrent: true,
|
||||
orgRevisionIsDraft: false,
|
||||
},
|
||||
},
|
||||
relations: ["orgChild1"],
|
||||
});
|
||||
if (posMasters == null || posMasters.orgRoot == null) {
|
||||
return new HttpSuccess(false);
|
||||
}
|
||||
return new HttpSuccess(posMasters);
|
||||
}
|
||||
|
||||
/**
|
||||
* API ข้อมูลทะเบียนประวัติตาม keycloakid
|
||||
*
|
||||
|
|
@ -3865,7 +3978,12 @@ export class ProfileController extends Controller {
|
|||
// await new permission().PermissionOrgUserGet(request, "SYS_REGISTRY_OFFICER", id);//ไม่แน่ใจOFFปิดไว้ก่อน
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: { id: id },
|
||||
relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"],
|
||||
relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot", "profileSalary"],
|
||||
order: {
|
||||
profileSalary: {
|
||||
order: "DESC",
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!profile) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
||||
|
|
@ -4042,6 +4160,7 @@ export class ProfileController extends Controller {
|
|||
posNo: shortName,
|
||||
isPosmasterAct: data.length > 0,
|
||||
posmasterAct: data,
|
||||
salary: profile && profile.profileSalary.length > 0 ? profile.profileSalary[0].amount : null,
|
||||
};
|
||||
|
||||
if (_profile.child4Id != null) {
|
||||
|
|
@ -4800,6 +4919,7 @@ export class ProfileController extends Controller {
|
|||
const isProbation: boolean = true;
|
||||
const [findProfile, total] = await AppDataSource.getRepository(Profile)
|
||||
.createQueryBuilder("profile")
|
||||
.leftJoinAndSelect("profile.profileSalary", "profileSalary")
|
||||
.leftJoinAndSelect("profile.posLevel", "posLevel")
|
||||
.leftJoinAndSelect("profile.posType", "posType")
|
||||
.leftJoinAndSelect("profile.current_holders", "current_holders")
|
||||
|
|
@ -4914,9 +5034,13 @@ export class ProfileController extends Controller {
|
|||
lastName: item.lastName,
|
||||
position: item.position,
|
||||
idcard: item.citizenId,
|
||||
refCommandNo:
|
||||
item.profileSalary.sort((a, b) => b.order - a.order).length == 0
|
||||
? null
|
||||
: item.profileSalary.sort((a, b) => b.order - a.order)[0].refCommandNo,
|
||||
posLevelName: item.posLevel == null ? null : item.posLevel.posLevelName,
|
||||
posTypeName: item.posType == null ? null : item.posType.posTypeName,
|
||||
posNo: `${posMaster == null ? null : posMaster.posMasterNo}${shortName}`,
|
||||
posNo: posMaster == null ? null : `${posMaster.posMasterNo}${shortName}`,
|
||||
positionField: position == null ? null : position.positionField,
|
||||
positionArea: position == null ? null : position.positionArea,
|
||||
posExecutiveName: posExecutive,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
Route,
|
||||
Security,
|
||||
Tags,
|
||||
Query
|
||||
} from "tsoa";
|
||||
import { AppDataSource } from "../database/data-source";
|
||||
import HttpSuccess from "../interfaces/http-success";
|
||||
|
|
@ -25,7 +26,7 @@ import {
|
|||
} from "../entities/ProfileDevelopment";
|
||||
import permission from "../interfaces/permission";
|
||||
import { DevelopmentProject } from "../entities/DevelopmentProject";
|
||||
import { In } from "typeorm";
|
||||
import { In, Brackets } from "typeorm";
|
||||
@Route("api/v1/org/profile/development")
|
||||
@Tags("ProfileDevelopment")
|
||||
@Security("bearerAuth")
|
||||
|
|
@ -49,13 +50,58 @@ export class ProfileDevelopmentController extends Controller {
|
|||
}
|
||||
|
||||
@Get("{profileId}")
|
||||
public async getDevelopment(@Path() profileId: string, @Request() req: RequestWithUser) {
|
||||
public async getDevelopment(
|
||||
@Path() profileId: string,
|
||||
@Request() req: RequestWithUser,
|
||||
@Query("page") page: number = 1,
|
||||
@Query("pageSize") pageSize: number = 10,
|
||||
@Query() searchKeyword: string = "",
|
||||
) {
|
||||
await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId);
|
||||
const lists = await this.developmentRepository.find({
|
||||
where: { profileId: profileId },
|
||||
order: { createdAt: "ASC" },
|
||||
});
|
||||
return new HttpSuccess(lists);
|
||||
const [profileDevelopment, total] = await AppDataSource.getRepository(ProfileDevelopment)
|
||||
.createQueryBuilder("profileDevelopment")
|
||||
.where({ profileId: profileId })
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where(
|
||||
searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
|
||||
? "profileDevelopment.name LIKE :keyword"
|
||||
: "1=1",
|
||||
{
|
||||
keyword: `%${searchKeyword}%`,
|
||||
},
|
||||
)
|
||||
.orWhere(
|
||||
searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
|
||||
? "profileDevelopment.developmentTarget LIKE :keyword"
|
||||
: "1=1",
|
||||
{
|
||||
keyword: `%${searchKeyword}%`,
|
||||
},
|
||||
)
|
||||
.orWhere(
|
||||
searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
|
||||
? "profileDevelopment.developmentResults LIKE :keyword"
|
||||
: "1=1",
|
||||
{
|
||||
keyword: `%${searchKeyword}%`,
|
||||
},
|
||||
)
|
||||
.orWhere(
|
||||
searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
|
||||
? "profileDevelopment.developmentReport LIKE :keyword"
|
||||
: "1=1",
|
||||
{
|
||||
keyword: `%${searchKeyword}%`,
|
||||
},
|
||||
);
|
||||
}),
|
||||
)
|
||||
.orderBy("profileDevelopment.createdAt", "ASC")
|
||||
.skip((page - 1) * pageSize)
|
||||
.take(pageSize)
|
||||
.getManyAndCount();
|
||||
return new HttpSuccess({ data: profileDevelopment, total });
|
||||
}
|
||||
|
||||
@Get("history/{developmentId}")
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ export class ProfileEditController extends Controller {
|
|||
.getManyAndCount();
|
||||
const _data = getProfileEdit.map((item) => ({
|
||||
id: item.id,
|
||||
idcard: item.profile.citizenId,
|
||||
profileId: item.profile.id,
|
||||
topic: item.topic,
|
||||
detail: item.detail,
|
||||
status: item.status,
|
||||
|
|
@ -151,10 +153,10 @@ export class ProfileEditController extends Controller {
|
|||
// return new HttpSuccess(getProfileEdit);
|
||||
// }
|
||||
|
||||
@Get("{profileId}")
|
||||
public async detailProfileEdit(@Path() profileId: string) {
|
||||
@Get("{id}")
|
||||
public async detailProfileEdit(@Path() id: string) {
|
||||
const getProfileEdit = await this.profileEditRepo.findOne({
|
||||
where: { profileId: profileId },
|
||||
where: { id: id },
|
||||
relations: ["profile"],
|
||||
});
|
||||
if (!getProfileEdit) {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ export class ProfileEditEmployeeController extends Controller {
|
|||
|
||||
const _data = getProfileEdit.map((item) => ({
|
||||
id: item.id,
|
||||
idcard: item.profile.citizenId,
|
||||
profileId: item.profile.id,
|
||||
topic: item.topic,
|
||||
detail: item.detail,
|
||||
status: item.status,
|
||||
|
|
|
|||
|
|
@ -3705,7 +3705,12 @@ export class ProfileEmployeeController extends Controller {
|
|||
async getProfileByProfileid(@Request() request: RequestWithUser, @Path() id: string) {
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: { id: id },
|
||||
relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"],
|
||||
relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot", "profileSalarys"],
|
||||
order: {
|
||||
profileSalarys: {
|
||||
order: "DESC"
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!profile) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
||||
|
|
@ -3826,6 +3831,7 @@ export class ProfileEmployeeController extends Controller {
|
|||
node: null,
|
||||
nodeId: null,
|
||||
posNo: shortName,
|
||||
salary: profile && profile.profileSalarys.length > 0 ? profile.profileSalarys[0].amount : null
|
||||
};
|
||||
|
||||
if (_profile.child4Id != null) {
|
||||
|
|
|
|||
|
|
@ -30,11 +30,15 @@ import {
|
|||
getRoleMappings,
|
||||
getUserCount,
|
||||
enableStatus,
|
||||
getUserCountOrg,
|
||||
getUserListOrg,
|
||||
} from "../keycloak";
|
||||
import { AppDataSource } from "../database/data-source";
|
||||
import { Profile } from "../entities/Profile";
|
||||
import { ProfileEmployee } from "../entities/ProfileEmployee";
|
||||
import { IsNull } from "typeorm";
|
||||
import { IsNull, Not } from "typeorm";
|
||||
import { RequestWithUser } from "../middlewares/user";
|
||||
import permission from "../interfaces/permission";
|
||||
// import * as io from "../lib/websocket";
|
||||
// import elasticsearch from "../elasticsearch";
|
||||
// import { StorageFolder } from "../interfaces/storage-fs";
|
||||
|
|
@ -94,7 +98,6 @@ export class KeycloakController extends Controller {
|
|||
firstName: body.firstName,
|
||||
lastName: body.lastName,
|
||||
email: body.email,
|
||||
requiredActions: ["UPDATE_PASSWORD"],
|
||||
});
|
||||
|
||||
if (typeof userId !== "string") {
|
||||
|
|
@ -239,7 +242,89 @@ export class KeycloakController extends Controller {
|
|||
}
|
||||
|
||||
@Get("user")
|
||||
async getUserList(@Query() first = "", @Query() max = "", @Query() search = "") {
|
||||
async getUserList(
|
||||
@Request() request: RequestWithUser,
|
||||
@Query() first = "",
|
||||
@Query() max = "",
|
||||
@Query() search = "",
|
||||
) {
|
||||
// let _data: any = {
|
||||
// root: null,
|
||||
// child1: null,
|
||||
// child2: null,
|
||||
// child3: null,
|
||||
// child4: null,
|
||||
// };
|
||||
// if (!request.user.role.includes("SUPER_ADMIN")) {
|
||||
// _data = await new permission().PermissionOrgList(request, "SYS_ORG");
|
||||
// }
|
||||
// const profiles = await this.profileRepo
|
||||
// .createQueryBuilder("profile")
|
||||
// .leftJoinAndSelect("profile.current_holders", "current_holders")
|
||||
// .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
|
||||
// .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
|
||||
// .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
|
||||
// .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
|
||||
// .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
|
||||
// .andWhere(
|
||||
// _data.root != undefined && _data.root != null
|
||||
// ? _data.root[0] != null
|
||||
// ? `current_holders.orgRootId IN (:...root)`
|
||||
// : `current_holders.orgRootId is null`
|
||||
// : "1=1",
|
||||
// {
|
||||
// root: _data.root,
|
||||
// },
|
||||
// )
|
||||
// .andWhere(
|
||||
// _data.child1 != undefined && _data.child1 != null
|
||||
// ? _data.child1[0] != null
|
||||
// ? `current_holders.orgChild1Id IN (:...child1)`
|
||||
// : `current_holders.orgChild1Id is null`
|
||||
// : "1=1",
|
||||
// {
|
||||
// child1: _data.child1,
|
||||
// },
|
||||
// )
|
||||
// .andWhere(
|
||||
// _data.child2 != undefined && _data.child2 != null
|
||||
// ? _data.child2[0] != null
|
||||
// ? `current_holders.orgChild2Id IN (:...child2)`
|
||||
// : `current_holders.orgChild2Id is null`
|
||||
// : "1=1",
|
||||
// {
|
||||
// child2: _data.child2,
|
||||
// },
|
||||
// )
|
||||
// .andWhere(
|
||||
// _data.child3 != undefined && _data.child3 != null
|
||||
// ? _data.child3[0] != null
|
||||
// ? `current_holders.orgChild3Id IN (:...child3)`
|
||||
// : `current_holders.orgChild3Id is null`
|
||||
// : "1=1",
|
||||
// {
|
||||
// child3: _data.child3,
|
||||
// },
|
||||
// )
|
||||
// .andWhere(
|
||||
// _data.child4 != undefined && _data.child4 != null
|
||||
// ? _data.child4[0] != null
|
||||
// ? `current_holders.orgChild4Id IN (:...child4)`
|
||||
// : `current_holders.orgChild4Id is null`
|
||||
// : "1=1",
|
||||
// {
|
||||
// child4: _data.child4,
|
||||
// },
|
||||
// )
|
||||
// .andWhere({ keycloak: Not(IsNull()) })
|
||||
// .andWhere({ keycloak: Not("") })
|
||||
// .select("profile.keycloak", "keycloak")
|
||||
// .getRawMany();
|
||||
// let keycloakArray = profiles.map((p) => p.keycloak);
|
||||
|
||||
// const total = await getUserCountOrg(first, max, search, keycloakArray);
|
||||
// const result = await getUserListOrg(first, max, search, keycloakArray);
|
||||
|
||||
const total = await getUserCount(first, max, search);
|
||||
const result = await getUserList(first, max, search);
|
||||
|
||||
|
|
|
|||
628
src/controllers/WorkflowController.ts
Normal file
628
src/controllers/WorkflowController.ts
Normal file
|
|
@ -0,0 +1,628 @@
|
|||
import { Body, Controller, Get, Post, Request, Route, Security, Tags } from "tsoa";
|
||||
import { AppDataSource } from "../database/data-source";
|
||||
import { RequestWithUser } from "../middlewares/user";
|
||||
import HttpError from "../interfaces/http-error";
|
||||
import HttpStatus from "../interfaces/http-status";
|
||||
import HttpSuccess from "../interfaces/http-success";
|
||||
import { Workflow } from "../entities/Workflow";
|
||||
import { State } from "../entities/State";
|
||||
import { StateOperator } from "../entities/StateOperator";
|
||||
import { StateOperatorUser } from "../entities/StateOperatorUser";
|
||||
import CallAPI from "../interfaces/call-api";
|
||||
import { Profile } from "../entities/Profile";
|
||||
import { StateUserComment } from "../entities/StateUserComment";
|
||||
import { MetaWorkflow } from "../entities/MetaWorkflow";
|
||||
import { MetaState } from "../entities/MetaState";
|
||||
import { MetaStateOperator } from "../entities/MetaStateOperator";
|
||||
import { PosMaster } from "../entities/PosMaster";
|
||||
import { IsNull, Not } from "typeorm";
|
||||
|
||||
@Route("api/v1/org/workflow")
|
||||
@Tags("Workflow")
|
||||
@Security("bearerAuth")
|
||||
export class WorkflowController extends Controller {
|
||||
private workflowRepo = AppDataSource.getRepository(Workflow);
|
||||
private stateRepo = AppDataSource.getRepository(State);
|
||||
private stateOperatorRepo = AppDataSource.getRepository(StateOperator);
|
||||
private stateOperatorUserRepo = AppDataSource.getRepository(StateOperatorUser);
|
||||
private stateUserCommentRepo = AppDataSource.getRepository(StateUserComment);
|
||||
private profileRepo = AppDataSource.getRepository(Profile);
|
||||
|
||||
private metaWorkflowRepo = AppDataSource.getRepository(MetaWorkflow);
|
||||
private metaStateRepo = AppDataSource.getRepository(MetaState);
|
||||
private metaStateOperatorRepo = AppDataSource.getRepository(MetaStateOperator);
|
||||
private posMasterRepo = AppDataSource.getRepository(PosMaster);
|
||||
|
||||
@Post("add-workflow")
|
||||
public async checkWorkflow(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refId: string;
|
||||
sysName: string;
|
||||
posLevelName: string;
|
||||
posTypeName: string;
|
||||
},
|
||||
) {
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: {
|
||||
keycloak: req.user.sub,
|
||||
},
|
||||
});
|
||||
if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");
|
||||
|
||||
const metaWorkflow = await this.metaWorkflowRepo.findOne({
|
||||
where: {
|
||||
sysName: body.sysName,
|
||||
posLevelName: body.posLevelName,
|
||||
posTypeName: body.posTypeName,
|
||||
},
|
||||
});
|
||||
if (!metaWorkflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบกระบวนการนี้ได้");
|
||||
|
||||
const meta = {
|
||||
createdUserId: req.user.sub,
|
||||
createdFullName: req.user.name,
|
||||
lastUpdateUserId: req.user.sub,
|
||||
lastUpdateFullName: req.user.name,
|
||||
createdAt: new Date(),
|
||||
lastUpdatedAt: new Date(),
|
||||
};
|
||||
const workflow = new Workflow();
|
||||
Object.assign(workflow, {
|
||||
...metaWorkflow,
|
||||
id: undefined,
|
||||
...meta,
|
||||
...body,
|
||||
system: body.sysName,
|
||||
});
|
||||
await this.workflowRepo.save(workflow);
|
||||
const metaState = await this.metaStateRepo.find({
|
||||
where: {
|
||||
metaWorkflowId: metaWorkflow.id,
|
||||
},
|
||||
order: { order: "ASC" },
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
metaState.map(async (item) => {
|
||||
const state = new State();
|
||||
Object.assign(state, { ...item, id: undefined, workflowId: workflow.id, ...meta });
|
||||
await this.stateRepo.save(state);
|
||||
if (state.order == 1) {
|
||||
workflow.stateId = state.id;
|
||||
await this.workflowRepo.save(workflow);
|
||||
}
|
||||
const metaStateOperator = await this.metaStateOperatorRepo.find({
|
||||
where: {
|
||||
metaStateId: item.id,
|
||||
},
|
||||
});
|
||||
await Promise.all(
|
||||
metaStateOperator.map(async (item1) => {
|
||||
const stateOperator = new StateOperator();
|
||||
Object.assign(stateOperator, { ...item1, id: undefined, stateId: state.id, ...meta });
|
||||
await this.stateOperatorRepo.save(stateOperator);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
const stateOperatorUser = new StateOperatorUser();
|
||||
Object.assign(stateOperatorUser, {
|
||||
profileId: profile.id,
|
||||
operator: "Owner",
|
||||
order: 1,
|
||||
workflowId: workflow.id,
|
||||
...meta,
|
||||
});
|
||||
await this.stateOperatorUserRepo.save(stateOperatorUser);
|
||||
|
||||
const profileOfficer = await this.posMasterRepo.find({
|
||||
where: {
|
||||
posMasterAssigns: { assignId: body.sysName },
|
||||
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
|
||||
},
|
||||
relations: ["orgChild1"],
|
||||
});
|
||||
await Promise.all(
|
||||
profileOfficer.map(async (item, i) => {
|
||||
if (item.orgChild1 == null || item.orgChild1.isOfficer == false) {
|
||||
const stateOperatorUser = new StateOperatorUser();
|
||||
Object.assign(stateOperatorUser, {
|
||||
profileId: item.current_holderId,
|
||||
operator: "Officer",
|
||||
order: i + 2,
|
||||
workflowId: workflow.id,
|
||||
...meta,
|
||||
});
|
||||
await this.stateOperatorUserRepo.save(stateOperatorUser);
|
||||
} else {
|
||||
const stateOperatorUser = new StateOperatorUser();
|
||||
Object.assign(stateOperatorUser, {
|
||||
profileId: item.current_holderId,
|
||||
operator: "PersonnelOfficer",
|
||||
order: i + 2,
|
||||
workflowId: workflow.id,
|
||||
...meta,
|
||||
});
|
||||
await this.stateOperatorUserRepo.save(stateOperatorUser);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
@Post("check-iscan")
|
||||
public async checkIsCan(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
workflowId: string;
|
||||
stateId: string;
|
||||
profileId: string;
|
||||
action: string;
|
||||
},
|
||||
) {
|
||||
const stateOperatorUser = await this.stateOperatorUserRepo.findOne({
|
||||
where: {
|
||||
profileId: body.profileId,
|
||||
workflowId: body.workflowId,
|
||||
},
|
||||
});
|
||||
if (!stateOperatorUser)
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ผู้ใช้งานนี้ไม่มีหน้าที่ในกระบวนการนี้");
|
||||
|
||||
const operator = await this.stateOperatorRepo.findOne({
|
||||
where: {
|
||||
operator: stateOperatorUser.operator,
|
||||
state: { id: body.stateId, workflow: { id: body.workflowId } },
|
||||
},
|
||||
});
|
||||
if (!operator) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");
|
||||
|
||||
let isCan = false;
|
||||
switch (body.action.trim().toLocaleUpperCase()) {
|
||||
case "VIEW":
|
||||
isCan = operator.canView;
|
||||
case "UPDATE":
|
||||
isCan = operator.canUpdate;
|
||||
case "DELETE":
|
||||
isCan = operator.canDelete;
|
||||
case "CANCEL":
|
||||
isCan = operator.canCancel;
|
||||
case "OPERATE":
|
||||
isCan = operator.canOperate;
|
||||
case "CHANGESTATE":
|
||||
isCan = operator.canChangeState;
|
||||
case "COMMENT":
|
||||
isCan = operator.canComment;
|
||||
case "SIGN":
|
||||
isCan = operator.canSign;
|
||||
default:
|
||||
isCan = false;
|
||||
}
|
||||
if (isCan == false) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการได้");
|
||||
} else {
|
||||
return new HttpSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@Post("check-state-now")
|
||||
public async checkStateNow(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refId: string;
|
||||
system: string;
|
||||
},
|
||||
) {
|
||||
const workflow = await this.workflowRepo.findOne({
|
||||
where: {
|
||||
refId: body.refId,
|
||||
sysName: body.system,
|
||||
},
|
||||
relations: ["stateOperatorUsers"],
|
||||
});
|
||||
if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");
|
||||
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: workflow.stateId,
|
||||
},
|
||||
relations: ["stateOperators"],
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
return new HttpSuccess({
|
||||
stateId: state.id,
|
||||
stateNo: state.order,
|
||||
stateName: state.name,
|
||||
});
|
||||
}
|
||||
|
||||
@Post("check-user-now")
|
||||
public async checkUserNow(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refId: string;
|
||||
system: string;
|
||||
},
|
||||
) {
|
||||
const stateOperatorUser = await this.stateOperatorUserRepo.findOne({
|
||||
where: {
|
||||
workflow: {
|
||||
refId: body.refId,
|
||||
sysName: body.system,
|
||||
},
|
||||
profile: {
|
||||
keycloak: req.user.sub,
|
||||
},
|
||||
},
|
||||
relations: ["workflow"],
|
||||
});
|
||||
if (!stateOperatorUser)
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ผู้ใช้งานนี้ไม่มีหน้าที่ในกระบวนการนี้");
|
||||
console.log(stateOperatorUser.operator);
|
||||
console.log(stateOperatorUser.workflow.stateId);
|
||||
const operator = await this.stateOperatorRepo.findOne({
|
||||
where: {
|
||||
operator: stateOperatorUser.operator,
|
||||
stateId: stateOperatorUser.workflow.stateId,
|
||||
},
|
||||
relations: ["state"],
|
||||
});
|
||||
if (!operator)
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ผู้ใช้งานนี้ไม่มีหน้าที่ในขั้นตอนนี้");
|
||||
return new HttpSuccess({
|
||||
stateId: operator.state.id,
|
||||
stateNo: operator.state.order,
|
||||
stateName: operator.state.name,
|
||||
operator: operator.operator,
|
||||
can_view: operator.canView,
|
||||
can_update: operator.canUpdate,
|
||||
can_operate: operator.canOperate,
|
||||
can_change_state: operator.canChangeState,
|
||||
can_delete: operator.canDelete,
|
||||
can_cancel: operator.canCancel,
|
||||
});
|
||||
}
|
||||
|
||||
@Post("check-state-all")
|
||||
public async checkStateAll(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refId: string;
|
||||
system: string;
|
||||
},
|
||||
) {
|
||||
const state = await this.stateRepo.find({
|
||||
where: {
|
||||
workflow: {
|
||||
refId: body.refId,
|
||||
sysName: body.system,
|
||||
},
|
||||
},
|
||||
order: { order: "ASC", stateUserComments: { order: "ASC" } },
|
||||
relations: ["stateUserComments"],
|
||||
});
|
||||
const _state = state.map((x) => ({
|
||||
stateId: x.id,
|
||||
stateNo: x.order,
|
||||
stateName: x.name,
|
||||
stateUserComments: x.stateUserComments,
|
||||
}));
|
||||
return new HttpSuccess(_state);
|
||||
}
|
||||
|
||||
@Post("state-next")
|
||||
public async stateNext(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
refId: string;
|
||||
system: string;
|
||||
},
|
||||
) {
|
||||
const stateOperatorUser = await this.stateOperatorUserRepo.find({
|
||||
where: {
|
||||
workflow: {
|
||||
refId: body.refId,
|
||||
sysName: body.system,
|
||||
},
|
||||
profile: {
|
||||
keycloak: Not(req.user.sub),
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.stateOperatorUserRepo.remove(stateOperatorUser);
|
||||
|
||||
const workflow = await this.workflowRepo.findOne({
|
||||
where: {
|
||||
refId: body.refId,
|
||||
sysName: body.system,
|
||||
},
|
||||
relations: ["stateOperatorUsers"],
|
||||
});
|
||||
if (!workflow) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่สามารถดำเนินการกระบวนการนี้ได้");
|
||||
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: workflow.stateId,
|
||||
},
|
||||
relations: ["stateOperators"],
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
const _state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
order: state.order + 1,
|
||||
workflowId: state.workflowId,
|
||||
},
|
||||
relations: ["stateOperators"],
|
||||
});
|
||||
//noti
|
||||
let profileNow = workflow.stateOperatorUsers
|
||||
.filter((x) => state.stateOperators.map((s) => s.operator).includes(x.operator))
|
||||
.map((x) => x.profile);
|
||||
await new CallAPI()
|
||||
.PostData(req, "/placement/noti/profiles", {
|
||||
subject: `รายการถูกส่ง`,
|
||||
body: `รายการถูกส่ง`,
|
||||
receiverUserIds: profileNow,
|
||||
payload: "", //แนบไฟล์
|
||||
isSendMail: true,
|
||||
isSendInbox: true,
|
||||
isSendNotification: true,
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error calling API:", error);
|
||||
});
|
||||
if (_state != null) {
|
||||
let profileNext = workflow.stateOperatorUsers
|
||||
.filter((x) => _state.stateOperators.map((s) => s.operator).includes(x.operator))
|
||||
.map((x) => x.profile);
|
||||
await new CallAPI()
|
||||
.PostData(req, "/placement/noti/profiles", {
|
||||
subject: `ได้รับรายการ`,
|
||||
body: `ได้รับรายการ`,
|
||||
receiverUserIds: profileNext,
|
||||
payload: "", //แนบไฟล์
|
||||
isSendMail: true,
|
||||
isSendInbox: true,
|
||||
isSendNotification: true,
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error calling API:", error);
|
||||
});
|
||||
workflow.stateId = _state.id;
|
||||
await this.workflowRepo.save(workflow);
|
||||
}
|
||||
|
||||
return new HttpSuccess({
|
||||
stateId: _state?.id || null,
|
||||
stateNo: _state?.order || null,
|
||||
stateName: _state?.name || null,
|
||||
stateType: _state?.type || null,
|
||||
});
|
||||
}
|
||||
|
||||
@Post("state-back")
|
||||
public async stateBack(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
stateId: string;
|
||||
},
|
||||
) {
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: body.stateId,
|
||||
},
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
const _state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
order: state.order - 1,
|
||||
workflowId: state.workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
return new HttpSuccess({
|
||||
stateId: _state?.id || null,
|
||||
stateNo: _state?.order || null,
|
||||
stateName: _state?.name || null,
|
||||
stateType: _state?.type || null,
|
||||
});
|
||||
}
|
||||
|
||||
@Post("add-step")
|
||||
public async addStep(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
stateId: string;
|
||||
profileId: string;
|
||||
isAcceptSetting: boolean;
|
||||
isApproveSetting: boolean;
|
||||
isReasonSetting: boolean;
|
||||
},
|
||||
) {
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: {
|
||||
id: body.profileId,
|
||||
},
|
||||
});
|
||||
if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบผู้ใช้งานนี้");
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: body.stateId,
|
||||
},
|
||||
relations: ["stateUserComments"],
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
|
||||
const stateUserComment = new StateUserComment();
|
||||
stateUserComment.order = state.stateUserComments.length + 1;
|
||||
stateUserComment.stateId = body.stateId;
|
||||
stateUserComment.profileId = body.profileId;
|
||||
stateUserComment.isAcceptSetting = body.isAcceptSetting;
|
||||
stateUserComment.isApproveSetting = body.isApproveSetting;
|
||||
stateUserComment.isReasonSetting = body.isReasonSetting;
|
||||
stateUserComment.createdUserId = req.user.sub;
|
||||
stateUserComment.createdFullName = req.user.name;
|
||||
stateUserComment.createdAt = new Date();
|
||||
stateUserComment.lastUpdateUserId = req.user.sub;
|
||||
stateUserComment.lastUpdateFullName = req.user.name;
|
||||
stateUserComment.lastUpdatedAt = new Date();
|
||||
await this.stateUserCommentRepo.save(stateUserComment);
|
||||
|
||||
await new CallAPI()
|
||||
.PostData(req, "/placement/noti/profiles", {
|
||||
subject: `ได้รับรายการ`,
|
||||
body: `ได้รับรายการ`,
|
||||
receiverUserIds: [body.profileId],
|
||||
payload: "", //แนบไฟล์
|
||||
isSendMail: true,
|
||||
isSendInbox: true,
|
||||
isSendNotification: true,
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error calling API:", error);
|
||||
});
|
||||
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
@Post("comment")
|
||||
public async createcomment(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
stateId: string;
|
||||
isAccept?: boolean | null;
|
||||
isApprove?: boolean | null;
|
||||
reason?: string | null;
|
||||
},
|
||||
) {
|
||||
const profile = await this.profileRepo.findOne({
|
||||
where: {
|
||||
keycloak: req.user.sub,
|
||||
},
|
||||
});
|
||||
if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งาน");
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: body.stateId,
|
||||
},
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
let _null: any = null;
|
||||
const stateUserComment = new StateUserComment();
|
||||
stateUserComment.stateId = body.stateId;
|
||||
stateUserComment.profileId = profile.id;
|
||||
stateUserComment.isAccept = body.isAccept == null ? _null : body.isAccept;
|
||||
stateUserComment.isApprove = body.isApprove == null ? _null : body.isAccept;
|
||||
stateUserComment.reason = body.reason == null ? _null : body.isAccept;
|
||||
stateUserComment.createdUserId = req.user.sub;
|
||||
stateUserComment.createdFullName = req.user.name;
|
||||
stateUserComment.createdAt = new Date();
|
||||
stateUserComment.lastUpdateUserId = req.user.sub;
|
||||
stateUserComment.lastUpdateFullName = req.user.name;
|
||||
stateUserComment.lastUpdatedAt = new Date();
|
||||
await this.stateUserCommentRepo.save(stateUserComment);
|
||||
|
||||
return new HttpSuccess();
|
||||
}
|
||||
|
||||
@Post("comment-state")
|
||||
public async getCommentState(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
stateId: string;
|
||||
},
|
||||
) {
|
||||
const state = await this.stateRepo.findOne({
|
||||
where: {
|
||||
id: body.stateId,
|
||||
},
|
||||
order: { stateUserComments: { order: "ASC" } },
|
||||
relations: ["stateUserComments"],
|
||||
});
|
||||
if (!state) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลขั้นตอนการอนุมัติ");
|
||||
|
||||
return new HttpSuccess(state.stateUserComments);
|
||||
}
|
||||
|
||||
@Post("comment-state-user")
|
||||
public async getCommentStateUser(
|
||||
@Request() req: RequestWithUser,
|
||||
@Body()
|
||||
body: {
|
||||
stateId: string;
|
||||
},
|
||||
) {
|
||||
const stateUserComment = await this.stateUserCommentRepo.findOne({
|
||||
where: {
|
||||
profile: {
|
||||
keycloak: req.user.sub,
|
||||
},
|
||||
stateId: body.stateId,
|
||||
},
|
||||
});
|
||||
|
||||
return new HttpSuccess({
|
||||
isAccept: stateUserComment?.isAccept || null,
|
||||
isApprove: stateUserComment?.isApprove || null,
|
||||
reason: stateUserComment?.reason || null,
|
||||
isAcceptSetting: stateUserComment?.isAcceptSetting || null,
|
||||
isApproveSetting: stateUserComment?.isApproveSetting || null,
|
||||
isReasonSetting: stateUserComment?.isReasonSetting || null,
|
||||
order: stateUserComment?.order || null,
|
||||
stateId: stateUserComment?.stateId || null,
|
||||
profileId: stateUserComment?.profileId || null,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Get("commander")
|
||||
async getProfilePlacement(@Request() req: RequestWithUser) {
|
||||
const posMasterUser = await this.posMasterRepo.findOne({
|
||||
where: {
|
||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||
current_holder: { keycloak: req.user.sub },
|
||||
},
|
||||
});
|
||||
if (!posMasterUser || !posMasterUser.orgRootId)
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");
|
||||
|
||||
const posMasters = await this.posMasterRepo.find({
|
||||
where: {
|
||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||
isDirector: true,
|
||||
current_holderId: Not(IsNull()),
|
||||
orgRootId: posMasterUser.orgRootId,
|
||||
},
|
||||
relations: ["current_holder", "orgRoot"],
|
||||
});
|
||||
|
||||
let _posMasters = posMasters.map((data) => ({
|
||||
id: data.current_holderId,
|
||||
prefix: data.current_holder.prefix,
|
||||
firstName: data.current_holder.firstName,
|
||||
lastName: data.current_holder.lastName,
|
||||
position: data.current_holder.position,
|
||||
posLevel: data.current_holder.posLevel,
|
||||
posType: data.current_holder.posType,
|
||||
orgRoot: data.orgRoot.orgRootName,
|
||||
}));
|
||||
|
||||
return new HttpSuccess(_posMasters);
|
||||
}
|
||||
}
|
||||
|
|
@ -94,11 +94,11 @@ export class Command extends EntityBase {
|
|||
|
||||
@Column({
|
||||
nullable: true,
|
||||
default: null,
|
||||
type: "boolean",
|
||||
comment: "คำสั่งกรุงเทพมหานคร",
|
||||
length: 20,
|
||||
default: null,
|
||||
})
|
||||
isBangkok: boolean;
|
||||
isBangkok: string;
|
||||
|
||||
@Column({
|
||||
comment: "สถานะบัญชีแนบท้าย",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
import { CommandType } from "./CommandType";
|
||||
import { CommandSalary } from "./CommandSalary";
|
||||
import { Assign } from "./Assign";
|
||||
import { Workflow } from "./Workflow";
|
||||
|
||||
@Entity("commandSys")
|
||||
export class CommandSys {
|
||||
|
|
@ -75,6 +76,9 @@ export class CommandSys {
|
|||
|
||||
@OneToMany(() => Assign, (assgin) => assgin.commandAssignSys)
|
||||
assgins: Assign[];
|
||||
|
||||
// @OneToMany(() => Workflow, (workflow) => workflow.commandSys)
|
||||
// workflows: Workflow[];
|
||||
}
|
||||
|
||||
export class CreateCommandSys {
|
||||
|
|
|
|||
45
src/entities/MetaState.ts
Normal file
45
src/entities/MetaState.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { MetaStateOperator } from "./MetaStateOperator";
|
||||
import { MetaWorkflow } from "./MetaWorkflow";
|
||||
|
||||
@Entity("metaState")
|
||||
export class MetaState extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อประเภทขั้นตอน",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ประเภทขั้นตอน",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
type: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ลำดับ",
|
||||
default: null,
|
||||
})
|
||||
order: number;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง metaWorkflow",
|
||||
default: null,
|
||||
})
|
||||
metaWorkflowId: string;
|
||||
|
||||
@ManyToOne(() => MetaWorkflow, (metaWorkflow) => metaWorkflow.metaStates)
|
||||
@JoinColumn({ name: "metaWorkflowId" })
|
||||
metaWorkflow: MetaWorkflow;
|
||||
|
||||
@OneToMany(() => MetaStateOperator, (metaStateOperator) => metaStateOperator.metaState)
|
||||
metaStateOperators: MetaStateOperator[];
|
||||
}
|
||||
74
src/entities/MetaStateOperator.ts
Normal file
74
src/entities/MetaStateOperator.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { MetaState } from "./MetaState";
|
||||
|
||||
@Entity("metaStateOperator")
|
||||
export class MetaStateOperator extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ผู้ดำเนินการ",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
operator: string;
|
||||
|
||||
@Column({
|
||||
comment: "ดูเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canView: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "แก้ไขเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canUpdate: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ลบเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canDelete: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ยกเลิกเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canCancel: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ดำเนินการเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canOperate: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "เปลี่ยนสถานะเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canChangeState: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "แสดงความเห็นเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canComment: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ลงนามอนุมัติ",
|
||||
default: false,
|
||||
})
|
||||
canSign: boolean;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง metaState",
|
||||
default: null,
|
||||
})
|
||||
metaStateId: string;
|
||||
|
||||
@ManyToOne(() => MetaState, (metaState) => metaState.metaStateOperators)
|
||||
@JoinColumn({ name: "metaStateId" })
|
||||
metaState: MetaState;
|
||||
}
|
||||
52
src/entities/MetaWorkflow.ts
Normal file
52
src/entities/MetaWorkflow.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { Entity, Column, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { MetaState } from "./MetaState";
|
||||
|
||||
@Entity("metaWorkflow")
|
||||
export class MetaWorkflow extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อ flow",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ระบบ", //PLACEMENT
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
category: string;
|
||||
|
||||
@OneToMany(() => MetaState, (metaState) => metaState.metaWorkflow)
|
||||
metaStates: MetaState[];
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อระบบ", //สอบคัดเลือก
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
sysName: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อระดับ",
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
posLevelName: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อประเภท",
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
posTypeName: string;
|
||||
|
||||
// @OneToMany(() => metaStateOperatorUser, (metaStateOperatorUser) => metaStateOperatorUser.metaWorkflow)
|
||||
// metaStateOperatorUsers: metaStateOperatorUser[];
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import { Position } from "./Position";
|
|||
import { PosDict } from "./PosDict";
|
||||
import { Profile } from "./Profile";
|
||||
import { profile } from "console";
|
||||
import { Workflow } from "./Workflow";
|
||||
|
||||
enum PosLevelAuthority {
|
||||
HEAD = "HEAD",
|
||||
|
|
@ -56,6 +57,9 @@ export class PosLevel extends EntityBase {
|
|||
|
||||
@OneToMany(() => Profile, (profile) => profile.posLevel)
|
||||
profiles: Profile[];
|
||||
|
||||
// @OneToMany(() => Workflow, (workflow) => workflow.posLevel)
|
||||
// workflows: Workflow[];
|
||||
}
|
||||
|
||||
export class CreatePosLevel {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { PosLevel } from "./PosLevel";
|
|||
import { Position } from "./Position";
|
||||
import { PosDict } from "./PosDict";
|
||||
import { Profile } from "./Profile";
|
||||
import { Workflow } from "./Workflow";
|
||||
|
||||
@Entity("posType")
|
||||
export class PosType extends EntityBase {
|
||||
|
|
@ -34,6 +35,9 @@ export class PosType extends EntityBase {
|
|||
|
||||
@OneToMany(() => Profile, (profile) => profile.posType)
|
||||
profiles: Profile[];
|
||||
|
||||
// @OneToMany(() => Workflow, (workflow) => workflow.posType)
|
||||
// workflows: Workflow[];
|
||||
}
|
||||
|
||||
export class CreatePosType {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ import { ProfileDevelopment } from "./ProfileDevelopment";
|
|||
import { PermissionOrg } from "./PermissionOrg";
|
||||
import { CommandSend } from "./CommandSend";
|
||||
import { DevelopmentRequest } from "./DevelopmentRequest";
|
||||
import { StateOperatorUser } from "./StateOperatorUser";
|
||||
import { StateUserComment } from "./StateUserComment";
|
||||
|
||||
@Entity("profile")
|
||||
export class Profile extends EntityBase {
|
||||
|
|
@ -378,6 +380,12 @@ export class Profile extends EntityBase {
|
|||
@OneToMany(() => CommandSend, (v) => v.profile)
|
||||
commandSends: CommandSend[];
|
||||
|
||||
@OneToMany(() => StateOperatorUser, (v) => v.profile)
|
||||
stateOperatorUsers: StateOperatorUser[];
|
||||
|
||||
@OneToMany(() => StateUserComment, (v) => v.profile)
|
||||
stateUserComments: StateUserComment[];
|
||||
|
||||
@ManyToOne(() => PosLevel, (posLevel) => posLevel.profiles)
|
||||
@JoinColumn({ name: "posLevelId" })
|
||||
posLevel: PosLevel;
|
||||
|
|
|
|||
|
|
@ -192,9 +192,9 @@ export class CreateProfileDevelopment {
|
|||
isDevelopment10: boolean | null;
|
||||
// summary?: number | null;
|
||||
// point?: number | null;
|
||||
developmentTarget?: number | null;
|
||||
developmentResults?: number | null;
|
||||
developmentReport?: number | null;
|
||||
developmentTarget?: string | null;
|
||||
developmentResults?: string | null;
|
||||
developmentReport?: string | null;
|
||||
developmentProjects?: string[];
|
||||
}
|
||||
|
||||
|
|
@ -215,9 +215,9 @@ export class CreateProfileEmployeeDevelopment {
|
|||
isDevelopment10: boolean | null;
|
||||
// summary?: number | null;
|
||||
// point?: number | null;
|
||||
developmentTarget?: number | null;
|
||||
developmentResults?: number | null;
|
||||
developmentReport?: number | null;
|
||||
developmentTarget?: string | null;
|
||||
developmentResults?: string | null;
|
||||
developmentReport?: string | null;
|
||||
developmentProjects?: string[];
|
||||
}
|
||||
|
||||
|
|
@ -237,8 +237,8 @@ export type UpdateProfileDevelopment = {
|
|||
isDevelopment10: boolean | null;
|
||||
// summary?: number | null;
|
||||
// point?: number | null;
|
||||
developmentTarget?: number | null;
|
||||
developmentResults?: number | null;
|
||||
developmentReport?: number | null;
|
||||
developmentTarget?: string | null;
|
||||
developmentResults?: string | null;
|
||||
developmentReport?: string | null;
|
||||
developmentProjects?: string[];
|
||||
};
|
||||
|
|
|
|||
49
src/entities/State.ts
Normal file
49
src/entities/State.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { StateOperator } from "./StateOperator";
|
||||
import { Workflow } from "./Workflow";
|
||||
import { StateUserComment } from "./StateUserComment";
|
||||
|
||||
@Entity("state")
|
||||
export class State extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อประเภทขั้นตอน",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ประเภทขั้นตอน",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
type: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ลำดับ",
|
||||
default: null,
|
||||
})
|
||||
order: number;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง workflow",
|
||||
default: null,
|
||||
})
|
||||
workflowId: string;
|
||||
|
||||
@ManyToOne(() => Workflow, (workflow) => workflow.states)
|
||||
@JoinColumn({ name: "workflowId" })
|
||||
workflow: Workflow;
|
||||
|
||||
@OneToMany(() => StateOperator, (stateOperator) => stateOperator.state)
|
||||
stateOperators: StateOperator[];
|
||||
|
||||
@OneToMany(() => StateUserComment, (stateUserComment) => stateUserComment.state)
|
||||
stateUserComments: StateUserComment[];
|
||||
}
|
||||
75
src/entities/StateOperator.ts
Normal file
75
src/entities/StateOperator.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { State } from "./State";
|
||||
import { StateOperatorUser } from "./StateOperatorUser";
|
||||
|
||||
@Entity("stateOperator")
|
||||
export class StateOperator extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ผู้ดำเนินการ",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
operator: string;
|
||||
|
||||
@Column({
|
||||
comment: "ดูเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canView: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "แก้ไขเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canUpdate: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ลบเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canDelete: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ยกเลิกเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canCancel: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ดำเนินการเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canOperate: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "เปลี่ยนสถานะเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canChangeState: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "แสดงความเห็นเอกสาร",
|
||||
default: false,
|
||||
})
|
||||
canComment: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "ลงนามอนุมัติ",
|
||||
default: false,
|
||||
})
|
||||
canSign: boolean;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง state",
|
||||
default: null,
|
||||
})
|
||||
stateId: string;
|
||||
|
||||
@ManyToOne(() => State, (state) => state.stateOperators)
|
||||
@JoinColumn({ name: "stateId" })
|
||||
state: State;
|
||||
}
|
||||
48
src/entities/StateOperatorUser.ts
Normal file
48
src/entities/StateOperatorUser.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { StateOperator } from "./StateOperator";
|
||||
import { Workflow } from "./Workflow";
|
||||
import { Profile } from "./Profile";
|
||||
|
||||
@Entity("stateOperatorUser")
|
||||
export class StateOperatorUser extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ผู้ดำเนินการ",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
operator: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ลำดับ",
|
||||
default: null,
|
||||
})
|
||||
order: number;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง workflow",
|
||||
default: null,
|
||||
})
|
||||
workflowId: string;
|
||||
|
||||
@ManyToOne(() => Workflow, (workflow) => workflow.stateOperatorUsers)
|
||||
@JoinColumn({ name: "workflowId" })
|
||||
workflow: Workflow;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง profile",
|
||||
type: "uuid",
|
||||
default: null,
|
||||
})
|
||||
profileId: string;
|
||||
|
||||
@ManyToOne(() => Profile, (profile) => profile.stateOperatorUsers)
|
||||
@JoinColumn({ name: "profileId" })
|
||||
profile: Profile;
|
||||
}
|
||||
79
src/entities/StateUserComment.ts
Normal file
79
src/entities/StateUserComment.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { State } from "./State";
|
||||
import { Profile } from "./Profile";
|
||||
|
||||
@Entity("stateUserComment")
|
||||
export class StateUserComment extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "เลือกรับทราบ",
|
||||
default: null,
|
||||
})
|
||||
isAccept: boolean;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "เลือกพิจารณา",
|
||||
default: null,
|
||||
})
|
||||
isApprove: boolean;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "แสดงความคิดเห็น",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
reason: string;
|
||||
|
||||
@Column({
|
||||
comment: "เลือกรับทราบ",
|
||||
default: false,
|
||||
})
|
||||
isAcceptSetting: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "เลือกพิจารณา",
|
||||
default: false,
|
||||
})
|
||||
isApproveSetting: boolean;
|
||||
|
||||
@Column({
|
||||
comment: "แสดงความคิดเห็น",
|
||||
default: false,
|
||||
})
|
||||
isReasonSetting: boolean;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ลำดับ",
|
||||
default: null,
|
||||
})
|
||||
order: number;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง state",
|
||||
default: null,
|
||||
})
|
||||
stateId: string;
|
||||
|
||||
@ManyToOne(() => State, (state) => state.stateUserComments)
|
||||
@JoinColumn({ name: "stateId" })
|
||||
state: State;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 40,
|
||||
comment: "คีย์นอก(FK)ของตาราง profile",
|
||||
type: "uuid",
|
||||
default: null,
|
||||
})
|
||||
profileId: string;
|
||||
|
||||
@ManyToOne(() => Profile, (profile) => profile.stateUserComments)
|
||||
@JoinColumn({ name: "profileId" })
|
||||
profile: Profile;
|
||||
}
|
||||
69
src/entities/Workflow.ts
Normal file
69
src/entities/Workflow.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { Entity, Column, OneToMany } from "typeorm";
|
||||
import { EntityBase } from "./base/Base";
|
||||
import { State } from "./State";
|
||||
import { StateOperatorUser } from "./StateOperatorUser";
|
||||
|
||||
@Entity("workflow")
|
||||
export class Workflow extends EntityBase {
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "refIdw",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
refId: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อ flow",
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ระบบ", //PLACEMENT
|
||||
length: 255,
|
||||
default: null,
|
||||
})
|
||||
category: string;
|
||||
|
||||
@OneToMany(() => State, (state) => state.workflow)
|
||||
states: State[];
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อระบบ", //สอบคัดเลือก
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
sysName: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อระดับ",
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
posLevelName: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "id state",
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
stateId: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
comment: "ชื่อประเภท",
|
||||
length: 100,
|
||||
default: null,
|
||||
})
|
||||
posTypeName: string;
|
||||
|
||||
@OneToMany(() => StateOperatorUser, (stateOperatorUser) => stateOperatorUser.workflow)
|
||||
stateOperatorUsers: StateOperatorUser[];
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ class CallAPI {
|
|||
}
|
||||
}
|
||||
//Post
|
||||
public async PostData(request: any, @Path() path: any, sendData: any) {
|
||||
public async PostData(request: any, @Path() path: any, sendData: any, log = true) {
|
||||
const token = "Bearer " + request.headers.authorization.replace("Bearer ", "");
|
||||
const url = process.env.API_URL + path;
|
||||
try {
|
||||
|
|
@ -52,7 +52,7 @@ class CallAPI {
|
|||
api_key: process.env.API_KEY,
|
||||
},
|
||||
});
|
||||
addLogSequence(request, {
|
||||
if (log) addLogSequence(request, {
|
||||
action: "request",
|
||||
status: "success",
|
||||
description: "connected",
|
||||
|
|
@ -65,7 +65,7 @@ class CallAPI {
|
|||
});
|
||||
return response.data.result;
|
||||
} catch (error) {
|
||||
addLogSequence(request, {
|
||||
if (log) addLogSequence(request, {
|
||||
action: "request",
|
||||
status: "error",
|
||||
description: "unconnected",
|
||||
|
|
@ -76,10 +76,10 @@ class CallAPI {
|
|||
response: JSON.stringify(error),
|
||||
},
|
||||
});
|
||||
console.log(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//Post
|
||||
public async PostDataKeycloak(@Path() path: any, sendData: any) {
|
||||
// const token = request.headers.authorization;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class CheckAuth {
|
|||
return await new CallAPI()
|
||||
.GetData(req, `/org/permission/org/${system}/${action}`)
|
||||
.then(async (x) => {
|
||||
console.log(x);
|
||||
let privilege = x.privilege;
|
||||
// if (action.trim().toLocaleUpperCase() == "CREATE")
|
||||
// privilege = await this.PermissionCreate(req, system);
|
||||
|
|
@ -84,7 +83,16 @@ class CheckAuth {
|
|||
} else if (x.orgChild4Id == null) {
|
||||
node = 3;
|
||||
}
|
||||
if (privilege == "ROOT") {
|
||||
if (privilege == "OWNER") {
|
||||
data = {
|
||||
root: null,
|
||||
child1: null,
|
||||
child2: null,
|
||||
child3: null,
|
||||
child4: null,
|
||||
privilege: "OWNER",
|
||||
};
|
||||
} else if (privilege == "ROOT") {
|
||||
data = {
|
||||
root: [x.orgRootId],
|
||||
child1: null,
|
||||
|
|
@ -112,15 +120,6 @@ class CheckAuth {
|
|||
privilege: "NORMAL",
|
||||
};
|
||||
} else if (privilege == "SPECIFIC") {
|
||||
} else if (privilege == "OWNER") {
|
||||
data = {
|
||||
root: null,
|
||||
child1: null,
|
||||
child2: null,
|
||||
child3: null,
|
||||
child4: null,
|
||||
privilege: "OWNER",
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -209,3 +209,93 @@ export function addLogSequence(req: RequestWithUser, data: LogSequence) {
|
|||
export function editLogSequence(req: RequestWithUser, index: number, data: LogSequence) {
|
||||
req.app.locals.logData.sequence[index] = data;
|
||||
}
|
||||
|
||||
export function commandTypePath(commandCode: string): string | null {
|
||||
switch (commandCode) {
|
||||
case "C-PM-01":
|
||||
return "/placement/recruit/report";
|
||||
case "C-PM-02":
|
||||
return "/placement/candidate/report";
|
||||
case "C-PM-03":
|
||||
return "/placement/appoint/report";
|
||||
case "C-PM-04":
|
||||
return "/placement/move/report";
|
||||
case "C-PM-05":
|
||||
return "/placement/appointment/appoint/report";
|
||||
case "C-PM-06":
|
||||
return "/placement/appointment/slip/report";
|
||||
case "C-PM-07":
|
||||
return "/placement/appointment/move/report";
|
||||
case "C-PM-08":
|
||||
return "/retirement/other/appoint/report";
|
||||
case "C-PM-09":
|
||||
return "/retirement/other/out/report";
|
||||
case "C-PM-10":
|
||||
return "/xxxxxx";
|
||||
case "C-PM-11":
|
||||
return "/probation/report/command11/officer/report";
|
||||
case "C-PM-12":
|
||||
return "/probation/report/command12/officer/report";
|
||||
case "C-PM-13":
|
||||
return "/placement/transfer/command/report";
|
||||
case "C-PM-14":
|
||||
return "/placement/Receive/command/report";
|
||||
case "C-PM-15":
|
||||
return "/placement/officer/command/report";
|
||||
case "C-PM-16":
|
||||
return "/placement/repatriation/command/report";
|
||||
case "C-PM-17":
|
||||
return "/retirement/resign/command/report";
|
||||
case "C-PM-18":
|
||||
return "/retirement/out/command/report";
|
||||
case "C-PM-19":
|
||||
return "/discipline/result/command19/report";
|
||||
case "C-PM-20":
|
||||
return "/discipline/result/command20/report";
|
||||
case "C-PM-21":
|
||||
return "/org/command/command21/employee/report";
|
||||
case "C-PM-22":
|
||||
return "/placement/appointment/employee-appoint/report";
|
||||
case "C-PM-23":
|
||||
return "/retirement/resign/employee/report";
|
||||
case "C-PM-24":
|
||||
return "/placement/appointment/employee-move/report";
|
||||
case "C-PM-25":
|
||||
return "/discipline/result/command25/report";
|
||||
case "C-PM-26":
|
||||
return "/discipline/result/command26/report";
|
||||
case "C-PM-27":
|
||||
return "/discipline/result/command27/report";
|
||||
case "C-PM-28":
|
||||
return "/discipline/result/command28/report";
|
||||
case "C-PM-29":
|
||||
return "/discipline/result/command29/report";
|
||||
case "C-PM-30":
|
||||
return "/discipline/result/command30/report";
|
||||
case "C-PM-31":
|
||||
return "/discipline/result/command31/report";
|
||||
case "C-PM-32":
|
||||
return "/discipline/result/command32/report";
|
||||
case "C-PM-33":
|
||||
return "/salary/report/command/officer/report";
|
||||
case "C-PM-34":
|
||||
return "/salary/report/command/officer/report";
|
||||
case "C-PM-35":
|
||||
return "/salary/report/command/officer/report";
|
||||
case "C-PM-36":
|
||||
return "/salary/report/command/employee/report";
|
||||
case "C-PM-37":
|
||||
return "/salary/report/command/employee/report";
|
||||
case "C-PM-38":
|
||||
return "/org/command/command38/officer/report";
|
||||
case "C-PM-39":
|
||||
return "/placement/slip/report";
|
||||
case "C-PM-40":
|
||||
return "/org/command/command40/officer/report";
|
||||
case "C-PM-41":
|
||||
return "/retirement/resign/leave-cancel/report";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export async function createUser(username: string, password: string, opts?: Reco
|
|||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
enabled: true,
|
||||
credentials: [{ type: "password", value: password }],
|
||||
credentials: [{ type: "password", value: password ,temporary: false,}],
|
||||
username,
|
||||
...opts,
|
||||
}),
|
||||
|
|
@ -168,6 +168,69 @@ export async function getUserCount(first = "", max = "", search = "") {
|
|||
return await res.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keycloak user list
|
||||
*
|
||||
* Client must have permission to manage realm's user
|
||||
*
|
||||
* @returns user list if success, false otherwise.
|
||||
*/
|
||||
export async function getUserListOrg(first = "", max = "", search = "", userIds: string[] = []) {
|
||||
const userIdsParam = userIds.join(",");
|
||||
const res = await fetch(
|
||||
// `${KC_URL}/admin/realms/${KC_REALM}/users`.concat(!!search ? `?search=${search}` : ""),
|
||||
`${KC_URL}/admin/realms/${KC_REALM}/users?first=${first || "0"}&max=${max || "-1"}${search ? `&search=${search}` : ""}${userIdsParam ? `&id=${userIdsParam}` : ""}`,
|
||||
{
|
||||
// prettier-ignore
|
||||
headers: {
|
||||
"authorization": `Bearer ${await getToken()}`,
|
||||
"content-type": `application/json`,
|
||||
},
|
||||
},
|
||||
).catch((e) => console.log("Keycloak Error: ", e));
|
||||
|
||||
if (!res) return false;
|
||||
if (!res.ok) {
|
||||
return Boolean(console.error("Keycloak Error Response: ", await res.json()));
|
||||
}
|
||||
|
||||
return ((await res.json()) as any[]).map((v: Record<string, string>) => ({
|
||||
id: v.id,
|
||||
username: v.username,
|
||||
firstName: v.firstName,
|
||||
lastName: v.lastName,
|
||||
email: v.email,
|
||||
enabled: v.enabled,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function getUserCountOrg(first = "", max = "", search = "", userIds: string[] = []) {
|
||||
console.log(userIds);
|
||||
const userIdsParam = userIds.join(",");
|
||||
console.log(userIdsParam);
|
||||
console.log("xxxxxxxxxxxxxxxxx");
|
||||
console.log(
|
||||
`${KC_URL}/admin/realms/${KC_REALM}/users/count?first=${first || "0"}&max=${max || "-1"}${search ? `&search=${search}` : ""}${userIdsParam && userIdsParam != "" ? `&id=${userIdsParam}` : ""}`,
|
||||
);
|
||||
console.log("aaaaaaaaaaaaaaaaaa");
|
||||
const res = await fetch(
|
||||
`${KC_URL}/admin/realms/${KC_REALM}/users/count?first=${first || "0"}&max=${max || "-1"}${search ? `&search=${search}` : ""}${userIdsParam && userIdsParam != "" ? `&id=${userIdsParam}` : ""}`,
|
||||
{
|
||||
headers: {
|
||||
authorization: `Bearer ${await getToken()}`,
|
||||
"content-type": `application/json`,
|
||||
},
|
||||
},
|
||||
).catch((e) => console.log("Keycloak Error: ", e));
|
||||
|
||||
if (!res) return false;
|
||||
if (!res.ok) {
|
||||
return Boolean(console.error("Keycloak Error Response: ", await res.json()));
|
||||
}
|
||||
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update keycloak user by uuid
|
||||
*
|
||||
|
|
|
|||
28
src/migration/1728399911271-add_table_workflow.ts
Normal file
28
src/migration/1728399911271-add_table_workflow.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow1728399911271 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow1728399911271'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE \`stateOperator\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`operator\` varchar(255) NULL COMMENT 'ผู้ดำเนินการ', \`canView\` tinyint NOT NULL COMMENT 'ดูเอกสาร' DEFAULT 0, \`canUpdate\` tinyint NOT NULL COMMENT 'แก้ไขเอกสาร' DEFAULT 0, \`canDelete\` tinyint NOT NULL COMMENT 'ลบเอกสาร' DEFAULT 0, \`canCancel\` tinyint NOT NULL COMMENT 'ยกเลิกเอกสาร' DEFAULT 0, \`canOperate\` tinyint NOT NULL COMMENT 'ดำเนินการเอกสาร' DEFAULT 0, \`canChangeState\` tinyint NOT NULL COMMENT 'เปลี่ยนสถานะเอกสาร' DEFAULT 0, \`canComment\` tinyint NOT NULL COMMENT 'แสดงความเห็นเอกสาร' DEFAULT 0, \`canSign\` tinyint NOT NULL COMMENT 'ลงนามอนุมัติ' DEFAULT 0, \`stateId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง state', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`CREATE TABLE \`state\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อประเภทขั้นตอน', \`type\` varchar(255) NULL COMMENT 'ประเภทขั้นตอน', \`order\` varchar(255) NULL COMMENT 'ลำดับ', \`workflowId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง workflow', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`CREATE TABLE \`workflow\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อ flow', \`category\` varchar(255) NULL COMMENT 'ระบบ', \`commandSysId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง commandSys', \`posLevelId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posLevel', \`posTypeId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posType', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperator\` ADD CONSTRAINT \`FK_72292e09e5c83c34016a4b17ce4\` FOREIGN KEY (\`stateId\`) REFERENCES \`state\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` ADD CONSTRAINT \`FK_fad8656b57142ed4a41584057a7\` FOREIGN KEY (\`workflowId\`) REFERENCES \`workflow\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_248dca7108cc3ba484d7eac2bc2\` FOREIGN KEY (\`commandSysId\`) REFERENCES \`commandSys\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_0eadcb967c5bdb18867395b8bf9\` FOREIGN KEY (\`posLevelId\`) REFERENCES \`posLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_77889a7cde943b64fc28dd06025\` FOREIGN KEY (\`posTypeId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_77889a7cde943b64fc28dd06025\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_0eadcb967c5bdb18867395b8bf9\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_248dca7108cc3ba484d7eac2bc2\``);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` DROP FOREIGN KEY \`FK_fad8656b57142ed4a41584057a7\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperator\` DROP FOREIGN KEY \`FK_72292e09e5c83c34016a4b17ce4\``);
|
||||
await queryRunner.query(`DROP TABLE \`workflow\``);
|
||||
await queryRunner.query(`DROP TABLE \`state\``);
|
||||
await queryRunner.query(`DROP TABLE \`stateOperator\``);
|
||||
}
|
||||
|
||||
}
|
||||
30
src/migration/1728442861469-add_table_workflow1.ts
Normal file
30
src/migration/1728442861469-add_table_workflow1.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow11728442861469 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow11728442861469'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_0eadcb967c5bdb18867395b8bf9\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_248dca7108cc3ba484d7eac2bc2\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP FOREIGN KEY \`FK_77889a7cde943b64fc28dd06025\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`commandSysId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`posLevelId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`posTypeId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`commandSysName\` varchar(100) NULL COMMENT 'ชื่อระบบ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`posLevelName\` varchar(100) NULL COMMENT 'ชื่อระดับ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`posTypeName\` varchar(100) NULL COMMENT 'ชื่อประเภท'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`posTypeName\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`posLevelName\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`commandSysName\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`posTypeId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posType'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`posLevelId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posLevel'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`commandSysId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง commandSys'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_77889a7cde943b64fc28dd06025\` FOREIGN KEY (\`posTypeId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_248dca7108cc3ba484d7eac2bc2\` FOREIGN KEY (\`commandSysId\`) REFERENCES \`commandSys\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD CONSTRAINT \`FK_0eadcb967c5bdb18867395b8bf9\` FOREIGN KEY (\`posLevelId\`) REFERENCES \`posLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
}
|
||||
26
src/migration/1728456793035-add_table_workflow2.ts
Normal file
26
src/migration/1728456793035-add_table_workflow2.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow21728456793035 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow21728456793035'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` CHANGE \`commandSysName\` \`sysName\` varchar(100) NULL COMMENT 'ชื่อระบบ'`);
|
||||
await queryRunner.query(`CREATE TABLE \`stateOperatorUser\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`profile\` varchar(255) NULL, \`type\` varchar(255) NULL, \`order\` int NULL COMMENT 'ลำดับ', \`stateOperatorId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง stateOperator', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`ALTER TABLE \`command\` DROP COLUMN \`isBangkok\``);
|
||||
await queryRunner.query(`ALTER TABLE \`command\` ADD \`isBangkok\` varchar(20) NULL COMMENT 'คำสั่งกรุงเทพมหานคร'`);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` DROP COLUMN \`order\``);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` ADD \`order\` int NULL COMMENT 'ลำดับ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD CONSTRAINT \`FK_bef7391c37f03a3b809406beebf\` FOREIGN KEY (\`stateOperatorId\`) REFERENCES \`stateOperator\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP FOREIGN KEY \`FK_bef7391c37f03a3b809406beebf\``);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` DROP COLUMN \`order\``);
|
||||
await queryRunner.query(`ALTER TABLE \`state\` ADD \`order\` varchar(255) NULL COMMENT 'ลำดับ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`command\` DROP COLUMN \`isBangkok\``);
|
||||
await queryRunner.query(`ALTER TABLE \`command\` ADD \`isBangkok\` tinyint NULL COMMENT 'คำสั่งกรุงเทพมหานคร'`);
|
||||
await queryRunner.query(`DROP TABLE \`stateOperatorUser\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` CHANGE \`sysName\` \`commandSysName\` varchar(100) NULL COMMENT 'ชื่อระบบ'`);
|
||||
}
|
||||
|
||||
}
|
||||
26
src/migration/1728465477520-add_table_workflow3.ts
Normal file
26
src/migration/1728465477520-add_table_workflow3.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow31728465477520 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow31728465477520'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP FOREIGN KEY \`FK_bef7391c37f03a3b809406beebf\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`stateOperatorId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`type\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`operator\` varchar(255) NULL COMMENT 'ผู้ดำเนินการ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`refId\` varchar(255) NULL COMMENT 'ผู้ดำเนินการ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`workflowId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง workflow'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD CONSTRAINT \`FK_9499ff9ae0444f59f19800aca05\` FOREIGN KEY (\`workflowId\`) REFERENCES \`workflow\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP FOREIGN KEY \`FK_9499ff9ae0444f59f19800aca05\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`workflowId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`refId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`operator\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`type\` varchar(255) NULL`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`stateOperatorId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง stateOperator'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD CONSTRAINT \`FK_bef7391c37f03a3b809406beebf\` FOREIGN KEY (\`stateOperatorId\`) REFERENCES \`stateOperator\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
}
|
||||
22
src/migration/1728618339457-add_table_workflow4.ts
Normal file
22
src/migration/1728618339457-add_table_workflow4.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow41728618339457 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow41728618339457'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE \`metaStateOperator\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`operator\` varchar(255) NULL COMMENT 'ผู้ดำเนินการ', \`canView\` tinyint NOT NULL COMMENT 'ดูเอกสาร' DEFAULT 0, \`canUpdate\` tinyint NOT NULL COMMENT 'แก้ไขเอกสาร' DEFAULT 0, \`canDelete\` tinyint NOT NULL COMMENT 'ลบเอกสาร' DEFAULT 0, \`canCancel\` tinyint NOT NULL COMMENT 'ยกเลิกเอกสาร' DEFAULT 0, \`canOperate\` tinyint NOT NULL COMMENT 'ดำเนินการเอกสาร' DEFAULT 0, \`canChangeState\` tinyint NOT NULL COMMENT 'เปลี่ยนสถานะเอกสาร' DEFAULT 0, \`canComment\` tinyint NOT NULL COMMENT 'แสดงความเห็นเอกสาร' DEFAULT 0, \`canSign\` tinyint NOT NULL COMMENT 'ลงนามอนุมัติ' DEFAULT 0, \`metaStateId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง metaState', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`CREATE TABLE \`metaState\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อประเภทขั้นตอน', \`type\` varchar(255) NULL COMMENT 'ประเภทขั้นตอน', \`order\` int NULL COMMENT 'ลำดับ', \`metaWorkflowId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง metaWorkflow', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`CREATE TABLE \`metaWorkflow\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'ชื่อ flow', \`category\` varchar(255) NULL COMMENT 'ระบบ', \`sysName\` varchar(100) NULL COMMENT 'ชื่อระบบ', \`posLevelName\` varchar(100) NULL COMMENT 'ชื่อระดับ', \`posTypeName\` varchar(100) NULL COMMENT 'ชื่อประเภท', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`ALTER TABLE \`metaStateOperator\` ADD CONSTRAINT \`FK_b7489ef0f2b87666caecaadeb1e\` FOREIGN KEY (\`metaStateId\`) REFERENCES \`metaState\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`metaState\` ADD CONSTRAINT \`FK_73a4a241baa54b4e454f6914e4a\` FOREIGN KEY (\`metaWorkflowId\`) REFERENCES \`metaWorkflow\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`metaState\` DROP FOREIGN KEY \`FK_73a4a241baa54b4e454f6914e4a\``);
|
||||
await queryRunner.query(`ALTER TABLE \`metaStateOperator\` DROP FOREIGN KEY \`FK_b7489ef0f2b87666caecaadeb1e\``);
|
||||
await queryRunner.query(`DROP TABLE \`metaWorkflow\``);
|
||||
await queryRunner.query(`DROP TABLE \`metaState\``);
|
||||
await queryRunner.query(`DROP TABLE \`metaStateOperator\``);
|
||||
}
|
||||
|
||||
}
|
||||
14
src/migration/1729044078594-add_table_workflow5.ts
Normal file
14
src/migration/1729044078594-add_table_workflow5.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow51729044078594 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow51729044078594'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`stateId\` varchar(100) NULL COMMENT 'id state'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`stateId\``);
|
||||
}
|
||||
|
||||
}
|
||||
26
src/migration/1729047708690-add_table_workflow6.ts
Normal file
26
src/migration/1729047708690-add_table_workflow6.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow61729047708690 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow61729047708690'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` CHANGE \`profile\` \`profileId\` varchar(255) NULL`);
|
||||
await queryRunner.query(`CREATE TABLE \`stateUserComment\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`isAccept\` tinyint NULL COMMENT 'เลือกรับทราบ', \`isApprove\` tinyint NULL COMMENT 'เลือกพิจารณา', \`reason\` varchar(255) NULL COMMENT 'แสดงความคิดเห็น', \`isAcceptSetting\` tinyint NOT NULL COMMENT 'เลือกรับทราบ' DEFAULT 0, \`isApproveSetting\` tinyint NOT NULL COMMENT 'เลือกพิจารณา' DEFAULT 0, \`isReasonSetting\` tinyint NOT NULL COMMENT 'แสดงความคิดเห็น' DEFAULT 0, \`order\` int NULL COMMENT 'ลำดับ', \`stateId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง state', \`profileId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง profile', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`profileId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`profileId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง profile'`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateUserComment\` ADD CONSTRAINT \`FK_f6ed25f165eb356ea5499484452\` FOREIGN KEY (\`stateId\`) REFERENCES \`state\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateUserComment\` ADD CONSTRAINT \`FK_f83cf9aef7ece2cddc2bb7c5a55\` FOREIGN KEY (\`profileId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD CONSTRAINT \`FK_f64285e5016ad2932f38c8687a1\` FOREIGN KEY (\`profileId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP FOREIGN KEY \`FK_f64285e5016ad2932f38c8687a1\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateUserComment\` DROP FOREIGN KEY \`FK_f83cf9aef7ece2cddc2bb7c5a55\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateUserComment\` DROP FOREIGN KEY \`FK_f6ed25f165eb356ea5499484452\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`profileId\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`profileId\` varchar(255) NULL`);
|
||||
await queryRunner.query(`DROP TABLE \`stateUserComment\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` CHANGE \`profileId\` \`profile\` varchar(255) NULL`);
|
||||
}
|
||||
|
||||
}
|
||||
16
src/migration/1729055668134-add_table_workflow7.ts
Normal file
16
src/migration/1729055668134-add_table_workflow7.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow71729055668134 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow71729055668134'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`refId\` varchar(255) NULL COMMENT 'refIdw'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`system\` varchar(255) NULL COMMENT 'system'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`system\``);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`refId\``);
|
||||
}
|
||||
|
||||
}
|
||||
16
src/migration/1729073909711-add_table_workflow8.ts
Normal file
16
src/migration/1729073909711-add_table_workflow8.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTableWorkflow81729073909711 implements MigrationInterface {
|
||||
name = 'AddTableWorkflow81729073909711'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` DROP COLUMN \`system\``);
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` DROP COLUMN \`refId\``);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE \`stateOperatorUser\` ADD \`refId\` varchar(255) NULL COMMENT 'ผู้ดำเนินการ'`);
|
||||
await queryRunner.query(`ALTER TABLE \`workflow\` ADD \`system\` varchar(255) NULL COMMENT 'system'`);
|
||||
}
|
||||
|
||||
}
|
||||
126
src/services/rabbitmq.ts
Normal file
126
src/services/rabbitmq.ts
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
import amqp from "amqplib";
|
||||
import { AppDataSource } from "../database/data-source";
|
||||
import { Command } from "../entities/Command";
|
||||
import { commandTypePath } from "../interfaces/utils";
|
||||
import CallAPI from "../interfaces/call-api";
|
||||
import HttpError from "../interfaces/http-error";
|
||||
import HttpStatusCode from "../interfaces/http-status";
|
||||
import { RequestWithUser } from "../middlewares/user";
|
||||
|
||||
export let sendToQueue: (payload: any) => void;
|
||||
|
||||
export async function init() { //----> (1) Producer
|
||||
if (!process.env.AMQ_URL || !process.env.AMQ_QUEUE) return;
|
||||
|
||||
const { AMQ_URL: url, AMQ_QUEUE: queue } = process.env; //----> (1.2) get url and queue from .env
|
||||
|
||||
const connection = await amqp.connect(url); //----> (1.3) set up url with amqp protocol
|
||||
|
||||
const channel = await connection.createChannel(); //----> (1.4) create Channel
|
||||
|
||||
channel.assertQueue(queue, { durable: true }); //----> (1.5) assert queue and set durable (if "true" save to disk on RabbitMQ)
|
||||
channel.prefetch(1);
|
||||
|
||||
sendToQueue = (payload: any, persistent = true) => { //----> (2) sendQueue To RabbitMQ and set persistent (if "true" redo the failed queue when server run again)
|
||||
channel.sendToQueue(queue, Buffer.from(JSON.stringify(payload)), {
|
||||
persistent,
|
||||
});
|
||||
};
|
||||
|
||||
console.log("[AMQ] Listening for message...");
|
||||
|
||||
createConsumer(queue, channel, handler); //----> (3) Process Consumer
|
||||
// createConsumer(queue1, channel, handler1);
|
||||
// createConsumer(queue2, channel, handler2);
|
||||
}
|
||||
|
||||
function createConsumer( //----> consumer
|
||||
queue: string,
|
||||
channel: amqp.Channel,
|
||||
handler: (msg: amqp.ConsumeMessage) => Promise<boolean> | boolean,
|
||||
) {
|
||||
channel.consume(
|
||||
queue,
|
||||
async (msg) => {
|
||||
if (!msg) return;
|
||||
|
||||
if (await handler(msg)) return channel.ack(msg);
|
||||
|
||||
return await new Promise((resolve) => setTimeout(() => resolve(channel.nack(msg)), 3000));
|
||||
},
|
||||
{ noAck: false },
|
||||
);
|
||||
}
|
||||
|
||||
async function handler(msg: amqp.ConsumeMessage): Promise<boolean> { //----> condition before process consumer
|
||||
const repo = AppDataSource.getRepository(Command);
|
||||
const { data, token, user } = JSON.parse(msg.content.toString());
|
||||
|
||||
const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = data;
|
||||
|
||||
const command = await repo.findOne({
|
||||
where: { id: id },
|
||||
relations: ["commandType", "commandRecives"],
|
||||
});
|
||||
|
||||
if (!command) return true;
|
||||
|
||||
const path = commandTypePath(command.commandType.code);
|
||||
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
|
||||
|
||||
return await new CallAPI()
|
||||
.PostData(
|
||||
{
|
||||
headers: { authorization: token }, //time bomb
|
||||
},
|
||||
path + "/excecute",
|
||||
{
|
||||
refIds: command.commandRecives
|
||||
.filter((x) => x.refId != null)
|
||||
.map((x) => ({
|
||||
refId: x.refId,
|
||||
commandAffectDate: command.commandAffectDate,
|
||||
commandNo: command.commandNo,
|
||||
commandYear: command.commandYear,
|
||||
templateDoc: command.positionDetail,
|
||||
amount: x.amount,
|
||||
positionSalaryAmount: x.positionSalaryAmount,
|
||||
mouthSalaryAmount: x.mouthSalaryAmount,
|
||||
})),
|
||||
},
|
||||
false,
|
||||
)
|
||||
.then(async (res) => {
|
||||
console.log("[AMQ] Excecute Command Success");
|
||||
Object.assign(command, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt });
|
||||
const result = await repo.save(command).catch((e) => console.log(e));
|
||||
if (result) return true;
|
||||
return false;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// async function handler(msg: amqp.ConsumeMessage): Promise<boolean> { //----> condition before process consumer
|
||||
// const repo = AppDataSource.getRepository(Command);
|
||||
|
||||
// const { id, status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt } = JSON.parse(
|
||||
// msg.content.toString(),
|
||||
// );
|
||||
|
||||
// const record = await repo.findOne({
|
||||
// where: { id },
|
||||
// });
|
||||
|
||||
// if (!record) return true;
|
||||
|
||||
// Object.assign(record, { status, lastUpdateUserId, lastUpdateFullName, lastUpdatedAt });
|
||||
|
||||
// const result = await repo.save(record).catch((e) => console.log(e));
|
||||
|
||||
// if (result) return true;
|
||||
|
||||
// return false;
|
||||
// }
|
||||
Loading…
Add table
Add a link
Reference in a new issue