From a6be1ab427bcff676ba1255626e3da6ae907d868 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 17 Jul 2019 14:07:35 +0200 Subject: [PATCH] . --- core/controllers/index.js | 103 ++++++++++++-------- helpers/service.helper.js | 40 +++++--- modules/events/event.controller.js | 46 +++++---- modules/events/event.model.js | 101 ++++++++++++------- modules/events/event.routes.js | 30 ++++-- modules/events/event.service.js | 34 +++++-- modules/events/events_reservations.model.js | 2 +- script-carga-bd-completa.sql | 4 +- 8 files changed, 239 insertions(+), 121 deletions(-) diff --git a/core/controllers/index.js b/core/controllers/index.js index 02367d3..dd527e7 100644 --- a/core/controllers/index.js +++ b/core/controllers/index.js @@ -2,16 +2,17 @@ const _find = require('./find'); const httpStatus = require('http-status'); const { extractParamsFromRequest, handleErrorResponse, handleResultResponse } = require('../../helpers/controller.helper'); -function buildContext(req, res) { +function buildContext(req, config) { return { - user: req.user + user: req.user, + ...config, } } const defaultOptions = { MODULE_NAME: 'default', params: { - find: { includeAll: true }, + find: { includeAll: false }, findOne: { includeAll: true, paginate: { limit: 1, page: 1 } }, count: {}, } @@ -24,63 +25,79 @@ const generateControllers = (service, extraControllers = {}, options = {}) => { }; const defaultControllers = { - find: async (req, res, next) => { - const params = extractParamsFromRequest(req, res, _options.params.find); - try { - const result = await service.fetchAll(params, buildContext(req, res)); - return handleResultResponse(result.rows, result.count, params, res); - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'find', error, res) + find: (config) => { + return async (req, res, next) => { + config = config || { + scopes: [], + }; + + const params = extractParamsFromRequest(req, res, _options.params.find); + try { + const result = await service.fetchAll(params, buildContext(req, config)); + return handleResultResponse(result.rows, result.count, params, res); + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'find', error, res) + } } }, - findOne: async (req, res, next) => { - const params = extractParamsFromRequest(req, res, _options.params.findOne); + findOne: (config) => { + return async (req, res, next) => { + const params = extractParamsFromRequest(req, res, _options.params.findOne); - try { - const result = await service.fetchOne(params, buildContext(req, res)); - return handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK); - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'findOne', error, res) + try { + const result = await service.fetchOne(params, buildContext(req, config)); + return handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK); + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'findOne', error, res) + } } }, - count: async(req, res, next) => { - const params = extractParamsFromRequest(req, res, _options.params.count); + count: (config) => { + return async(req, res, next) => { + const params = extractParamsFromRequest(req, res, _options.params.count); - try { - const result = await service.count(params, buildContext(req, res)); - return handleResultResponse(result, null, params, res); - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'count', error, res) + try { + const result = await service.count(params, buildContext(req, config)); + return handleResultResponse(result, null, params, res); + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'count', error, res) + } } }, - create: async (req, res, next) => { - try { - console.log(req.body); - const result = await service.create(req.body, buildContext(req, res)); - return handleResultResponse(result, null, null, res, httpStatus.CREATED) - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'create', error, res) + create: (config) => { + return async (req, res, next) => { + try { + console.log(req.body); + const result = await service.create(req.body, buildContext(req, config)); + return handleResultResponse(result, null, null, res, httpStatus.CREATED) + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'create', error, res) + } } }, - update: async (req, res, next) => { - try { - const result = await service.update(req.params, req.body, buildContext(req, res)); - return handleResultResponse(result, null, req.params, res, httpStatus.OK) - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'update', error, res) + update: (config) => { + return async (req, res, next) => { + try { + const result = await service.update(req.params, req.body, buildContext(req, config)); + return handleResultResponse(result, null, req.params, res, httpStatus.OK) + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'update', error, res) + } } }, - delete: async (req, res, next) => { - try { - const result = await service.delete(req.params, buildContext(req, res)); - return handleResultResponse(result, null, req.params, res, httpStatus.NO_CONTENT); - } catch (error) { - handleErrorResponse(_options.MODULE_NAME, 'delete', error, res) + delete: (config) => { + return async (req, res, next) => { + try { + const result = await service.delete(req.params, buildContext(req, config)); + return handleResultResponse(result, null, req.params, res, httpStatus.NO_CONTENT); + } catch (error) { + handleErrorResponse(_options.MODULE_NAME, 'delete', error, res) + } } }, } diff --git a/helpers/service.helper.js b/helpers/service.helper.js index ea948c1..09b1d45 100644 --- a/helpers/service.helper.js +++ b/helpers/service.helper.js @@ -122,6 +122,8 @@ function hasAssociation(params) { const defaultOptions = {}; const generateService = (model, extraMethods = {}, options = defaultOptions) => { + + const defaultService = { fetchAssociation: async(params, context) => { const associationName = hasAssociation(params); @@ -149,40 +151,56 @@ const generateService = (model, extraMethods = {}, options = defaultOptions) => return defaultService.fetchAssociation(params, context) } else { const findOptions = parseParamsToFindOptions(params); - console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'); - console.log(findOptions); - const result = await model.findAndCountAll(findOptions); - console.log(result); - return result; + const result = await model.scope(context.scopes).findAndCountAll(findOptions); + + if (extraMethods.afterFetchAll) { + return extraMethods.afterFetchAll(result, params, context); + } else { + return result; + } } }, fetchOne: async (params, context) => { const findOptions = parseParamsToFindOptions(params); - console.log(findOptions); - return await model.findOne({ + + const result = await model.scope(context.scopes).findOne({ where: findOptions.where, include: findOptions.include }); + + if (extraMethods.afterFetchOne) { + return extraMethods.afterFetchOne(result, params, context); + } else { + return result; + } + }, count: async (params, context) => { const findOptions = parseParamsToFindOptions(params); - return await model.count(findOptions); + const result = await model.scope(context.scopes).count(findOptions); + + if (extraMethods.afterCount) { + return extraMethods.afterCount(result, params, context); + } else { + return result; + } + }, create: async (values, context) => { - return await model.create(values); + return await model.scope(context.scopes).create(values); }, update: async (params, values, context) => { const findOptions = parseParamsToFindOptions(params); - return await model.update(values, findOptions) + return await model.scope(context.scopes).update(values, findOptions) }, delete: async (params, context) => { const findOptions = parseParamsToFindOptions(params); - const numAffectedRows = await model.destroy(findOptions); + const numAffectedRows = await model.scope(context.scopes).destroy(findOptions); return (numAffectedRows > 0); }, diff --git a/modules/events/event.controller.js b/modules/events/event.controller.js index 4805f42..fd1ad73 100644 --- a/modules/events/event.controller.js +++ b/modules/events/event.controller.js @@ -16,26 +16,36 @@ const MODULE_NAME = '[event.controller]'; const controllerOptions = { MODULE_NAME }; const extraControllers = { - findNext: async (req, res, next) => { - const params = extractParamsFromRequest(req, res, { includeAll: false }); - try { - const result = await eventService.fetch(params, { user: req.user, lapse: 'next' }); - console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - // Joi validation options - const _validationOptions = { - abortEarly: false, // abort after the last validation error - allowUnknown: true, // allow unknown keys that will be ignored - stripUnknown: true // remove unknown keys from the validated data - }; - console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222'); - const data = Joi.validate(result.dataValues, eventValidation.EventsListOutputType, _validationOptions); - console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333'); + findNext: (config) => { + config = config || { + scopes: [], + } + + return async function (req, res, next) { + const params = extractParamsFromRequest(req, res, { includeAll: false }); + try { + const result = await eventService.fetch(params, { + user: req.user, + scopes: config.scopes, + lapse: 'next' + }); + console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); + // Joi validation options + const _validationOptions = { + abortEarly: false, // abort after the last validation error + allowUnknown: true, // allow unknown keys that will be ignored + stripUnknown: true // remove unknown keys from the validated data + }; + console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa222'); + const data = Joi.validate(result.dataValues, eventValidation.EventsListOutputType, _validationOptions); + console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa333'); - console.log(data); - return handleResultResponse(result, result.count, params, res); - } catch (error) { - handleErrorResponse(MODULE_NAME, 'findNext', error, res); + console.log(data); + return handleResultResponse(result, result.count, params, res); + } catch (error) { + handleErrorResponse(MODULE_NAME, 'findNext', error, res); + } } }, diff --git a/modules/events/event.model.js b/modules/events/event.model.js index 4db10f9..1d1a6f9 100644 --- a/modules/events/event.model.js +++ b/modules/events/event.model.js @@ -61,7 +61,7 @@ module.exports = function (sequelize, DataTypes) { state: { type: DataTypes.STRING, allowNull: false, - defaultValue: 'borrador' + defaultValue: 'draft' }, typeId: { type: DataTypes.UUID, @@ -80,7 +80,7 @@ module.exports = function (sequelize, DataTypes) { url_registration: { type: DataTypes.STRING, }, - marketingList: { + marketing_list: { type: DataTypes.STRING, }, userId: { @@ -94,39 +94,12 @@ module.exports = function (sequelize, DataTypes) { timestamps: true, defaultScope: { -//Se pude poner algo en función del usuario????? + where: { + state: 'publish' + } }, - - scopes: { - next: { - where: { - date: { - [Sequelize.Op.gte]: moment().add(1, 'days').startOf('day').utc() - } - }, - }, - current: { - where: { - date: { - [Sequelize.Op.gte]: moment().startOf('day').utc(), - [Sequelize.Op.lt]: moment().add(1, 'days').startOf('day').utc(), - } - } - - }, - past: { - where: { - date: { - [Sequelize.Op.lt]: moment().startOf('day').utc() - } - } - - }, - } }); - - - + Event.associate = function (models) { // Event.OverflowEvent = Event.belongsTo(models.Event, { // as: 'overflowEvent', @@ -140,17 +113,79 @@ module.exports = function (sequelize, DataTypes) { Event.Comments = Event.hasMany(models.Comment, { foreignKey: 'entityId', + scope: { + entityName: 'event' + }, as: "comments" }); Event.Multimedias = Event.hasMany(models.Multimedia, { foreignKey: 'entityId', + scope: { + entityName: 'event' + }, as: { singular: 'multimedia', plural: 'multimedias' }}); Event.Reservations = Event.hasMany(models.EventReservation, { foreignKey: 'eventId', as: "reservations" }); Event.Inscriptions = Event.hasMany(models.EventInscription, { foreignKey: 'eventId', as: "inscriptions" }); Event.Questions = Event.hasMany(models.EventQuestion, { foreignKey: 'eventId', as: "questions" }); }; + + Event.addScope('includeVenue', () => { + return { + include: [ + { model: sequelize.models.Venue, as: 'venue' } + ] + } + }); + + Event.addScope('includeSchedule', () => { + return { + include: [ + { model: sequelize.models.EventSchedule, as: 'schedule' } + ] + } + }); + + Event.addScope('includeSpeakers', () => { + return { + include: [{ + model: sequelize.models.EventSchedule, + as: 'schedule', + where: { + speakerId: { + [Sequelize.Op.ne]: null + } + }, + include: [{ model: sequelize.models.Speaker, as: 'speaker' }] + }] + } + }) + + Event.addScope('next', { + where: { + date: { + [Sequelize.Op.gte]: moment().add(1, 'days').startOf('day').utc() + } + }, + }); + + Event.addScope('current', { + where: { + date: { + [Sequelize.Op.gte]: moment().startOf('day').utc(), + [Sequelize.Op.lt]: moment().add(1, 'days').startOf('day').utc(), + } + } + }); + + Event.addScope('past', { + where: { + date: { + [Sequelize.Op.lt]: moment().startOf('day').utc() + } + } + }); return Event; }; \ No newline at end of file diff --git a/modules/events/event.routes.js b/modules/events/event.routes.js index b7895c0..eb40f55 100644 --- a/modules/events/event.routes.js +++ b/modules/events/event.routes.js @@ -11,25 +11,32 @@ const SortMiddleware = require('../../middlewares/sort'); const eventController = require('./event.controller'); const eventValidation = require('./event.validations'); +const generalInvalidFields = [ + 'userId', 'createdAt', 'updatedAt', + 'assistants', 'confirmed', 'allow_multiple', + 'multiple_limit', 'allow_overflow', 'marketing_list', +]; + routes.get('/events', isLoggedUser, - /*FieldMiddleware.middleware({ - invalidFields: ['user', 'createdAt'] - }),*/ + FieldMiddleware.middleware({ + invalidFields: generalInvalidFields + }), PaginateMiddleware.middleware(), SortMiddleware.middleware({ default: "-date" }), eventController.find ); routes.get('/events/next', - isLoggedUser, + //isLoggedUser, FieldMiddleware.middleware({ - invalidFields: ['userId', 'createdAt', 'updatedAt'] + invalidFields: generalInvalidFields }), PaginateMiddleware.middleware(), SortMiddleware.middleware({ default: "init_available_date" }), - //ScopeMiddleware - eventController.findNext, + eventController.find({ + scopes: ['defaultScope', 'next', 'includeVenue', 'includeSchedule', 'includeSpeakers'], + }), //eventController.find // model.scope('next').findAll(); ///SchemaValidator(eventValidation.EventsListOutputType, true), @@ -38,6 +45,9 @@ routes.get('/events/next', routes.get('/events/pass', isLoggedUser, + FieldMiddleware.middleware({ + invalidFields: generalInvalidFields + }), PaginateMiddleware.middleware(), SortMiddleware.middleware({ default: "-date" }), eventController.findPass @@ -45,6 +55,9 @@ routes.get('/events/pass', routes.get('/events/current', isLoggedUser, + FieldMiddleware.middleware({ + invalidFields: generalInvalidFields + }), PaginateMiddleware.middleware(), SortMiddleware.middleware({ default: "init_available_date" }), eventController.findCurrent @@ -53,6 +66,9 @@ routes.get('/events/current', routes.get('/events/:id', isLoggedUser, + FieldMiddleware.middleware({ + invalidFields: generalInvalidFields + }), FieldMiddleware.middleware({ invalidFields: ['createdAt'] }), diff --git a/modules/events/event.service.js b/modules/events/event.service.js index f36dd0d..f7d3d84 100644 --- a/modules/events/event.service.js +++ b/modules/events/event.service.js @@ -8,11 +8,33 @@ const Sequelize = require('sequelize'); const models = require('../../core/models'); const extraMethods = { - fetch: async (params, context) => { - const lapse = context.lapse; + afterFetchAll: (result, params, context) => { + if (!result.count) { + return result; + } + + let rows = result.rows.map(row => row.toJSON()); + + if (context.scopes.includes('includeSpeakers')) { + rows = rows.map(event => Object.assign({}, event, /*{ schedule: undefined },*/ { speakers: event.schedule.map(schedule => schedule.speaker) })); + } + + /*rows.map(event => { + const info = event.schedule + })*/ + + return { + count: rows.length, + rows: rows + } + }, + + + fetch2: async (params, context) => { + //const lapse = context.lapse; const findOptions = parseParamsToFindOptions(params); - switch (lapse) { + /*switch (lapse) { case 'next': findOptions.where = Object.assign({}, findOptions.where, { @@ -40,7 +62,7 @@ const extraMethods = { break; default: break; - } + }*/ // Incluir findOptions.include.push({ @@ -73,9 +95,9 @@ const extraMethods = { state: 'publish' }); - + console.log(context); try { - return await models.Event.findAll(findOptions); + return await models.Event.scope(context.scopes).findAll(findOptions); } catch(error) { throw error; } diff --git a/modules/events/events_reservations.model.js b/modules/events/events_reservations.model.js index b360d6c..30fee35 100644 --- a/modules/events/events_reservations.model.js +++ b/modules/events/events_reservations.model.js @@ -56,7 +56,7 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.UUID, foreignKey: true, }, - marketingList: { + marketing_list: { type: DataTypes.STRING, }, }, { diff --git a/script-carga-bd-completa.sql b/script-carga-bd-completa.sql index 74662ce..e80e56b 100644 --- a/script-carga-bd-completa.sql +++ b/script-carga-bd-completa.sql @@ -208,7 +208,7 @@ CREATE TABLE `events` ( `url_streaming` varchar(255) DEFAULT NULL, `url_poll` varchar(255) DEFAULT NULL, `url_registration` varchar(255) DEFAULT NULL, - `marketingList` varchar(255) DEFAULT NULL, + `marketing_list` varchar(255) DEFAULT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `userId` char(36) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, @@ -334,7 +334,7 @@ CREATE TABLE `events_reservations` ( `color` varchar(255) NOT NULL, `allow_overflow` tinyint(1) NOT NULL DEFAULT '0', `overflow_event_reservationId` char(36) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, - `marketingList` varchar(255) DEFAULT NULL, + `marketing_list` varchar(255) DEFAULT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `userId` char(36) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,