Skip to content

Commit

Permalink
chore: merge pull request #1 from AEGEE/add-categories
Browse files Browse the repository at this point in the history
Add categories
  • Loading branch information
serge1peshcoff authored May 18, 2019
2 parents e9f3368 + c609b40 commit e8dac78
Show file tree
Hide file tree
Showing 16 changed files with 708 additions and 18 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# [0.5.0](https://github.com/AEGEE/oms-discounts/compare/0.4.2...0.5.0) (2019-05-18)


### Bug Fixes

* **categories:** fixed categories endpoints ([08320a0](https://github.com/AEGEE/oms-discounts/commit/08320a0))


### Features

* **discounts:** added categories. Fixes MEMB-529 ([67d7380](https://github.com/AEGEE/oms-discounts/commit/67d7380))
* **test:** testing categories CRUD ([53af8e7](https://github.com/AEGEE/oms-discounts/commit/53af8e7))



## [0.4.2](https://github.com/AEGEE/oms-discounts/compare/0.4.1...0.4.2) (2019-05-03)


Expand Down
75 changes: 75 additions & 0 deletions lib/categories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const { Category } = require('../models');
const errors = require('./errors');
const helpers = require('./helpers');

exports.createCategory = async (req, res) => {
if (!req.permissions.manage_discounts) {
return errors.makeForbiddenError(res, 'You are not allowed to create integrations.');
}

const category = await Category.create(req.body);

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

exports.listAllCategories = async (req, res) => {
const categories = await Category.findAll({});

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

exports.findCategory = async (req, res, next) => {
const isNumber = helpers.isNumber(req.params.category_id);

if (!isNumber) {
return errors.makeBadRequestError(res, 'The category ID is not a number.');
}

const category = await Category.findOne({ where: { id: Number(req.params.category_id) } });

if (!category) {
return errors.makeNotFoundError(res, 'The category is not found.');
}

req.category = category;
return next();
};

exports.getCategory = async (req, res) => {
return res.json({
success: true,
data: req.category
});
};

exports.updateCategory = async (req, res) => {
if (!req.permissions.manage_discounts) {
return errors.makeForbiddenError(res, 'You are not allowed to update category.');
}

await req.category.update(req.body);

return res.json({
success: true,
data: req.category
});
};

exports.deleteCategory = async (req, res) => {
if (!req.permissions.manage_discounts) {
return errors.makeForbiddenError(res, 'You are not allowed to delete category.');
}

await req.category.destroy();

return res.json({
success: true,
data: req.category
});
};
4 changes: 2 additions & 2 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ exports.isNumber = (value) => {
return false;
};

exports.getMailText = ({ code, integration, user}) => {
exports.getMailText = ({ code, integration, user }) => {
return `Hey ${user.first_name},<br/>
<br/>
You've claimed the code for the discount, here are the details.<br/>
Expand All @@ -29,7 +29,7 @@ Claimed on: ${moment(code.updated_at).format('YYYY-MM-DD HH:MM')}<br/>
${integration.description}<br/>
<br/>
Sincerely yours,<br/>
MyAEGEE discounts team.`
MyAEGEE discounts team.`;
};

// A helper to determine if user has permission.
Expand Down
2 changes: 1 addition & 1 deletion lib/integrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ exports.updateIntegration = async (req, res) => {

exports.deleteIntegration = async (req, res) => {
if (!req.permissions.manage_discounts) {
return errors.makeForbiddenError(res, 'You are not allowed to update integration.');
return errors.makeForbiddenError(res, 'You are not allowed to delete integration.');
}

await req.integration.destroy();
Expand Down
10 changes: 10 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const bugsnag = require('./bugsnag');
const morgan = require('./morgan');
const middlewares = require('./middlewares');
const integrations = require('./integrations');
const categories = require('./categories');
const db = require('./sequelize');

const server = express();
Expand All @@ -26,6 +27,8 @@ process.on('unhandledRejection', (err) => {
});

GeneralRouter.use(middlewares.authenticateUser);

// integrations and codes
GeneralRouter.get('/integrations', integrations.listAllIntegrations);
GeneralRouter.post('/integrations', integrations.createIntegration);
GeneralRouter.post('/integrations/:integration_id/codes', integrations.findIntegration, integrations.addCodesToIntegration);
Expand All @@ -36,6 +39,13 @@ GeneralRouter.delete('/integrations/:integration_id', integrations.findIntegrati

GeneralRouter.get('/codes/mine', integrations.getMyCodes);

// categories and discounts (for listing to members)
GeneralRouter.get('/categories', categories.listAllCategories);
GeneralRouter.post('/categories', categories.createCategory);
GeneralRouter.get('/categories/:category_id', categories.findCategory, categories.getCategory);
GeneralRouter.put('/categories/:category_id', categories.findCategory, categories.updateCategory);
GeneralRouter.delete('/categories/:category_id', categories.findCategory, categories.deleteCategory);

server.use('/', GeneralRouter);
server.use(middlewares.notFound);
server.use(middlewares.errorHandler);
Expand Down
27 changes: 27 additions & 0 deletions migrations/20190518200032-create-category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('categories', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
allowNull: false,
type: Sequelize.STRING
},
discounts: {
allowNull: false,
type: Sequelize.JSONB
},
created_at: {
allowNull: false,
type: Sequelize.DATE
},
updated_at: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('categories')
};
38 changes: 38 additions & 0 deletions models/Category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const Joi = require('joi');
const { Sequelize, sequelize } = require('../lib/sequelize');

const categoriesSchema = Joi.array().min(1).items(Joi.object().keys({
icon: Joi.string().trim().required(),
name: Joi.string().trim().required(),
shortDescription: Joi.string().trim().required(),
longDescription: Joi.string().trim().required(),
}));

const Category = sequelize.define('category', {
name: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: '',
validate: {
notEmpty: { msg: 'Name should be set.' },
},
},
discounts: {
type: Sequelize.JSONB,
allowNull: false,
defaultValue: '',
validate: {
isValid(categoriesValue) {
const { error, value } = Joi.validate(categoriesValue, categoriesSchema);
if (error) {
throw error;
}

// eslint-disable-next-line no-param-reassign
categoriesValue = value;
}
},
}
}, { underscored: true, tableName: 'categories' });

module.exports = Category;
4 changes: 3 additions & 1 deletion models/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const Integration = require('./Integration');
const Code = require('./Code');
const Category = require('./Category');

Integration.hasMany(Code);
Code.belongsTo(Integration);

module.exports = {
Integration,
Code
Code,
Category
};
Loading

0 comments on commit e8dac78

Please sign in to comment.