feat: customer branch citizen
This commit is contained in:
parent
b12babdc09
commit
a0168ee4fb
4 changed files with 254 additions and 0 deletions
39
prisma/migrations/20240917034817_add_relation/migration.sql
Normal file
39
prisma/migrations/20240917034817_add_relation/migration.sql
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `customerBranchId` to the `CustomerBranchCitizen` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `customerBranchId` to the `CustomerBranchCommercialRegis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `customerBranchId` to the `CustomerBranchHouseRegis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `customerBranchId` to the `CustomerBranchPoa` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `customerBranchId` to the `CustomerBranchVatRegis` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerBranchCitizen" ADD COLUMN "customerBranchId" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerBranchCommercialRegis" ADD COLUMN "customerBranchId" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerBranchHouseRegis" ADD COLUMN "customerBranchId" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerBranchPoa" ADD COLUMN "customerBranchId" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerBranchVatRegis" ADD COLUMN "customerBranchId" TEXT NOT NULL;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerBranchCitizen" ADD CONSTRAINT "CustomerBranchCitizen_customerBranchId_fkey" FOREIGN KEY ("customerBranchId") REFERENCES "CustomerBranch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerBranchPoa" ADD CONSTRAINT "CustomerBranchPoa_customerBranchId_fkey" FOREIGN KEY ("customerBranchId") REFERENCES "CustomerBranch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerBranchHouseRegis" ADD CONSTRAINT "CustomerBranchHouseRegis_customerBranchId_fkey" FOREIGN KEY ("customerBranchId") REFERENCES "CustomerBranch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerBranchCommercialRegis" ADD CONSTRAINT "CustomerBranchCommercialRegis_customerBranchId_fkey" FOREIGN KEY ("customerBranchId") REFERENCES "CustomerBranch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerBranchVatRegis" ADD CONSTRAINT "CustomerBranchVatRegis_customerBranchId_fkey" FOREIGN KEY ("customerBranchId") REFERENCES "CustomerBranch"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
|
@ -527,6 +527,12 @@ model CustomerBranch {
|
|||
|
||||
employee Employee[]
|
||||
quotation Quotation[]
|
||||
|
||||
citizen CustomerBranchCitizen[]
|
||||
poa CustomerBranchPoa[]
|
||||
houseRegis CustomerBranchHouseRegis[]
|
||||
commercialRegis CustomerBranchCommercialRegis[]
|
||||
vatRegis CustomerBranchVatRegis[]
|
||||
}
|
||||
|
||||
model CustomerBranchCitizen {
|
||||
|
|
@ -560,12 +566,18 @@ model CustomerBranchCitizen {
|
|||
subDistrictId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customerBranchId String
|
||||
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||
}
|
||||
|
||||
model CustomerBranchPoa {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customerBranchId String
|
||||
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||
}
|
||||
|
||||
model CustomerBranchHouseRegis {
|
||||
|
|
@ -616,6 +628,9 @@ model CustomerBranchHouseRegis {
|
|||
fatherNationality String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customerBranchId String
|
||||
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||
}
|
||||
|
||||
enum CommercialType {
|
||||
|
|
@ -635,12 +650,18 @@ model CustomerBranchCommercialRegis {
|
|||
romanLetter String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customerBranchId String
|
||||
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||
}
|
||||
|
||||
model CustomerBranchVatRegis {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customerBranchId String
|
||||
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||
}
|
||||
|
||||
model Employee {
|
||||
|
|
|
|||
161
src/controllers/03-customer-branch-citizen-controller.ts
Normal file
161
src/controllers/03-customer-branch-citizen-controller.ts
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Middlewares,
|
||||
Path,
|
||||
Post,
|
||||
Put,
|
||||
Route,
|
||||
Security,
|
||||
Tags,
|
||||
} from "tsoa";
|
||||
import { RequestWithUser } from "../interfaces/user";
|
||||
import prisma from "../db";
|
||||
import HttpStatus from "../interfaces/http-status";
|
||||
import { connectOrDisconnect, connectOrNot } from "../utils/relation";
|
||||
import { notFoundError, relationError } from "../utils/error";
|
||||
import { permissionCheck } from "../middlewares/customer-branch";
|
||||
|
||||
const MANAGE_ROLES = [
|
||||
"system",
|
||||
"head_of_admin",
|
||||
"admin",
|
||||
"head_of_account",
|
||||
"account",
|
||||
"head_of_sale",
|
||||
"sale",
|
||||
];
|
||||
|
||||
function globalAllow(user: RequestWithUser["user"]) {
|
||||
const allowList = ["system", "head_of_admin", "admin", "head_of_account", "head_of_sale"];
|
||||
return allowList.some((v) => user.roles?.includes(v));
|
||||
}
|
||||
|
||||
type CustomerBranchCitizenPayload = {
|
||||
namePrefix?: string;
|
||||
firstName: string;
|
||||
firstNameEN?: string;
|
||||
middleName?: string;
|
||||
middleNameEN?: string;
|
||||
lastName: string;
|
||||
lastNameEN?: string;
|
||||
issueDate: Date;
|
||||
expireDate: Date;
|
||||
nationality: string;
|
||||
religion: string;
|
||||
gender: string;
|
||||
address?: string;
|
||||
addressEN?: string;
|
||||
soi?: string;
|
||||
soiEN?: string;
|
||||
moo?: string;
|
||||
mooEN?: string;
|
||||
street?: string;
|
||||
streetEN?: string;
|
||||
provinceId?: string;
|
||||
districtId?: string;
|
||||
subDistrictId?: string;
|
||||
};
|
||||
|
||||
@Route("api/v1/customer-branch/{branchId}/citizen")
|
||||
@Tags("Customer Branch Citizen")
|
||||
@Middlewares(permissionCheck(globalAllow))
|
||||
export class CustomerBranchCitizenController extends Controller {
|
||||
@Get()
|
||||
@Security("keycloak")
|
||||
async list(@Path() branchId: string) {
|
||||
return prisma.customerBranchCitizen.findMany({
|
||||
orderBy: { createdAt: "asc" },
|
||||
where: { customerBranchId: branchId },
|
||||
});
|
||||
}
|
||||
|
||||
@Get("{citizenId}")
|
||||
@Security("keycloak")
|
||||
async getById(@Path() branchId: string, @Path() citizenId: string) {
|
||||
const record = await prisma.customerBranchCitizen.findFirst({
|
||||
where: { id: citizenId, customerBranchId: branchId },
|
||||
});
|
||||
if (!record) throw notFoundError("Citizen");
|
||||
return record;
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Security("keycloak", MANAGE_ROLES)
|
||||
async create(@Path() branchId: string, @Body() body: CustomerBranchCitizenPayload) {
|
||||
const { provinceId, districtId, subDistrictId, ...rest } = body;
|
||||
const [province, district, subDistrict] = await prisma.$transaction([
|
||||
prisma.province.findUnique({ where: { id: body.provinceId ?? undefined } }),
|
||||
prisma.district.findUnique({ where: { id: body.districtId ?? undefined } }),
|
||||
prisma.subDistrict.findUnique({ where: { id: body.subDistrictId ?? undefined } }),
|
||||
]);
|
||||
if (body.provinceId && !province) throw relationError("Province");
|
||||
if (body.districtId && !district) throw relationError("District");
|
||||
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
|
||||
const record = await prisma.customerBranchCitizen.create({
|
||||
data: {
|
||||
...rest,
|
||||
province: connectOrNot(provinceId),
|
||||
district: connectOrNot(districtId),
|
||||
subDistrict: connectOrNot(subDistrictId),
|
||||
customerBranch: { connect: { id: branchId } },
|
||||
},
|
||||
});
|
||||
|
||||
this.setStatus(HttpStatus.CREATED);
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
@Put("{citizenId}")
|
||||
@Security("keycloak", MANAGE_ROLES)
|
||||
async editById(
|
||||
@Path() branchId: string,
|
||||
@Path() citizenId: string,
|
||||
@Body() body: CustomerBranchCitizenPayload,
|
||||
) {
|
||||
const { provinceId, districtId, subDistrictId, ...rest } = body;
|
||||
const [province, district, subDistrict, citizen] = await prisma.$transaction([
|
||||
prisma.province.findUnique({ where: { id: body.provinceId ?? undefined } }),
|
||||
prisma.district.findUnique({ where: { id: body.districtId ?? undefined } }),
|
||||
prisma.subDistrict.findUnique({ where: { id: body.subDistrictId ?? undefined } }),
|
||||
prisma.customerBranchCitizen.findUnique({
|
||||
where: { id: citizenId, customerBranchId: branchId },
|
||||
}),
|
||||
]);
|
||||
if (body.provinceId && !province) throw relationError("Province");
|
||||
if (body.districtId && !district) throw relationError("District");
|
||||
if (body.subDistrictId && !subDistrict) throw relationError("SubDistrict");
|
||||
if (!citizen) throw notFoundError("Citizen");
|
||||
|
||||
const record = await prisma.customerBranchCitizen.update({
|
||||
where: { id: citizenId, customerBranchId: branchId },
|
||||
data: {
|
||||
...rest,
|
||||
province: connectOrDisconnect(provinceId),
|
||||
district: connectOrDisconnect(districtId),
|
||||
subDistrict: connectOrDisconnect(subDistrictId),
|
||||
},
|
||||
});
|
||||
|
||||
this.setStatus(HttpStatus.CREATED);
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
@Delete("{citizenId}")
|
||||
@Security("keycloak", MANAGE_ROLES)
|
||||
async deleteById(@Path() branchId: string, @Path() citizenId: string) {
|
||||
const record = await prisma.customerBranchCitizen.findFirst({
|
||||
where: { id: citizenId, customerBranchId: branchId },
|
||||
});
|
||||
|
||||
if (!record) throw notFoundError("Citizen");
|
||||
|
||||
return await prisma.customerBranchCitizen.delete({
|
||||
where: { id: citizenId, customerBranchId: branchId },
|
||||
});
|
||||
}
|
||||
}
|
||||
33
src/middlewares/customer-branch.ts
Normal file
33
src/middlewares/customer-branch.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import express from "express";
|
||||
import { RequestWithUser } from "../interfaces/user";
|
||||
import prisma from "../db";
|
||||
import { branchRelationPermInclude, createPermCheck } from "../services/permission";
|
||||
import { notFoundError } from "../utils/error";
|
||||
|
||||
export function permissionCheck(globalAllow: (user: RequestWithUser["user"]) => boolean) {
|
||||
const checker = createPermCheck(globalAllow);
|
||||
|
||||
return async (req: RequestWithUser, _res: express.Response, next: express.NextFunction) => {
|
||||
if ("employeeId" in req.params && typeof req.params.employeeId === "string") {
|
||||
const id = req.params.customerBranchId;
|
||||
const employee = await prisma.customerBranch.findFirst({
|
||||
where: { id },
|
||||
|
||||
include: {
|
||||
customer: {
|
||||
include: {
|
||||
registeredBranch: {
|
||||
include: branchRelationPermInclude(req.user),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!employee) throw notFoundError("Customer Branch");
|
||||
|
||||
await checker(req.user, employee.customer.registeredBranch);
|
||||
}
|
||||
next();
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue