Skip to content

Commit

Permalink
feature(priorities) Customizable Priorities
Browse files Browse the repository at this point in the history
  • Loading branch information
polonel committed Sep 7, 2018
1 parent 96b403d commit a7f1d8b
Show file tree
Hide file tree
Showing 21 changed files with 1,496 additions and 749 deletions.
153 changes: 150 additions & 3 deletions src/controllers/api/v1/tickets.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,11 +841,17 @@ api_tickets.createType = function(req, res) {
if (_.isUndefined(typeName) || typeName.length < 3) return res.status(400).json({success: false, error: 'Invalid Type Name!'});

var ticketTypeSchema = require('../../../models/tickettype');
ticketTypeSchema.create({name: typeName}, function(err, ticketType) {
var ticketPrioritiesSchema = require('../../../models/ticketpriority');
ticketPrioritiesSchema.find({default: true}, function(err, priorities) {
if (err) return res.status(400).json({success: false, error: err.message});
priorities = _.sortBy(priorities, 'migrationNum');

ticketTypeSchema.create({name: typeName, priorities: priorities}, function(err, ticketType) {
if (err) return res.status(400).json({success: false, error: err.message});

return res.json({success: true, tickettype: ticketType});
})
return res.json({success: true, tickettype: ticketType});
})
});
};

