This commit is contained in:
2025-07-03 17:02:07 +07:00
parent 838dea2515
commit 11c0ef2969

View File

@ -7,15 +7,22 @@ import { ILogObj, Logger } from "tslog";
import { Language } from "../langs/lang"; import { Language } from "../langs/lang";
import { Paging } from "entity"; import { Paging } from "entity";
import CommonHelper from "../helpers/common"; import CommonHelper from "../helpers/common";
import * as fastcsv from 'fast-csv'; import * as fastcsv from "fast-csv";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { Application } from "entity"; import { Application } from "entity";
const log: Logger<ILogObj> = new Logger({ name: '[ApplicationController]', type: 'pretty' }); const log: Logger<ILogObj> = new Logger({
name: "[ApplicationController]",
type: "pretty",
});
export class ApplicationController { export class ApplicationController {
static async list(req: Request, res: Response, next: NextFunction): Promise<Response> { static async list(
/* req: Request,
res: Response,
next: NextFunction
): Promise<Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.parameters['filter'] = { #swagger.parameters['filter'] = {
description: 'Filter with 2 format : <ul><li>Simple format use text plaint will filter eq:code or like %name%</li><li>Advance format using field existing {status:\'Y\', any:\'SAME AS PLAINT LOGIC\', etc...}</li></ul>', description: 'Filter with 2 format : <ul><li>Simple format use text plaint will filter eq:code or like %name%</li><li>Advance format using field existing {status:\'Y\', any:\'SAME AS PLAINT LOGIC\', etc...}</li></ul>',
@ -56,58 +63,79 @@ export class ApplicationController {
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
filter: Joi.string().allow('').optional().label('Filter'), filter: Joi.string().allow("").optional().label("Filter"),
page: Joi.number().required().min(1).label('Page'), page: Joi.number().required().min(1).label("Page"),
limit: Joi.number().required().min(1).label('Limit'), limit: Joi.number().required().min(1).label("Limit"),
with_deleted: Joi.bool().required().label('With Deleted'), with_deleted: Joi.bool().required().label("With Deleted"),
order_field: Joi.string().required().label('Order Field'), order_field: Joi.string().required().label("Order Field"),
order_direction: Joi.string().allow('asc', 'desc').required().label('Order Direction'), order_direction: Joi.string()
token: Joi.string().required().label('Token'), .allow("asc", "desc")
}); .required()
.label("Order Direction"),
token: Joi.string().required().label("Token"),
});
const param: Paging = await schema.validateAsync(req.query); const param: Paging = await schema.validateAsync(req.query);
const repo = OrmHelper.DB.getRepository(Application); const repo = OrmHelper.DB.getRepository(Application);
const offset = (param.page - 1) * param.limit const offset = (param.page - 1) * param.limit;
const { whereAttr, whereVal } = CommonHelper.handleFilter({ const { whereAttr, whereVal } = CommonHelper.handleFilter({
filter: param.filter, filter: param.filter,
col_any_eq: ['code'], col_any_eq: ["code"],
col_any_like: ['name'] col_any_like: ["name"],
}); });
const res_count = repo.createQueryBuilder() const res_count = repo.createQueryBuilder().where(whereAttr, whereVal);
.where(whereAttr, whereVal); const res_list = repo
const res_list = repo.createQueryBuilder() .createQueryBuilder()
.where(whereAttr, whereVal) .where(whereAttr, whereVal)
.orderBy(param.order_field, param.order_direction) .orderBy(param.order_field, param.order_direction)
.offset(offset) .offset(offset)
.limit(param.limit); .limit(param.limit);
if (param.with_deleted) { if (param.with_deleted) {
res_count.withDeleted(); res_count.withDeleted();
res_list.withDeleted(); res_list.withDeleted();
} }
const current_page = param.page; const current_page = param.page;
const total_count_data = await res_count.getCount(); const total_count_data = await res_count.getCount();
const list_data = await res_list.getMany(); const list_data = await res_list.getMany();
const count_data = CommonHelper.countObject(list_data); const count_data = CommonHelper.countObject(list_data);
return ReturnHelper.successResponselist(res, 200, Language.lang.success_view, count_data, current_page, total_count_data, list_data); return ReturnHelper.successResponselist(
} catch (e: unknown) { res,
log.error(e); 200,
const err = e as Error; Language.lang.success_view,
count_data,
current_page,
total_count_data,
list_data
);
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message); return ReturnHelper.errorResponse(
} res,
400,
401,
Language.lang.failed_view,
err.message
);
} }
}
static async export(req: Request, res: Response, next: NextFunction): Promise<void | Response> { static async export(
/* req: Request,
res: Response,
next: NextFunction
): Promise<void | Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.parameters['filter'] = { #swagger.parameters['filter'] = {
description: 'Filter with 2 format : <ul><li>Simple format use text plaint will filter eq:code or like %name%</li><li>Advance format using field existing {status:\'Y\', any:\'SAME AS PLAINT LOGIC\', etc...}</li></ul>', description: 'Filter with 2 format : <ul><li>Simple format use text plaint will filter eq:code or like %name%</li><li>Advance format using field existing {status:\'Y\', any:\'SAME AS PLAINT LOGIC\', etc...}</li></ul>',
@ -137,80 +165,90 @@ export class ApplicationController {
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
filter: Joi.string().allow('').optional().label('Filter'), filter: Joi.string().allow("").optional().label("Filter"),
order_field: Joi.string().required().label('Order Field'), order_field: Joi.string().required().label("Order Field"),
order_direction: Joi.string().allow('asc', 'desc').required().label('Order Direction'), order_direction: Joi.string()
token: Joi.string().required().label('Token'), .allow("asc", "desc")
}); .required()
.label("Order Direction"),
token: Joi.string().required().label("Token"),
});
const param: Paging = await schema.validateAsync(req.query); const param: Paging = await schema.validateAsync(req.query);
const repo = OrmHelper.DB.getRepository(Application); const repo = OrmHelper.DB.getRepository(Application);
const { whereAttr, whereVal } = CommonHelper.handleFilter({ const { whereAttr, whereVal } = CommonHelper.handleFilter({
filter: param.filter, filter: param.filter,
col_any_eq: ['code'], col_any_eq: ["code"],
col_any_like: ['name'] col_any_like: ["name"],
}); });
const filename = "application.csv"; const filename = "application.csv";
res.setHeader('Content-Type', 'text/csv'); res.setHeader("Content-Type", "text/csv");
res.setHeader('Content-Disposition', 'attachment; filename=' + filename); res.setHeader("Content-Disposition", "attachment; filename=" + filename);
const csvStream = fastcsv.format({ const csvStream = fastcsv.format({
headers: true, headers: true,
writeHeaders: true, writeHeaders: true,
transform: (row: Application): any => ({ transform: (row: Application): any => ({
...row, ...row,
created_at: dayjs(row.created_at).format('DD-MM-YYYY HH:MM:ss'), created_at: dayjs(row.created_at).format("DD-MM-YYYY HH:MM:ss"),
}) }),
}); });
csvStream.pipe(res); csvStream.pipe(res);
const limit = 50; const limit = 50;
const fetchAndWrite = async (page: any) => { const fetchAndWrite = async (page: any) => {
const offset = (page - 1) * limit const offset = (page - 1) * limit;
const data = await repo.createQueryBuilder() const data = await repo
.where(whereAttr, whereVal) .createQueryBuilder()
.select([ .where(whereAttr, whereVal)
'id', .select(["id", "code", "name", "status", "created_at"])
'code', .orderBy(param.order_field, param.order_direction)
'name', .offset(offset)
'status', .limit(limit)
'created_at']) .getRawMany();
.orderBy(param.order_field, param.order_direction)
.offset(offset)
.limit(limit).getRawMany();
if (CommonHelper.countObject(data) === 0) { if (CommonHelper.countObject(data) === 0) {
csvStream.end(); csvStream.end();
} else { } else {
data.forEach((item: any) => csvStream.write(item)); data.forEach((item: any) => csvStream.write(item));
if (CommonHelper.countObject(data) == limit) { if (CommonHelper.countObject(data) == limit) {
fetchAndWrite(page + 1); fetchAndWrite(page + 1);
} else { } else {
csvStream.end(); csvStream.end();
} }
}
};
fetchAndWrite(1);
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message);
} }
} };
static async create(req: Request, res: Response, next: NextFunction): Promise<Response> { fetchAndWrite(1);
/* } catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(
res,
400,
401,
Language.lang.failed_view,
err.message
);
}
}
static async create(
req: Request,
res: Response,
next: NextFunction
): Promise<Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.security = [{ #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
@ -228,35 +266,54 @@ export class ApplicationController {
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
id: Joi.string().max(32).required().label('ID'), id: Joi.string().max(32).required().label("ID"),
name: Joi.string().max(256).required().label('Name'), name: Joi.string().max(256).required().label("Name"),
reset_password_url: Joi.string().max(512).optional().allow('').label('Url reset password'), reset_password_url: Joi.string()
status: Joi.string().required().label('Status'), .max(512)
}); .optional()
.allow("")
.label("Url reset password"),
status: Joi.string().required().label("Status"),
});
const param: Application = await schema.validateAsync(req.body); const param: Application = await schema.validateAsync(req.body);
const data = new Application() const data = new Application();
data.id = param.id data.id = param.id;
data.name = param.name data.name = param.name;
data.reset_password_url = param.reset_password_url data.reset_password_url = param.reset_password_url;
data.status = param.status data.status = param.status;
await OrmHelper.DB.manager.save(data); await OrmHelper.DB.manager.save(data);
return ReturnHelper.successResponseAny(res, 200, Language.lang.success_insert, data); return ReturnHelper.successResponseAny(
} catch (e: unknown) { res,
log.error(e); 200,
const err = e as Error; Language.lang.success_insert,
data
);
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(res, 500, 401, Language.lang.failed_insert, err.message); return ReturnHelper.errorResponse(
} res,
500,
401,
Language.lang.failed_insert,
err.message
);
} }
}
static async update(req: Request, res: Response, next: NextFunction): Promise<Response> { static async update(
/* req: Request,
res: Response,
next: NextFunction
): Promise<Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.security = [{ #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
@ -280,42 +337,65 @@ export class ApplicationController {
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
name: Joi.string().max(256).required().label('Name'), name: Joi.string().max(256).required().label("Name"),
reset_password_url: Joi.string().max(512).optional().allow('').label('Url reset password'), reset_password_url: Joi.string()
status: Joi.string().required().label('Status'), .max(512)
}); .optional()
.allow("")
.label("Url reset password"),
status: Joi.string().required().label("Status"),
});
req.body.id = req.params['id']; const param: Application = await schema.validateAsync(req.params);
const param: Application = await schema.validateAsync(req.body); const repo = OrmHelper.DB.getRepository(Application);
const repo = OrmHelper.DB.getRepository(Application); const data = await repo.findOneBy({ id: param.id });
const data = await repo.findOneBy({ id: param.id }); if (data != null) {
data.name = param.name;
data.reset_password_url = param.reset_password_url;
data.status = param.status;
if (data != null) { await repo.save(data);
data.name = param.name
data.reset_password_url = param.reset_password_url
data.status = param.status
await repo.save(data); return ReturnHelper.successResponseAny(
res,
200,
Language.lang.success_update,
data
);
} else {
return ReturnHelper.errorResponse(
res,
404,
401,
Language.lang.failed_not_found,
""
);
}
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.successResponseAny(res, 200, Language.lang.success_update, data); return ReturnHelper.errorResponse(
} else { res,
return ReturnHelper.errorResponse(res, 404, 401, Language.lang.failed_not_found, ""); 500,
} 402,
} catch (e: unknown) { Language.lang.failed_update,
log.error(e); err.message
const err = e as Error; );
return ReturnHelper.errorResponse(res, 500, 402, Language.lang.failed_update, err.message);
}
} }
}
static async delete(req: Request, res: Response, next: NextFunction): Promise<Response> { static async delete(
/* req: Request,
res: Response,
next: NextFunction
): Promise<Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.security = [{ #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
@ -333,33 +413,60 @@ export class ApplicationController {
type: 'boolean' type: 'boolean'
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
id: Joi.string().uuid().required().label('ID'), id: Joi.string().uuid().required().label("ID"),
hard: Joi.bool().optional().allow('').label('Is hard delete?') hard: Joi.bool().optional().allow("").label("Is hard delete?"),
}); });
const param: { id: string, hard: boolean } = await schema.validateAsync(req.params); const param: { id: string; hard: boolean } = await schema.validateAsync(
req.params
);
const repo = OrmHelper.DB.getRepository(Application); const repo = OrmHelper.DB.getRepository(Application);
const affected = (!param.hard ? await repo.softDelete({ id: param.id }) : await repo.delete({ id: param.id })).affected; const affected = (
!param.hard
? await repo.softDelete({ id: param.id })
: await repo.delete({ id: param.id })
).affected;
if (affected > 0) { if (affected > 0) {
return ReturnHelper.successResponseAny(res, 200, Language.lang.success_delete, {}); return ReturnHelper.successResponseAny(
} else { res,
return ReturnHelper.errorResponse(res, 404, 401, Language.lang.failed_not_found, ""); 200,
} Language.lang.success_delete,
} catch (e: unknown) { {}
log.error(e); );
const err = e as Error; } else {
return ReturnHelper.errorResponse(
res,
404,
401,
Language.lang.failed_not_found,
""
);
}
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(res, 500, 402, Language.lang.failed_delete, err.message); return ReturnHelper.errorResponse(
} res,
500,
402,
Language.lang.failed_delete,
err.message
);
} }
}
static async restore(req: Request, res: Response, next: NextFunction): Promise<Response> { static async restore(
/* req: Request,
res: Response,
next: NextFunction
): Promise<Response> {
/*
#swagger.tags = ['Application'] #swagger.tags = ['Application']
#swagger.security = [{ #swagger.security = [{
"bearerAuth": [] "bearerAuth": []
@ -372,27 +479,44 @@ export class ApplicationController {
type: 'string' type: 'string'
} }
*/ */
try { try {
const schema = Joi.object().keys({ const schema = Joi.object().keys({
id: Joi.string().uuid().required().label('ID') id: Joi.string().uuid().required().label("ID"),
}); });
const param: Application = await schema.validateAsync(req.params); const param: Application = await schema.validateAsync(req.params);
const repo = OrmHelper.DB.getRepository(Application); const repo = OrmHelper.DB.getRepository(Application);
const affected = (await repo.restore({ id: param.id })).affected; const affected = (await repo.restore({ id: param.id })).affected;
if (affected > 0) { if (affected > 0) {
return ReturnHelper.successResponseAny(res, 200, Language.lang.success_restore, {}); return ReturnHelper.successResponseAny(
} else { res,
return ReturnHelper.errorResponse(res, 404, 401, Language.lang.failed_not_found, ""); 200,
} Language.lang.success_restore,
} catch (e: unknown) { {}
log.error(e); );
const err = e as Error; } else {
return ReturnHelper.errorResponse(
res,
404,
401,
Language.lang.failed_not_found,
""
);
}
} catch (e: unknown) {
log.error(e);
const err = e as Error;
return ReturnHelper.errorResponse(res, 500, 402, Language.lang.failed_restore, err.message); return ReturnHelper.errorResponse(
} res,
500,
402,
Language.lang.failed_restore,
err.message
);
} }
} }
}