feat: add address fields

This commit is contained in:
Methapon Metanipat 2024-09-11 15:06:27 +07:00
parent 730ebd6907
commit a7cafd25d0
8 changed files with 209 additions and 206 deletions

View file

@ -25,8 +25,8 @@ import {
createPermCondition,
} from "../services/permission";
import { filterStatus } from "../services/prisma";
import { connectOrDisconnect, connectOrNot } from "../utils/relation";
import { notFoundError } from "../utils/error";
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
import { notFoundError, relationError } from "../utils/error";
if (!process.env.MINIO_BUCKET) {
throw Error("Require MinIO bucket.");
@ -46,7 +46,12 @@ type BranchCreate = {
name: string;
addressEN: string;
address: string;
zipCode: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email: string;
contactName?: string | null;
webUrl?: string | null;
@ -80,7 +85,12 @@ type BranchUpdate = {
name?: string;
addressEN?: string;
address?: string;
zipCode?: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email?: string;
telephoneNo?: string;
contactName?: string;
@ -202,7 +212,6 @@ export class BranchController extends Controller {
@Security("keycloak")
async getBranch(
@Request() req: RequestWithUser,
@Query() zipCode?: string,
@Query() filter?: "head" | "sub",
@Query() headOfficeId?: string,
@Query() includeHead?: boolean,
@ -215,7 +224,6 @@ export class BranchController extends Controller {
const where = {
AND: {
...filterStatus(status),
zipCode,
headOfficeId: headOfficeId ?? (filter === "head" || tree ? null : undefined),
NOT: { headOfficeId: filter === "sub" && !headOfficeId ? null : undefined },
OR: permissionCond(req.user, true),
@ -225,6 +233,20 @@ export class BranchController extends Controller {
{ name: { contains: query } },
{ email: { contains: query } },
{ telephoneNo: { contains: query } },
...whereAddressQuery(query),
{
branch: {
some: {
OR: [
{ nameEN: { contains: query } },
{ name: { contains: query } },
{ email: { contains: query } },
{ telephoneNo: { contains: query } },
...whereAddressQuery(query),
],
},
},
},
],
} satisfies Prisma.BranchWhereInput;
@ -247,6 +269,15 @@ export class BranchController extends Controller {
: false,
branch: tree
? {
where: {
OR: [
{ nameEN: { contains: query } },
{ name: { contains: query } },
{ email: { contains: query } },
{ telephoneNo: { contains: query } },
...whereAddressQuery(query),
],
},
include: {
province: true,
district: true,
@ -312,30 +343,10 @@ export class BranchController extends Controller {
prisma.subDistrict.findFirst({ where: { id: body.subDistrictId || undefined } }),
prisma.branch.findFirst({ where: { id: body.headOfficeId || undefined } }),
]);
if (body.provinceId && !province)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Province cannot be found.",
"relationProvinceNotFound",
);
if (body.districtId && !district)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"District cannot be found.",
"relationDistrictNotFound",
);
if (body.subDistrictId && !subDistrict)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Sub-district cannot be found.",
"relationSubDistrictNotFound",
);
if (body.headOfficeId && !head)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Headquaters cannot be found.",
"relationHQNotFound",
);
if (body.provinceId && !province) throw relationError("Province");
if (body.districtId && !district) throw relationError("District");
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
if (body.headOfficeId && !head) throw relationError("HQ");
const { provinceId, districtId, subDistrictId, headOfficeId, bank, contact, code, ...rest } =
body;
@ -447,30 +458,10 @@ export class BranchController extends Controller {
prisma.subDistrict.findFirst({ where: { id: body.subDistrictId || undefined } }),
prisma.branch.findFirst({ where: { id: body.headOfficeId || undefined } }),
]);
if (body.provinceId && !province)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Province cannot be found.",
"relationProvinceNotFound",
);
if (body.districtId && !district)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"District cannot be found.",
"relationDistrictNotFound",
);
if (body.subDistrictId && !subDistrict)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Sub-district cannot be found.",
"relationSubDistrictNotFound",
);
if (body.headOfficeId && !branch)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Headquaters cannot be found.",
"relationHQNotFound",
);
if (body.provinceId && !province) throw relationError("Province");
if (body.districtId && !district) throw relationError("District");
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
if (body.headOfficeId && !branch) throw relationError("HQ");
}
const { provinceId, districtId, subDistrictId, headOfficeId, bank, contact, ...rest } = body;

