%PDF- %PDF-
| Direktori : /home/opti/workflow/src/routes/ |
| Current File : /home/opti/workflow/src/routes/flow.js |
var express = require('express');
var router = express.Router();
var bcrypt = require('bcrypt')
var formidable = require('formidable');
var fs = require('fs');
var path = require('path');
var con = require('../../config');
var secured = require('../middleware/login');
var db = require('../models');
//get all structures, it could be a get request but, post works fine
router.post('/get', function(req, res, next) {
db.Structure.all()
.then( structures=>{
res.json(structures);
})
});
//get method/route for sll flow list/view,
router.get('/', secured, function(req, res, next) {
// var orgId = 0;
var user = req.user;
let orgId = user.orgId ;
db.Flow.findAll({ where: {orgId: orgId}, include: [{ all: true, nested: true }]/*, order: [['parentId','ASC']]*/ } ).then(flows => {
// console.log(structures[3])
res.render('flow/index', { user, flows});
})
.catch(error => {
// Ooops, do some error-handling
console.log(error);
})
});
router.get('/add', secured, function(req, res, next) {
// var orgId = 0;
var user = req.user;
let orgId = user.orgId ;
db.CompanyStructure.findAll({ where: {orgId: orgId}, include: [{ all: true, nested: true }]/*, order: [['parentId','ASC']]*/ } ).then(structures => {
console.log(structures.length)
res.render('flow/addFlow', { user, structures});
})
.catch(error => {
// Ooops, do some error-handling
console.log(error);
})
});
//post method for creating new flow
router.post('/add', secured, async(req, res, next) => {
var user = req.user;
db.Flow.create({companyStructureId:req.body.companyStructureId, title:req.body.flowName, description:req.body.description, orgId: user.orgId, createdBy:user.id})
.then(flow => {
res.json(flow);
})
});
router.post('/addFlowColumns', secured, async(req, res, next) => {
var user = req.user;
// var form = new formidable.IncomingForm();
// await form.parse(req, async(err, fields, files) =>{
// console.log(req.body)
columns = req.body['columns[]'];
title = req.body.title;
flowId = req.body.flowId;
stage = req.body.currentStage;
// })
// console.log(columns.le)
await db.FlowTitle.findOrCreate({where:{flowId, title, stage, orgId: user.orgId, createdBy:user.id}})
.spread((flowTitle, created) => {
if(created){
// it sometimes throe columns.foreach is not a function when the column is just 1 item
//so i check first
if(Array.isArray(columns)){
columns.forEach(async column => {
await db.FlowFields.create({flowId, flowTitleId:flowTitle.id, stage, label: column, createdBy: user.id})
})
}
else{
db.FlowFields.create({flowId, flowTitleId:flowTitle.id, stage, label: columns, createdBy: user.id})
}
res.json({status:"success"});
}
//return res.redirect(`/workflow/request/${request.uuid}`);
})
});
//finish entering flow and mark flow active
router.post('/addFlowFinish', secured, async(req, res, next) => {
var user = req.user;
db.Flow.findOne({where:{id:req.body.flowId}})
.then(flow => {
flow.active = 1;
flow.save({fields:['active']})
.then(()=>{
res.json({status: "success"});
})
})
});
router.get('/view/:uuid', secured, async(req, res, next) => {
var user = req.user;
const [ flow ] = await Promise.all([
db.Flow.findOne({where:{uuid:req.params.uuid}, include:[ /*{ model: db.CompanyStructure, as: */'structure' /*} */, {model:db.FlowTitle, as:'flowTitles', include:['flowFields']},]}),
]);
return res.render('flow/viewFlow', {user, flow});
});
router.get('/create/:uuid', secured, async(req, res, next) => {
var user = req.user;
const [ flow ] = await Promise.all([
//TODO::fix the parentStructureId of CompanyStructure model and then reduce the include[{include[{include}]}] below
db.Flow.findOne({where:{uuid:req.params.uuid}, include:[ { model: db.CompanyStructure, as: 'structure' , include:[{model:db.OrganisationStructure, as : 'orgStructure', include:[{model:db.Structure, as : "structure"}]}]} , {model:db.FlowTitle, as:'flowTitles', include:['flowFields']},]}),
]);
// const [ requests ] = await Promise.all([
// db.Request.findAll({where:{owner:user.id}, workflowId:workflow.id, include:[{ all: true, nested: true }]}),
// ]);
//the page/view needs the processReference to check if its aa new process or not, cause the view is been used for two routes, 'process/create/uuid' and 'process/continue/uuid'
return res.render('flow/createProcess', {user, flow, processReference : null});
});
router.post('/create/:uuid', secured, async(req, res, next) => {
var user = req.user;
// console.log(req.body)
let fields = req.body['fields[]'];
let flowTitleId = req.body.flowTitleId;
let processId = req.body.processId;
let stage = req.body.currentStage;
let comment = req.body.comment;
const [flowTitle] = await Promise.all([
db.FlowTitle.findOne({where:{id:flowTitleId}, include:['flow', 'flowFields']}),
])
if(!flowTitle){
return res.json({status:"error", msg:"Stage not found!", title:"Error"});
}
let processReference;
if(processId == 0 || isNaN(processId) ){ //new processReference
// console.log(req.body);
var ref1 = Math.round(Math.random() * 10000)
var ref2 = Math.round(Math.random() * 10000)
processReference = await db.ProcessReference.build({flowId:flowTitle.flowId, companyStructureId:flowTitle.flow.companyStructureId, orgId:flowTitle.flow.orgId, createdBy: user.id, status:"In Progress"});
processReference.reference = ref1 + ref2;
// processReference.currentStage = stage;
[processReference] = await Promise.all([processReference.save()]);
console.log(processReference);
}
else{ //not a new process ref, so find ref using id
[processReference] = await Promise.all([db.ProcessReference.findOne({where:{id:processId}})]);
}
// it sometimes throws fields.foreach is not a function when the column is just 1 item
//so i check first
if(Array.isArray(fields)){
fields.forEach(async field => {
await db.FlowProcess.create({flowId: processReference.flowId, flowProcessId: processReference.id ,flowTitleId:flowTitle.id, stage, flowFieldId: field, value :"true", createdBy: user.id, comment})
});
}
else{
await db.FlowProcess.create({flowId: processReference.flowId, flowProcessId: processReference.id, flowTitleId:flowTitle.id, stage, flowFieldId: fields, value :"true", createdBy: user.id})
}
processReference.currentStage = stage;
[processReference] = await Promise.all([processReference.save()]);
//need to send the next stage fields/columns to view to
//lets increment stage and find the fields for new stage
stage++;
const [nextStage] = await Promise.all([
db.FlowTitle.findOne({where:{flowId:flowTitle.flowId, stage, orgId:user.orgId}, include:['flow', 'flowFields']}), //orgId does matter at all, just put it there.
])
if(nextStage == null){
processReference.status = "Completed";
await processReference.save();
}
res.json({status:"success", processId:processReference.id, nextStage});
//return res.redirect(`/workflow/request/${request.uuid}`);
});
////////////////////////
/////employeee
//////////////////
router.get('/:uuid', secured, async(req, res, next)=>{
const user = req.user;
const [ flow, processes ] = await Promise.all([
db.Flow.findOne({where:{uuid:req.params.uuid}, include:[ /*{ model: db.CompanyStructure, as: */'structure' /*} */, {model:db.FlowTitle, as:'flowTitles', include:['flowFields']},]}),
db.ProcessReference.findAll({where:{createdBy:user.id}})
]);
return res.render('flow/employee/viewProcess', {user, flow, processes})
})
//uuid is processReference.uuid not flow.uuid
router.get('/continue/:uuid', secured, async(req, res, next) => {
var user = req.user;
const [processReference] = await Promise.all([
db.ProcessReference.findOne({where:{uuid:req.params.uuid}})
])
console.log(processReference)
const [ flow ] = await Promise.all([
//TODO::fix the parentStructureId of CompanyStructure model and then reduce the include[{include[{include}]}] below
db.Flow.findOne({where:{id:processReference.flowId}, include:[ { model: db.CompanyStructure, as: 'structure' , include:[{model:db.OrganisationStructure, as : 'orgStructure', include:[{model:db.Structure, as : "structure"}]}]} , {model:db.FlowTitle, as:'flowTitles', include:['flowFields']},]}),
]);
// const [ requests ] = await Promise.all([
// db.Request.findAll({where:{owner:user.id}, workflowId:workflow.id, include:[{ all: true, nested: true }]}),
// ]);
return res.render('flow/createProcess', {user, flow, processReference});
});
//uuid is flow.uuid
router.get('/records/:uuid', secured, async(req, res, next) => {
var user = req.user;
const [ flow ] = await Promise.all([
db.Flow.findOne({where:{uuid:req.params.uuid}, include:[ /*{ model: db.CompanyStructure, as: */'structure' /*} */, {model:db.FlowTitle, as:'flowTitles', include:['flowFields']},]}),
]);
if(!flow){
req.flash('error', 'Business Process Flow not found' );
return res.redirect('/flow');
}
const [processReference] = await Promise.all([
db.ProcessReference.findAll({where:{flowId:flow.id, orgId:user.orgId}, include:['user']})
])
return res.render('flow/viewRecords', {user, flow, processReference});
});
//uuid is process.uuid
router.get('/records/view/:uuid', secured, async(req, res, next) => {
var user = req.user;
const [ processReference ] = await Promise.all([
db.ProcessReference.findOne({where:{uuid:req.params.uuid}, include:[ {model:db.Flow, as: 'flow', include:['structure'/*, 'flowTitles'*/]}, 'user', {model:db.FlowProcess, as:'processes', order:['stage'], include:['field', 'title','user']},]}),
]);
if(!processReference){
req.flash('error', 'Process Record not found' );
return res.redirect('/flow');
}
return res.render('flow/viewProcess', {user, process:processReference, flow: processReference.flow});
});
router.get('/request/:uuid', secured, async(req, res, next) => {
var user = req.user;
// var [nextOfficer =
const [request] = await Promise.all([
db.Request.findOne({where:{uuid: req.params.uuid}, include:[{ all: true, nested: true }]})
])
console.log(request.id + " hegehehe")
switch(request.workflowId){
case 1:
return res.render('workflow/itRequestView', {user, request})
case 25:
return res.render('workflow/capitalExpenditureRequestView', {user, request})
}
// return res.render('workflow/itRequestView', {user, request})
// switch(req.params.id){
// case "1":
// db.Request.create({serviceType:req.body.serviceType, description:req.body.description, owner:user.id, targetedStructure:targetedStructure.id, nextOfficer:targetedStructure.headId, status:"New", workflowId:workflow.id})
// .then(request=>{
// // console.log(request);
// //lets keep it in history
// db.RequestHistory.create({requestId:request.id,updatedBy:user.id,status:request.status,message:user.firstName+" "+user.lastName+" made a new IT Service Request"});
// //lets send notification
// db.Notification.create({senderId:user.id,receiverId:targetedStructure.headId,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has made an IT Service Request and needs your review",url:"/workflow/"+workflow.id,seen:0})
// .then(notification =>console.log(notification))
// // oh lets notify the assistant head also
// db.Notification.create({senderId:user.id,receiverId:targetedStructure.assistantId,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has made an IT Service Request and needs your review",url:"/workflow/"+workflow.id+"/"+request.uuid,seen:0})
// .then(notification =>console.log(notification))
// })
// .catch(error=>console.log(error))
// return res.render('workflow', {user, workflow});
// }
});
router.get('/request/:uuid/:action', secured, async(req, res, next) => {
var user = req.user;
// var [nextOfficer =
const [request] = await Promise.all([
db.Request.findOne({where:{uuid: req.params.uuid}, include:[{ all: true, nested: true }]})
])
const [workflow] = await Promise.all([
db.Workflow.findOne({where:{id: request.workflowId}, include:[{ all: true, nested: true }]})
])
request.supervisorComment = req.body.supervisorComment;
switch(req.params.action){
case "1": //reject
request.status = "Rejected";
request.nextOfficer = request.owner;
request.save({fields:['supervisorComment','status','nextOfficer']})
.then(()=>{
db.RequestHistory.create({requestId:request.id,updatedBy:user.id,status:request.status,message:user.firstName+" "+user.lastName+" rejected "+workflow.name});
//lets send notification
db.Notification.create({senderId:user.id,receiverId:request.owner,type:"Re: IT Service Request",message:user.firstName+" "+user.lastName+" has rejected your "+workflow.name,url:"/workflow/request/"+request.uuid,seen:0})
.then(notification =>console.log(notification));
req.flash('success', 'Request has been rejected!' );
});
break;
// case 2: //rework
// request.status = "To be reworked";
// request.save({fields:['supervisorComment','status']})
// .then(()=>{
// db.RequestHistory.create({requestId:request.id,updatedBy:user.id,status:request.status,message:user.firstName+" "+user.lastName+" returned IT Service Request for rework"});
// //lets send notification
// db.Notification.create({senderId:user.id,receiverId:request.owner,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has returned your IT Service Request for rework",url:"/workflow/"+workflow.id+"/"+request.uuid,seen:0})
// .then(notification =>console.log(notification));
// req.flash('success', 'Request has been returned for rework!' );
// });
// break;
case "3": //approve
request.status = "Approved";
request.nextOfficer = request.structure.headId;
request.save({fields:['supervisorComment','status','nextOfficer']})
.then(()=>{
db.RequestHistory.create({requestId:request.id,updatedBy:user.id,status:request.status,message:user.firstName+" "+user.lastName+" Approved the Request!"});
//lets send notification
db.Notification.create({senderId:user.id,receiverId:request.owner,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has Approved your IT Service Request and it's now forwarded to "+request.structure.name+"!",url:"/workflow/request/"+request.uuid,seen:0})
.then(notification =>console.log(notification));
db.Notification.create({senderId:user.id,receiverId:request.structure.headId,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has forwarded an IT Service Request approval to your office for review",url:"/workflow/request/"+request.uuid,seen:0})
.then(notification =>console.log(notification));
req.flash('success', `Request has been Approved and now forwarded to ${request.structure.name} !` );
});
break;
}
res.redirect('/workflow/request/'+request.uuid)
// switch(req.params.id){
// case "1":
// db.Request.create({serviceType:req.body.serviceType, description:req.body.description, owner:user.id, targetedStructure:targetedStructure.id, nextOfficer:targetedStructure.headId, status:"New", workflowId:workflow.id})
// .then(request=>{
// // console.log(request);
// //lets keep it in history
// db.RequestHistory.create({requestId:request.id,updatedBy:user.id,status:request.status,message:user.firstName+" "+user.lastName+" made a new IT Service Request"});
// //lets send notification
// db.Notification.create({senderId:user.id,receiverId:targetedStructure.headId,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has made an IT Service Request and needs your review",url:"/workflow/"+workflow.id,seen:0})
// .then(notification =>console.log(notification))
// // oh lets notify the assistant head also
// db.Notification.create({senderId:user.id,receiverId:targetedStructure.assistantId,type:"IT Service Request",message:user.firstName+" "+user.lastName+" has made an IT Service Request and needs your review",url:"/workflow/"+workflow.id+"/"+request.uuid,seen:0})
// .then(notification =>console.log(notification))
// })
// .catch(error=>console.log(error))
// return res.render('workflow', {user, workflow});
// }
});
module.exports = router;