diff --git a/api/routes/_generic.js b/api/routes/_generic.js new file mode 100644 index 0000000..0d466cd --- /dev/null +++ b/api/routes/_generic.js @@ -0,0 +1,37 @@ +"use strict"; + +// HTTP status codes by name +const codes = require('./http-codes'); + +const genericPatch = (req, res, next, modelClass) => { + if (!req.body || (req.body._id && req.body._id !== req.params.id)) { + // little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match + const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + ' ' + + req.body._id); + err.status = codes.notfound; + next(err); + return; // prevent node to process this function further after next() has finished. + } + + req.body.updatedAt = new Date(); + req.body.$inc = {__v: 1}; + if (req.body.hasOwnProperty('__v')) { + delete req.body.__v; + } + + // PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to + // reset attributes that are missing. + modelClass.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => { + if (err) { + err.status = codes.wrongrequest; + } else if (!item) { + err = new Error('item not found'); + err.status = codes.notfound; + } else { + res.locals.items = item; + } + next(err); + }); +}; + +exports.genericPatch = genericPatch; diff --git a/api/routes/campaigns.js b/api/routes/campaigns.js index c992cbf..136b2ce 100644 --- a/api/routes/campaigns.js +++ b/api/routes/campaigns.js @@ -16,6 +16,9 @@ const idValidator = require('../middleware/validators').idValidator; const CampaignModel = require('../models/campaign'); const WarModel = require('../models/war'); +// util +const genericPatch = require('./_generic').genericPatch; + const campaigns = new express.Router(); // routes ********************** @@ -56,34 +59,7 @@ campaigns.route('/:id') }) .patch(apiAuthenticationMiddleware, checkMT, (req, res, next) => { - if (!req.body || (req.body._id && req.body._id !== req.params.id)) { - // little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match - const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + ' ' + - req.body._id); - err.status = codes.notfound; - next(err); - return; // prevent node to process this function further after next() has finished. - } - - req.body.updatedAt = new Date(); - req.body.$inc = {__v: 1}; - if (req.body.hasOwnProperty('__v')) { - delete req.body.__v; - } - - // PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to - // reset attributes that are missing. - CampaignModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => { - if (err) { - err.status = codes.wrongrequest; - } else if (!item) { - err = new Error('item not found'); - err.status = codes.notfound; - } else { - res.locals.items = item; - } - next(err); - }); + return genericPatch(req, res, next, CampaignModel); }) .delete((req, res, next) => { diff --git a/api/routes/wars.js b/api/routes/wars.js index eb42cf9..65b04d2 100644 --- a/api/routes/wars.js +++ b/api/routes/wars.js @@ -35,6 +35,9 @@ const LogFlagModel = require('../models/logs/flag'); const LogBudgetModel = require('../models/logs/budget'); const LogPointsModel = require('../models/logs/points'); +// util +const genericPatch = require('./_generic').genericPatch; + const wars = new express.Router(); // routes ********************** @@ -169,34 +172,7 @@ wars.route('/:id') }) .patch(apiAuthenticationMiddleware, checkMT, (req, res, next) => { - if (!req.body || (req.body._id && req.body._id !== req.params.id)) { - // little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match - const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + ' ' + - req.body._id); - err.status = codes.notfound; - next(err); - return; // prevent node to process this function further after next() has finished. - } - - req.body.updatedAt = new Date(); - req.body.$inc = {__v: 1}; - if (req.body.hasOwnProperty('__v')) { - delete req.body.__v; - } - - // PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to - // reset attributes that are missing. - WarModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => { - if (err) { - err.status = codes.wrongrequest; - } else if (!item) { - err = new Error('item not found'); - err.status = codes.notfound; - } else { - res.locals.items = item; - } - next(err); - }); + return genericPatch(req, res, next, WarModel); }) .delete(apiAuthenticationMiddleware, checkMT, (req, res, next) => { diff --git a/api/tools/signature-tool.js b/api/tools/signature-tool.js index 8fe9b7e..86a0010 100644 --- a/api/tools/signature-tool.js +++ b/api/tools/signature-tool.js @@ -137,48 +137,7 @@ let addDecorationsAndSave = (userId, loadedImage, res, next) => { return next(err); } if (awardings.length > 0) { - // TODO: simplify this sorting hell - awardings.sort((a1, a2) => { - if (!a1.decorationId.isMedal && !a2.decorationId.isMedal) { - if (a1.decorationId.fraction === a2.decorationId.fraction) { - if (a1.date !== a2.date) { - if (a1.date < a2.date) { - return -1; - } - if (a1.date > a2.date) { - return 1; - } - } - return 0; - } else { - if (a1.decorationId.fraction === 'GLOBAL' && a2.decorationId.fraction !== 'GLOBAL') { - return -1; - } - if (a2.decorationId.fraction === 'GLOBAL' && a1.decorationId.fraction !== 'GLOBAL') { - return 1; - } - } - } - if (a1.decorationId.isMedal !== a2.decorationId.isMedal) { - if (a1.decorationId.isMedal && !a2.decorationId.isMedal) { - return 1; - } - if (!a1.decorationId.isMedal && a2.decorationId.isMedal) { - return -1; - } - } - if (a1.decorationId.isMedal && a2.decorationId.isMedal) { - if (a1.date !== a2.date) { - if (a1.date < a2.date) { - return -1; - } - if (a1.date > a2.date) { - return 1; - } - } - return 0; - } - }); + awardings.sort((a1, a2) => sortAwardingsForSignature(a1, a2)); // use synchronized call to keep correct order of decorations async.eachSeries(awardings, (award, callback) => { @@ -262,5 +221,47 @@ let saveJimpImageAndCompress = (image, userId, res, next) => { }, 3000); }; +const sortAwardingsForSignature = (a1, a2) => { + if (!a1.decorationId.isMedal && !a2.decorationId.isMedal) { + if (a1.decorationId.fraction === a2.decorationId.fraction) { + if (a1.date !== a2.date) { + if (a1.date < a2.date) { + return -1; + } + if (a1.date > a2.date) { + return 1; + } + } + return 0; + } else { + if (a1.decorationId.fraction === 'GLOBAL' && a2.decorationId.fraction !== 'GLOBAL') { + return -1; + } + if (a2.decorationId.fraction === 'GLOBAL' && a1.decorationId.fraction !== 'GLOBAL') { + return 1; + } + } + } + if (a1.decorationId.isMedal !== a2.decorationId.isMedal) { + if (a1.decorationId.isMedal && !a2.decorationId.isMedal) { + return 1; + } + if (!a1.decorationId.isMedal && a2.decorationId.isMedal) { + return -1; + } + } + if (a1.decorationId.isMedal && a2.decorationId.isMedal) { + if (a1.date !== a2.date) { + if (a1.date < a2.date) { + return -1; + } + if (a1.date > a2.date) { + return 1; + } + } + return 0; + } +}; + module.exports = createSignature; diff --git a/api/tools/util.js b/api/tools/util.js index 155ac34..86f699e 100644 --- a/api/tools/util.js +++ b/api/tools/util.js @@ -39,7 +39,6 @@ const timeStringToDecimal = (timeString) => { return hour + (sek / 3600); }; - const decimalToTimeString = (decimal) => { const hours = parseInt(decimal.toString().split('.')[0]); const minutesFloat = ((decimal % 1) * 3600) / 60;