Merge Staging in Preprod

This commit is contained in:
Arnaud D. Natali 2023-10-24 22:01:00 +02:00 committed by GitHub
commit 258c930d09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 29554 additions and 626 deletions

File diff suppressed because it is too large Load Diff

6744
doc/swagger.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@
"@mailchimp/mailchimp_transactional": "^1.0.50",
"@pinata/sdk": "^2.1.0",
"@prisma/client": "^4.11.0",
"adm-zip": "^0.5.10",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"classnames": "^2.3.2",
@ -53,7 +54,7 @@
"express": "^4.18.2",
"fp-ts": "^2.16.1",
"jsonwebtoken": "^9.0.0",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.90",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.94",
"module-alias": "^2.2.2",
"monocle-ts": "^2.3.13",
"multer": "^1.4.5-lts.1",
@ -71,6 +72,7 @@
"uuidv4": "^6.2.13"
},
"devDependencies": {
"@types/adm-zip": "^0.5.3",
"@types/cors": "^2.8.13",
"@types/cron": "^2.0.1",
"@types/express": "^4.17.16",

View File

@ -25,14 +25,17 @@ export default class CustomersController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.CustomersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
if(query.where?.office_folders?.some?.office_uid) delete query.where.office_folders.some.office_uid;
if(query.where?.office_folders?.some?.office?.uid) delete query.where?.office_folders?.some?.office?.uid;
if (query.where?.office_folders) delete query.where.office_folders;
const customerWhereInput: Prisma.CustomersWhereInput = { ...query.where, office_folders: { some: { office_uid: officeId } } };
query.where = customerWhereInput;
@ -53,14 +56,34 @@ export default class CustomersController extends ApiController {
/**
* @description Create a new customer
*/
@Post("/api/v1/admin/customers", [authHandler, ruleHandler])
@Post("/api/v1/notary/customers", [authHandler, ruleHandler])
protected async post(req: Request, response: Response) {
try {
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["createCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length > 0) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
//call service to get prisma entity
const customerEntityCreated = await this.customersService.create(customerEntity);
//Hydrate ressource with prisma entity
@ -79,7 +102,7 @@ export default class CustomersController extends ApiController {
/**
* @description Modify a specific customer by uid
*/
@Put("/api/v1/admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
@Put("/api/v1/notary/customers/:uid", [authHandler, ruleHandler, customerHandler])
protected async put(req: Request, response: Response) {
try {
const uid = req.params["uid"];
@ -95,15 +118,47 @@ export default class CustomersController extends ApiController {
return;
}
req.body.contact.uid = userFound.contact_uid;
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["updateCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
if (customerEntity.contact?.email) {
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length != 0) {
try {
customers.forEach((customer) => {
if (customer.uid != uid) {
throw new Error("email déjà utilisé");
}
});
} catch (error) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
}
}
//call service to get prisma entity
try {
const customerEntityUpdated = await this.customersService.update(uid, customerEntity);
//Hydrate ressource with prisma entity
const customer = Customer.hydrate<Customer>(customerEntityUpdated, {
strategy: "excludeAll",
@ -111,6 +166,11 @@ export default class CustomersController extends ApiController {
//success
this.httpSuccess(response, customer);
} catch (error) {
console.log(error);
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -29,6 +29,10 @@ export default class DeedTypesController extends ApiController {
let query: Prisma.DeedTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {
@ -74,11 +78,6 @@ export default class DeedTypesController extends ApiController {
//validate deed type
await validateOrReject(deedTypeEntity, { groups: ["createDeedType"], forbidUnknownValues: false });
const doesExist = await this.deedTypesService.get({ where: { name: deedTypeEntity.name } });
if (doesExist.length > 0) {
this.httpBadRequest(response, "Deed type name already used");
return;
}
//call service to get prisma entity
const deedTypeEntityCreated = await this.deedTypesService.create(deedTypeEntity);

View File

@ -29,6 +29,10 @@ export default class DeedsController extends ApiController {
let query: Prisma.DeedsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -29,6 +29,10 @@ export default class DocumentTypesController extends ApiController {
let query: Prisma.DocumentTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -10,11 +10,12 @@ import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import documentHandler from "@App/middlewares/OfficeMembershipHandlers/DocumentHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import EmailBuilder from "@Common/emails/EmailBuilder";
@Controller()
@Service()
export default class DocumentsController extends ApiController {
constructor(private documentsService: DocumentsService) {
constructor(private documentsService: DocumentsService, private emailBuilder: EmailBuilder) {
super();
}
@ -29,6 +30,10 @@ export default class DocumentsController extends ApiController {
let query: Prisma.DocumentsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
@ -70,6 +75,10 @@ export default class DocumentsController extends ApiController {
strategy: "excludeAll",
});
//create email for asked document
await this.emailBuilder.sendDocumentEmails(documentEntityCreated);
//success
this.httpCreated(response, document);
} catch (error) {
@ -120,7 +129,7 @@ export default class DocumentsController extends ApiController {
/**
* @description Update a specific document
*/
@Put("/api/v1/notary/documents/:uid/refuse", [authHandler, ruleHandler, documentHandler])
@Put("/api/v1/admin/documents/:uid/refuse", [authHandler, roleHandler, ruleHandler, documentHandler])
protected async refuseDocument(req: Request, response: Response) {
try {
const uid = req.params["uid"];
@ -151,8 +160,7 @@ export default class DocumentsController extends ApiController {
const documentEntityUpdated: Documents = await this.documentsService.refuse(uid, documentEntity, req.body.refused_reason);
//create email for asked document
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
// this.notificationBuilder.sendDocumentAnchoredNotificatiom(documentEntityUpdated);
await this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
//Hydrate ressource with prisma entity
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });

View File

@ -1,5 +1,5 @@
import { Response, Request } from "express";
import { Controller, Delete, Get } from "@ControllerPattern/index";
import { Controller, Get } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import FilesService from "@Services/common/FilesService/FilesService";
@ -28,6 +28,10 @@ export default class FilesController extends ApiController {
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
@ -75,44 +79,6 @@ export default class FilesController extends ApiController {
}
}
/**
* @description Delete a specific File
*/
@Delete("/api/v1/admin/files/:uid", [authHandler, roleHandler, ruleHandler, fileHandler])
protected async delete(req: Request, response: Response) {
try {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "No uid provided");
return;
}
const fileFound = await this.filesService.getByUid(uid);
if (!fileFound) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//call service to get prisma entity
const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpInternalError(response, error);
return;
}
}
/**
* @description Get a specific File by uid
*/

View File

@ -28,6 +28,10 @@ export default class OfficeFoldersController extends ApiController {
let query: Prisma.OfficeFoldersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {
@ -89,6 +93,7 @@ export default class OfficeFoldersController extends ApiController {
await officeFolderRessource.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
//call service to get prisma entity
try {
const officeFolderEntity = await this.officeFoldersService.create(officeFolderRessource);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntity, {
@ -96,6 +101,10 @@ export default class OfficeFoldersController extends ApiController {
});
//success
this.httpCreated(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;
@ -128,6 +137,7 @@ export default class OfficeFoldersController extends ApiController {
await validateOrReject(officeFolderEntity, { groups: ["updateFolder"], forbidUnknownValues: false });
//call service to get prisma entity
try {
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officeFolderEntity);
//Hydrate ressource with prisma entity
@ -137,6 +147,10 @@ export default class OfficeFoldersController extends ApiController {
//success
this.httpSuccess(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -29,6 +29,10 @@ export default class OfficeRolesController extends ApiController {
let query: Prisma.OfficeRolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -3,7 +3,7 @@ import { Controller, Get } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import OfficesService from "@Services/admin/OfficesService/OfficesService";
import { Service } from "typedi";
import { Offices } from "@prisma/client";
import { Offices, Prisma } from "@prisma/client";
import { Office as OfficeResource } from "le-coffre-resources/dist/Admin";
import ruleHandler from "@App/middlewares/RulesHandler";
import authHandler from "@App/middlewares/AuthHandler";
@ -22,9 +22,13 @@ export default class OfficesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.OfficesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity
const officesEntities: Offices[] = await this.officesService.get(query);

View File

@ -7,6 +7,7 @@ import { Role } from "le-coffre-resources/dist/Admin";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -22,9 +23,13 @@ export default class RolesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity

View File

@ -7,6 +7,7 @@ import { Rule } from "le-coffre-resources/dist/Admin";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -22,9 +23,13 @@ export default class RulesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RulesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity

View File

@ -29,6 +29,10 @@ export default class UsersController extends ApiController {
let query: Prisma.UsersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -4,12 +4,11 @@ import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
import { Documents, Prisma } from "@prisma/client";
import { Document } from "le-coffre-resources/dist/Customer";
import { Document, OfficeFolder } from "le-coffre-resources/dist/Customer";
import authHandler from "@App/middlewares/AuthHandler";
import documentHandler from "@App/middlewares/CustomerHandler/DocumentHandler";
import { validateOrReject } from "class-validator";
import OfficeFoldersService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService";
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
@Controller()
@Service()
@ -29,18 +28,25 @@ export default class DocumentsController extends ApiController {
let query: Prisma.DocumentsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const email: string = req.body.user.email;
if (!email) {
this.httpBadRequest(response, "Missing customer email");
return;
}
const customerId: string = req.body.user.customerId;
if (query.where?.depositor) delete query.where.depositor;
if (query.where?.depositor_uid) delete query.where.depositor_uid;
const customerWhereInput: Prisma.DocumentsWhereInput = { ...query.where, depositor: { uid: customerId } };
const customerWhereInput: Prisma.DocumentsWhereInput = { ...query.where, depositor: { contact: { email: email } } };
query.where = customerWhereInput;
if (query.include?.folder) delete query.include.folder;
//call service to get prisma entity
const documentEntities: Documents[] = await this.documentsService.get(query);
//Hydrate ressource with prisma entity
const documents = Document.hydrateArray<Document>(documentEntities, { strategy: "excludeAll" });
@ -67,6 +73,8 @@ export default class DocumentsController extends ApiController {
let query;
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.folder) delete query.folder;
}
const documentEntity = await this.documentsService.getByUid(uid, query);
@ -82,6 +90,7 @@ export default class DocumentsController extends ApiController {
//success
this.httpSuccess(response, document);
} catch (error) {
console.log(error);
this.httpInternalError(response);
return;
}
@ -91,29 +100,43 @@ export default class DocumentsController extends ApiController {
* @description Create a new File
* @returns File created
*/
@Post("/api/v1/customer/documents", [authHandler])
@Post("/api/v1/customer/documents", [authHandler, documentHandler])
protected async post(req: Request, response: Response) {
try {
//init Document resource with request body values
const documentEntity = Document.hydrate<Document>(req.body);
const email = req.body.user.email;
if (!documentEntity.folder?.uid) {
this.httpBadRequest(response, "No folder uid provided");
return;
}
const folder = await this.officeFoldersService.getByUid(documentEntity.folder.uid, {folder_anchor: true});
const folder = await this.officeFoldersService.getByUid(documentEntity.folder.uid, {
folder_anchor: true,
customers: { include: { contact: true } },
});
if (!folder) {
this.httpBadRequest(response, "Folder not found");
return;
}
const folderEntity = OfficeFolder.hydrate<OfficeFolder>(folder);
if (folderEntity.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
this.httpBadRequest(response, "Cannot update a verified folder");
const folderEntity = OfficeFolder.hydrate<OfficeFolder>(folder, { strategy: "excludeAll" });
if (!folderEntity.customers) {
this.httpBadRequest(response, "No customers found in folder");
return;
}
const depositor = folderEntity.customers.find((customer) => customer.contact?.email === email);
delete documentEntity.depositor;
documentEntity.depositor = depositor;
try {
//validate document
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
//call service to get prisma entity
const documentEntityCreated = await this.documentsService.create(documentEntity);

View File

@ -1,9 +1,9 @@
import { Response, Request } from "express";
import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
import { Controller, Delete, Get, Post } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import FilesService from "@Services/common/FilesService/FilesService";
import { Files, Prisma } from "@prisma/client";
import { Prisma } from "@prisma/client";
import { File } from "le-coffre-resources/dist/Customer";
import { Document } from "le-coffre-resources/dist/Customer";
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
@ -15,7 +15,11 @@ import { validateOrReject } from "class-validator";
@Controller()
@Service()
export default class FilesController extends ApiController {
constructor(private filesService: FilesService, private documentService: DocumentsService, private notificationBuilder : NotificationBuilder) {
constructor(
private filesService: FilesService,
private documentService: DocumentsService,
private notificationBuilder: NotificationBuilder,
) {
super();
}
@ -30,10 +34,21 @@ export default class FilesController extends ApiController {
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
const customerId: string = req.body.user.customerId;
const customerWhereInput: Prisma.FilesWhereInput = { document: { depositor: { uid: customerId } } };
}
const email: string = req.body.user.email;
if (!email) {
this.httpBadRequest(response, "Missing customer email");
return;
}
if (query.where?.document?.depositor) delete query.where.document.depositor;
const customerWhereInput: Prisma.FilesWhereInput = { ...query.where, document: { depositor: { contact: { email: email } } } };
query.where = customerWhereInput;
if (query.include?.document) delete query.include.document;
//call service to get prisma entity
const fileEntities = await this.filesService.get(query);
@ -113,7 +128,6 @@ export default class FilesController extends ApiController {
strategy: "excludeAll",
});
//success
this.httpCreated(response, fileEntityHydrated);
} catch (error) {
@ -122,41 +136,6 @@ export default class FilesController extends ApiController {
}
}
/**
* @description Update a specific file
*/
@Put("/api/v1/customer/files/:uid", [authHandler, fileHandler])
protected async update(req: Request, response: Response) {
try {
const uid = req.params["uid"];
if (!uid) {
throw new Error("No uid provided");
}
const fileFound = await this.filesService.getByUid(uid);
if (!fileFound) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//init File resource with request body values
const fileEntity = File.hydrate<File>(req.body);
//call service to get prisma entity
const fileEntityUpdated: Files = await this.filesService.update(uid, fileEntity);
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntityUpdated, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpBadRequest(response, error);
return;
}
}
/**
* @description Delete a specific File
*/
@ -169,19 +148,22 @@ export default class FilesController extends ApiController {
return;
}
const fileFound = await this.filesService.getByUid(uid);
const fileFound = await this.filesService.getByUid(uid, { document: { include: { files: true, document_type: true } } });
if (!fileFound) {
this.httpNotFoundRequest(response, "file not found");
return;
}
const fileFoundEntity = File.hydrate<File>(fileFound, { strategy: "excludeAll" });
//call service to get prisma entity
const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
if (
!(fileFoundEntity.document!.files?.find((file) => file.archived_at === null && file.uid !== uid)) &&
fileFoundEntity.document!.document_type!.name === "Autres documents"
) {
await this.documentService.delete(fileFoundEntity.document!.uid!);
}
//Hydrate ressource with prisma entity
@ -210,6 +192,7 @@ export default class FilesController extends ApiController {
let query;
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.document) delete query.document;
}
const fileEntity = await this.filesService.getByUid(uid, query);

View File

@ -7,9 +7,6 @@ import { OfficeFolders, Prisma } from "@prisma/client";
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
import officeFolderHandler from "@App/middlewares/CustomerHandler/FolderHandler";
import authHandler from "@App/middlewares/AuthHandler";
// import authHandler from "@App/middlewares/AuthHandler";
// import ruleHandler from "@App/middlewares/RulesHandler";
// import folderHandler from "@App/middlewares/OfficeMembershipHandlers/FolderHandler";
@Controller()
@Service()
@ -28,16 +25,25 @@ export default class OfficeFoldersController extends ApiController {
let query: Prisma.OfficeFoldersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const customerId: string = req.body.user.customerId;
if(!customerId) {
this.httpBadRequest(response, "No customerId provided");
const email: string = req.body.user.email;
if (!email) {
this.httpBadRequest(response, "Missing customer email");
return;
}
if (query.where?.customers) delete query.where.customers;
const officeFolderWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, customers: { some: { uid: customerId } }};
const officeFolderWhereInput: Prisma.OfficeFoldersWhereInput = {
...query.where,
customers: { some: { contact: { email: email } } },
};
query.where = officeFolderWhereInput;
if (query.include) delete query.include;
query.include = { customers: { include: { contact: true } } };
//call service to get prisma entity
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
@ -46,6 +52,11 @@ export default class OfficeFoldersController extends ApiController {
const officeFolders = OfficeFolder.hydrateArray<OfficeFolder>(officeFolderEntities, {
strategy: "excludeAll",
});
officeFolders.forEach((officeFolder) => {
officeFolder.customers = officeFolder.customers!.filter((customer) => customer.contact?.email === email);
});
//success
this.httpSuccess(response, officeFolders);
} catch (error) {
@ -67,12 +78,13 @@ export default class OfficeFoldersController extends ApiController {
return;
}
const email: string = req.body.user.email;
let query;
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query?.customers) {
query.customers = true;
}
if (query?.customers) delete query.customers;
query.customers = { include: { contact: true } };
}
const officeFolderEntity = await this.officeFoldersService.getByUid(uid, query);
@ -84,6 +96,10 @@ export default class OfficeFoldersController extends ApiController {
//Hydrate ressource with prisma entity
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntity, { strategy: "excludeAll" });
if(officeFolder.customers) {
officeFolder.customers = officeFolder.customers!.filter((customer) => customer.contact?.email === email);
}
//success
this.httpSuccess(response, officeFolder);
} catch (error) {

View File

@ -1,67 +0,0 @@
import { Response, Request } from "express";
import { Controller, Post } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import AuthService, { ICustomerJwtPayload } from "@Services/common/AuthService/AuthService";
import { JwtPayload } from "jsonwebtoken";
@Controller()
@Service()
export default class CustomerController extends ApiController {
constructor(private authService: AuthService) {
super();
}
// @Post("/api/v1/france-connect/customer/login/:email")
// protected async login(req: Request, response: Response) {
// try {
// const email = req.params["email"];
// if (!email) throw new Error("email is required");
// const payload = await this.authService.getCustomerJwtPayload(email);
// if (!payload) {
// this.httpNotFoundRequest(response);
// return;
// }
// const accessToken = this.authService.generateAccessToken(payload);
// const refreshToken = this.authService.generateRefreshToken(payload);
// //success
// this.httpSuccess(response, { accessToken, refreshToken });
// } catch (error) {
// this.httpInternalError(response);
// return;
// }
// }
@Post("/api/v1/france-connect/customer/refresh-token")
protected async refreshToken(req: Request, response: Response) {
try {
const authHeader = req.headers["authorization"];
const token = authHeader && authHeader.split(" ")[1];
if (!token) {
this.httpBadRequest(response);
return;
}
let accessToken;
this.authService.verifyRefreshToken(token, (err, customerPayload) => {
if (err) {
this.httpUnauthorized(response);
return;
}
const customer = customerPayload as JwtPayload;
delete customer.iat;
delete customer!.exp;
accessToken = this.authService.generateAccessToken({...customer} as ICustomerJwtPayload);
});
//success
this.httpSuccess(response, {accessToken});
} catch (error) {
this.httpInternalError(response);
return;
}
}
}

View File

@ -4,7 +4,7 @@ import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import Id360Service, { EnrollmentResponse } from "@Services/common/Id360Service/Id360Service";
import CustomersService from "@Services/customer/CustomersService/CustomersService";
import AuthService from "@Services/common/AuthService/AuthService";
import AuthService, { ICustomerJwtPayload } from "@Services/common/AuthService/AuthService";
import { Customer } from "le-coffre-resources/dist/SuperAdmin";
@Controller()
@ -34,28 +34,34 @@ export default class CustomerController extends ApiController {
return;
}
try {
await new Promise((resolve) => setTimeout(resolve, 3000)); // wait 3 seconds to be sure that the enrollment is finilazed
const res = await this.id360Service.getEnrollment(callbackToken);
const enrollment = await res.json() as EnrollmentResponse;
if(enrollment.status === "STARTED") {
this.loginCallback(req, response);
}
const enrollment = (await res.json()) as EnrollmentResponse;
if (enrollment.status !== "OK") {
this.httpUnauthorized(response, "Enrollment status is not OK");
return;
}
const customerData = await this.id360Service.getReport(enrollment.id);
const customer = await this.customerService.get({
where: {
contact: {
last_name: { contains: customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].family_name,
mode: 'insensitive' },
first_name: { contains: customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].given_name.split(" ")[0],
mode: 'insensitive'},
last_name: {
contains: customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].family_name,
mode: "insensitive",
},
first_name: {
contains:
customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].given_name.split(
" ",
)[0],
mode: "insensitive",
},
},
},
include: {
contact: true,
}
},
});
// const contact = await this.customerService.getByEmail(
// customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].email,
@ -66,7 +72,7 @@ export default class CustomerController extends ApiController {
}
const customersHydrated = Customer.hydrateArray<Customer>(customer);
const payload = await this.authService.getCustomerJwtPayload(customersHydrated[0]!);
const payload = await this.authService.getCustomerJwtPayload(customersHydrated);
const accessToken = this.authService.generateAccessToken(payload);
const refreshToken = this.authService.generateRefreshToken(payload);
this.httpSuccess(response, { accessToken, refreshToken });
@ -88,4 +94,38 @@ export default class CustomerController extends ApiController {
return;
}
}
@Post("/api/v1/id360/customers/refresh-token")
protected async refreshToken(req: Request, response: Response) {
try {
const authHeader = req.headers["authorization"];
const token = authHeader && authHeader.split(" ")[1];
if (!token) {
this.httpBadRequest(response);
return;
}
let accessToken;
this.authService.verifyRefreshToken(token, (err, userPayload) => {
if (err) {
console.log(err);
this.httpUnauthorized(response);
return;
}
const user = userPayload as ICustomerJwtPayload;
delete user.iat;
delete user.exp;
accessToken = this.authService.generateAccessToken(user);
});
//success
this.httpSuccess(response, { accessToken });
} catch (error) {
console.log(error);
this.httpInternalError(response);
return;
}
}
}

View File

@ -70,12 +70,15 @@ export default class UserController extends ApiController {
}
const user = userPayload as IUserJwtPayload;
delete user.iat;
delete user.exp;
accessToken = this.authService.generateAccessToken(user);
});
//success
this.httpSuccess(response, { accessToken });
} catch (error) {
console.log(error);
this.httpInternalError(response);
return;
}

View File

@ -27,6 +27,10 @@ export default class CustomersController extends ApiController {
let query: Prisma.CustomersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
@ -57,8 +61,28 @@ export default class CustomersController extends ApiController {
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["createCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length > 0) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
//call service to get prisma entity
const customerEntityCreated = await this.customersService.create(customerEntity);
//Hydrate ressource with prisma entity
@ -93,15 +117,47 @@ export default class CustomersController extends ApiController {
return;
}
req.body.contact.uid = userFound.contact_uid;
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["updateCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
if (customerEntity.contact?.email) {
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length != 0) {
try {
customers.forEach((customer) => {
if (customer.uid != uid) {
throw new Error("email déjà utilisé");
}
});
} catch (error) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
}
}
//call service to get prisma entity
try {
const customerEntityUpdated = await this.customersService.update(uid, customerEntity);
//Hydrate ressource with prisma entity
const customer = Customer.hydrate<Customer>(customerEntityUpdated, {
strategy: "excludeAll",
@ -109,6 +165,11 @@ export default class CustomersController extends ApiController {
//success
this.httpSuccess(response, customer);
} catch (error) {
console.log(error);
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -28,6 +28,10 @@ export default class DeedTypesController extends ApiController {
let query: Prisma.DeedTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -28,11 +28,15 @@ export default class DeedsController extends ApiController {
let query: Prisma.DeedsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
if(!query.where) query.where = { deed_type : {office: officeWhereInput}};
query.where.deed_type!.office = officeWhereInput;
if(query.where?.deed_type) delete query.where.deed_type;
query.where = {...query.where, deed_type : {office: officeWhereInput}};
//call service to get prisma entity
const deedEntities: Deeds[] = await this.deedsService.get(query);

View File

@ -4,7 +4,6 @@ import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import DocumentTypesService from "@Services/notary/DocumentTypesService/DocumentTypesService";
import { DocumentTypes, Prisma } from "@prisma/client";
import ObjectHydrate from "@Common/helpers/ObjectHydrate";
import { DocumentType } from "le-coffre-resources/dist/Notary";
import { validateOrReject } from "class-validator";
import authHandler from "@App/middlewares/AuthHandler";
@ -28,6 +27,10 @@ export default class DocumentTypesController extends ApiController {
let query: Prisma.DocumentTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
@ -133,11 +136,15 @@ export default class DocumentTypesController extends ApiController {
const documentTypeEntity = await this.documentTypesService.getByUid(uid, query);
//Hydrate ressource with prisma entity
const user = ObjectHydrate.hydrate<DocumentType>(new DocumentType(), documentTypeEntity!, { strategy: "excludeAll" });
if (!documentTypeEntity) {
this.httpNotFoundRequest(response, "document type not found");
return;
}
const documentType = DocumentType.hydrate<DocumentType>(documentTypeEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, user);
this.httpSuccess(response, documentType);
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -35,6 +35,10 @@ export default class DocumentsController extends ApiController {
let query: Prisma.DocumentsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
@ -86,7 +90,7 @@ export default class DocumentsController extends ApiController {
const documentEntityCreated = await this.documentsService.create(documentEntity);
//create email for asked document
this.emailBuilder.sendDocumentEmails(documentEntityCreated);
await this.emailBuilder.sendDocumentEmails(documentEntityCreated);
//Hydrate ressource with prisma entity
const document = Document.hydrate<Document>(documentEntityCreated, {
@ -120,6 +124,11 @@ export default class DocumentsController extends ApiController {
return;
}
if(documentFound.document_status === EDocumentStatus.REFUSED || documentFound.document_status === EDocumentStatus.VALIDATED) {
this.httpForbidden(response, "You are not allowed to update a VALIDATED or REFUSED document");
return;
}
//init Document resource with request body values
const documentEntity = Document.hydrate<Document>(req.body);
@ -177,9 +186,10 @@ export default class DocumentsController extends ApiController {
//call service to get prisma entity
const documentEntityUpdated: Documents = await this.documentsService.refuse(uid, documentEntity, req.body.refused_reason);
//create email for asked document
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
// this.notificationBuilder.sendDocumentAnchoredNotificatiom(documentEntityUpdated);
await this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
//Hydrate ressource with prisma entity
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });

View File

@ -1,5 +1,5 @@
import { Response, Request } from "express";
import { Controller, Delete, Get } from "@ControllerPattern/index";
import { Controller, Get } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import FilesService from "@Services/common/FilesService/FilesService";
@ -27,6 +27,10 @@ export default class FilesController extends ApiController {
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
@ -74,44 +78,6 @@ export default class FilesController extends ApiController {
}
}
/**
* @description Delete a specific File
*/
@Delete("/api/v1/notary/files/:uid", [authHandler, ruleHandler, fileHandler])
protected async delete(req: Request, response: Response) {
try {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "No uid provided");
return;
}
const fileFound = await this.filesService.getByUid(uid);
if (!fileFound) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//call service to get prisma entity
const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpInternalError(response, error);
return;
}
}
/**
* @description Get a specific File by uid
*/

View File

@ -3,9 +3,10 @@ import { Controller, Get, Post } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary";
import { getFolderHashes } from "@Common/optics/notary";
import { getFolderHashes, getFolderFilesUid } from "@Common/optics/notary";
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
import FilesService from "@Services/common/FilesService/FilesService";
import SecureService from "@Services/common/SecureService/SecureService";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
@ -14,6 +15,7 @@ import OfficeFolderAnchor from "le-coffre-resources/dist/Notary/OfficeFolderAnch
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
import { Prisma } from "@prisma/client";
import OfficeFolderAnchorsService from "@Services/notary/OfficeFolderAnchorsService/OfficeFolderAnchorsService";
import Zip from "adm-zip";
const hydrateOfficeFolderAnchor = (data: any): OfficeFolderAnchor =>
OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(
@ -41,13 +43,14 @@ export default class OfficeFoldersController extends ApiController {
private officeFolderAnchorsRepository: OfficeFolderAnchorsRepository,
private officeFolderAnchorsService: OfficeFolderAnchorsService,
private officeFoldersService: OfficeFoldersService,
private filesService: FilesService,
private notificationBuilder: NotificationBuilder,
) {
super();
}
/**
* @description Download a folder anchoring proof document
* @description Download a folder anchoring proof document along with all accessible files
*/
@Get("/api/v1/notary/anchors/download/:uid", [authHandler, ruleHandler, folderHandler])
protected async download(req: Request, response: Response) {
@ -76,6 +79,7 @@ export default class OfficeFoldersController extends ApiController {
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
const folderHashes = getFolderHashes(officeFolder);
const folderFilesUid = getFolderFilesUid(officeFolder);
if (folderHashes.length === 0) {
this.httpNotFoundRequest(response, "No file hash to anchor");
@ -83,10 +87,25 @@ export default class OfficeFoldersController extends ApiController {
}
const sortedHashes = [...folderHashes].sort();
const buffer = await this.secureService.download(sortedHashes);
const anchoringProof = await this.secureService.download(sortedHashes);
response.setHeader("Content-Type", "application/pdf");
this.httpSuccess(response, buffer);
const addFileToZip = (zip: Zip) => (uid: string): Promise<void> =>
(async () => {
const data = await this.filesService.download(uid);
if (!data?.buffer) return;
zip.addFile(`Documents du client/${uid}-${data.file.file_name}`, data.buffer);
})()
const uids: string[] = folderFilesUid.filter((uid): uid is string => uid !== undefined);
const zip = new Zip();
zip.addFile("Certificat de dépôt du dossier.pdf", anchoringProof);
await Promise.allSettled(
uids.map(addFileToZip(zip))
)
response.setHeader("Content-Type", "application/zip");
this.httpSuccess(response, zip.toBuffer());
} catch (error) {
this.httpInternalError(response, error);
return;
@ -256,6 +275,10 @@ export default class OfficeFoldersController extends ApiController {
let query: Prisma.OfficeFolderAnchorsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
query.where = {

View File

@ -27,6 +27,10 @@ export default class OfficeFoldersController extends ApiController {
let query: Prisma.OfficeFoldersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {
@ -86,6 +90,7 @@ export default class OfficeFoldersController extends ApiController {
await officeFolderRessource.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
//call service to get prisma entity
try {
const officeFolderEntity = await this.officeFoldersService.create(officeFolderRessource);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntity, {
@ -93,6 +98,10 @@ export default class OfficeFoldersController extends ApiController {
});
//success
this.httpCreated(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;
@ -111,9 +120,7 @@ export default class OfficeFoldersController extends ApiController {
return;
}
const officeFolderFound = await this.officeFoldersService.getByUid(uid, {
folder_anchor: true,
});
const officeFolderFound = await this.officeFoldersService.getByUid(uid);
if (!officeFolderFound) {
this.httpNotFoundRequest(response, "office folder not found");
@ -121,17 +128,14 @@ export default class OfficeFoldersController extends ApiController {
}
//init OfficeFolder resource with request body values
const officefolderToUpdate = OfficeFolder.hydrate<OfficeFolder>(req.body);
const officeFolderFoundEntity = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound);
//validate folder
await validateOrReject(officefolderToUpdate, { groups: ["updateFolder"], forbidUnknownValues: false });
const officeFolderEntity = OfficeFolder.hydrate<OfficeFolder>(req.body);
//validate folder
await validateOrReject(officeFolderEntity, { groups: ["updateFolder"], forbidUnknownValues: false });
if (officeFolderFoundEntity.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
this.httpBadRequest(response, "Cannot update a verified folder");
return;
}
//call service to get prisma entity
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
try {
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officeFolderEntity);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
@ -140,6 +144,10 @@ export default class OfficeFoldersController extends ApiController {
//success
this.httpSuccess(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;
@ -182,7 +190,7 @@ export default class OfficeFoldersController extends ApiController {
}
//call service to get prisma entity
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
const officeFolderEntityUpdated = await this.officeFoldersService.updateStatus(uid, officefolderToUpdate);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
@ -228,7 +236,7 @@ export default class OfficeFoldersController extends ApiController {
await validateOrReject(officefolderToUpdate, { groups: ["updateFolder"], forbidUnknownValues: false });
//call service to get prisma entity
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
const officeFolderEntityUpdated = await this.officeFoldersService.updateStatus(uid, officefolderToUpdate);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {

View File

@ -26,6 +26,10 @@ export default class OfficeRolesController extends ApiController {
let query: Prisma.OfficeRolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -3,7 +3,7 @@ import { Controller, Get } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import OfficesService from "@Services/notary/OfficesService/OfficesService";
import { Service } from "typedi";
import { Offices } from "@prisma/client";
import { Offices, Prisma } from "@prisma/client";
import { Office as OfficeResource } from "le-coffre-resources/dist/Notary";
import ruleHandler from "@App/middlewares/RulesHandler";
import authHandler from "@App/middlewares/AuthHandler";
@ -21,9 +21,13 @@ export default class OfficesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.OfficesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity
const officesEntities: Offices[] = await this.officesService.get(query);

View File

@ -6,6 +6,7 @@ import { Service } from "typedi";
import { Role } from "le-coffre-resources/dist/Notary";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -21,9 +22,13 @@ export default class RolesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity

View File

@ -6,6 +6,7 @@ import { Service } from "typedi";
import { Rule } from "le-coffre-resources/dist/Notary";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -21,9 +22,13 @@ export default class RulesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RulesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
query.where = {

View File

@ -6,6 +6,7 @@ import UserNotification from "le-coffre-resources/dist/Notary/UserNotification";
import UserNotificationService from "@Services/common/UserNotificationService/UserNotificationService";
import authHandler from "@App/middlewares/AuthHandler";
import { Prisma } from "@prisma/client";
import roleHandler from "@App/middlewares/RolesHandler";
@Controller()
@Service()
@ -17,16 +18,18 @@ export default class UserNotificationController extends ApiController {
/**
* @description Get all customers
*/
@Get("/api/v1/notary/notifications", [authHandler])
@Get("/api/v1/notary/notifications", [authHandler, roleHandler])
protected async get(req: Request, response: Response) {
try {
//get query
let query: any = {};
let query: Prisma.UserNotificationsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const userId: string = req.body.user.userId;
if(query.where?.user_uid) delete query.where.user_uid;
if(query.where?.user?.uid) delete query.where.user.uid;
@ -51,7 +54,7 @@ export default class UserNotificationController extends ApiController {
/**
* @description Modify a specific customer by uid
*/
@Put("/api/v1/notary/notifications/:uid", [authHandler])
@Put("/api/v1/notary/notifications/:uid", [authHandler, roleHandler])
protected async put(req: Request, response: Response) {
try {
const uid = req.params["uid"];
@ -94,7 +97,7 @@ export default class UserNotificationController extends ApiController {
/**
* @description Get a specific customer by uid
*/
@Get("/api/v1/notary/notifications/:uid", [authHandler])
@Get("/api/v1/notary/notifications/:uid", [authHandler, roleHandler])
protected async getOneByUid(req: Request, response: Response) {
try {
const uid = req.params["uid"];

View File

@ -26,6 +26,10 @@ export default class UsersController extends ApiController {
let query: Prisma.UsersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -25,9 +25,13 @@ export default class CustomersController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.CustomersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
@ -53,14 +57,34 @@ export default class CustomersController extends ApiController {
/**
* @description Create a new customer
*/
@Post("/api/v1/super-admin/customers", [authHandler, roleHandler, ruleHandler])
@Post("/api/v1/notary/customers", [authHandler, ruleHandler])
protected async post(req: Request, response: Response) {
try {
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["createCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length > 0) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
//call service to get prisma entity
const customerEntityCreated = await this.customersService.create(customerEntity);
//Hydrate ressource with prisma entity
@ -79,7 +103,7 @@ export default class CustomersController extends ApiController {
/**
* @description Modify a specific customer by uid
*/
@Put("/api/v1/super-admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
@Put("/api/v1/notary/customers/:uid", [authHandler, ruleHandler, customerHandler])
protected async put(req: Request, response: Response) {
try {
const uid = req.params["uid"];
@ -95,15 +119,47 @@ export default class CustomersController extends ApiController {
return;
}
req.body.contact.uid = userFound.contact_uid;
//init IUser resource with request body values
const customerEntity = Customer.hydrate<Customer>(req.body);
//validate user
try {
await validateOrReject(customerEntity, { groups: ["updateCustomer"], forbidUnknownValues: false });
} catch (error) {
this.httpValidationError(response, error);
return;
}
if (customerEntity.contact?.email) {
const customers = await this.customersService.get({
where: {
contact: { email: customerEntity.contact?.email },
office_folders: {
some: {
office_uid: req.body.user.office_Id,
},
},
},
});
if (customers.length != 0) {
try {
customers.forEach((customer) => {
if (customer.uid != uid) {
throw new Error("email déjà utilisé");
}
});
} catch (error) {
this.httpValidationError(response, [{ property: "email", constraints: { unique: "email déjà utilisé" } }]);
return;
}
}
}
//call service to get prisma entity
try {
const customerEntityUpdated = await this.customersService.update(uid, customerEntity);
//Hydrate ressource with prisma entity
const customer = Customer.hydrate<Customer>(customerEntityUpdated, {
strategy: "excludeAll",
@ -111,6 +167,11 @@ export default class CustomersController extends ApiController {
//success
this.httpSuccess(response, customer);
} catch (error) {
console.log(error);
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -29,6 +29,10 @@ export default class DeedTypesController extends ApiController {
let query: Prisma.DeedTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -29,6 +29,10 @@ export default class DeedsController extends ApiController {
let query: Prisma.DeedsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -29,6 +29,10 @@ export default class DocumentTypesController extends ApiController {
let query: Prisma.DocumentTypesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;

View File

@ -2,6 +2,7 @@ import authHandler from "@App/middlewares/AuthHandler";
import documentHandler from "@App/middlewares/OfficeMembershipHandlers/DocumentHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import EmailBuilder from "@Common/emails/EmailBuilder";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
import { Documents, EDocumentStatus, Prisma } from "@prisma/client";
@ -14,7 +15,7 @@ import { Service } from "typedi";
@Controller()
@Service()
export default class DocumentsController extends ApiController {
constructor(private documentsService: DocumentsService) {
constructor(private documentsService: DocumentsService, private emailBuilder: EmailBuilder) {
super();
}
@ -29,6 +30,10 @@ export default class DocumentsController extends ApiController {
let query: Prisma.DocumentsFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
@ -36,8 +41,6 @@ export default class DocumentsController extends ApiController {
if (!query.where) query.where = { document_type: { office: officeWhereInput } };
// query.where.document_type!.office = officeWhereInput;
//call service to get prisma entity
const documentEntities = await this.documentsService.get(query);
@ -74,6 +77,9 @@ export default class DocumentsController extends ApiController {
strategy: "excludeAll",
});
//create email for asked document
await this.emailBuilder.sendDocumentEmails(documentEntityCreated);
//success
this.httpCreated(response, document);
} catch (error) {
@ -124,7 +130,7 @@ export default class DocumentsController extends ApiController {
/**
* @description Update a specific document
*/
@Put("/api/v1/notary/documents/:uid/refuse", [authHandler, ruleHandler, documentHandler])
@Put("/api/v1/super-admin/documents/:uid/refuse", [authHandler, roleHandler, ruleHandler, documentHandler])
protected async refuseDocument(req: Request, response: Response) {
try {
const uid = req.params["uid"];
@ -155,8 +161,7 @@ export default class DocumentsController extends ApiController {
const documentEntityUpdated: Documents = await this.documentsService.refuse(uid, documentEntity, req.body.refused_reason);
//create email for asked document
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
// this.notificationBuilder.sendDocumentAnchoredNotificatiom(documentEntityUpdated);
await this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
//Hydrate ressource with prisma entity
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });

View File

@ -1,5 +1,5 @@
import { Response, Request } from "express";
import { Controller, Delete, Get } from "@ControllerPattern/index";
import { Controller, Get } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import FilesService from "@Services/common/FilesService/FilesService";
@ -28,6 +28,10 @@ export default class FilesController extends ApiController {
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
@ -76,44 +80,6 @@ export default class FilesController extends ApiController {
}
}
/**
* @description Delete a specific File
*/
@Delete("/api/v1/super-admin/files/:uid", [authHandler, roleHandler, ruleHandler, fileHandler])
protected async delete(req: Request, response: Response) {
try {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "No uid provided");
return;
}
const fileFound = await this.filesService.getByUid(uid);
if (!fileFound) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//call service to get prisma entity
const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpInternalError(response, error);
return;
}
}
/**
* @description Get a specific File by uid
*/

View File

@ -28,6 +28,10 @@ export default class OfficeFoldersController extends ApiController {
let query: Prisma.OfficeFoldersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {
@ -87,6 +91,7 @@ export default class OfficeFoldersController extends ApiController {
await officeFolderRessource.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
//call service to get prisma entity
try {
const officeFolderEntity = await this.officeFoldersService.create(officeFolderRessource);
//Hydrate ressource with prisma entity
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntity, {
@ -94,6 +99,10 @@ export default class OfficeFoldersController extends ApiController {
});
//success
this.httpCreated(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;
@ -126,6 +135,7 @@ export default class OfficeFoldersController extends ApiController {
await validateOrReject(officeFolderEntity, { groups: ["updateFolder"], forbidUnknownValues: false });
//call service to get prisma entity
try {
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officeFolderEntity);
//Hydrate ressource with prisma entity
@ -135,6 +145,10 @@ export default class OfficeFoldersController extends ApiController {
//success
this.httpSuccess(response, officeFolders);
} catch (error) {
this.httpValidationError(response, error);
return;
}
} catch (error) {
this.httpInternalError(response, error);
return;

View File

@ -28,6 +28,10 @@ export default class OfficeRolesController extends ApiController {
let query: Prisma.OfficeRolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if(req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -3,7 +3,7 @@ import { Controller, Get, Post, Put } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import OfficesService from "@Services/super-admin/OfficesService/OfficesService";
import { Service } from "typedi";
import { Offices } from "@prisma/client";
import { Offices, Prisma } from "@prisma/client";
import { Office as OfficeResource } from "le-coffre-resources/dist/SuperAdmin";
import { validateOrReject } from "class-validator";
import ruleHandler from "@App/middlewares/RulesHandler";
@ -23,9 +23,13 @@ export default class OfficesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.OfficesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if(req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -8,6 +8,7 @@ import { Role } from "le-coffre-resources/dist/SuperAdmin";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -23,9 +24,13 @@ export default class RolesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RolesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity

View File

@ -8,6 +8,7 @@ import { Rule } from "le-coffre-resources/dist/SuperAdmin";
import authHandler from "@App/middlewares/AuthHandler";
import ruleHandler from "@App/middlewares/RulesHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -23,9 +24,13 @@ export default class RulesController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.RulesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
//call service to get prisma entity

View File

@ -10,6 +10,7 @@ import ruleHandler from "@App/middlewares/RulesHandler";
import roleHandler from "@App/middlewares/RolesHandler";
import RolesService from "@Services/super-admin/RolesService/RolesService";
import OfficeRolesService from "@Services/super-admin/OfficeRolesService/OfficeRolesService";
import { Prisma } from "@prisma/client";
@Controller()
@Service()
@ -25,9 +26,13 @@ export default class UsersController extends ApiController {
protected async get(req: Request, response: Response) {
try {
//get query
let query;
let query: Prisma.UsersFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
if (req.query["search"] && typeof req.query["search"] === "string") {

View File

@ -9,7 +9,6 @@ import DeedTypesControllerSuperAdmin from "./api/super-admin/DeedTypesController
import DocumentsControllerSuperAdmin from "./api/super-admin/DocumentsController";
import DocumentTypesControllerSuperAdmin from "./api/super-admin/DocumentTypesController";
import IdNotUserController from "./api/idnot/UserController";
import FranceConnectCustomerController from "./api/franceConnect/CustomerController";
import FilesControllerSuperAdmin from "./api/super-admin/FilesController";
import RulesControllerSuperAdmin from "./api/super-admin/RulesController";
import RolesControllerSuperAdmin from "./api/super-admin/RolesController";
@ -64,7 +63,6 @@ export default {
Container.get(DocumentTypesControllerSuperAdmin);
Container.get(LiveVoteController);
Container.get(IdNotUserController);
Container.get(FranceConnectCustomerController);
Container.get(FilesControllerSuperAdmin);
Container.get(DocumentsControllerSuperAdmin);
Container.get(RulesControllerSuperAdmin);

View File

@ -3,17 +3,17 @@ import DocumentsService from "@Services/customer/DocumentsService/DocumentsServi
import Document from "le-coffre-resources/dist/SuperAdmin/Document";
import { NextFunction, Request, Response } from "express";
import Container from "typedi";
import OfficeFoldersService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService";
import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin";
import CustomersService from "@Services/super-admin/CustomersService/CustomersService";
export default async function documentHandler(req: Request, response: Response, next: NextFunction) {
try {
const customerId = req.body.user.customerId;
const customerEmail = req.body.user.email;
const uid = req.path && req.path.split("/")[5];
if (!uid) {
response.status(HttpCodes.BAD_REQUEST).send("Missing document uid");
return;
}
if (uid) {
const documentService = Container.get(DocumentsService);
const document = await documentService.getByUid(uid, { folder: { include: { folder_anchor: true } } });
@ -23,17 +23,46 @@ export default async function documentHandler(req: Request, response: Response,
}
if (document?.depositor_uid != customerId) {
const customerService = Container.get(CustomersService);
const customers = await customerService.get({where: {contact: { email: customerEmail}}});
if (customers && !customers.find((customer) => customer.uid === document?.depositor_uid)) {
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
return;
}
}
if (req.method === "POST" || req.method === "PUT") {
if (req.method === "PUT" || req.method === "DELETE") {
const documentEntity = Document.hydrate<Document>(document);
if (documentEntity.folder?.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
if (documentEntity.folder!.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a verified folder");
return;
}
}
}
if (req.method === "POST") {
const documentEntity = Document.hydrate<Document>(req.body);
const officeFolderService = Container.get(OfficeFoldersService);
if (documentEntity.folder?.uid) {
const folder = await officeFolderService.getByUid(documentEntity.folder.uid, {
folder_anchor: true,
customers: { include: { contact: true } },
});
if (!folder) {
response.status(HttpCodes.NOT_FOUND).send("Folder not found");
return;
}
const folderEntity = OfficeFolder.hydrate<OfficeFolder>(folder);
if (folderEntity.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a verified folder");
return;
}
if (!folderEntity.customers?.find((customer) => customer.contact?.email === customerEmail)) {
response.status(HttpCodes.BAD_REQUEST).send("Cannot post a document in this folder");
return;
}
}
}
next();
} catch (error) {

View File

@ -5,9 +5,11 @@ import File from "le-coffre-resources/dist/SuperAdmin/File";
import { NextFunction, Request, Response } from "express";
import Container from "typedi";
import { EDocumentStatus } from "@prisma/client";
import CustomersService from "@Services/super-admin/CustomersService/CustomersService";
export default async function fileHandler(req: Request, response: Response, next: NextFunction) {
const customerId = req.body.user.customerId;
const customerEmail = req.body.user.email;
const uid = req.path && req.path.split("/")[5];
const file: string | undefined = req.body["q"];
@ -24,9 +26,13 @@ export default async function fileHandler(req: Request, response: Response, next
return;
}
if (file.document.depositor_uid != customerId) {
const customerService = Container.get(CustomersService);
const customers = await customerService.get({where: {contact: { email: customerEmail}}});
if (customers && !customers.find((customer) => customer.uid === file.document.depositor_uid)) {
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
return;
}
}
if (req.method === "PUT") {
if (file.document.document_status === EDocumentStatus.VALIDATED) {
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a validated document");
@ -43,9 +49,13 @@ export default async function fileHandler(req: Request, response: Response, next
return;
}
if (documentFound.depositor_uid != customerId) {
const customerService = Container.get(CustomersService);
const customers = await customerService.get({where: {contact: { email: customerEmail}}});
if (customers && !customers.find((customer) => customer.uid === documentFound.depositor_uid)) {
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
return;
}
}
if (documentFound.document_status === EDocumentStatus.VALIDATED) {
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a validated document");
return;

View File

@ -1,10 +1,12 @@
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
import OfficeFoldersService from "@Services/customer/OfficeFoldersService/OfficeFoldersService";
import CustomersService from "@Services/super-admin/CustomersService/CustomersService";
import { NextFunction, Request, Response } from "express";
import Container from "typedi";
export default async function officeFolderHandler(req: Request, response: Response, next: NextFunction) {
const customerId = req.body.user.customerId;
const customerEmail = req.body.user.email;
const uid = req.path && req.path.split("/")[5];
if (uid) {
@ -15,10 +17,14 @@ export default async function officeFolderHandler(req: Request, response: Respon
return;
}
if (!officeFolder.customers.find((customer) => customer.uid == customerId)) {
const customerService = Container.get(CustomersService);
const customers = await customerService.get({where: {contact: { email: customerEmail}}});
if (customers && !customers.filter((customer) => officeFolder.customers.includes(customer))) {
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
return;
}
}
}
next();
}

View File

@ -11,12 +11,24 @@ export default async function deedTypeHandler(req: Request, response: Response,
const uid = req.path && req.path.split("/")[5];
const documentTypes: DocumentType[] = req.body.document_types;
const office = req.body.office;
const name = req.body.name;
if (office && office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
return;
}
if (name) {
const deedTypeService = Container.get(DeedTypesService);
const deedType = await deedTypeService.get({
where: { AND: [{ name: { equals: name, mode: "insensitive" } }, { office: { uid: officeId } }] },
});
if (deedType[0] && (!uid || deedType[0].uid != uid)) {
response.status(HttpCodes.VALIDATION_ERROR).send([{ property: "name", constraints: { name: "Nom d'acte déjà utilisé" } }]);
return;
}
}
if (uid) {
const deedTypeService = Container.get(DeedTypesService);
const deedType = await deedTypeService.getByUidWithOffice(uid!);

View File

@ -8,12 +8,24 @@ export default async function documentTypeHandler(req: Request, response: Respon
const officeId = req.body.user.office_Id;
const uid = req.path && req.path.split("/")[5];
const office = req.body.office;
const name = req.body.name;
if (office && office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
return;
}
if (name) {
const documentTypeService = Container.get(DocumentTypesService);
const documentType = await documentTypeService.get({
where: { AND: [{ name: { equals: name, mode: "insensitive" } }, { office: { uid: officeId } }] },
});
if (documentType[0] && (!uid || documentType[0].uid != uid)) {
response.status(HttpCodes.VALIDATION_ERROR).send([{ property: "name", constraints: { name: "Nom de document déjà utilisé" } }]);
return;
}
}
if (uid) {
const documentTypeService = Container.get(DocumentTypesService);
const documentType = await documentTypeService.getByUidWithOffice(uid!);

View File

@ -10,14 +10,32 @@ export default async function folderHandler(req: Request, response: Response, ne
const userId = req.body.user.userId;
let uid = req.path && req.path.split("/")[5];
const office = req.body.office;
const officeFolderNumber = req.body.folder_number;
const deed = req.body.deed;
const folderNumber = req.body.folder_number;
const stakeHolders = req.body.stakeholders as any[];
if (office && office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
return;
}
if(folderNumber) {
const officeFolderService = Container.get(OfficeFoldersService);
const sameFolderNumber = await officeFolderService.get({
where: { AND: [{ folder_number: folderNumber }, { office_uid: officeId }] },
});
if(sameFolderNumber[0] && (!uid || uid != sameFolderNumber[0]?.uid)) {
const error = [{property: "folder_number", constraints: { folder_number: "Numéro de dossier déjà utilisé" } }];
response.status(HttpCodes.VALIDATION_ERROR).send(error);
return;
}
}
if(stakeHolders && stakeHolders.length === 0) {
response.status(HttpCodes.VALIDATION_ERROR).send([{ property: "stakeholders", constraints: { stakeholders: "Au moins un collaborateur est requis" } }]);
return;
}
if (deed && deed.deed_type) {
const deedTypeService = Container.get(DeedTypesService);
const deedTypeWithOffice = await deedTypeService.getByUidWithOffice(deed.deed_type.uid!);
@ -25,20 +43,12 @@ export default async function folderHandler(req: Request, response: Response, ne
response.status(HttpCodes.NOT_FOUND).send("Deed type not found");
return;
}
if (deedTypeWithOffice.office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this deed type");
if(deedTypeWithOffice.archived_at) {
response.status(HttpCodes.FORBIDDEN).send("Deed type is archived");
return;
}
}
const officeFolderService = Container.get(OfficeFoldersService);
if (officeFolderNumber && req.method == "POST") {
const officeFoldersWithSameNumber = await officeFolderService.get({
where: { folder_number: officeFolderNumber, office: { uid: officeId } },
});
if (officeFoldersWithSameNumber.length) {
response.status(HttpCodes.BAD_REQUEST).send("Office number already used");
if (deedTypeWithOffice.office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this deed type");
return;
}
}
@ -47,6 +57,8 @@ export default async function folderHandler(req: Request, response: Response, ne
if(uid === "download") {
uid = req.path && req.path.split("/")[6];
}
const officeFolderService = Container.get(OfficeFoldersService);
const officeFolder = await officeFolderService.getByUidWithStakeholders(uid!);
if (!officeFolder) {

View File

@ -7,6 +7,11 @@ export default async function roleHandler(req: Request, response: Response, next
const namespace = req.path && req.path.split("/")[3];
const role = req.body.user.role;
if(!role) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized without role");
return;
}
if (namespace != "notary" && role != namespace && role != "super-admin") {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this role");
return;

View File

@ -0,0 +1,5 @@
-- DropIndex
DROP INDEX "contacts_cell_phone_number_key";
-- DropIndex
DROP INDEX "contacts_email_key";

View File

@ -35,9 +35,9 @@ model Contacts {
uid String @id @unique @default(uuid())
first_name String @db.VarChar(255)
last_name String @db.VarChar(255)
email String @unique @db.VarChar(255)
email String @db.VarChar(255)
phone_number String? @db.VarChar(50)
cell_phone_number String @unique @db.VarChar(50)
cell_phone_number String @db.VarChar(50)
civility ECivility @default(MALE)
address Addresses? @relation(fields: [address_uid], references: [uid], onDelete: Cascade)
address_uid String? @unique @db.VarChar(255)

View File

@ -1,4 +1,3 @@
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
import { Documents } from "@prisma/client";
import User, { Document } from "le-coffre-resources/dist/SuperAdmin";
@ -6,31 +5,20 @@ import { Service } from "typedi";
import { ETemplates } from "./Templates/EmailTemplates";
import MailchimpService from "@Services/common/MailchimpService/MailchimpService";
import { BackendVariables } from "@Common/config/variables/Variables";
import UsersService from "@Services/super-admin/UsersService/UsersService";
@Service()
export default class EmailBuilder {
public constructor(private mailchimpService: MailchimpService ,private documentsService: DocumentsService, protected variables: BackendVariables){}
public constructor(
private mailchimpService: MailchimpService,
private documentsService: DocumentsService,
protected variables: BackendVariables,
private usersService: UsersService,
) {}
public async sendDocumentEmails(documentEntity: Documents) {
if (documentEntity.document_status !== "ASKED" && documentEntity.document_status !== "REFUSED") return;
const documentPrisma = await this.documentsService.getByUid(documentEntity.uid, { depositor: {include: {contact: true}}, folder:{include:{ office: true}} });
if(!documentPrisma) throw new Error("Document not found");
const document = Document.hydrate<Document>(documentPrisma);
//Use mailchimpService.get get if an email was sent to the user in the lst hour
const lastEmail = await this.mailchimpService.get({ where: { to: document.depositor!.contact!.email, sentAt: { gte: new Date(Date.now() - 3600000) } } });
if(lastEmail.length > 0) return;
const to = document.depositor!.contact!.email;
const civility = this.getCivility(document.depositor!.contact!.civility);
const templateVariables = {
civility: civility,
last_name: document.depositor!.contact!.last_name,
office_name: document.folder!.office!.name,
link: this.variables.APP_HOST
};
let templateName = ETemplates.DOCUMENT_ASKED;
let subject = "Votre notaire vous demande de déposer des pièces pour traiter votre dossier.";
if (documentEntity.document_status === "REFUSED") {
@ -38,6 +26,31 @@ export default class EmailBuilder {
subject = "Un ou plusieurs documents ne sont pas validés. Vous avez une nouvelle action à réaliser.";
}
const documentPrisma = await this.documentsService.getByUid(documentEntity.uid, {
depositor: { include: { contact: true } },
folder: { include: { office: true } },
});
if (!documentPrisma) throw new Error("Document not found");
const document = Document.hydrate<Document>(documentPrisma);
//Use mailchimpService.get get if an email was sent to the user in the lst hour
const lastEmail = await this.mailchimpService.get({
where: {
to: document.depositor!.contact!.email,
OR: [{ sentAt: { gte: new Date(Date.now() - 3600000) } }, { sentAt: null }],
templateName: templateName,
},
});
if (lastEmail.length > 0) return;
const to = document.depositor!.contact!.email;
const templateVariables = {
first_name: document.depositor!.contact!.first_name,
last_name: document.depositor!.contact!.last_name,
office_name: document.folder!.office!.name,
link: `${this.variables.APP_HOST}/customer-login`,
};
this.mailchimpService.create({
templateName,
to,
@ -53,15 +66,21 @@ export default class EmailBuilder {
});
}
public async sendRecapEmails(usersToEmail: User[]){
usersToEmail.forEach(user => {
public async sendRecapEmails() {
const usersToEmail: User[] = await this.usersService.get({
where: { office_folders: { some: { documents: { some: { document_status: "DEPOSITED" } } } } },
distinct: ["uid"],
include: { contact: true },
});
usersToEmail.forEach((user) => {
const to = user.contact!.email;
const civility = this.getCivility(user.contact!.civility);
const templateVariables = {
civility: civility,
last_name: user.contact!.last_name,
link: this.variables.APP_HOST
link: this.variables.APP_HOST,
};
const templateName = ETemplates.DOCUMENT_RECAP;
@ -84,7 +103,7 @@ export default class EmailBuilder {
}
public getCivility(civility: string) {
if(civility === "MALE") return "Mr"
else return "Mme"
if (civility === "MALE") return "Mr";
else return "Mme";
}
}

View File

@ -10,6 +10,7 @@ import { Document, File, OfficeFolder } from "le-coffre-resources/dist/Notary";
export const folderDocumentsLens = Optics.Lens.fromNullableProp<OfficeFolder>()("documents", []);
export const documentFilesLens = Optics.Lens.fromNullableProp<Document>()("files", []);
export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
export const fileUidLens = Optics.Lens.fromProp<File>()("uid");
/**
* Traversals
@ -17,13 +18,17 @@ export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
export const documentsTraversal = Optics.fromTraversable(Array.Traversable)<Document>();
export const filesTraversal = Optics.fromTraversable(Array.Traversable)<File>();
export const folderHashesTraversal = folderDocumentsLens
export const folderFilesTraversal = folderDocumentsLens
.composeTraversal(documentsTraversal)
.composeLens(documentFilesLens)
.composeTraversal(filesTraversal)
.composeLens(fileHashLens);
.composeTraversal(filesTraversal);
export const folderHashesTraversal = folderFilesTraversal.composeLens(fileHashLens);
export const folderFilesUidTraversal = folderFilesTraversal.composeLens(fileUidLens);
/**
* Getters
*/
export const getFolderFiles = (folder: OfficeFolder) => Traversal.getAll(folder)(folderFilesTraversal);
export const getFolderHashes = (folder: OfficeFolder) => Traversal.getAll(folder)(folderHashesTraversal);
export const getFolderFilesUid = (folder: OfficeFolder) => Traversal.getAll(folder)(folderFilesUidTraversal);

View File

@ -18,12 +18,24 @@ export default class ContactRepository extends BaseRepository {
/**
* @description : Find unique customer by email
*/
public async findOneByEmail(email: string): Promise<(Contacts & {customers: Customers | null}) | null> {
return this.model.findUnique({
public async findSomeByEmail(email: string): Promise<(Contacts & {customers: Customers | null})[] | null> {
return this.model.findMany({
where: {
email: email,
},
include: { customers: true }
});
}
/**
* @description : Find unique customer by email
*/
public async findSomeByPhoneNumber(cell_phone_number: string): Promise<(Contacts & {customers: Customers | null})[] | null> {
return this.model.findMany({
where: {
cell_phone_number: cell_phone_number,
},
include: { customers: true }
});
}
}

View File

@ -114,16 +114,16 @@ export default class DocumentsRepository extends BaseRepository {
/**
* @description : Update data of a document
*/
public async refuse(uid: string, document: Partial<DocumentCustomer>, refusedReason?: string): Promise<Documents> {
public async refuse(uid: string, refusedReason?: string): Promise<Documents> {
return this.model.update({
where: {
uid: uid,
},
data: {
document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus],
document_status: EDocumentStatus.REFUSED,
document_history: {
create: {
document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus],
document_status: EDocumentStatus.REFUSED,
refused_reason: refusedReason,
},
},

View File

@ -36,7 +36,7 @@ export default class OfficeFoldersRepository extends BaseRepository {
status: EFolderStatus.LIVE,
deed: {
connect: {
uid: officeFolder.deed?.uid,
uid: officeFolder.deed!.uid,
},
},
office: {
@ -55,6 +55,18 @@ export default class OfficeFoldersRepository extends BaseRepository {
return this.model.create({ ...createArgs, include: { stakeholders: true } });
}
public async updateStatus(uid: string, status: EFolderStatus, archived_description: string | null) {
return this.model.update({
where: {
uid: uid,
},
data: {
status: status,
archived_description: archived_description,
},
});
}
/**
* @description : Update data of an office folder
*/
@ -67,8 +79,6 @@ export default class OfficeFoldersRepository extends BaseRepository {
folder_number: officeFolder.folder_number,
name: officeFolder.name,
description: officeFolder.description,
status: EFolderStatus[officeFolder.status as keyof typeof EFolderStatus],
archived_description: officeFolder.archived_description,
stakeholders: {
set: officeFolder.stakeholders?.map((stakeholder) => ({
uid: stakeholder.uid!,
@ -121,7 +131,7 @@ export default class OfficeFoldersRepository extends BaseRepository {
},
include: {
customers: true,
}
},
});
}

View File

@ -46,12 +46,11 @@ export default class DocumentsService extends BaseService {
public async refuse(uid: string, document: Partial<Document>, refused_reason: string): Promise<Documents> {
if (document.files) {
for (let i = 0; i < document.files.length; i++) {
console.log("archiving file", document.files[i]?.uid);
await this.filesRepository.deleteKeyAndArchive(document.files[i]?.uid as string);
}
}
return this.documentsRepository.refuse(uid, document, refused_reason);
return this.documentsRepository.refuse(uid, refused_reason);
}
/**

View File

@ -3,16 +3,12 @@ import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository";
import BaseService from "@Services/BaseService";
import { OfficeFolder } from "le-coffre-resources/dist/Admin";
import { Service } from "typedi";
import DeedTypesService from "../DeedTypesService/DeedTypesService";
import DeedsRepository from "@Repositories/DeedsRepository";
import { Prisma } from "@prisma/client";
@Service()
export default class OfficeFoldersService extends BaseService {
constructor(
private officeFoldersRepository: OfficeFoldersRepository,
private deedTypeService: DeedTypesService,
private deedRepository: DeedsRepository,
) {
super();
}
@ -30,11 +26,6 @@ export default class OfficeFoldersService extends BaseService {
* @throws {Error} If folder cannot be created
*/
public async create(officeFolderEntity: OfficeFolder): Promise<OfficeFolders> {
const deedType = await this.deedTypeService.getByUid(officeFolderEntity.deed!.deed_type!.uid!);
if (!deedType) throw new Error("deed type not found");
if (deedType.archived_at) throw new Error("deed type is archived");
const deed = await this.deedRepository.create(officeFolderEntity.deed!);
officeFolderEntity.deed!.uid = deed.uid;
return this.officeFoldersRepository.create(officeFolderEntity);
}

View File

@ -14,6 +14,8 @@ enum PROVIDER_OPENID {
export interface ICustomerJwtPayload {
customerId: string;
email: string;
iat?: number;
exp?: number;
}
export interface IdNotJwtPayload {
@ -31,6 +33,8 @@ export interface IUserJwtPayload {
office_Id: string;
role: string;
rules: string[];
iat?: number;
exp?: number;
}
@Service()
@ -39,14 +43,16 @@ export default class AuthService extends BaseService {
super();
}
public async getCustomerJwtPayload(customer: Customer): Promise<ICustomerJwtPayload | null> {
public async getCustomerJwtPayload(customers: Customer[]): Promise<ICustomerJwtPayload | null> {
for (const customer of customers){
if (customer.status === ECustomerStatus["PENDING"]) {
customer.status = ECustomerStatus["VALIDATED"];
this.customerService.update(customer.uid!, customer);
await this.customerService.update(customer.uid!, customer);
}
}
return {
customerId: customer.uid!,
email: customer.contact!.email,
customerId: customers[0]!.uid!,
email: customers[0]!.contact!.email,
};
}

View File

@ -0,0 +1,27 @@
import { Contacts, Customers } from "@prisma/client";
import ContactsRepository from "@Repositories/ContactRepository";
import BaseService from "@Services/BaseService";
import { Service } from "typedi";
@Service()
export default class ContactsService extends BaseService {
constructor(private customerRepository: ContactsRepository) {
super();
}
/**
* @description : Get all Contacts
* @throws {Error} If Contacts cannot be get
*/
public async getByEmail(email: string): Promise<(Contacts & {customers: Customers | null})[] | null> {
return this.customerRepository.findSomeByEmail(email);
}
/**
* @description : Create a new customer
* @throws {Error} If customer cannot be created
*/
public async getByPhone(cell_phone_number: string): Promise<(Contacts & {customers: Customers | null})[] | null> {
return this.customerRepository.findSomeByPhoneNumber(cell_phone_number);
}
}

View File

@ -5,6 +5,7 @@ import FilesService from "../FilesService/FilesService";
import IdNotService from "../IdNotService/IdNotService";
import { PrismaClient } from "@prisma/client";
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
import EmailBuilder from "@Common/emails/EmailBuilder";
// import { PrismaClient } from "@prisma/client";
@Service()
@ -13,7 +14,8 @@ export default class CronService {
private mailchimpService: MailchimpService,
private filesService: FilesService,
private idNotService: IdNotService,
private notificationBuilder: NotificationBuilder
private notificationBuilder: NotificationBuilder,
private emailBuilder: EmailBuilder,
) {}
public async sendMails() {
@ -36,7 +38,7 @@ export default class CronService {
const cronJob = new CronJob("0 20 * * FRI", async () => {
// Every friday at 20:00
try {
await this.mailchimpService.sendRecapEmails();
await this.emailBuilder.sendRecapEmails();
} catch (e) {
console.error(e);
}

View File

@ -4,18 +4,14 @@ import { Emails, Prisma } from "@prisma/client";
import { Service } from "typedi";
import MailchimpClient from "@mailchimp/mailchimp_transactional";
import { BackendVariables } from "@Common/config/variables/Variables";
import UsersService from "@Services/super-admin/UsersService/UsersService";
import EmailBuilder from "@Common/emails/EmailBuilder";
@Service()
export default class MailchimpService extends BaseService {
private static readonly from = "vincent.alamelle@smart-chain.fr";
private static readonly from = "no-reply@smart-chain.fr";
constructor(
private emailRepository: EmailRepository,
protected variables: BackendVariables,
private usersService: UsersService,
private emailBuilder: EmailBuilder,
) {
super();
}
@ -120,10 +116,4 @@ export default class MailchimpService extends BaseService {
};
});
}
public async sendRecapEmails() {
const usersToEmail = await this.usersService.get({ where: { office_folders: { some:{ documents: { some: { document_status: "DEPOSITED" } } }} }, distinct: ["uid"], include: { contact: true } });
await this.emailBuilder.sendRecapEmails(usersToEmail);
}
}

View File

@ -34,6 +34,14 @@ export default class DocumentsService extends BaseService {
return this.documentsRepository.create(document);
}
/**
* @description : Delete a document
* @throws {Error} If document cannot be created
*/
public async delete(uid: string): Promise<Documents> {
return this.documentsRepository.delete(uid);
}
/**
* @description : Modify a document
* @throws {Error} If document cannot be modified

View File

@ -23,14 +23,6 @@ export default class CustomersService extends BaseService {
* @throws {Error} If customer cannot be created
*/
public async create(customerEntity: Customer): Promise<Customers> {
const customers = await this.get({
where: {
contact: {
OR: [{ email: customerEntity.contact?.email }, { cell_phone_number: customerEntity.contact?.cell_phone_number }],
},
},
});
if(customers[0]) return customers[0];
return this.customerRepository.create(customerEntity);
}

View File

@ -46,12 +46,11 @@ export default class DocumentsService extends BaseService {
public async refuse(uid: string, document: Partial<Document>, refused_reason: string): Promise<Documents> {
if (document.files) {
for (let i = 0; i < document.files.length; i++) {
console.log("archiving file", document.files[i]?.uid);
await this.filesRepository.deleteKeyAndArchive(document.files[i]?.uid as string);
}
}
return this.documentsRepository.refuse(uid, document, refused_reason);
return this.documentsRepository.refuse(uid, refused_reason);
}
/**

View File

@ -3,16 +3,14 @@ import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository";
import BaseService from "@Services/BaseService";
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
import { Service } from "typedi";
import DeedTypesService from "../DeedTypesService/DeedTypesService";
import DeedsRepository from "@Repositories/DeedsRepository";
import { Prisma } from "@prisma/client";
import { EFolderStatus, Prisma } from "@prisma/client";
import DeedsService from "../DeedsService/DeedsService";
@Service()
export default class OfficeFoldersService extends BaseService {
constructor(
private officeFoldersRepository: OfficeFoldersRepository,
private deedTypeService: DeedTypesService,
private deedRepository: DeedsRepository,
private deedService: DeedsService,
) {
super();
}
@ -30,10 +28,7 @@ export default class OfficeFoldersService extends BaseService {
* @throws {Error} If folder cannot be created
*/
public async create(officeFolderEntity: OfficeFolder): Promise<OfficeFolders> {
const deedType = await this.deedTypeService.getByUid(officeFolderEntity.deed!.deed_type!.uid!);
if (!deedType) throw new Error("deed type not found");
if (deedType.archived_at) throw new Error("deed type is archived");
const deed = await this.deedRepository.create(officeFolderEntity.deed!);
const deed = await this.deedService.create(officeFolderEntity.deed!);
officeFolderEntity.deed!.uid = deed.uid;
return this.officeFoldersRepository.create(officeFolderEntity);
}
@ -46,6 +41,14 @@ export default class OfficeFoldersService extends BaseService {
return this.officeFoldersRepository.update(officeFolderuid, officeFolderEntity);
}
/**
* @description : Modify a folder status
* @throws {Error} If folder cannot be modified
*/
public async updateStatus(uid: string, officeFolderEntity: OfficeFolder) {
return this.officeFoldersRepository.updateStatus(uid,officeFolderEntity.status as EFolderStatus, officeFolderEntity.archived_description);
}
/**
* @description : Get a folder by uid
* @throws {Error} If folder cannot be get by uid

View File

@ -46,12 +46,11 @@ export default class DocumentsService extends BaseService {
public async refuse(uid: string, document: Partial<Document>, refused_reason: string): Promise<Documents> {
if (document.files) {
for (let i = 0; i < document.files.length; i++) {
console.log("archiving file", document.files[i]?.uid);
await this.filesRepository.deleteKeyAndArchive(document.files[i]?.uid as string);
}
}
return this.documentsRepository.refuse(uid, document, refused_reason);
return this.documentsRepository.refuse(uid, refused_reason);
}
/**

View File

@ -3,16 +3,12 @@ import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository";
import BaseService from "@Services/BaseService";
import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin";
import { Service } from "typedi";
import DeedTypesService from "../DeedTypesService/DeedTypesService";
import DeedsRepository from "@Repositories/DeedsRepository";
import { Prisma } from "@prisma/client";
@Service()
export default class OfficeFoldersService extends BaseService {
constructor(
private officeFoldersRepository: OfficeFoldersRepository,
private deedTypeService: DeedTypesService,
private deedRepository: DeedsRepository,
) {
super();
}
@ -30,11 +26,6 @@ export default class OfficeFoldersService extends BaseService {
* @throws {Error} If folder cannot be created
*/
public async create(officeFolderEntity: OfficeFolder): Promise<OfficeFolders> {
const deedType = await this.deedTypeService.getByUid(officeFolderEntity.deed!.deed_type!.uid!);
if (!deedType) throw new Error("deed type not found");
if (deedType.archived_at) throw new Error("deed type is archived");
const deed = await this.deedRepository.create(officeFolderEntity.deed!);
officeFolderEntity.deed!.uid = deed.uid;
return this.officeFoldersRepository.create(officeFolderEntity);
}

View File

@ -18,15 +18,11 @@ import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository";
import OfficeFolderService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService";
import { initCustomers, initDeedType, initDocumentType, initOffice, initUsers } from "@Test/config/Init";
import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin";
import DeedTypesService from "@Services/super-admin/DeedTypesService/DeedTypesService";
import DeedsRepository from "@Repositories/DeedsRepository";
const prisma = new PrismaClient();
const OfficeFolderServiceTest = new OfficeFolderService(
Container.get(OfficeFoldersRepository),
Container.get(DeedTypesService),
Container.get(DeedsRepository),
Container.get(OfficeFoldersRepository)
);
beforeAll(async () => {