UNPKG

synt_backend

Version:

Synt light-weight node backend service

488 lines (451 loc) 13.5 kB
const express = require("express"); const router = express.Router(); const db = require("./../mysql/models/index"); import * as ValidationHelper from "./../helpers/validations"; const userHelper = require("./../helpers/user"); var keypoint = require("./../helpers/keypoint"); import { attachUploadedFiles } from "./../helpers/db-storage"; const notifier = require("./../helpers/notifier"); // routes router.get("/", getIncidents); router.get("/:IncidentId", getIncident); router.post("/", postIncident); router.post("/:IncidentId/comment", postIncidentComment); module.exports = router; async function getIncident(req, res) { const { t } = req; let user = await userHelper.getAuthUser(req); const { IncidentId } = req.params; if (user) { let VmeValidation = await ValidationHelper.validateVme(t, user.VMEId); if (!VmeValidation.success) { return res.json(VmeValidation); } const { VME } = VmeValidation; db.Incident.findOne({ where: { id: IncidentId }, include: [ { model: db.ReportType }, { model: db.Supplier, include: [{ model: db.Company }] }, { model: db.Image }, { model: db.IncidentComment, include: [ { model: db.User, attributes: { exclude: [ "email", "phone", "email_verified_at", "phone_verified_at", ], }, }, ], }, ], }).then(async (Incident) => { //FIXME: TypeError: Cannot read property 'VMEId' of null if (Incident.VMEId !== VME.id) { return res.json({ success: false, error: t( "api.incidents.errors.notYourVme", "This message does not belong to your VME." ), }); } else if (Incident) { // return results if (Incident.ReportType?.category === "other") { if (Incident.Supplier) { Incident.setDataValue("new_supplier", true); if (Incident.Supplier.CompanyId) { Incident.Supplier.setDataValue("has_vat_number", true); } else { Incident.Supplier.setDataValue("has_vat_number", false); } } else { Incident.setDataValue("new_supplier", false); } } await Promise.all( Incident.Images.map(async (I) => { I.setDataValue("presignedUrl", await I.getPresignedUrl()); }) ); return res.json({ success: true, Incident, }); } else { return res.json({ success: false, error: t( "api.incidents.errors.missingMessage", "This message does not exist. Contact support" ), }); } }); } } async function getIncidents(req, res) { const { t } = req; try { // verify vme and get vme let user = await userHelper.getAuthUser(req); let VmeValidation = await ValidationHelper.validateVme(t, user.VMEId); if (!VmeValidation.success) { return res.json(VmeValidation); } const { VME } = VmeValidation; if (VME) { VME.getIncidents({ include: [ { model: db.ReportType }, { model: db.User, attributes: { exclude: ["email_verified_at", "phone_verified_at"], }, }, { model: db.Image }, { model: db.IncidentComment, include: [ { model: db.User, attributes: { exclude: [ "email", "phone", "email_verified_at", "phone_verified_at", ], }, }, ], }, ], }).then((Incidents) => { return res.json({ success: true, Incidents: Incidents.sort( (a, b) => new Date(b.createdAt) - new Date(a.createdAt) ), }); }); } else { return res.json({ success: false, error: t("api.incidents.errors.noVmeSelected", "No VME selected yet."), }); } } catch (error) { return res.json({ success: false, error }); } } async function postIncident(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, report_description, is_urgent, has_tried_to_call, has_called, is_covered, ReportType, call_description, solved_at, Images, new_supplier, Supplier, // new supplier/ aannemer } = req.body; //const { IncidentId } = req.params; //TODO: Check which user wants to change (roles / reporter) const IncidentData = { UserId: User.id, ReportTypeId: ReportType.id || null, VMEId: VME.id, report_description, is_urgent, has_tried_to_call, has_called, is_covered, call_description, solved_at, }; let errors = {}; if ( ReportType.category === "other" && !Supplier && typeof new_supplier === "undefined" ) { errors["new_supplier"] = t( "api.incidents.errors.newSupplier", "You must indicate whether you know a contractor." ); } if (ReportType.category === "other" && new_supplier) { let temp = {}; if (Supplier.has_vat_number) { if (!Supplier.vat_number) { temp["vat_number"] = t( "api.incidents.errors.vatNumber", "Enter the company number." ); } } else { if (!Supplier.alias) { temp["alias"] = t( "api.incidents.errors.alias", "Enter the company alias/name." ); } if (!Supplier.email) { temp["email"] = t( "api.incidents.errors.email", "Company email is required." ); } /* if (!Supplier.phone) { temp["phone"] = t( "api.incidents.errors.phone", "Company phone number is required." ); } */ } if (Object.keys(temp).length) { errors["Supplier"] = temp; } } if (!ReportType.name) { errors["ReportTypeId"] = t( "api.incidents.errors.reportType", "Selection of notification type is required." ); } if (!report_description || report_description === "") { errors["report_description"] = t( "api.incidents.errors.reportDescription", "A description of the notification is required." ); } if (typeof is_urgent === "undefined") { errors["is_urgent"] = t( "api.incidents.errors.isUrgent", "You must indicate whether it is urgent." ); } if (has_called && (!call_description || call_description === "")) { errors["call_description"] = t( "api.incidents.errors.callDescription", "A description of the phone call is required." ); } // return errors if there are any if (Object.keys(errors).length) { return res.json({ success: false, errors, }); } if (id) { // update exisiting incident // TODO: Check other details editable? db.Incident.findOne({ where: { id }, include: db.IncidentComment }).then( (Incident) => { Incident.update(IncidentData); if (solved_at) { /* sendRemarkToKeypoint( Incident, "Synt gebruiker sluit de melding af: " + solved_at ); */ } attachUploadedFiles("Incident", Incident, Images, "Image"); // only images can be added keypoint.createClient("demo").then(async (client) => { // send images to kp for (const File of Images) { console.log("hello"); client.postCaseFile(Incident.case_id, File); } }); return res.json({ success: true, Incident: IncidentData }); } ); } else { let NewSupplier; if (ReportType.category === "other" && new_supplier) { let Company; if (Supplier.has_vat_number) { Company = await db.Company.findOne({ where: { company_number: Supplier.company_number, country_code: Supplier.country_code, }, }); if (!Company) { Company = await db.Company.create({ ...Supplier }); } } // find or add new supplier // FIXME: existing supplier NewSupplier = await db.Supplier.create({ alias: Supplier.alias || null, CompanyId: Company?.id || null, ReportTypeId: null, VMEId: VME.id, }); } db.Incident.create({ ...IncidentData, SupplierId: NewSupplier?.id || null, }).then((newItem) => { // handle images attachUploadedFiles("Incident", newItem, Images, "Image"); //notify //FIXME: limit user VME.getUsers().then((Users) => { Users.forEach((U) => { notifier.notify(U, "new_incident", { Incident: newItem, VME, Notifier: User, }); }); }); if (ReportType.category === "other" && !new_supplier) { // only sending other incident without new supplier to keypoint keypoint .createClient("demo") .then(async (client) => { // save the initial object send to kp (in case something fails, we have backup) newItem.declaration = JSON.stringify({ ReportType, ...IncidentData, id: newItem.id, }); // send incident to keypoint let result = await client.postDeclaration( { ReportType, ...IncidentData, id: newItem.id }, VME, User ); if (typeof result === "number") { // newItem.case = JSON.stringify(result); newItem.case_id = result; newItem.save(); } console.log(result); // send images to kp if (Images) { for (const File of Images) { let result = await client.postCaseFile(newItem.case_id, File); console.log(result); } } }) .catch((error) => { console.log(error); }); } else { // notify supplier (if not to keypoint) // if a supplier is selected if (Supplier) { notifier.sendMail(Supplier.email, "new_incident_to_supplier", { Incident: newItem, Supplier, VME, Notifier: User, }); } } return res.json({ success: true, Incident: newItem }); }); } } } // function sendRemarkToKeypoint(Incident, message) { // // send incident remark to keypoint // // last incident comment is message // keypoint // .createClient("demo") // .then(async (client) => { // let remark = // Incident.createdAt + ": " + Incident.report_description || ""; // for (const comment of Incident.IncidentComments) { // remark = // remark + " " + comment.createdAt + ": " + comment.message; // } // let result = await client.postDeclarationRemark( // Incident.declaration_id, // remark // ); // console.log(result); // }) // .catch((error) => { // console.log(error); // }); // } async function postIncidentComment(req, res) { const { t } = req; let user = await userHelper.getAuthUser(req); if (user) { const { message } = req.body; const { IncidentId } = req.params; //TODO: Check which user wants to change (roles / reporter) const IncidentComment = { UserId: user.id, IncidentId, message, }; if (!IncidentId) { return res.json({ success: false, errors: { message: t( "api.incidents.errors.notificationRequired", "An existing notification is required." ), }, }); } if (!message || message === "") { return res.json({ success: false, errors: { message: t( "api.incidents.errors.messageRequired", "Message is required." ), }, }); } db.IncidentComment.create(IncidentComment) .then((response) => { /* db.Incident.findOne({ where: { id: IncidentId }, include: db.IncidentComment, }).then((Incident) => { sendRemarkToKeypoint(Incident, message); }); */ console.log(response); }) .catch((err) => { console.log(err); }); return res.json({ success: true }); } }