View file

@ -98,10 +98,11 @@ export class UserBranchController extends Controller {
@Query() pageSize: number = 30,
) {
const where = {
OR: [
{ branch: { name: { contains: query }, zipCode }, userId },
{ branch: { nameEN: { contains: query }, zipCode }, userId },
],
AND: {
branch: { subDistrict: { zipCode } },
userId,
},
OR: [{ branch: { name: { contains: query } } }, { branch: { nameEN: { contains: query } } }],
} satisfies Prisma.BranchUserWhereInput;
const [result, total] = await prisma.$transaction([
@ -147,13 +148,17 @@ export class BranchUserController extends Controller {
@Query() pageSize: number = 30,
) {
const where = {
AND: {
user: { subDistrict: { zipCode } },
branchId,
},
OR: [
{ user: { firstName: { contains: query }, zipCode }, branchId },
{ user: { firstNameEN: { contains: query }, zipCode }, branchId },
{ user: { lastName: { contains: query }, zipCode }, branchId },
{ user: { lastNameEN: { contains: query }, zipCode }, branchId },
{ user: { email: { contains: query }, zipCode }, branchId },
{ user: { telephoneNo: { contains: query }, zipCode }, branchId },
{ user: { firstName: { contains: query } } },
{ user: { firstNameEN: { contains: query } } },
{ user: { lastName: { contains: query } } },
{ user: { lastNameEN: { contains: query } } },
{ user: { email: { contains: query } } },
{ user: { telephoneNo: { contains: query } } },
],
} satisfies Prisma.BranchUserWhereInput;

View file

@ -36,7 +36,7 @@ import {
createPermCheck,
createPermCondition,
} from "../services/permission";
import { connectOrDisconnect, connectOrNot } from "../utils/relation";
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
if (!process.env.MINIO_BUCKET) {
throw Error("Require MinIO bucket.");
@ -84,7 +84,12 @@ type UserCreate = {
address: string;
addressEN: string;
zipCode: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email: string;
telephoneNo: string;
@ -131,7 +136,12 @@ type UserUpdate = {
address?: string;
addressEN?: string;
zipCode?: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email?: string;
telephoneNo?: string;
@ -223,7 +233,6 @@ export class UserController extends Controller {
async getUser(
@Request() req: RequestWithUser,
@Query() userType?: UserType,
@Query() zipCode?: string,
@Query() includeBranch: boolean = false,
@Query() query: string = "",
@Query() page: number = 1,
@ -238,10 +247,10 @@ export class UserController extends Controller {
{ lastNameEN: { contains: query } },
{ email: { contains: query } },
{ telephoneNo: { contains: query } },
...whereAddressQuery(query),
],
AND: {
userRole: { not: "system" },
zipCode,
userType,
...filterStatus(status),
branch: isSystem(req.user)

View file

@ -17,10 +17,16 @@ import { RequestWithUser } from "../interfaces/user";
import prisma from "../db";
import HttpStatus from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
import minio from "../services/minio";
import minio, { deleteFolder } from "../services/minio";
import { isSystem } from "../utils/keycloak";
import { branchRelationPermInclude, createPermCheck } from "../services/permission";
import {
branchRelationPermInclude,
createPermCheck,
createPermCondition,
} from "../services/permission";
import { filterStatus } from "../services/prisma";
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
import { notFoundError, relationError } from "../utils/error";
if (!process.env.MINIO_BUCKET) {
throw Error("Require MinIO bucket.");
@ -42,6 +48,7 @@ function globalAllow(user: RequestWithUser["user"]) {
return allowList.some((v) => user.roles?.includes(v));
}
const permissionCond = createPermCondition(globalAllow);
const permissionCheck = createPermCheck(globalAllow);
function imageLocation(id: string) {
@ -74,6 +81,12 @@ export type CustomerBranchCreate = (
workplaceEN: string;
address: string;
addressEN: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email: string;
contactName: string;
@ -116,6 +129,12 @@ export type CustomerBranchUpdate = (
workplaceEN: string;
address: string;
addressEN: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
email?: string;
contactName?: string;
@ -158,14 +177,7 @@ export class CustomerBranchController extends Controller {
{ registerNameEN: { contains: query } },
{ email: { contains: query } },
{ code: { contains: query } },
{ address: { contains: query } },
{ addressEN: { contains: query } },
{ province: { name: { contains: query } } },
{ province: { nameEN: { contains: query } } },
{ district: { name: { contains: query } } },
{ district: { nameEN: { contains: query } } },
{ subDistrict: { name: { contains: query } } },
{ subDistrict: { nameEN: { contains: query } } },
...whereAddressQuery(query),
{
customer: {
OR: [
@ -183,26 +195,7 @@ export class CustomerBranchController extends Controller {
? undefined
: {
registeredBranch: {
OR: [
{
user: { some: { userId: req.user.sub } },
},
{
branch: globalAllow(req.user)
? { some: { user: { some: { userId: req.user.sub } } } }
: undefined,
},
{
headOffice: globalAllow(req.user)
? { branch: { some: { user: { some: { userId: req.user.sub } } } } }
: undefined,
},
{
headOffice: globalAllow(req.user)
? { user: { some: { userId: req.user.sub } } }
: undefined,
},
],
OR: permissionCond(req.user),
},
},
customerId,
@ -248,9 +241,7 @@ export class CustomerBranchController extends Controller {
where: { id: branchId },
});
if (!record) {
throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound");
}
if (!record) throw notFoundError("Branch");
return record;
}
@ -266,14 +257,6 @@ export class CustomerBranchController extends Controller {
@Query() page: number = 1,
@Query() pageSize: number = 30,
) {
const filterStatus = (val?: Status) => {
if (!val) return {};
return val !== Status.CREATED && val !== Status.ACTIVE
? { status: val }
: { OR: [{ status: Status.CREATED }, { status: Status.ACTIVE }] };
};
const where = {
OR: [
{ firstName: { contains: query } },
@ -281,6 +264,7 @@ export class CustomerBranchController extends Controller {
{ lastName: { contains: query } },
{ lastNameEN: { contains: query } },
{ passportNumber: { contains: query } },
...whereAddressQuery(query),
],
AND: {
...filterStatus(status),
@ -344,32 +328,14 @@ export class CustomerBranchController extends Controller {
},
}),
]);
if (body.provinceId && !province)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Province cannot be found.",
"relationProvinceNotFound",
);
if (body.districtId && !district)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"District cannot be found.",
"relationDistrictNotFound",
);
if (body.subDistrictId && !subDistrict)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Sub-district cannot be found.",
"relationSubDistrictNotFound",
);
if (!customer)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Customer cannot be found.",
"relationCustomerNotFound",
);
if (body.provinceId && !province) throw relationError("Province");
if (body.districtId && !district) throw relationError("District");
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
if (!customer) throw relationError("Customer");
await permissionCheck(req.user, customer.registeredBranch);
let company = await permissionCheck(req.user, customer.registeredBranch).then(
(v) => (v.headOffice || v).code,
);
const { provinceId, districtId, subDistrictId, customerId, ...rest } = body;
@ -381,11 +347,11 @@ export class CustomerBranchController extends Controller {
let runningKey = "";
if (headofficeCode) {
runningKey = `CUSTOMER_BRANCH_${headofficeCode}`;
runningKey = `CUSTOMER_BRANCH_${company}_${headofficeCode}`;
} else if ("citizenId" in body) {
runningKey = `CUSTOMER_BRANCH_${body.citizenId}`;
runningKey = `CUSTOMER_BRANCH_${company}_${body.citizenId}`;
} else {
runningKey = `CUSTOMER_BRANCH_${body.legalPersonNo}`;
runningKey = `CUSTOMER_BRANCH_${company}_${body.legalPersonNo}`;
}
const last = await tx.runningNo.upsert({
@ -478,30 +444,10 @@ export class CustomerBranchController extends Controller {
},
}),
]);
if (body.provinceId && !province)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Province cannot be found.",
"relationProvinceNotFound",
);
if (body.districtId && !district)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"District cannot be found.",
"relationDistrictNotFound",
);
if (body.subDistrictId && !subDistrict)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Sub-district cannot be found.",
"relationSubDistrictNotFound",
);
if (!customer)
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Customer cannot be found.",
"relationCustomerNotFound",
);
if (body.provinceId && !province) throw relationError("Province");
if (body.districtId && !district) throw relationError("District");
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
if (!customer) throw relationError("Customer");
await permissionCheck(req.user, customer.registeredBranch);
}
@ -519,19 +465,10 @@ export class CustomerBranchController extends Controller {
data: {
...rest,
statusOrder: +(rest.status === "INACTIVE"),
customer: { connect: customerId ? { id: customerId } : undefined },
province: {
connect: provinceId ? { id: provinceId } : undefined,
disconnect: provinceId === null || undefined,
},
district: {
connect: districtId ? { id: districtId } : undefined,
disconnect: districtId === null || undefined,
},
subDistrict: {
connect: subDistrictId ? { id: subDistrictId } : undefined,
disconnect: subDistrictId === null || undefined,
},
customer: connectOrNot(customerId),
province: connectOrDisconnect(provinceId),
district: connectOrDisconnect(districtId),
subDistrict: connectOrDisconnect(subDistrictId),
updatedBy: { connect: { id: req.user.sub } },
},
});
@ -553,13 +490,7 @@ export class CustomerBranchController extends Controller {
},
});
if (!record) {
throw new HttpError(
HttpStatus.NOT_FOUND,
"Customer branch cannot be found.",
"customerBranchNotFound",
);
}
if (!record) throw notFoundError("Customer Branch");
await permissionCheck(req.user, record.customer.registeredBranch);
@ -577,22 +508,7 @@ export class CustomerBranchController extends Controller {
where: { id: branchId },
})
.then((v) => {
new Promise<string[]>((resolve, reject) => {
const item: string[] = [];
const stream = minio.listObjectsV2(
MINIO_BUCKET,
`${attachmentLocation(record.customerId, branchId)}/`,
);
stream.on("data", (v) => v && v.name && item.push(v.name));
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("MinIO error.")));
}).then((list) => {
list.map(async (v) => {
await minio.removeObject(MINIO_BUCKET, v, { forceDelete: true });
});
});
deleteFolder(MINIO_BUCKET, `${attachmentLocation(record.customerId, branchId)}/`);
return v;
});
}