/**
Expand Down Expand Up @@ -883,6 +889,58 @@ api_tickets.updateType = function(req, res) {
});
};

api_tickets.typeAddPriority = function(req, res) {
var id = req.params.id;
var data = req.body;
if (!id || !data || !data.priority)
return res.status(400).json({success: false, error: 'Invalid request data'});

var ticketTypeSchema = require('../../../models/tickettype');
ticketTypeSchema.getType(id, function(err, type) {
if (err) return res.status(400).json({success: false, error: err.message});

type.addPriority(data.priority, function(err, type) {
if (err) return res.status(400).json({success: false, error: err.message});

type.save(function(err, t) {
if (err) return res.status(400).json({success: false, error: err.message});

t.populate('priorities', function(err, tt) {
if (err) return res.status(400).json({success: false, error: err.message});

return res.json({success: true, type: tt});
});
});
});
});
};

api_tickets.typeRemovePriority = function(req, res) {
var id = req.params.id;
var data = req.body;
if (!id || !data || !data.priority)
return res.status(400).json({success: false, error: 'Invalid request data'});

var ticketTypeSchema = require('../../../models/tickettype');
ticketTypeSchema.getType(id, function(err, type) {
if (err) return res.status(400).json({success: false, error: err.message});

type.removePriority(data.priority, function(err, type) {
if (err) return res.status(400).json({success: false, error: err.message});

type.save(function(err, t) {
if (err) return res.status(400).json({success: false, error: err.message});

t.populate('priorities', function(err, tt) {
if (err) return res.status(400).json({success: false, error: err.message});

return res.json({success: true, type: tt});
});
});
});
});
};

/**
* @api {delete} /api/v1/tickets/types/:id Delete Ticket Type
* @apiName deleteType
Expand Down Expand Up @@ -940,6 +998,95 @@ api_tickets.deleteType = function(req, res) {
});
};

api_tickets.createPriority = function(req, res) {
var data = req.body;
var pName = data.name;
var pOverdueIn = data.overdueIn;
var pHtmlColor = data.htmlColor;

if (!pName)
return res.status(400).json({success: false, error: 'Invalid Request Data.'});

var ticketPrioritySchema = require('../../../models/ticketpriority');
var P = new ticketPrioritySchema({
name: pName,
overdueIn: pOverdueIn,
htmlColor: pHtmlColor
});

P.save(function(err, savedPriority) {
if (err)
return res.status(400).json({success: false, error: err.message});

return res.json({success: true, priority: savedPriority});
});
};

api_tickets.getPriorities = function(req, res) {
var ticketPrioritySchema = require('../../../models/ticketpriority');
ticketPrioritySchema.find({}, function(err, priorities) {
if (err) return res.status(400).json({success: false, error: err.message});

priorities = _.sortBy(priorities, ['migrationNum', 'name']);

return res.json({success: true, priorities: priorities});
});
};

api_tickets.updatePriority = function(req, res) {
var id = req.params.id;
var data = req.body;
if (_.isUndefined(id) || _.isNull(id) || _.isNull(data) || _.isUndefined(data))
return res.status(400).json({success: false, error: 'Invalid Request Data'});

var ticketPrioritySchema = require('../../../models/ticketpriority');
ticketPrioritySchema.findOne({_id: id}, function(err, priority) {
if (err) return res.status(400).json({success: false, error: err.message});

if (data.name)
priority.name = data.name;
if (data.htmlColor)
priority.htmlColor = data.htmlColor;
if (data.overdueIn)
priority.overdueIn = data.overdueIn;

priority.save(function(err, p) {
if (err) return res.status(400).json({success: false, error: err.message});

return res.json({success: true, priority: p});
});
});
};

api_tickets.deletePriority = function(req, res) {
var id = req.params.id;
var newPriority = req.body.newPriority;
if (!id || !newPriority)
return res.status(400).json({success: false, error: 'Invalid Request Data'});

async.series([
function(next) {
var ticketSchema = require('../../../models/ticket');
ticketSchema.updateMany({priority: id}, {priority: newPriority}, next);
},
function(next) {
var ticketPrioritySchema = require('../../../models/ticketpriority');
ticketPrioritySchema.findOne({_id: id}, function(err, priority) {
if (err) return next(err);

if (priority.default)
return next('Unable to delete default priority: ' + priority.name);

priority.remove(next);
});
}
], function(err) {
if (err) return res.status(400).json({success: false, error: err.message});

return res.json({success: true});
});
};

/**
* @api {get} /api/v1/tickets/stats Get Ticket Stats
* @apiName getTicketStats
Expand Down
48 changes: 17 additions & 31 deletions src/controllers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ settingsController.general = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand All @@ -59,7 +59,7 @@ settingsController.ticketSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand All @@ -78,7 +78,7 @@ settingsController.mailerSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand All @@ -97,7 +97,7 @@ settingsController.notificationsSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand All @@ -116,7 +116,7 @@ settingsController.tpsSettings = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand All @@ -135,7 +135,7 @@ settingsController.legal = function(req, res) {
getSettings(content, function(err) {
if (err) return handleError(res, err);

return res.render('subviews/settings/settings-tickets', content);
return res.render('settings', content);
});
};

Expand Down Expand Up @@ -208,36 +208,22 @@ function getSettings(content, callback) {
if (err) return callback(err);

content.data.ticketTypes = _.sortBy(types, function(o){ return o.name; });
_.each(content.data.ticketTypes, function(type) {
type.priorities = _.sortBy(type.priorities, ['migrationNum', 'name']);
});

var ticketPrioritySchema = require('../models/ticketpriority');
ticketPrioritySchema.getPriorities(function(err, priorities) {
if (err) return callback(err);

content.data.priorities = _.sortBy(priorities, ['migrationNum', 'name']);

return callback();
return callback();
});
});
});
}

// settingsController.legal = function(req, res) {
// var content = {};
// content.title = "Legal Settings";
// content.nav = 'settings';
// content.subnav = 'settings-legal';
//
// content.data = {};
// content.data.user = req.user;
// content.data.common = req.viewdata;
//
// settingSchema.getSettings(function(err, settings) {
// if (err) return handleError(res, 'Invalid Settings');
//
// var s = {};
// s.privacyPolicy = _.find(settings, function(x){return x.name === 'legal:privacypolicy'});
// s.privacyPolicy = (s.privacyPolicy === undefined) ? {value: ''} : s.privacyPolicy;
// s.privacyPolicy.value = jsStringEscape(s.privacyPolicy.value);
//
// content.data.settings = s;
//
// return res.render('subviews/settings/legal', content);
// });
// };

settingsController.logs = function(req, res) {
if (!checkPerms(req, 'settings:logs')) return res.redirect('/settings');

Expand Down
23 changes: 23 additions & 0 deletions src/helpers/viewdata/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ viewController.getData = function(request, cb) {
return callback();
});
},
function(callback) {
viewController.getPriorities(request, function(err, data) {
if (err) return callback();

viewdata.priorities = data;

return callback();
});
},
function(callback) {
viewController.getTags(request, function(err, data) {
if (err) return callback();
Expand Down Expand Up @@ -329,6 +338,20 @@ viewController.getDefaultTicketType = function(request, callback) {
});
};

viewController.getPriorities = function(request, callback) {
var ticketPrioritySchema = require('../../models/ticketpriority');
ticketPrioritySchema.getPriorities(function(err, priorities) {
if (err) {
winston.debug('Error viewController:getPriorities: ' + err);
return callback(err);
}

priorities = _.sortBy(priorities, ['migrationNum', 'name']);

return callback(null, priorities);
});
};

viewController.getTags = function(request, callback) {
var tagSchema = require('../../models/tag');

Expand Down
2 changes: 1 addition & 1 deletion src/models/ticket.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ var ticketSchema = mongoose.Schema({
deleted: { type: Boolean, default: false, required: true, index: true },
type: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'tickettypes' },
status: { type: Number, default: 0, required: true, index: true },
// priority: { type: Number, required: true },

priority: { type: mongoose.Schema.Types.ObjectId, ref: 'priorities', required: true },
tags: [{ type: mongoose.Schema.Types.ObjectId, ref: 'tags' }],
subject: { type: String, required: true },
Expand Down
19 changes: 15 additions & 4 deletions src/models/ticketpriority.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,29 @@
**/

