Merge Staging in Prepod
This commit is contained in:
commit
9b493dd075
@ -1,9 +0,0 @@
|
|||||||
const {join} = require('path');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {import("puppeteer").Configuration}
|
|
||||||
*/
|
|
||||||
module.exports = {
|
|
||||||
// Changes the cache location for Puppeteer.
|
|
||||||
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
|
|
||||||
};
|
|
31
Dockerfile
31
Dockerfile
@ -1,14 +1,19 @@
|
|||||||
# Install dependencies only when needed
|
# Install dependencies only when needed
|
||||||
FROM node:19-alpine AS deps
|
FROM node:18-bullseye-slim AS deps
|
||||||
|
|
||||||
WORKDIR leCoffre
|
WORKDIR leCoffre
|
||||||
|
|
||||||
RUN npm install -D prisma@4.11.0
|
RUN npm install -D prisma@4.11.0
|
||||||
COPY package.json ./
|
COPY package.json ./
|
||||||
|
|
||||||
RUN apk update && apk add openssh-client git
|
RUN apt-get update \
|
||||||
# ENV PUPPETEER_CACHE_DIR=~/leCoffre/.cache/puppeteer
|
&& apt-get install -y wget gnupg \
|
||||||
# ENV PUPPETEER_SKIP_DOWNLOAD=false
|
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/googlechrome-linux-keyring.gpg \
|
||||||
|
&& sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrome-linux-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y google-chrome-stable chromium fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-khmeros fonts-kacst fonts-freefont-ttf libxss1 openssh-client git \
|
||||||
|
--no-install-recommends \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY id_rsa /root/.ssh/id_rsa
|
COPY id_rsa /root/.ssh/id_rsa
|
||||||
RUN chmod 600 ~/.ssh/id_rsa
|
RUN chmod 600 ~/.ssh/id_rsa
|
||||||
@ -18,13 +23,12 @@ RUN ssh-keyscan github.com smart-chain-fr/leCoffre-resources.git >> /root/.ssh/k
|
|||||||
RUN npm install --frozen-lockfile
|
RUN npm install --frozen-lockfile
|
||||||
|
|
||||||
# Rebuild the source code only when needed
|
# Rebuild the source code only when needed
|
||||||
FROM node:19-alpine AS builder
|
FROM node:18-bullseye-slim AS builder
|
||||||
|
|
||||||
WORKDIR leCoffre
|
WORKDIR leCoffre
|
||||||
|
|
||||||
COPY --from=deps leCoffre/node_modules ./node_modules
|
COPY --from=deps leCoffre/node_modules ./node_modules
|
||||||
COPY --from=deps leCoffre/package.json package.json
|
COPY --from=deps leCoffre/package.json package.json
|
||||||
#COPY --from=deps leCoffre/.cache ./.cache
|
|
||||||
|
|
||||||
COPY tsconfig.json tsconfig.json
|
COPY tsconfig.json tsconfig.json
|
||||||
COPY src src
|
COPY src src
|
||||||
@ -33,19 +37,24 @@ RUN npx prisma generate
|
|||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Production image, copy all the files and run next
|
# Production image, copy all the files and run next
|
||||||
FROM node:19-alpine AS production
|
FROM node:18-bullseye-slim AS production
|
||||||
|
|
||||||
WORKDIR leCoffre
|
WORKDIR leCoffre
|
||||||
|
|
||||||
RUN adduser -D lecoffreuser --uid 10000 && chown -R lecoffreuser .
|
RUN adduser --disabled-password lecoffreuser --uid 10000 && chown -R lecoffreuser .
|
||||||
|
|
||||||
|
RUN mkdir -p /home/lecoffreuser/Downloads \
|
||||||
|
&& mkdir -p /home/lecoffreuser/Downloads \
|
||||||
|
&& chown -R lecoffreuser:lecoffreuser /home/lecoffreuser
|
||||||
|
|
||||||
COPY --from=builder --chown=lecoffreuser leCoffre/node_modules ./node_modules
|
COPY --from=builder --chown=lecoffreuser leCoffre/node_modules ./node_modules
|
||||||
COPY --from=builder --chown=lecoffreuser leCoffre/dist dist
|
COPY --from=builder --chown=lecoffreuser leCoffre/dist dist
|
||||||
COPY --from=builder --chown=lecoffreuser leCoffre/package.json ./package.json
|
COPY --from=builder --chown=lecoffreuser leCoffre/package.json ./package.json
|
||||||
COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/common/databases
|
COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/common/databases
|
||||||
#COPY --from=builder --chown=lecoffreuser leCoffre/.cache ./.cache
|
|
||||||
|
|
||||||
USER lecoffreuser
|
USER lecoffreuser
|
||||||
|
|
||||||
CMD ["npm", "run", "start"]
|
CMD ["npm", "run", "start"]
|
||||||
EXPOSE 3001
|
EXPOSE 3001
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ lecoffreBack:
|
|||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/client_max_body_size: 200m
|
||||||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 2M
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: 200m
|
||||||
env:
|
env:
|
||||||
- key: .env
|
- key: .env
|
||||||
scwID: "id:430001f8-68ab-47b2-92e8-38024c35a80d"
|
scwID: "id:430001f8-68ab-47b2-92e8-38024c35a80d"
|
||||||
|
@ -28,6 +28,9 @@ lecoffreBack:
|
|||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/client_max_body_size: 200m
|
||||||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 2M
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: 200m
|
||||||
env:
|
env:
|
||||||
- key: .env
|
- key: .env
|
||||||
scwID: "id:8f66af26-2481-4ef2-b4f0-7f076f9ee18b"
|
scwID: "id:8f66af26-2481-4ef2-b4f0-7f076f9ee18b"
|
||||||
|
@ -28,6 +28,9 @@ lecoffreBack:
|
|||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/client_max_body_size: 200m
|
||||||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 2M
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: 200m
|
||||||
# key is name of the environment variable, scwID is the secret ID in SCW with "id:" in front
|
# key is name of the environment variable, scwID is the secret ID in SCW with "id:" in front
|
||||||
env:
|
env:
|
||||||
- key: .env
|
- key: .env
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"fp-ts": "^2.16.1",
|
"fp-ts": "^2.16.1",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.89",
|
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.90",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
"monocle-ts": "^2.3.13",
|
"monocle-ts": "^2.3.13",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
|
@ -9,6 +9,7 @@ import authHandler from "@App/middlewares/AuthHandler";
|
|||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
import roleHandler from "@App/middlewares/RolesHandler";
|
import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
import customerHandler from "@App/middlewares/OfficeMembershipHandlers/CustomerHandler";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
@ -78,7 +79,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Modify a specific customer by uid
|
* @description Modify a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Put("/api/v1/admin/customers/:uid", [authHandler, roleHandler, ruleHandler])
|
@Put("/api/v1/admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
|
||||||
protected async put(req: Request, response: Response) {
|
protected async put(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
@ -119,7 +120,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Get a specific customer by uid
|
* @description Get a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Get("/api/v1/admin/customers/:uid", [authHandler, roleHandler, ruleHandler])
|
@Get("/api/v1/admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
|
||||||
protected async getOneByUid(req: Request, response: Response) {
|
protected async getOneByUid(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
|
@ -3,7 +3,7 @@ import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
|
|||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import DocumentsService from "@Services/admin/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/admin/DocumentsService/DocumentsService";
|
||||||
import { Documents, Prisma } from "@prisma/client";
|
import { Documents, EDocumentStatus, Prisma } from "@prisma/client";
|
||||||
import { Document } from "le-coffre-resources/dist/Admin";
|
import { Document } from "le-coffre-resources/dist/Admin";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
@ -31,8 +31,8 @@ export default class DocumentsController extends ApiController {
|
|||||||
query = JSON.parse(req.query["q"] as string);
|
query = JSON.parse(req.query["q"] as string);
|
||||||
}
|
}
|
||||||
const officeId: string = req.body.user.office_Id;
|
const officeId: string = req.body.user.office_Id;
|
||||||
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
|
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
|
||||||
if(!query.where) query.where = { document_type : {office: officeWhereInput}};
|
if (!query.where) query.where = { document_type: { office: officeWhereInput } };
|
||||||
query.where.document_type!.office = officeWhereInput;
|
query.where.document_type!.office = officeWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
@ -104,7 +104,55 @@ export default class DocumentsController extends ApiController {
|
|||||||
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity, req.body.refused_reason);
|
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity);
|
||||||
|
|
||||||
|
//Hydrate ressource with prisma entity
|
||||||
|
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response, document);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Update a specific document
|
||||||
|
*/
|
||||||
|
@Put("/api/v1/notary/documents/:uid/refuse", [authHandler, ruleHandler, documentHandler])
|
||||||
|
protected async refuseDocument(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const documentFound = await this.documentsService.getByUid(uid, {
|
||||||
|
files: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!documentFound) {
|
||||||
|
this.httpNotFoundRequest(response, "document not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init Document resource with request body values
|
||||||
|
const documentEntity = Document.hydrate<Document>(documentFound);
|
||||||
|
|
||||||
|
// Status to refuse
|
||||||
|
documentEntity.document_status = EDocumentStatus.REFUSED;
|
||||||
|
|
||||||
|
//validate document
|
||||||
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
||||||
|
@ -58,10 +58,10 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const officeId: string = req.body.user.office_Id;
|
const userId: string = req.body.user.userId;
|
||||||
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
|
if (query.where?.stakeholders) delete query.where.stakeholders;
|
||||||
if(!query.where) query.where = { office: officeWhereInput};
|
const officeFoldersWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, stakeholders: { some: { uid: userId } } };
|
||||||
query.where.office = officeWhereInput;
|
query.where = officeFoldersWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
|
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
|
||||||
|
@ -8,11 +8,13 @@ import { Document } from "le-coffre-resources/dist/Customer";
|
|||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import documentHandler from "@App/middlewares/CustomerHandler/DocumentHandler";
|
import documentHandler from "@App/middlewares/CustomerHandler/DocumentHandler";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
|
import OfficeFoldersService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService";
|
||||||
|
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class DocumentsController extends ApiController {
|
export default class DocumentsController extends ApiController {
|
||||||
constructor(private documentsService: DocumentsService) {
|
constructor(private documentsService: DocumentsService, private officeFoldersService: OfficeFoldersService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,8 +95,23 @@ export default class DocumentsController extends ApiController {
|
|||||||
protected async post(req: Request, response: Response) {
|
protected async post(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
//init Document resource with request body values
|
//init Document resource with request body values
|
||||||
const documentEntity = Document.hydrate<Document>(req.body);
|
const documentEntity = Document.hydrate<Document>(req.body);
|
||||||
|
if(!documentEntity.folder?.uid) {
|
||||||
|
this.httpBadRequest(response, "No folder uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const folder = await this.officeFoldersService.getByUid(documentEntity.folder.uid, {folder_anchor: 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");
|
||||||
|
return;
|
||||||
|
}
|
||||||
//validate document
|
//validate document
|
||||||
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
||||||
|
|
||||||
|
@ -6,19 +6,16 @@ import FilesService from "@Services/common/FilesService/FilesService";
|
|||||||
import { Files, Prisma } from "@prisma/client";
|
import { Files, Prisma } from "@prisma/client";
|
||||||
import { File } from "le-coffre-resources/dist/Customer";
|
import { File } from "le-coffre-resources/dist/Customer";
|
||||||
import { Document } from "le-coffre-resources/dist/Customer";
|
import { Document } from "le-coffre-resources/dist/Customer";
|
||||||
import { validateOrReject } from "class-validator";
|
|
||||||
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import fileHandler from "@App/middlewares/CustomerHandler/FileHandler";
|
import fileHandler from "@App/middlewares/CustomerHandler/FileHandler";
|
||||||
import DocumentTypesService from "@Services/super-admin/DocumentTypesService/DocumentTypesService";
|
|
||||||
import { DocumentType } from "le-coffre-resources/dist/SuperAdmin";
|
|
||||||
import ObjectHydrate from "@Common/helpers/ObjectHydrate";
|
|
||||||
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
||||||
|
import { validateOrReject } from "class-validator";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class FilesController extends ApiController {
|
export default class FilesController extends ApiController {
|
||||||
constructor(private filesService: FilesService, private documentService: DocumentsService, private documentTypesService : DocumentTypesService, private notificationBuilder : NotificationBuilder) {
|
constructor(private filesService: FilesService, private documentService: DocumentsService, private notificationBuilder : NotificationBuilder) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +90,12 @@ export default class FilesController extends ApiController {
|
|||||||
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
|
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
|
||||||
|
|
||||||
//validate File
|
//validate File
|
||||||
// await validateOrReject(fileEntity, { groups: ["createFile"] });
|
try {
|
||||||
|
await validateOrReject(fileEntity, { groups: ["createFile"] });
|
||||||
|
} catch (error) {
|
||||||
|
this.httpBadRequest(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const fileEntityCreated = await this.filesService.create(fileEntity, req.file);
|
const fileEntityCreated = await this.filesService.create(fileEntity, req.file);
|
||||||
@ -111,6 +113,7 @@ export default class FilesController extends ApiController {
|
|||||||
strategy: "excludeAll",
|
strategy: "excludeAll",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpCreated(response, fileEntityHydrated);
|
this.httpCreated(response, fileEntityHydrated);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -226,52 +229,4 @@ export default class FilesController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Create a new File
|
|
||||||
* @returns File created
|
|
||||||
*/
|
|
||||||
@Post("/api/v1/customer/addPersonalFile", [authHandler, fileHandler])
|
|
||||||
protected async addPersonalFile(req: Request, response: Response) {
|
|
||||||
try {
|
|
||||||
//get file
|
|
||||||
if (!req.file) throw new Error("No file provided");
|
|
||||||
|
|
||||||
//init File resource with request body values
|
|
||||||
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
|
|
||||||
|
|
||||||
const documentTypeEntities = await this.documentTypesService.get({ where: { name: "Other"} });
|
|
||||||
const documentTypeEntity = documentTypeEntities[0];
|
|
||||||
const documentType = ObjectHydrate.hydrate<DocumentType>(new DocumentType(), documentTypeEntity!, { strategy: "excludeAll" });
|
|
||||||
|
|
||||||
const documentEntity = Document.hydrate<Document>({document_type: documentType});
|
|
||||||
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
|
||||||
const documentEntityCreated = await this.documentService.create(documentEntity);
|
|
||||||
|
|
||||||
const document = Document.hydrate<Document>(documentEntityCreated, {
|
|
||||||
strategy: "excludeAll",
|
|
||||||
});
|
|
||||||
|
|
||||||
fileEntity.document = document;
|
|
||||||
|
|
||||||
const fileEntityCreated = await this.filesService.create(fileEntity, req.file);
|
|
||||||
|
|
||||||
const documentToUpdate = Document.hydrate<Document>(document!);
|
|
||||||
|
|
||||||
documentToUpdate!.document_status = "DEPOSITED";
|
|
||||||
await this.documentService.update(document!.uid!, documentToUpdate);
|
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
|
||||||
const fileEntityHydrated = File.hydrate<File>(fileEntityCreated, {
|
|
||||||
strategy: "excludeAll",
|
|
||||||
});
|
|
||||||
|
|
||||||
//success
|
|
||||||
this.httpCreated(response, fileEntityHydrated);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
this.httpBadRequest(response, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Response, Request } from "express";
|
|||||||
import { Controller, Post } from "@ControllerPattern/index";
|
import { Controller, Post } from "@ControllerPattern/index";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import Id360Service from "@Services/common/Id360Service/Id360Service";
|
import Id360Service, { EnrollmentResponse } from "@Services/common/Id360Service/Id360Service";
|
||||||
import CustomersService from "@Services/customer/CustomersService/CustomersService";
|
import CustomersService from "@Services/customer/CustomersService/CustomersService";
|
||||||
import AuthService from "@Services/common/AuthService/AuthService";
|
import AuthService from "@Services/common/AuthService/AuthService";
|
||||||
import { Customer } from "le-coffre-resources/dist/SuperAdmin";
|
import { Customer } from "le-coffre-resources/dist/SuperAdmin";
|
||||||
@ -34,7 +34,11 @@ export default class CustomerController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const enrollment = await this.id360Service.getEnrollment(callbackToken);
|
const res = await this.id360Service.getEnrollment(callbackToken);
|
||||||
|
const enrollment = await res.json() as EnrollmentResponse;
|
||||||
|
if(enrollment.status === "STARTED") {
|
||||||
|
this.loginCallback(req, response);
|
||||||
|
}
|
||||||
if (enrollment.status !== "OK") {
|
if (enrollment.status !== "OK") {
|
||||||
this.httpUnauthorized(response, "Enrollment status is not OK");
|
this.httpUnauthorized(response, "Enrollment status is not OK");
|
||||||
return;
|
return;
|
||||||
|
@ -20,7 +20,6 @@ export default class DocumentController extends ApiController {
|
|||||||
protected async getDocumentVerificationFromId360(req: Request, response: Response) {
|
protected async getDocumentVerificationFromId360(req: Request, response: Response) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log("document callback", req, response)
|
|
||||||
this.httpSuccess(response);
|
this.httpSuccess(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@ -33,7 +32,6 @@ export default class DocumentController extends ApiController {
|
|||||||
protected async getCustomerVerificationFromId360(req: Request, response: Response) {
|
protected async getCustomerVerificationFromId360(req: Request, response: Response) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log("customer callback", req, response)
|
|
||||||
this.httpSuccess(response);
|
this.httpSuccess(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -25,6 +25,10 @@ export default class UserController extends ApiController {
|
|||||||
if (!code) throw new Error("code is required");
|
if (!code) throw new Error("code is required");
|
||||||
|
|
||||||
const idNotToken = await this.idNotService.getIdNotToken(code);
|
const idNotToken = await this.idNotService.getIdNotToken(code);
|
||||||
|
if(!idNotToken) {
|
||||||
|
this.httpValidationError(response, "IdNot token undefined");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const user = await this.idNotService.getOrCreateUser(idNotToken);
|
const user = await this.idNotService.getOrCreateUser(idNotToken);
|
||||||
|
|
||||||
if(!user) {
|
if(!user) {
|
||||||
|
@ -8,6 +8,7 @@ import { validateOrReject } from "class-validator";
|
|||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
import customerHandler from "@App/middlewares/OfficeMembershipHandlers/CustomerHandler";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
@ -76,7 +77,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Modify a specific customer by uid
|
* @description Modify a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Put("/api/v1/notary/customers/:uid", [authHandler, ruleHandler])
|
@Put("/api/v1/notary/customers/:uid", [authHandler, ruleHandler, customerHandler])
|
||||||
protected async put(req: Request, response: Response) {
|
protected async put(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
@ -117,7 +118,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Get a specific customer by uid
|
* @description Get a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Get("/api/v1/notary/customers/:uid", [authHandler, ruleHandler])
|
@Get("/api/v1/notary/customers/:uid", [authHandler, ruleHandler, customerHandler])
|
||||||
protected async getOneByUid(req: Request, response: Response) {
|
protected async getOneByUid(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
|
@ -3,19 +3,24 @@ import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
|
|||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import DocumentsService from "@Services/notary/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/notary/DocumentsService/DocumentsService";
|
||||||
import { Documents, Prisma } from "@prisma/client";
|
import { Documents, EDocumentStatus, Prisma } from "@prisma/client";
|
||||||
import { Document } from "le-coffre-resources/dist/Notary";
|
import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
import documentHandler from "@App/middlewares/OfficeMembershipHandlers/DocumentHandler";
|
import documentHandler from "@App/middlewares/OfficeMembershipHandlers/DocumentHandler";
|
||||||
import EmailBuilder from "@Common/emails/EmailBuilder";
|
import EmailBuilder from "@Common/emails/EmailBuilder";
|
||||||
|
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
||||||
// import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
// import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class DocumentsController extends ApiController {
|
export default class DocumentsController extends ApiController {
|
||||||
constructor(private documentsService: DocumentsService, private emailBuilder: EmailBuilder) {
|
constructor(
|
||||||
|
private documentsService: DocumentsService,
|
||||||
|
private emailBuilder: EmailBuilder,
|
||||||
|
private officeFoldersService: OfficeFoldersService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +37,8 @@ export default class DocumentsController extends ApiController {
|
|||||||
query = JSON.parse(req.query["q"] as string);
|
query = JSON.parse(req.query["q"] as string);
|
||||||
}
|
}
|
||||||
const officeId: string = req.body.user.office_Id;
|
const officeId: string = req.body.user.office_Id;
|
||||||
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
|
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
|
||||||
if(!query.where) query.where = { document_type : {office: officeWhereInput}};
|
if (!query.where) query.where = { document_type: { office: officeWhereInput } };
|
||||||
query.where.document_type!.office = officeWhereInput;
|
query.where.document_type!.office = officeWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
@ -60,6 +65,20 @@ export default class DocumentsController extends ApiController {
|
|||||||
//init Document resource with request body values
|
//init Document resource with request body values
|
||||||
const documentEntity = Document.hydrate<Document>(req.body);
|
const documentEntity = Document.hydrate<Document>(req.body);
|
||||||
|
|
||||||
|
const folder = await this.officeFoldersService.getByUid(documentEntity.folder?.uid!, {
|
||||||
|
folder_anchor: true,
|
||||||
|
});
|
||||||
|
if (!folder) {
|
||||||
|
this.httpBadRequest(response, "Folder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const folderRessource = OfficeFolder.hydrate<OfficeFolder>(folder);
|
||||||
|
if (folderRessource.folder_anchor) {
|
||||||
|
this.httpBadRequest(response, "Cannot ask document on an anchored or anchoring folder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//validate document
|
//validate document
|
||||||
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
||||||
|
|
||||||
@ -104,13 +123,59 @@ export default class DocumentsController extends ApiController {
|
|||||||
//init Document resource with request body values
|
//init Document resource with request body values
|
||||||
const documentEntity = Document.hydrate<Document>(req.body);
|
const documentEntity = Document.hydrate<Document>(req.body);
|
||||||
|
|
||||||
|
//validate document
|
||||||
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
|
//call service to get prisma entity
|
||||||
|
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity);
|
||||||
|
|
||||||
|
//create email for asked document
|
||||||
|
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
|
||||||
|
// this.notificationBuilder.sendDocumentAnchoredNotificatiom(documentEntityUpdated);
|
||||||
|
|
||||||
|
//Hydrate ressource with prisma entity
|
||||||
|
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response, document);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Update a specific document
|
||||||
|
*/
|
||||||
|
@Put("/api/v1/notary/documents/:uid/refuse", [authHandler, ruleHandler, documentHandler])
|
||||||
|
protected async refuseDocument(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const documentFound = await this.documentsService.getByUid(uid, {
|
||||||
|
files: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!documentFound) {
|
||||||
|
this.httpNotFoundRequest(response, "document not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init Document resource with request body values
|
||||||
|
const documentEntity = Document.hydrate<Document>(documentFound);
|
||||||
|
|
||||||
|
// Status to refuse
|
||||||
|
documentEntity.document_status = EDocumentStatus.REFUSED;
|
||||||
|
|
||||||
//validate document
|
//validate document
|
||||||
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity, req.body.refused_reason);
|
const documentEntityUpdated: Documents = await this.documentsService.refuse(uid, documentEntity, req.body.refused_reason);
|
||||||
|
|
||||||
//create email for asked document
|
//create email for asked document
|
||||||
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
|
// this.emailBuilder.sendDocumentEmails(documentEntityUpdated);
|
||||||
|
@ -2,7 +2,7 @@ import { Response, Request } from "express";
|
|||||||
import { Controller, Get, Post } from "@ControllerPattern/index";
|
import { Controller, Get, Post } from "@ControllerPattern/index";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
import { getFolderHashes } from "@Common/optics/notary";
|
import { getFolderHashes } from "@Common/optics/notary";
|
||||||
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
||||||
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
|
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
|
||||||
@ -136,6 +136,18 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
|
|
||||||
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
// Check if every document is validated in a folder
|
||||||
|
const documents = officeFolder.documents ?? [];
|
||||||
|
const documentsValidated = documents.filter((document) => {
|
||||||
|
let documentHydrated = Document.hydrate<Document>(document, { strategy: "excludeAll" });
|
||||||
|
return documentHydrated.document_status === "VALIDATED";
|
||||||
|
});
|
||||||
|
|
||||||
|
if (documentsValidated.length !== documents.length && documents.length !== 0) {
|
||||||
|
this.httpBadRequest(response, "Cannot anchor a folder with non validated documents");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const folderHashes = getFolderHashes(officeFolder);
|
const folderHashes = getFolderHashes(officeFolder);
|
||||||
|
|
||||||
if (folderHashes.length === 0) {
|
if (folderHashes.length === 0) {
|
||||||
|
@ -44,9 +44,9 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
customers: {
|
customers: {
|
||||||
some: {
|
some: {
|
||||||
OR: [
|
OR: [
|
||||||
{contact: { first_name: { contains: filter, mode: "insensitive" } }},
|
{ contact: { first_name: { contains: filter, mode: "insensitive" } } },
|
||||||
{contact: { last_name: { contains: filter, mode: "insensitive" } }},
|
{ contact: { last_name: { contains: filter, mode: "insensitive" } } },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -56,8 +56,8 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const userId: string = req.body.user.userId;
|
const userId: string = req.body.user.userId;
|
||||||
if(query.where?.stakeholders) delete query.where.stakeholders;
|
if (query.where?.stakeholders) delete query.where.stakeholders;
|
||||||
const officeFoldersWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, stakeholders: {some: {uid: userId }}};
|
const officeFoldersWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, stakeholders: { some: { uid: userId } } };
|
||||||
query.where = officeFoldersWhereInput;
|
query.where = officeFoldersWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
@ -111,7 +111,9 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const officeFolderFound = await this.officeFoldersService.getByUid(uid);
|
const officeFolderFound = await this.officeFoldersService.getByUid(uid, {
|
||||||
|
folder_anchor: true,
|
||||||
|
});
|
||||||
|
|
||||||
if (!officeFolderFound) {
|
if (!officeFolderFound) {
|
||||||
this.httpNotFoundRequest(response, "office folder not found");
|
this.httpNotFoundRequest(response, "office folder not found");
|
||||||
@ -119,13 +121,17 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//init OfficeFolder resource with request body values
|
//init OfficeFolder resource with request body values
|
||||||
const officeFolderEntity = OfficeFolder.hydrate<OfficeFolder>(req.body);
|
const officefolderToUpdate = OfficeFolder.hydrate<OfficeFolder>(req.body);
|
||||||
|
const officeFolderFoundEntity = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound);
|
||||||
//validate folder
|
//validate folder
|
||||||
await validateOrReject(officeFolderEntity, { groups: ["updateFolder"], forbidUnknownValues: false });
|
await validateOrReject(officefolderToUpdate, { 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
|
//call service to get prisma entity
|
||||||
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officeFolderEntity);
|
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
|
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
|
||||||
@ -140,6 +146,102 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Modify a specific folder by uid
|
||||||
|
*/
|
||||||
|
@Put("/api/v1/notary/folders/:uid/archive", [authHandler, ruleHandler, folderHandler])
|
||||||
|
protected async archive(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const officeFolderFound = await this.officeFoldersService.getByUid(uid, {
|
||||||
|
folder_anchor: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!officeFolderFound) {
|
||||||
|
this.httpNotFoundRequest(response, "office folder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init OfficeFolder resource with request body values
|
||||||
|
const officefolderToUpdate = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound);
|
||||||
|
|
||||||
|
officefolderToUpdate.status = "ARCHIVED";
|
||||||
|
officefolderToUpdate.archived_description = req.body.archived_description ?? "";
|
||||||
|
|
||||||
|
//validate folder
|
||||||
|
await validateOrReject(officefolderToUpdate, { groups: ["updateFolder"], forbidUnknownValues: false });
|
||||||
|
|
||||||
|
if ((officeFolderFound as any).folder_anchor?.status !== "VERIFIED_ON_CHAIN") {
|
||||||
|
this.httpBadRequest(response, "Cannot archive a not anchored folder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//call service to get prisma entity
|
||||||
|
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
|
||||||
|
|
||||||
|
//Hydrate ressource with prisma entity
|
||||||
|
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
|
||||||
|
strategy: "excludeAll",
|
||||||
|
});
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response, officeFolders);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Modify a specific folder by uid
|
||||||
|
*/
|
||||||
|
@Put("/api/v1/notary/folders/:uid/restore", [authHandler, ruleHandler, folderHandler])
|
||||||
|
protected async restore(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const officeFolderFound = await this.officeFoldersService.getByUid(uid, {
|
||||||
|
folder_anchor: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!officeFolderFound) {
|
||||||
|
this.httpNotFoundRequest(response, "office folder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init OfficeFolder resource with request body values
|
||||||
|
const officefolderToUpdate = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound);
|
||||||
|
|
||||||
|
officefolderToUpdate.status = "LIVE";
|
||||||
|
officefolderToUpdate.archived_description = "";
|
||||||
|
|
||||||
|
//validate folder
|
||||||
|
await validateOrReject(officefolderToUpdate, { groups: ["updateFolder"], forbidUnknownValues: false });
|
||||||
|
|
||||||
|
//call service to get prisma entity
|
||||||
|
const officeFolderEntityUpdated = await this.officeFoldersService.update(uid, officefolderToUpdate);
|
||||||
|
|
||||||
|
//Hydrate ressource with prisma entity
|
||||||
|
const officeFolders = OfficeFolder.hydrate<OfficeFolder>(officeFolderEntityUpdated, {
|
||||||
|
strategy: "excludeAll",
|
||||||
|
});
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response, officeFolders);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @description Get a specific folder by uid
|
* @description Get a specific folder by uid
|
||||||
* @returns IFolder
|
* @returns IFolder
|
||||||
|
@ -9,6 +9,7 @@ import authHandler from "@App/middlewares/AuthHandler";
|
|||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
import roleHandler from "@App/middlewares/RolesHandler";
|
import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
import customerHandler from "@App/middlewares/OfficeMembershipHandlers/CustomerHandler";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
@ -78,7 +79,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Modify a specific customer by uid
|
* @description Modify a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Put("/api/v1/super-admin/customers/:uid", [authHandler, roleHandler, ruleHandler])
|
@Put("/api/v1/super-admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
|
||||||
protected async put(req: Request, response: Response) {
|
protected async put(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
@ -119,7 +120,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Get a specific customer by uid
|
* @description Get a specific customer by uid
|
||||||
*/
|
*/
|
||||||
@Get("/api/v1/super-admin/customers/:uid", [authHandler, roleHandler, ruleHandler])
|
@Get("/api/v1/super-admin/customers/:uid", [authHandler, roleHandler, ruleHandler, customerHandler])
|
||||||
protected async getOneByUid(req: Request, response: Response) {
|
protected async getOneByUid(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
|
@ -4,7 +4,7 @@ import roleHandler from "@App/middlewares/RolesHandler";
|
|||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
|
import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index";
|
||||||
import { Documents, Prisma } from "@prisma/client";
|
import { Documents, EDocumentStatus, Prisma } from "@prisma/client";
|
||||||
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
@ -31,16 +31,16 @@ export default class DocumentsController extends ApiController {
|
|||||||
query = JSON.parse(req.query["q"] as string);
|
query = JSON.parse(req.query["q"] as string);
|
||||||
}
|
}
|
||||||
const officeId: string = req.body.user.office_Id;
|
const officeId: string = req.body.user.office_Id;
|
||||||
|
|
||||||
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
|
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
|
||||||
|
|
||||||
if(!query.where) query.where = { document_type : {office: officeWhereInput}};
|
if (!query.where) query.where = { document_type: { office: officeWhereInput } };
|
||||||
|
|
||||||
// query.where.document_type!.office = officeWhereInput;
|
// query.where.document_type!.office = officeWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
|
|
||||||
const documentEntities = await this.documentsService.get(query);
|
const documentEntities = await this.documentsService.get(query);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const documents = Document.hydrateArray<Document>(documentEntities, { strategy: "excludeAll" });
|
const documents = Document.hydrateArray<Document>(documentEntities, { strategy: "excludeAll" });
|
||||||
@ -108,7 +108,55 @@ export default class DocumentsController extends ApiController {
|
|||||||
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity, req.body.refused_reason);
|
const documentEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity);
|
||||||
|
|
||||||
|
//Hydrate ressource with prisma entity
|
||||||
|
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response, document);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Update a specific document
|
||||||
|
*/
|
||||||
|
@Put("/api/v1/notary/documents/:uid/refuse", [authHandler, ruleHandler, documentHandler])
|
||||||
|
protected async refuseDocument(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const documentFound = await this.documentsService.getByUid(uid, {
|
||||||
|
files: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!documentFound) {
|
||||||
|
this.httpNotFoundRequest(response, "document not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init Document resource with request body values
|
||||||
|
const documentEntity = Document.hydrate<Document>(documentFound);
|
||||||
|
|
||||||
|
// Status to refuse
|
||||||
|
documentEntity.document_status = EDocumentStatus.REFUSED;
|
||||||
|
|
||||||
|
//validate document
|
||||||
|
await validateOrReject(documentEntity, { groups: ["updateDocument"] });
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
const document = Document.hydrate<Document>(documentEntityUpdated, { strategy: "excludeAll" });
|
||||||
@ -170,7 +218,7 @@ export default class DocumentsController extends ApiController {
|
|||||||
if (req.query["q"]) {
|
if (req.query["q"]) {
|
||||||
query = JSON.parse(req.query["q"] as string);
|
query = JSON.parse(req.query["q"] as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
const documentEntity = await this.documentsService.getByUid(uid, query);
|
const documentEntity = await this.documentsService.getByUid(uid, query);
|
||||||
|
|
||||||
if (!documentEntity) {
|
if (!documentEntity) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import roleHandler from "@App/middlewares/RolesHandler";
|
import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Controller, Delete, Post } from "@ControllerPattern/index";
|
import { Controller, Delete, Post } from "@ControllerPattern/index";
|
||||||
import { EAppointmentStatus, Votes } from "@prisma/client";
|
import { EAppointmentStatus, Votes } from "@prisma/client";
|
||||||
@ -17,7 +16,6 @@ export default class LiveVoteController extends ApiController {
|
|||||||
constructor(
|
constructor(
|
||||||
private liveVoteService: LiveVoteService,
|
private liveVoteService: LiveVoteService,
|
||||||
private usersService: UsersService,
|
private usersService: UsersService,
|
||||||
private notificationBuilder: NotificationBuilder,
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -30,7 +28,7 @@ export default class LiveVoteController extends ApiController {
|
|||||||
try {
|
try {
|
||||||
const userId = req.body.user.userId;
|
const userId = req.body.user.userId;
|
||||||
//init IUser resource with request body values
|
//init IUser resource with request body values
|
||||||
const voteEntity = Vote.hydrate<Vote>(req.body);
|
const voteEntity = Vote.hydrate<Vote>(req.body, { strategy: "excludeAll" });
|
||||||
//validate user
|
//validate user
|
||||||
await validateOrReject(voteEntity, { groups: ["createVote"] });
|
await validateOrReject(voteEntity, { groups: ["createVote"] });
|
||||||
|
|
||||||
@ -54,7 +52,7 @@ export default class LiveVoteController extends ApiController {
|
|||||||
AND: [
|
AND: [
|
||||||
{
|
{
|
||||||
appointment: {
|
appointment: {
|
||||||
AND: [{ user_uid: voteEntity.appointment.targeted_user.uid }, { status: EAppointmentStatus.OPEN }],
|
AND: [{ user_uid: voteEntity.appointment.user.uid }, { status: EAppointmentStatus.OPEN }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ voter: { uid: userId } },
|
{ voter: { uid: userId } },
|
||||||
@ -79,11 +77,7 @@ export default class LiveVoteController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const vote = Vote.hydrate<Vote>(voteEntityCreated, {
|
const vote = Vote.hydrate<Vote>(voteEntityCreated, { strategy: "excludeAll" });
|
||||||
strategy: "excludeAll",
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.notificationBuilder.sendVoteNotification(vote);
|
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpCreated(response, vote);
|
this.httpCreated(response, vote);
|
||||||
|
@ -44,12 +44,10 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
{
|
{
|
||||||
customers: {
|
customers: {
|
||||||
some: {
|
some: {
|
||||||
contact: {
|
OR: [
|
||||||
OR: [
|
{ contact: { first_name: { contains: filter, mode: "insensitive" } } },
|
||||||
{ first_name: { contains: filter, mode: "insensitive" } },
|
{ contact: { last_name: { contains: filter, mode: "insensitive" } } },
|
||||||
{ last_name: { contains: filter, mode: "insensitive" } },
|
],
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -57,10 +55,11 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const officeId: string = req.body.user.office_Id;
|
|
||||||
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
|
const userId: string = req.body.user.userId;
|
||||||
if (!query.where) query.where = { office: officeWhereInput };
|
if (query.where?.stakeholders) delete query.where.stakeholders;
|
||||||
query.where.office = officeWhereInput;
|
const officeFoldersWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, stakeholders: { some: { uid: userId } } };
|
||||||
|
query.where = officeFoldersWhereInput;
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
|
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
|
||||||
|
@ -109,30 +109,31 @@ export default class UsersController extends ApiController {
|
|||||||
//init IUser resource with request body values
|
//init IUser resource with request body values
|
||||||
const userEntity = User.hydrate<User>(req.body);
|
const userEntity = User.hydrate<User>(req.body);
|
||||||
|
|
||||||
if(userEntity.role) {
|
if (userEntity.role) {
|
||||||
const role = await this.roleService.getByUid(userEntity.role.uid!);
|
const role = await this.roleService.getByUid(userEntity.role.uid!);
|
||||||
if(!role) {
|
if (!role) {
|
||||||
this.httpBadRequest(response, "Role not found");
|
this.httpBadRequest(response, "Role not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (role.name === "super-admin" || userFound.role.name === "super-admin" ) {
|
if (role.name === "super-admin" || userFound.role.name === "super-admin") {
|
||||||
this.httpBadRequest(response, "Cannot assign or remove super-admin role");
|
this.httpBadRequest(response, "Cannot assign or remove super-admin role");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(userEntity.office_role) {
|
if (userEntity.office_role) {
|
||||||
const officeRole = await this.officeRoleService.getByUid(userEntity.office_role.uid!);
|
const officeRole = await this.officeRoleService.getByUid(userEntity.office_role.uid!);
|
||||||
if(!officeRole) {
|
if (!officeRole) {
|
||||||
this.httpBadRequest(response, "Office role not found");
|
this.httpBadRequest(response, "Office role not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (officeRole.office_uid != userFound.office_uid) {
|
if (officeRole.office_uid != userFound.office_uid) {
|
||||||
this.httpBadRequest(response, "Cannot assign an office role from another office");
|
this.httpBadRequest(response, "Cannot assign an office role from another office");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const userEntityUpdated = await this.usersService.update(uid, userEntity);
|
const userEntityUpdated = await this.usersService.update(uid, userEntity);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
||||||
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
||||||
|
import Document from "le-coffre-resources/dist/SuperAdmin/Document";
|
||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import Container from "typedi";
|
import Container from "typedi";
|
||||||
|
|
||||||
@ -14,15 +15,27 @@ export default async function documentHandler(req: Request, response: Response,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const documentService = Container.get(DocumentsService);
|
const documentService = Container.get(DocumentsService);
|
||||||
const document = await documentService.getByUid(uid);
|
const document = await documentService.getByUid(uid, { folder: { include: { folder_anchor: true } } });
|
||||||
|
|
||||||
|
if (!document) {
|
||||||
|
response.status(HttpCodes.NOT_FOUND).send("Document not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (document?.depositor_uid != customerId) {
|
if (document?.depositor_uid != customerId) {
|
||||||
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.method === "POST" || req.method === "PUT") {
|
||||||
|
const documentEntity = Document.hydrate<Document>(document);
|
||||||
|
if (documentEntity.folder?.folder_anchor?.status === "VERIFIED_ON_CHAIN") {
|
||||||
|
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a verified folder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
response.status(HttpCodes.INTERNAL_ERROR).send("Internal server error");
|
response.status(HttpCodes.INTERNAL_ERROR).send("Internal server error");
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
||||||
import FilesService from "@Services/common/FilesService/FilesService";
|
import FilesService from "@Services/common/FilesService/FilesService";
|
||||||
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/customer/DocumentsService/DocumentsService";
|
||||||
|
import File from "le-coffre-resources/dist/SuperAdmin/File";
|
||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import Container from "typedi";
|
import Container from "typedi";
|
||||||
|
import { EDocumentStatus } from "@prisma/client";
|
||||||
|
|
||||||
export default async function fileHandler(req: Request, response: Response, next: NextFunction) {
|
export default async function fileHandler(req: Request, response: Response, next: NextFunction) {
|
||||||
const customerId = req.body.user.customerId;
|
const customerId = req.body.user.customerId;
|
||||||
const uid = req.path && req.path.split("/")[5];
|
const uid = req.path && req.path.split("/")[5];
|
||||||
const document = req.body.document;
|
const file: string | undefined = req.body["q"];
|
||||||
|
|
||||||
|
if (req.file && req.file.mimetype !== "application/pdf" && req.file.mimetype !== "image/png" && req.file.mimetype !== "image/jpeg") {
|
||||||
|
response.status(HttpCodes.BAD_REQUEST).send("File type not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (uid) {
|
if (uid) {
|
||||||
const fileService = Container.get(FilesService);
|
const fileService = Container.get(FilesService);
|
||||||
@ -20,12 +27,18 @@ export default async function fileHandler(req: Request, response: Response, next
|
|||||||
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (req.method === "PUT") {
|
||||||
|
if (file.document.document_status === EDocumentStatus.VALIDATED) {
|
||||||
|
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a validated document");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (file) {
|
||||||
if (document) {
|
const fileEntity = File.hydrate<File>(JSON.parse(file));
|
||||||
const documentService = Container.get(DocumentsService);
|
const documentService = Container.get(DocumentsService);
|
||||||
const documentFound = await documentService.getByUid(document.uid!);
|
const documentFound = await documentService.getByUid(fileEntity.document?.uid!, { folder: { include: { folder_anchor: true } } });
|
||||||
if(!documentFound) {
|
if (!documentFound) {
|
||||||
response.status(HttpCodes.NOT_FOUND).send("Document not found");
|
response.status(HttpCodes.NOT_FOUND).send("Document not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,6 +46,10 @@ export default async function fileHandler(req: Request, response: Response, next
|
|||||||
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (documentFound.document_status === EDocumentStatus.VALIDATED) {
|
||||||
|
response.status(HttpCodes.BAD_REQUEST).send("Cannot update a validated document");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
||||||
|
import { NextFunction, Request, Response } from "express";
|
||||||
|
import Container from "typedi";
|
||||||
|
import CustomersService from "@Services/super-admin/CustomersService/CustomersService";
|
||||||
|
|
||||||
|
export default async function customerHandler(req: Request, response: Response, next: NextFunction) {
|
||||||
|
try {
|
||||||
|
const officeId = req.body.user.office_Id;
|
||||||
|
const uid = req.path && req.path.split("/")[5];
|
||||||
|
|
||||||
|
if (uid) {
|
||||||
|
const customerService = Container.get(CustomersService);
|
||||||
|
const customer = await customerService.get({where:{AND: [{uid: uid}, {office_folders: {some: {office_uid: officeId}}}]}});
|
||||||
|
|
||||||
|
if (!customer[0]) {
|
||||||
|
response.status(HttpCodes.NOT_FOUND).send("Customer not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
response.status(HttpCodes.INTERNAL_ERROR).send("Internal server error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,11 @@ export default class EmailBuilder {
|
|||||||
const documentPrisma = await this.documentsService.getByUid(documentEntity.uid, { depositor: {include: {contact: true}}, folder:{include:{ office: true}} });
|
const documentPrisma = await this.documentsService.getByUid(documentEntity.uid, { depositor: {include: {contact: true}}, folder:{include:{ office: true}} });
|
||||||
if(!documentPrisma) throw new Error("Document not found");
|
if(!documentPrisma) throw new Error("Document not found");
|
||||||
const document = Document.hydrate<Document>(documentPrisma);
|
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 to = document.depositor!.contact!.email;
|
||||||
const civility = this.getCivility(document.depositor!.contact!.civility);
|
const civility = this.getCivility(document.depositor!.contact!.civility);
|
||||||
const templateVariables = {
|
const templateVariables = {
|
||||||
|
@ -14,7 +14,7 @@ export default class NotificationBuilder {
|
|||||||
private documentsService: DocumentsService,
|
private documentsService: DocumentsService,
|
||||||
private usersService: UsersService,
|
private usersService: UsersService,
|
||||||
private foldersService: OfficeFoldersService,
|
private foldersService: OfficeFoldersService,
|
||||||
private backendVariables: BackendVariables
|
private backendVariables: BackendVariables,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async sendDocumentDepositedNotification(documentEntity: Documents) {
|
public async sendDocumentDepositedNotification(documentEntity: Documents) {
|
||||||
@ -42,10 +42,12 @@ export default class NotificationBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async sendFolderAnchoredNotification(folderEntity: OfficeFolders) {
|
public async sendFolderAnchoredNotification(folderEntity: OfficeFolders) {
|
||||||
if(!folderEntity.uid) return;
|
if (!folderEntity.uid) return;
|
||||||
const officeFolderPrisma = await this.foldersService.getByUid(folderEntity.uid,
|
const officeFolderPrisma = await this.foldersService.getByUid(folderEntity.uid, {
|
||||||
{ folder_anchor: true, office: true, stakeholders: true }
|
folder_anchor: true,
|
||||||
);
|
office: true,
|
||||||
|
stakeholders: true,
|
||||||
|
});
|
||||||
if (!officeFolderPrisma) throw new Error("Folder not found");
|
if (!officeFolderPrisma) throw new Error("Folder not found");
|
||||||
const folder = OfficeFolder.hydrate<OfficeFolder>(officeFolderPrisma);
|
const folder = OfficeFolder.hydrate<OfficeFolder>(officeFolderPrisma);
|
||||||
if (folder.folder_anchor?.status !== "VERIFIED_ON_CHAIN") return;
|
if (folder.folder_anchor?.status !== "VERIFIED_ON_CHAIN") return;
|
||||||
@ -66,26 +68,24 @@ export default class NotificationBuilder {
|
|||||||
|
|
||||||
public async sendVoteNotification(vote: Vote) {
|
public async sendVoteNotification(vote: Vote) {
|
||||||
if (vote.appointment.status !== "OPEN") return;
|
if (vote.appointment.status !== "OPEN") return;
|
||||||
const superAdminList = await this.usersService.get({ where: { role: { label: "super-admin" } } });
|
const superAdminList = await this.usersService.get({ where: { role: { name: "super-admin" } } });
|
||||||
|
const voterIndex = superAdminList.findIndex((user) => user.uid === vote.voter.uid);
|
||||||
|
superAdminList.splice(voterIndex, 1);
|
||||||
|
const userTargeted = await this.usersService.getByUid(vote.appointment.user.uid!, { contact: true });
|
||||||
|
const userTargetedEntity = User.hydrate<User>(userTargeted!, { strategy: "excludeAll" });
|
||||||
let message = "";
|
let message = "";
|
||||||
if (vote.appointment.choice === "NOMINATE") {
|
if (vote.appointment.choice === "NOMINATE") {
|
||||||
message =
|
message = `Un collaborateur souhaite attribuer le titre de Super Administrateur à ${userTargetedEntity.contact?.first_name} ${userTargetedEntity.contact?.last_name}. Cliquez ici pour voter.`;
|
||||||
"Un collaborateur souhaite attribuer le titre de Super Administrateur à " +
|
|
||||||
vote.appointment.targeted_user +
|
|
||||||
". Cliquez ici pour voter.";
|
|
||||||
} else if (vote.appointment.choice === "DISMISS") {
|
} else if (vote.appointment.choice === "DISMISS") {
|
||||||
message =
|
message = `Un collaborateur souhaite retirer le titre de Super Administrateur à ${userTargetedEntity.contact?.first_name} ${userTargetedEntity.contact?.last_name}. Cliquez ici pour voter.`;
|
||||||
"Un collaborateur souhaite retirer le titre de Super Administrateur à " +
|
|
||||||
vote.appointment.targeted_user +
|
|
||||||
". Cliquez ici pour voter.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notificationsService.create({
|
this.notificationsService.create({
|
||||||
message: message,
|
message: message,
|
||||||
redirection_url: `${this.backendVariables.APP_HOST}/users/${vote.appointment.targeted_user.uid}`,
|
redirection_url: `${this.backendVariables.APP_HOST}/users/${vote.appointment.user.uid}`,
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
user: superAdminList || [],
|
user: superAdminList,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Database from "@Common/databases/database";
|
import Database from "@Common/databases/database";
|
||||||
import BaseRepository from "@Repositories/BaseRepository";
|
import BaseRepository from "@Repositories/BaseRepository";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import { Appointments, EAppointmentStatus, Prisma } from "@prisma/client";
|
import { Appointments, EAppointmentStatus, EVote, Prisma, Users, Votes } from "@prisma/client";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class AppointmentsRepository extends BaseRepository {
|
export default class AppointmentsRepository extends BaseRepository {
|
||||||
@ -39,6 +39,18 @@ export default class AppointmentsRepository extends BaseRepository {
|
|||||||
return this.model.update(updateArgs);
|
return this.model.update(updateArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async findOneByStatusUserAndChoice(userUid: string, choice: EVote, status: EAppointmentStatus): Promise<Appointments | null> {
|
||||||
|
return this.model.findUnique({
|
||||||
|
where: {
|
||||||
|
user_uid_choice_status: {
|
||||||
|
user_uid: userUid,
|
||||||
|
choice: choice,
|
||||||
|
status: status,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Find one appointment
|
* @description : Find one appointment
|
||||||
*/
|
*/
|
||||||
@ -54,12 +66,12 @@ export default class AppointmentsRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : Find one appointment with votes
|
* @description : Find one appointment with votes
|
||||||
*/
|
*/
|
||||||
public async findOneByUidWithVotes(uid: string) {
|
public async findOneByUidWithVotes(uid: string): Promise<(Appointments & {votes: Votes[], user: Users}) | null> {
|
||||||
return this.model.findUnique({
|
return this.model.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
},
|
},
|
||||||
include: {votes: true},
|
include: {votes: true, user: true},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ export default class DocumentsRepository extends BaseRepository {
|
|||||||
* @description : Find many documents
|
* @description : Find many documents
|
||||||
*/
|
*/
|
||||||
public async findMany(query: Prisma.DocumentsFindManyArgs) {
|
public async findMany(query: Prisma.DocumentsFindManyArgs) {
|
||||||
|
|
||||||
query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows);
|
query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows);
|
||||||
return this.model.findMany(query);
|
return this.model.findMany(query);
|
||||||
}
|
}
|
||||||
@ -96,7 +95,26 @@ export default class DocumentsRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : Update data of a document
|
* @description : Update data of a document
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, document: Partial<DocumentCustomer>, refusedReason?: string): Promise<Documents> {
|
public async update(uid: string, document: Partial<DocumentCustomer>): Promise<Documents> {
|
||||||
|
return this.model.update({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus],
|
||||||
|
document_history: {
|
||||||
|
create: {
|
||||||
|
document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Update data of a document
|
||||||
|
*/
|
||||||
|
public async refuse(uid: string, document: Partial<DocumentCustomer>, refusedReason?: string): Promise<Documents> {
|
||||||
return this.model.update({
|
return this.model.update({
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
|
@ -29,10 +29,10 @@ export default class VotesRepository extends BaseRepository {
|
|||||||
*/
|
*/
|
||||||
public async create(vote: Vote): Promise<Votes> {
|
public async create(vote: Vote): Promise<Votes> {
|
||||||
let whereArg: Prisma.AppointmentsWhereUniqueInput;
|
let whereArg: Prisma.AppointmentsWhereUniqueInput;
|
||||||
if(vote.appointment.targeted_user.uid) {
|
if(vote.appointment.user.uid) {
|
||||||
whereArg = {
|
whereArg = {
|
||||||
user_uid_choice_status: {
|
user_uid_choice_status: {
|
||||||
user_uid: vote.appointment.targeted_user.uid,
|
user_uid: vote.appointment.user.uid,
|
||||||
choice: EVote[vote.appointment.choice as keyof typeof EVote],
|
choice: EVote[vote.appointment.choice as keyof typeof EVote],
|
||||||
status: EAppointmentStatus.OPEN,
|
status: EAppointmentStatus.OPEN,
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ export default class VotesRepository extends BaseRepository {
|
|||||||
where: whereArg,
|
where: whereArg,
|
||||||
create: {
|
create: {
|
||||||
choice: EVote[vote.appointment.choice as keyof typeof EVote],
|
choice: EVote[vote.appointment.choice as keyof typeof EVote],
|
||||||
user_uid: vote.appointment.targeted_user.uid!,
|
user_uid: vote.appointment.user.uid!,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -61,7 +61,7 @@ export default class VotesRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.model.create({...createArgs, include: {appointment: {include: {votes: true}}}});
|
return this.model.create({...createArgs, include: {voter: true, appointment: {include: {votes: true, user: true}}}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,8 +25,8 @@ const storage = multer.memoryStorage();
|
|||||||
middlwares: [
|
middlwares: [
|
||||||
cors({ origin: "*" }),
|
cors({ origin: "*" }),
|
||||||
multer({ storage: storage, limits: { fileSize: 32000000 } }).single("file"), //32 MB maximum
|
multer({ storage: storage, limits: { fileSize: 32000000 } }).single("file"), //32 MB maximum
|
||||||
bodyParser.urlencoded({ extended: true }),
|
bodyParser.json({ limit: "35mb"}),
|
||||||
bodyParser.json(),
|
bodyParser.urlencoded({ extended: true, limit: "35mb", parameterLimit: 50000 }),
|
||||||
],
|
],
|
||||||
errorHandler,
|
errorHandler,
|
||||||
});
|
});
|
||||||
|
@ -3,10 +3,11 @@ import { Document } from "le-coffre-resources/dist/Admin";
|
|||||||
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
||||||
import BaseService from "@Services/BaseService";
|
import BaseService from "@Services/BaseService";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
|
import FilesRepository from "@Repositories/FilesRepository";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DocumentsService extends BaseService {
|
export default class DocumentsService extends BaseService {
|
||||||
constructor(private documentsRepository: DocumentsRepository) {
|
constructor(private documentsRepository: DocumentsRepository, private filesRepository: FilesRepository) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +39,19 @@ export default class DocumentsService extends BaseService {
|
|||||||
* @description : Modify a document
|
* @description : Modify a document
|
||||||
* @throws {Error} If document cannot be modified
|
* @throws {Error} If document cannot be modified
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, document: Partial<Document>, refused_reason?: string): Promise<Documents> {
|
public async update(uid: string, document: Partial<Document>): Promise<Documents> {
|
||||||
return this.documentsRepository.update(uid, document, refused_reason);
|
return this.documentsRepository.update(uid, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,8 +72,7 @@ export default class AnchoringProofService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
public async generate(data: AnchoringProofData): Promise<Buffer> {
|
public async generate(data: AnchoringProofData): Promise<Buffer> {
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
headless: "new",
|
headless: 'new',
|
||||||
executablePath: process.env['PUPPETEER_EXECUTABLE_PATH'],
|
|
||||||
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
||||||
});
|
});
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
@ -4,7 +4,7 @@ import { BackendVariables } from "@Common/config/variables/Variables";
|
|||||||
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
||||||
import FilesService from "../FilesService/FilesService";
|
import FilesService from "../FilesService/FilesService";
|
||||||
|
|
||||||
type EnrollmentResponse = {
|
export type EnrollmentResponse = {
|
||||||
url: string;
|
url: string;
|
||||||
id: number;
|
id: number;
|
||||||
api_key: string;
|
api_key: string;
|
||||||
@ -196,13 +196,12 @@ export default class Id360Service extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getEnrollment(token: string) {
|
public async getEnrollment(token: string) {
|
||||||
const res = await fetch(
|
return await fetch(
|
||||||
`${
|
`${
|
||||||
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
||||||
}/enrollment/status/${token}`,
|
}/enrollment/status/${token}`,
|
||||||
{ method: "GET" },
|
{ method: "GET" },
|
||||||
);
|
);
|
||||||
return (await res.json()) as EnrollmentResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async finalizeEnrollment(apiKey: string) {
|
public async finalizeEnrollment(apiKey: string) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import EmailRepository from "@Repositories/EmailRepository";
|
import EmailRepository from "@Repositories/EmailRepository";
|
||||||
import BaseService from "@Services/BaseService";
|
import BaseService from "@Services/BaseService";
|
||||||
import { Emails } from "@prisma/client";
|
import { Emails, Prisma } from "@prisma/client";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import MailchimpClient from "@mailchimp/mailchimp_transactional";
|
import MailchimpClient from "@mailchimp/mailchimp_transactional";
|
||||||
import { BackendVariables } from "@Common/config/variables/Variables";
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
@ -24,7 +24,7 @@ export default class MailchimpService extends BaseService {
|
|||||||
* @description : Get all emails
|
* @description : Get all emails
|
||||||
* @throws {Error} If emails cannot be get
|
* @throws {Error} If emails cannot be get
|
||||||
*/
|
*/
|
||||||
public async get(query: any): Promise<Emails[]> {
|
public async get(query: Prisma.EmailsFindManyArgs): Promise<Emails[]> {
|
||||||
return this.emailRepository.findMany(query);
|
return this.emailRepository.findMany(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,11 @@ import { Document } from "le-coffre-resources/dist/Notary";
|
|||||||
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
||||||
import BaseService from "@Services/BaseService";
|
import BaseService from "@Services/BaseService";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
|
import FilesRepository from "@Repositories/FilesRepository";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DocumentsService extends BaseService {
|
export default class DocumentsService extends BaseService {
|
||||||
constructor(private documentsRepository: DocumentsRepository) {
|
constructor(private documentsRepository: DocumentsRepository, private filesRepository: FilesRepository) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +39,19 @@ export default class DocumentsService extends BaseService {
|
|||||||
* @description : Modify a document
|
* @description : Modify a document
|
||||||
* @throws {Error} If document cannot be modified
|
* @throws {Error} If document cannot be modified
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, document: Partial<Document>, refused_reason?: string): Promise<Documents> {
|
public async update(uid: string, document: Partial<Document>): Promise<Documents> {
|
||||||
return this.documentsRepository.update(uid, document, refused_reason);
|
return this.documentsRepository.update(uid, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,10 +3,11 @@ import { Document } from "le-coffre-resources/dist/SuperAdmin";
|
|||||||
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
import DocumentsRepository from "@Repositories/DocumentsRepository";
|
||||||
import BaseService from "@Services/BaseService";
|
import BaseService from "@Services/BaseService";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
|
import FilesRepository from "@Repositories/FilesRepository";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DocumentsService extends BaseService {
|
export default class DocumentsService extends BaseService {
|
||||||
constructor(private documentsRepository: DocumentsRepository) {
|
constructor(private documentsRepository: DocumentsRepository, private filesRepository: FilesRepository) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +39,19 @@ export default class DocumentsService extends BaseService {
|
|||||||
* @description : Modify a document
|
* @description : Modify a document
|
||||||
* @throws {Error} If document cannot be modified
|
* @throws {Error} If document cannot be modified
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, document: Partial<Document>, refused_reason?: string): Promise<Documents> {
|
public async update(uid: string, document: Partial<Document>): Promise<Documents> {
|
||||||
return this.documentsRepository.update(uid, document, refused_reason);
|
return this.documentsRepository.update(uid, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +81,7 @@ export default class DocumentsService extends BaseService {
|
|||||||
* @description : Get a document by uid
|
* @description : Get a document by uid
|
||||||
* @throws {Error} If document cannot be get by uid
|
* @throws {Error} If document cannot be get by uid
|
||||||
*/
|
*/
|
||||||
public async getByUidWithFiles(uid: string): Promise<Documents & {files: Files[] | null} | null> {
|
public async getByUidWithFiles(uid: string): Promise<(Documents & { files: Files[] | null }) | null> {
|
||||||
return this.documentsRepository.findOneByUidWithFiles(uid);
|
return this.documentsRepository.findOneByUidWithFiles(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@ import BaseService from "@Services/BaseService";
|
|||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import User, { Appointment, Role, Vote } from "le-coffre-resources/dist/SuperAdmin";
|
import User, { Appointment, Role, Vote } from "le-coffre-resources/dist/SuperAdmin";
|
||||||
import VotesRepository from "@Repositories/VotesRepository";
|
import VotesRepository from "@Repositories/VotesRepository";
|
||||||
import { Appointments, EAppointmentStatus, EVote, Prisma, Votes } from "@prisma/client";
|
import { Appointments, EAppointmentStatus, EVote, Prisma, Users, Votes } from "@prisma/client";
|
||||||
import UsersService from "../UsersService/UsersService";
|
import UsersService from "../UsersService/UsersService";
|
||||||
import RolesService from "../RolesService/RolesService";
|
import RolesService from "../RolesService/RolesService";
|
||||||
import AppointmentsRepository from "@Repositories/AppointmentsRepository";
|
import AppointmentsRepository from "@Repositories/AppointmentsRepository";
|
||||||
|
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class LiveVoteService extends BaseService {
|
export default class LiveVoteService extends BaseService {
|
||||||
@ -14,12 +15,13 @@ export default class LiveVoteService extends BaseService {
|
|||||||
private appointmentRepository: AppointmentsRepository,
|
private appointmentRepository: AppointmentsRepository,
|
||||||
private userService: UsersService,
|
private userService: UsersService,
|
||||||
private roleService: RolesService,
|
private roleService: RolesService,
|
||||||
|
private notificationBuilder: NotificationBuilder,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async verifyVoterChoice(vote: Vote): Promise<boolean> {
|
public async verifyVoterChoice(vote: Vote): Promise<boolean> {
|
||||||
const userWithRole = await this.userService.getByUidWithRole(vote.appointment.targeted_user.uid!);
|
const userWithRole = await this.userService.getByUidWithRole(vote.appointment.user.uid!);
|
||||||
if (userWithRole!.role.name === "super-admin" && vote.appointment.choice === EVote.DISMISS) {
|
if (userWithRole!.role.name === "super-admin" && vote.appointment.choice === EVote.DISMISS) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -65,27 +67,35 @@ export default class LiveVoteService extends BaseService {
|
|||||||
return this.appointmentRepository.findOneByUid(uid, query);
|
return this.appointmentRepository.findOneByUid(uid, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAppointmentWithVotes(vote: Vote): Promise<Appointments | null> {
|
public async getAppointmentWithVotes(vote: Vote): Promise<(Appointments & { votes: Votes[]; user: Users }) | null> {
|
||||||
if (vote.appointment.uid) {
|
if (vote.appointment.uid) {
|
||||||
return this.appointmentRepository.findOneByUid(vote.appointment.uid);
|
return this.appointmentRepository.findOneByUidWithVotes(vote.appointment.uid);
|
||||||
}
|
}
|
||||||
const appointmentByUser = await this.appointmentRepository.findMany({
|
const appointmentByUser = await this.appointmentRepository.findMany({
|
||||||
where: {
|
where: {
|
||||||
AND: [
|
AND: [
|
||||||
{ user_uid: vote.appointment.targeted_user.uid },
|
{ user_uid: vote.appointment.user.uid },
|
||||||
{ status: EAppointmentStatus.OPEN },
|
{ status: EAppointmentStatus.OPEN },
|
||||||
{ choice: EVote[vote.appointment.choice as keyof typeof EVote] },
|
{ choice: EVote[vote.appointment.choice as keyof typeof EVote] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
include: { votes: true },
|
include: { votes: true, user: true },
|
||||||
});
|
});
|
||||||
if (appointmentByUser.length >= 1) {
|
if (appointmentByUser.length != 0) {
|
||||||
return this.appointmentRepository.findOneByUidWithVotes(appointmentByUser[0]!.uid);
|
return this.appointmentRepository.findOneByUidWithVotes(appointmentByUser[0]!.uid);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async closeVote(appointment: Appointments, vote: Votes) {
|
private async closeVote(appointment: Appointments, vote: Votes) {
|
||||||
|
const apointmentFound = await this.appointmentRepository.findOneByStatusUserAndChoice(
|
||||||
|
appointment.user_uid,
|
||||||
|
EVote[appointment.choice as keyof typeof EVote],
|
||||||
|
EAppointmentStatus.CLOSED,
|
||||||
|
);
|
||||||
|
if (apointmentFound) {
|
||||||
|
await this.appointmentRepository.delete(apointmentFound.uid);
|
||||||
|
}
|
||||||
await this.appointmentRepository.update(vote.appointment_uid, EAppointmentStatus.CLOSED);
|
await this.appointmentRepository.update(vote.appointment_uid, EAppointmentStatus.CLOSED);
|
||||||
const user = await this.userService.getByUid(appointment.user_uid, { role: true });
|
const user = await this.userService.getByUid(appointment.user_uid, { role: true });
|
||||||
const userEntity = User.hydrate<User>(user!, { strategy: "excludeAll" });
|
const userEntity = User.hydrate<User>(user!, { strategy: "excludeAll" });
|
||||||
@ -98,12 +108,14 @@ export default class LiveVoteService extends BaseService {
|
|||||||
const roles = await this.roleService.get({ where: { name: "default" } });
|
const roles = await this.roleService.get({ where: { name: "default" } });
|
||||||
const roleEntity = Role.hydrate<Role>(roles[0]!, { strategy: "excludeAll" });
|
const roleEntity = Role.hydrate<Role>(roles[0]!, { strategy: "excludeAll" });
|
||||||
userEntity.role = roleEntity;
|
userEntity.role = roleEntity;
|
||||||
|
await this.notificationBuilder.sendDismissNotification(userEntity);
|
||||||
await this.userService.update(appointment!.user_uid, userEntity);
|
await this.userService.update(appointment!.user_uid, userEntity);
|
||||||
return vote;
|
return vote;
|
||||||
} else if (appointment.choice === EVote.NOMINATE) {
|
} else if (appointment.choice === EVote.NOMINATE) {
|
||||||
const roles = await this.roleService.get({ where: { name: "super-admin" } });
|
const roles = await this.roleService.get({ where: { name: "super-admin" } });
|
||||||
const roleEntity = Role.hydrate<Role>(roles[0]!, { strategy: "excludeAll" });
|
const roleEntity = Role.hydrate<Role>(roles[0]!, { strategy: "excludeAll" });
|
||||||
userEntity!.role = roleEntity;
|
userEntity!.role = roleEntity;
|
||||||
|
await this.notificationBuilder.sendNominateNotification(userEntity);
|
||||||
await this.userService.update(appointment!.user_uid, userEntity);
|
await this.userService.update(appointment!.user_uid, userEntity);
|
||||||
return vote;
|
return vote;
|
||||||
}
|
}
|
||||||
@ -118,8 +130,10 @@ export default class LiveVoteService extends BaseService {
|
|||||||
const appointment = await this.getAppointmentWithVotes(vote);
|
const appointment = await this.getAppointmentWithVotes(vote);
|
||||||
|
|
||||||
if (appointment) {
|
if (appointment) {
|
||||||
const appointmentEntity = Appointment.hydrate<Appointment>(appointment, { strategy: "excludeAll" });
|
const voteEntity = Vote.hydrateArray<Vote>(appointment.votes, { strategy: "excludeAll" });
|
||||||
if (appointmentEntity?.votes && appointmentEntity.votes.length >= 2) {
|
const appointementWithVotesHydrated = { ...appointment, votes: voteEntity };
|
||||||
|
const appointmentEntity = Appointment.hydrate<Appointment>(appointementWithVotesHydrated, { strategy: "excludeAll" });
|
||||||
|
if (appointmentEntity.votes && appointmentEntity.votes.length >= 2) {
|
||||||
const voteCreated = await this.voteRepository.create(vote);
|
const voteCreated = await this.voteRepository.create(vote);
|
||||||
return this.closeVote(appointment, voteCreated);
|
return this.closeVote(appointment, voteCreated);
|
||||||
}
|
}
|
||||||
@ -127,7 +141,9 @@ export default class LiveVoteService extends BaseService {
|
|||||||
|
|
||||||
const approvedChoice = await this.verifyVoterChoice(vote);
|
const approvedChoice = await this.verifyVoterChoice(vote);
|
||||||
if (!approvedChoice) return null;
|
if (!approvedChoice) return null;
|
||||||
|
const voteCreated = await this.voteRepository.create(vote);
|
||||||
return this.voteRepository.create(vote);
|
const voteEntity = Vote.hydrate<Vote>(voteCreated, { strategy: "excludeAll" });
|
||||||
|
await this.notificationBuilder.sendVoteNotification(voteEntity);
|
||||||
|
return voteCreated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user