View file

@ -24,7 +24,7 @@ import {
createPermCheck,
createPermCondition,
} from "../services/permission";
import { connectOrDisconnect, connectOrNot } from "../utils/relation";
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
import { notFoundError, relationError } from "../utils/error";
import { deleteFile, fileLocation, getFile, listFile, setFile } from "../utils/minio";
@ -70,6 +70,12 @@ type EmployeeCreate = {
addressEN: string;
address: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
passportType: string;
passportNumber: string;
@ -156,6 +162,12 @@ type EmployeeUpdate = {
addressEN?: string;
address?: string;
soi?: string | null;
soiEN?: string | null;
moo?: string | null;
mooEN?: string | null;
street?: string | null;
streetEN?: string | null;
passportType?: string;
passportNumber?: string;
@ -253,6 +265,7 @@ export class EmployeeController extends Controller {
{ firstNameEN: { contains: query } },
{ lastName: { contains: query } },
{ lastNameEN: { contains: query } },
...whereAddressQuery(query),
],
AND: {
...filterStatus(status),
@ -294,6 +307,7 @@ export class EmployeeController extends Controller {
{ lastName: { contains: query } },
{ lastNameEN: { contains: query } },
{ passportNumber: { contains: query } },
...whereAddressQuery(query),
],
AND: {
...filterStatus(status),