UNPKG

synt_backend

Version:

Synt light-weight node backend service

547 lines (484 loc) 15.7 kB
const express = require("express"); const router = express.Router(); const db = require("./../mysql/models/index"); const userHelper = require("./../helpers/user"); import * as ValidationHelper from "./../helpers/validations"; import { attachUploadedFiles } from "./../helpers/db-storage"; const notifier = require("./../helpers/notifier"); import { findCommissioners } from "../helpers/format"; import { getGLAPurchasesDB, getOwnersDB, getSuppliersDB, getVmePurchases, } from "../database/documents"; // routes router.get("/owners/:vmeId/:start_date/:end_date", getOwners); router.get("/suppliers/:vmeId/:start_date/:end_date", getSuppliers); router.get("/globalSettlement/:vmeId/:start_date/:end_date", getGLAPurchases); router.get("/budgets/:vmeId/:start_date/:end_date", getBudgets); router.get("/purchases/:vmeId/:start_date/:end_date", getPurchases); router.get("/:DocumentId", getDocument); router.get("/", getDocuments); router.post("/", postDocument); module.exports = router; async function getDocument(req, res) { const { t } = req; let user = await userHelper.getAuthUser(req); const { DocumentId } = req.params; if (user) { // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, user.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const { VME } = VmeValidation; db.Document.findOne({ where: { id: DocumentId }, include: [ { model: db.DocumentType }, { model: db.DocumentFile }, { model: db.User }, ], }).then(async (Document) => { if (Document.VMEId !== VME.id) { return res.json({ success: false, error: t("api.documents.errors.notYourVme"), }); } else { await Promise.all( Document.DocumentFiles.map(async (DF) => { DF.setDataValue("presignedUrl", await DF.getPresignedUrl()); }) ); return res.json({ success: true, Document }); } }); } } async function getSuppliers(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); const { vmeId, start_date, end_date } = req.params; if (!User) { return res.json({ success: false, error: "No user" }); } const vme = await db.VME.findOne({ where: { id: vmeId }, include: [{ model: db.Company }], }); // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const result = await getSuppliersDB({ vme, start_date, end_date }); return res.json(result); } catch (error) { return res.json({ success: false, error: error.stack }); } } async function getOwners(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); const { vmeId, start_date, end_date } = req.params; if (!User) { return res.json({ success: false, error: "No user" }); } const vme = await db.VME.findOne({ where: { id: vmeId }, include: [{ model: db.Company }], }); // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const result = await getOwnersDB({ vme, include_past: true, start_date, end_date, }); return res.json(result); } catch (error) { return res.json({ success: false, error: error.stack }); } } async function getGLAPurchases(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); const { vmeId, start_date, end_date } = req.params; if (!User) { return res.json({ success: false, error: "No user" }); } const vme = await db.VME.findOne({ where: { id: vmeId }, include: [{ model: db.Company }], }); // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const result = await getGLAPurchasesDB({ vme, start_date, end_date, }); return res.json(result); } catch (error) { return res.json({ success: false, error: error.stack }); } } async function getPurchases(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); const { vmeId, start_date, end_date } = req.params; if (!User) { return res.json({ success: false, error: "No user" }); } const vme = await db.VME.findOne({ where: { id: vmeId }, include: [{ model: db.Company }], }); // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const purchases = await getVmePurchases({ vme, start_date, end_date, }); return res.json({ vme, start_date, end_date, purchases, success: true, }); } catch (error) { return res.json({ success: false, error: error.stack }); } } async function getBudgets(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); const { vmeId, start_date, end_date } = req.params; if (!User) { return res.json({ success: false, error: "No user" }); } const vme = await db.VME.findOne({ where: { id: vmeId }, include: [{ model: db.Company }], }); // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const result = await getGLAPurchasesDB({ vme, start_date, end_date, }); const financialYears = await vme.getFinancialYears(); return res.json({ ...result, financialYears }); } catch (error) { return res.json({ success: false, error: error.stack }); } } async function getDocuments(req, res) { const { t } = req; try { let User = await userHelper.getAuthUser(req); let { type } = req.query; if (User) { // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const { VME, role } = VmeValidation; if (VME) { try { // check whether owner let Lots = await VME.getLots({ include: { model: db.LotPhase, include: { model: db.User, where: { id: User.id } }, }, }); let is_owner = false; for (const Lot of Lots) { // FIXME: document visibility depending on create date and phase date let U = Lot.LotPhases.find((LP) => !LP.ends_at)?.Users.find( (U) => U.id === User.id ); if (U?.LotPhaseUser.type === ("owner" || "bare_owner")) { is_owner = true; break; } } // general documents (opstart en andere) const getDocuments = VME.getDocuments({ include: [ { model: db.DocumentType }, { model: db.DocumentFile }, { model: db.User }, ], }); let getSupplierFiles, getPurchaseFiles = null; let is_super = User.is_admin == true; let is_synt = role === "synt_authoriser" || role === "synt_viewer"; if (is_super) { // supplier files getSupplierFiles = db.SupplierFile.findAll({ include: [{ model: db.Supplier, where: { VMEId: VME.id } }], }); } // purchase files getPurchaseFiles = db.PurchaseFile.findAll({ include: [{ model: db.Purchase, where: { VMEId: VME.id } }], }); // settlement files const getSettlementFiles = db.SettlementFile.findAll({ include: [ { model: db.Settlement, include: [ { model: db.FinancialYear, where: { VMEId: VME.id } }, ], }, { model: db.User, ...(!is_super ? { where: { id: User.id } } : {}), }, ], }); // settlement files const getProvisionFiles = db.ProvisionFile.findAll({ include: [ { model: db.Provision, include: [ { model: db.Lot }, { model: db.User, ...(!is_super ? { where: { id: User.id } } : {}), }, ], where: { VMEId: VME.id }, }, ], }); // call all in parallel const [ Documents, SupplierFiles, SettlementFiles, PurchaseFiles, ProvisionFiles, ] = await Promise.all([ getDocuments, getSupplierFiles || [], getSettlementFiles, getPurchaseFiles || [], getProvisionFiles, ]); // Get all signed urls await Promise.all([ ...SupplierFiles.map(async (SF) => { SF.setDataValue("presignedUrl", await SF.getPresignedUrl()); }), ...ProvisionFiles.map(async (PF) => { PF.setDataValue("presignedUrl", await PF.getPresignedUrl()); }), ...SettlementFiles.map(async (SF) => { SF.setDataValue("presignedUrl", await SF.getPresignedUrl()); }), ...PurchaseFiles.map(async (PF) => { PF.setDataValue("presignedUrl", await PF.getPresignedUrl()); }), ]); return res.json({ success: true, Documents: Documents.filter((D) => { if ( D.visibility === "custom" && D.Users.map((U) => U.id).includes(User.id) ) { // custom visibility and user included return true; } else { // not custom return ( is_super || D.visibility === "everyone" || (is_owner && D.visibility === "owners") || (is_synt && D.visibility === "synt") ); } }).map((D) => ({ ...D.toJSON(), is_file: false })), SupplierFiles: SupplierFiles.map((F) => { F = F.toJSON(); F.DocumentType = { name: t("api.documents.documentType.names.supplier"), }; F.is_file = true; return F; }), SettlementFiles: SettlementFiles.map((F) => { F = F.toJSON(); F.DocumentType = { name: t("api.documents.documentType.names.settlement"), }; F.name = "S" + F.Settlement.FinancialYear.year + "/" + F.UserId; F.visibility = F.User.full_name; F.is_file = true; return F; }), PurchaseFiles: PurchaseFiles.map((F) => { F = F.toJSON(); F.DocumentType = { name: t("api.documents.documentType.names.purchaseInvoice"), }; F.name = F.Purchase.reference; F.visibility = "everyone"; F.is_file = true; return F; }), ProvisionFiles: ProvisionFiles.map((F) => { F = F.toJSON(); F.DocumentType = { name: t("api.documents.documentType.names.contribution"), }; F.name = F.original_name; F.visibility = F.Provision.Lot.name; F.is_file = true; return F; }), }); } catch (error) { console.log(error); } } else { return res.json({ success: false, error: t("api.documents.errors.noVmeSelected"), }); } } } catch (error) { return res.json({ success: false, error, }); } } async function postDocument(req, res) { const { t } = req; let User = await userHelper.getAuthUser(req); if (User) { // verify vme and get vme let VmeValidation = await ValidationHelper.validateVme(t, User.VMEId); //TODO: Validate user roles if (!VmeValidation.success) { return res.json(VmeValidation); } const { VME } = VmeValidation; const { id, name, visibility, DocumentTypeId, DocumentFiles } = req.body; let { Users } = req.body; const Data = { name, visibility, DocumentTypeId, VMEId: VME.id, UserId: User.id, Users, }; let errors = {}; if (!name) { errors.name = t("api.documents.errors.nameRequired"); } if (!id && !DocumentFiles) { errors.DocumentFiles = t("api.documents.errors.filesRequired"); } if (!visibility) { errors.visibility = t("api.documents.errors.visibilityRequired"); } if (visibility === "custom" && (!Users || Users?.length === 0)) { errors.Users = t("api.documents.errors.residentsRequired"); } if (!DocumentTypeId) { errors.DocumentType = t("api.documents.errors.typeRequired"); } let exists = await db.Document.findOne({ where: { VMEId: VME.id, name } }); if (exists) { errors.name = t("api.documents.errors.alreadyExists", { name }); } if (Object.keys(errors).length > 0) { return res.json({ success: false, errors, }); } //Set Users based on visibility if (typeof Users === "undefined") { Users = await VME.getUsers(); if (visibility === "synt") { Users = Users.filter( (U) => U.UserVME.type === "synt_viewer" || U.UserVME.type === "synt_authoriser" ); } else if (visibility === "owners") { Users = await findCommissioners(VME); } else if (visibility === "everyone") { // all users } } if (id) { // update exisiting document db.Document.findOne({ where: { id } }).then((Document) => { attachUploadedFiles("Document", Document, DocumentFiles); const update = { name, visibility, DocumentTypeId }; Document.update(update); if (Users) { // custom visibility Document.setUsers(Users.map((U) => U.id)); // who has access Users.forEach((U) => { notifier.notify(U, "update_document", { Document, VME, }); }); } return res.json({ success: true, Document }); }); } else { db.Document.create(Data).then((newItem) => { attachUploadedFiles("Document", newItem, DocumentFiles); if (Users) { // custom visibility newItem.setUsers(Users.map((U) => U.id)); // who has access Users.forEach((U) => { notifier.notify(U, "new_document", { Document: newItem, VME, }); }); } return res.json({ success: true, Document: newItem }); }); } } }