var mongoose = require('mongoose');
var _ = require('lodash');
var _ = require('lodash');
var mongoose = require('mongoose');
var moment = require('moment');
var durationFormat = require('moment-duration-format');

var COLLECTION = 'priorities';

var prioritySchema = mongoose.Schema({
name: { type: String, required: true, unique: true },
overdueIn: { type: Number, required: true, default: 2880}, // Minutes until overdue (48 Hours)
htmlColor: { type: String, default: '#29b955'},
overdueIn: { type: Number, required: true, default: 2880 }, // Minutes until overdue (48 Hours)
htmlColor: { type: String, default: '#29b955' },

migrationNum: { type: Number, index: true }, //Needed to convert <1.0 priorities to new format.
default: { type: Boolean }
}, {
toJSON: {
virtuals: true
}
});

prioritySchema.virtual('durationFormatted').get(function() {
var priority = this;
return moment.duration(priority.overdueIn, 'minutes').format('Y [year], M [month], d [day], h [hour], m [min]', {trim: 'both'});
});

prioritySchema.statics.getPriority = function(_id, callback) {
Expand Down
26 changes: 26 additions & 0 deletions src/models/tickettype.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
**/

var _ = require('lodash');
var mongoose = require('mongoose');

var COLLECTION = 'tickettypes';
Expand Down Expand Up @@ -88,4 +89,29 @@ ticketTypeSchema.statics.getTypeByName = function(name, callback) {
return q.exec(callback);
};

ticketTypeSchema.methods.addPriority = function(priorityId, callback) {
if (!priorityId) return callback({message: 'Invalid Priority Id'});

var self = this;

if (!_.isArray(self.priorities))
self.priorities = [];

self.priorities.push(priorityId);

return callback(null, self);
};

ticketTypeSchema.methods.removePriority = function(priorityId, callback) {
if (!priorityId) return callback({message: 'Invalid Priority Id'});

var self = this;

self.priorities = _.reject(self.priorities, function(p) {
return p._id.toString() === priorityId.toString();
});

return callback(null, self);
};

module.exports = mongoose.model(COLLECTION, ticketTypeSchema);
Loading

0 comments on commit a7f1d8b

Please sign in to comment.