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[]
|
employee Employee[]
|
||||||
quotation Quotation[]
|
quotation Quotation[]
|
||||||
|
|
||||||
|
citizen CustomerBranchCitizen[]
|
||||||
|
poa CustomerBranchPoa[]
|
||||||
|
houseRegis CustomerBranchHouseRegis[]
|
||||||
|
commercialRegis CustomerBranchCommercialRegis[]
|
||||||
|
vatRegis CustomerBranchVatRegis[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model CustomerBranchCitizen {
|
model CustomerBranchCitizen {
|
||||||
|
|
@ -560,12 +566,18 @@ model CustomerBranchCitizen {
|
||||||
subDistrictId String?
|
subDistrictId String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
customerBranchId String
|
||||||
|
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
model CustomerBranchPoa {
|
model CustomerBranchPoa {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
customerBranchId String
|
||||||
|
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
model CustomerBranchHouseRegis {
|
model CustomerBranchHouseRegis {
|
||||||
|
|
@ -616,6 +628,9 @@ model CustomerBranchHouseRegis {
|
||||||
fatherNationality String?
|
fatherNationality String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
customerBranchId String
|
||||||
|
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CommercialType {
|
enum CommercialType {
|
||||||
|
|
@ -635,12 +650,18 @@ model CustomerBranchCommercialRegis {
|
||||||
romanLetter String?
|
romanLetter String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
customerBranchId String
|
||||||
|
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
model CustomerBranchVatRegis {
|
model CustomerBranchVatRegis {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
customerBranchId String
|
||||||
|
customerBranch CustomerBranch @relation(fields: [customerBranchId], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
model Employee {
|
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