feat: file upload customer branch
This commit is contained in:
parent
3a8bb7a82d
commit
472db99c50
2 changed files with 313 additions and 115 deletions
|
|
@ -17,7 +17,6 @@ import { RequestWithUser } from "../interfaces/user";
|
||||||
import prisma from "../db";
|
import prisma from "../db";
|
||||||
import HttpStatus from "../interfaces/http-status";
|
import HttpStatus from "../interfaces/http-status";
|
||||||
import HttpError from "../interfaces/http-error";
|
import HttpError from "../interfaces/http-error";
|
||||||
import minio, { deleteFolder } from "../services/minio";
|
|
||||||
import { isSystem } from "../utils/keycloak";
|
import { isSystem } from "../utils/keycloak";
|
||||||
import {
|
import {
|
||||||
branchRelationPermInclude,
|
branchRelationPermInclude,
|
||||||
|
|
@ -27,12 +26,8 @@ import {
|
||||||
import { filterStatus } from "../services/prisma";
|
import { filterStatus } from "../services/prisma";
|
||||||
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
|
import { connectOrDisconnect, connectOrNot, whereAddressQuery } from "../utils/relation";
|
||||||
import { notFoundError, relationError } from "../utils/error";
|
import { notFoundError, relationError } from "../utils/error";
|
||||||
|
import { deleteFile, deleteFolder, fileLocation, getFile, listFile, setFile } from "../utils/minio";
|
||||||
|
|
||||||
if (!process.env.MINIO_BUCKET) {
|
|
||||||
throw Error("Require MinIO bucket.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const MINIO_BUCKET = process.env.MINIO_BUCKET;
|
|
||||||
const MANAGE_ROLES = [
|
const MANAGE_ROLES = [
|
||||||
"system",
|
"system",
|
||||||
"head_of_admin",
|
"head_of_admin",
|
||||||
|
|
@ -51,14 +46,6 @@ function globalAllow(user: RequestWithUser["user"]) {
|
||||||
const permissionCond = createPermCondition(globalAllow);
|
const permissionCond = createPermCondition(globalAllow);
|
||||||
const permissionCheck = createPermCheck(globalAllow);
|
const permissionCheck = createPermCheck(globalAllow);
|
||||||
|
|
||||||
function imageLocation(id: string) {
|
|
||||||
return `employee/profile-img-${id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function attachmentLocation(customerId: string, branchId: string) {
|
|
||||||
return `customer/${customerId}/branch/${branchId}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CustomerBranchCreate = {
|
export type CustomerBranchCreate = {
|
||||||
customerId: string;
|
customerId: string;
|
||||||
|
|
||||||
|
|
@ -299,16 +286,7 @@ export class CustomerBranchController extends Controller {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
result: await Promise.all(
|
result,
|
||||||
result.map(async (v) => ({
|
|
||||||
...v,
|
|
||||||
profileImageUrl: await minio.presignedGetObject(
|
|
||||||
MINIO_BUCKET,
|
|
||||||
imageLocation(v.id),
|
|
||||||
12 * 60 * 60,
|
|
||||||
),
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
page,
|
page,
|
||||||
pageSize,
|
pageSize,
|
||||||
total,
|
total,
|
||||||
|
|
@ -514,117 +492,323 @@ export class CustomerBranchController extends Controller {
|
||||||
include: { createdBy: true, updatedBy: true },
|
include: { createdBy: true, updatedBy: true },
|
||||||
where: { id: branchId },
|
where: { id: branchId },
|
||||||
})
|
})
|
||||||
.then((v) => {
|
.then((v) => deleteFolder(fileLocation.customerBranch.attachment(branchId)).then(() => v));
|
||||||
deleteFolder(MINIO_BUCKET, `${attachmentLocation(record.customerId, branchId)}/`);
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Route("api/v1/customer-branch/{branchId}/attachment")
|
// @Route("api/v1/customer-branch/{branchId}/attachment")
|
||||||
|
// @Tags("Customer Branch")
|
||||||
|
// @Security("keycloak")
|
||||||
|
// export class CustomerAttachmentController extends Controller {
|
||||||
|
// @Get()
|
||||||
|
// async listAttachment(@Path() branchId: string) {
|
||||||
|
// const record = await prisma.customerBranch.findFirst({
|
||||||
|
// where: { id: branchId },
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if (!record) {
|
||||||
|
// throw new HttpError(
|
||||||
|
// HttpStatus.NOT_FOUND,
|
||||||
|
// "Customer branch cannot be found.",
|
||||||
|
// "customerBranchNotFound",
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const list = await 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.")));
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// return list.map((v) => v.split("/").at(-1) as string);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Get("{filename}")
|
||||||
|
// async getAttachment(
|
||||||
|
// @Request() req: RequestWithUser,
|
||||||
|
// @Path() branchId: string,
|
||||||
|
// @Path() filename: string,
|
||||||
|
// ) {
|
||||||
|
// const record = await prisma.customerBranch.findFirst({
|
||||||
|
// where: { id: branchId },
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if (!record) {
|
||||||
|
// throw new HttpError(
|
||||||
|
// HttpStatus.NOT_FOUND,
|
||||||
|
// "Customer branch cannot be found.",
|
||||||
|
// "customerBranchNotFound",
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return await minio.presignedGetObject(
|
||||||
|
// MINIO_BUCKET,
|
||||||
|
// `${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
||||||
|
// 12 * 60 * 60,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Put("{filename}")
|
||||||
|
// async addAttachment(
|
||||||
|
// @Request() req: RequestWithUser,
|
||||||
|
// @Path() branchId: string,
|
||||||
|
// @Path() filename: string,
|
||||||
|
// ) {
|
||||||
|
// const record = await prisma.customerBranch.findFirst({
|
||||||
|
// where: { id: branchId },
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if (!record) {
|
||||||
|
// throw new HttpError(
|
||||||
|
// HttpStatus.NOT_FOUND,
|
||||||
|
// "Customer branch cannot be found.",
|
||||||
|
// "customerBranchNotFound",
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return req.res?.redirect(
|
||||||
|
// await minio.presignedPutObject(
|
||||||
|
// MINIO_BUCKET,
|
||||||
|
// `${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
||||||
|
// 12 * 60 * 60,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Delete("{filename}")
|
||||||
|
// async deleteAttachment(@Path() branchId: string, @Path() filename: string) {
|
||||||
|
// const record = await prisma.customerBranch.findFirst({
|
||||||
|
// where: { id: branchId },
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if (!record) throw notFoundError("Customer Branch");
|
||||||
|
//
|
||||||
|
// await minio.removeObject(
|
||||||
|
// MINIO_BUCKET,
|
||||||
|
// `${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
||||||
|
// { forceDelete: true },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Route("api/v1/customer-branch/{branchId}")
|
||||||
@Tags("Customer Branch")
|
@Tags("Customer Branch")
|
||||||
@Security("keycloak")
|
export class CustomerBranchFileController extends Controller {
|
||||||
export class CustomerAttachmentController extends Controller {
|
private async checkPermission(user: RequestWithUser["user"], id: string) {
|
||||||
@Get()
|
const data = await prisma.customerBranch.findFirst({
|
||||||
async listAttachment(@Path() branchId: string) {
|
where: { id },
|
||||||
const record = await prisma.customerBranch.findFirst({
|
include: {
|
||||||
where: { id: branchId },
|
customer: {
|
||||||
|
include: {
|
||||||
|
registeredBranch: {
|
||||||
|
include: branchRelationPermInclude(user),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
if (!data) throw notFoundError("Customer Branch");
|
||||||
if (!record) {
|
await permissionCheck(user, data.customer.registeredBranch);
|
||||||
throw new HttpError(
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
"Customer branch cannot be found.",
|
|
||||||
"customerBranchNotFound",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const list = await 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.")));
|
|
||||||
});
|
|
||||||
|
|
||||||
return list.map((v) => v.split("/").at(-1) as string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("{filename}")
|
@Get("attachment")
|
||||||
async getAttachment(
|
@Security("keycloak")
|
||||||
@Request() req: RequestWithUser,
|
async listAttachment(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
@Path() branchId: string,
|
await this.checkPermission(req.user, branchId);
|
||||||
@Path() filename: string,
|
return await listFile(fileLocation.customerBranch.attachment(branchId));
|
||||||
) {
|
|
||||||
const record = await prisma.customerBranch.findFirst({
|
|
||||||
where: { id: branchId },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!record) {
|
|
||||||
throw new HttpError(
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
"Customer branch cannot be found.",
|
|
||||||
"customerBranchNotFound",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await minio.presignedGetObject(
|
|
||||||
MINIO_BUCKET,
|
|
||||||
`${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
|
||||||
12 * 60 * 60,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put("{filename}")
|
@Get("attachment/{name}")
|
||||||
async addAttachment(
|
@Security("keycloak")
|
||||||
|
async getAttachment(@Path() branchId: string, @Path() name: string) {
|
||||||
|
return await getFile(fileLocation.customerBranch.attachment(branchId, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("attachment/{name}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putAttachment(
|
||||||
@Request() req: RequestWithUser,
|
@Request() req: RequestWithUser,
|
||||||
@Path() branchId: string,
|
@Path() branchId: string,
|
||||||
@Path() filename: string,
|
@Path() name: string,
|
||||||
) {
|
) {
|
||||||
const record = await prisma.customerBranch.findFirst({
|
await this.checkPermission(req.user, branchId);
|
||||||
where: { id: branchId },
|
return req.res?.redirect(await setFile(fileLocation.customerBranch.attachment(branchId, name)));
|
||||||
});
|
}
|
||||||
|
|
||||||
if (!record) {
|
@Delete("attachment/{name}")
|
||||||
throw new HttpError(
|
@Security("keycloak")
|
||||||
HttpStatus.NOT_FOUND,
|
async delAttachment(
|
||||||
"Customer branch cannot be found.",
|
@Request() req: RequestWithUser,
|
||||||
"customerBranchNotFound",
|
@Path() branchId: string,
|
||||||
);
|
@Path() name: string,
|
||||||
}
|
) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await deleteFile(fileLocation.customerBranch.attachment(branchId, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-citizen")
|
||||||
|
@Security("keycloak")
|
||||||
|
async listCitizen(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await listFile(fileLocation.customerBranch.attachment(branchId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-citizen/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async getCitizen(@Path() branchId: string, @Path() id: string) {
|
||||||
|
return await getFile(fileLocation.customerBranch.attachment(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("file-citizen/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putCitizen(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return req.res?.redirect(await setFile(fileLocation.customerBranch.attachment(branchId, id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("file-citizen/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async delCitizen(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await deleteFile(fileLocation.customerBranch.citizen(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-power-of-attorney")
|
||||||
|
@Security("keycloak")
|
||||||
|
async listPoa(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await listFile(fileLocation.customerBranch.powerOfAttorney(branchId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-power-of-attorney/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async getPoa(@Path() branchId: string, @Path() id: string) {
|
||||||
|
return await getFile(fileLocation.customerBranch.powerOfAttorney(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("file-power-of-attorney/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putPoa(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
return req.res?.redirect(
|
return req.res?.redirect(
|
||||||
await minio.presignedPutObject(
|
await setFile(fileLocation.customerBranch.powerOfAttorney(branchId, id)),
|
||||||
MINIO_BUCKET,
|
|
||||||
`${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
|
||||||
12 * 60 * 60,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete("{filename}")
|
@Delete("file-power-of-attorney/{id}")
|
||||||
async deleteAttachment(@Path() branchId: string, @Path() filename: string) {
|
@Security("keycloak")
|
||||||
const record = await prisma.customerBranch.findFirst({
|
async delPoa(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
where: { id: branchId },
|
await this.checkPermission(req.user, branchId);
|
||||||
});
|
return await deleteFile(fileLocation.customerBranch.powerOfAttorney(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
if (!record) {
|
@Get("file-house-registration")
|
||||||
throw new HttpError(
|
@Security("keycloak")
|
||||||
HttpStatus.NOT_FOUND,
|
async listHouseRegis(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
"Customer branch cannot be found.",
|
await this.checkPermission(req.user, branchId);
|
||||||
"customerBranchNotFound",
|
return await listFile(fileLocation.customerBranch.houseRegistration(branchId));
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await minio.removeObject(
|
@Get("file-house-registration/{id}")
|
||||||
MINIO_BUCKET,
|
@Security("keycloak")
|
||||||
`${attachmentLocation(record.customerId, branchId)}/${filename}`,
|
async getHouseRegis(@Path() branchId: string, @Path() id: string) {
|
||||||
{ forceDelete: true },
|
return await getFile(fileLocation.customerBranch.houseRegistration(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("file-house-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putHouseRegis(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path() branchId: string,
|
||||||
|
@Path() id: string,
|
||||||
|
) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return req.res?.redirect(
|
||||||
|
await setFile(fileLocation.customerBranch.houseRegistration(branchId, id)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Delete("file-house-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async delHouseRegis(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path() branchId: string,
|
||||||
|
@Path() id: string,
|
||||||
|
) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await deleteFile(fileLocation.customerBranch.houseRegistration(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-commercial-registration")
|
||||||
|
@Security("keycloak")
|
||||||
|
async listCommercialRegis(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await listFile(fileLocation.customerBranch.commercialRegistration(branchId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-commercial-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async getCommercialRegis(@Path() branchId: string, @Path() id: string) {
|
||||||
|
return await getFile(fileLocation.customerBranch.commercialRegistration(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("file-commercial-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putCommercialRegis(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path() branchId: string,
|
||||||
|
@Path() id: string,
|
||||||
|
) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return req.res?.redirect(
|
||||||
|
await setFile(fileLocation.customerBranch.commercialRegistration(branchId, id)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("file-commercial-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async delCommercialRegis(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Path() branchId: string,
|
||||||
|
@Path() id: string,
|
||||||
|
) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await deleteFile(fileLocation.customerBranch.commercialRegistration(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-vat-registration")
|
||||||
|
@Security("keycloak")
|
||||||
|
async listVatRegis(@Request() req: RequestWithUser, @Path() branchId: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await listFile(fileLocation.customerBranch.vatRegistration(branchId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("file-vat-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async getVatRegis(@Path() branchId: string, @Path() id: string) {
|
||||||
|
return await getFile(fileLocation.customerBranch.vatRegistration(branchId, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("file-vat-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async putVatRegis(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return req.res?.redirect(
|
||||||
|
await setFile(fileLocation.customerBranch.vatRegistration(branchId, id)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("file-vat-registration/{id}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async delVatRegis(@Request() req: RequestWithUser, @Path() branchId: string, @Path() id: string) {
|
||||||
|
await this.checkPermission(req.user, branchId);
|
||||||
|
return await deleteFile(fileLocation.customerBranch.vatRegistration(branchId, id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,20 @@ export const fileLocation = {
|
||||||
customer: {
|
customer: {
|
||||||
img: (customerId: string, name?: string) => `customer/img-${customerId}/${name || ""}`,
|
img: (customerId: string, name?: string) => `customer/img-${customerId}/${name || ""}`,
|
||||||
},
|
},
|
||||||
|
customerBranch: {
|
||||||
|
attachment: (customerBranchId: string, name?: string) =>
|
||||||
|
`customer-branch/attachment-${customerBranchId}/${name || ""}`,
|
||||||
|
citizen: (customerBranchId: string, citizenId?: string) =>
|
||||||
|
`customer-branch/citizen-${customerBranchId}/${citizenId || ""}`,
|
||||||
|
houseRegistration: (customerBranchId: string, houseRegistrationId?: string) =>
|
||||||
|
`customer-branch/house-registration-${customerBranchId}/${houseRegistrationId || ""}`,
|
||||||
|
commercialRegistration: (customerBranchId: string, commercialRegistrationId?: string) =>
|
||||||
|
`customer-branch/commercial-registration-${customerBranchId}/${commercialRegistrationId || ""}`,
|
||||||
|
vatRegistration: (customerBranchId: string, vatRegistrationId?: string) =>
|
||||||
|
`customer-branch/vat-registration-${customerBranchId}/${vatRegistrationId || ""}`,
|
||||||
|
powerOfAttorney: (customerBranchId: string, powerOfAttorneyId?: string) =>
|
||||||
|
`customer-branch/power-of-attorney-${customerBranchId}/${powerOfAttorneyId || ""}`,
|
||||||
|
},
|
||||||
employee: {
|
employee: {
|
||||||
img: (employeeId: string, name?: string) => `employee/img-${employeeId}/${name || ""}`,
|
img: (employeeId: string, name?: string) => `employee/img-${employeeId}/${name || ""}`,
|
||||||
attachment: (employeeId: string, name?: string) =>
|
attachment: (employeeId: string, name?: string) =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue