diff --git a/back/methods/osticket/osTicketReportEmail.js b/back/methods/osticket/osTicketReportEmail.js new file mode 100644 index 000000000..ebb74c385 --- /dev/null +++ b/back/methods/osticket/osTicketReportEmail.js @@ -0,0 +1,29 @@ +const {Email} = require('vn-print'); + +module.exports = Self => { + Self.remoteMethodCtx('osTicketReportEmail', { + description: 'Sends the buyer waste email', + accessType: 'WRITE', + accepts: [], + returns: { + type: ['object'], + root: true + }, + http: { + path: '/osticket-report-email', + verb: 'POST' + } + }); + + Self.osTicketReportEmail = async ctx => { + const models = Self.app.models; + const printConfig = await models.PrintConfig.findOne(); + + const email = new Email('osticket-report', { + recipient: printConfig.itRecipient, + lang: ctx.req.getLocale() + }); + + return email.send(); + }; +}; diff --git a/back/model-config.json b/back/model-config.json index 343210383..3297d84e5 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -118,6 +118,9 @@ }, "Edi": { "dataSource": "vn" + }, + "PrintConfig": { + "dataSource": "vn" } } diff --git a/back/models/osticket.js b/back/models/osticket.js new file mode 100644 index 000000000..9b13110bb --- /dev/null +++ b/back/models/osticket.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/osticket/osTicketReportEmail')(Self); +}; diff --git a/back/models/osticket.json b/back/models/osticket.json index 0c673d004..6ba80b30e 100644 --- a/back/models/osticket.json +++ b/back/models/osticket.json @@ -1,12 +1,5 @@ { "name": "OsTicket", - "base": "VnModel", - "acls": [{ - "property": "validations", - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }] + "base": "VnModel" } \ No newline at end of file diff --git a/back/models/print-config.json b/back/models/print-config.json new file mode 100644 index 000000000..badb57083 --- /dev/null +++ b/back/models/print-config.json @@ -0,0 +1,29 @@ +{ + "name": "PrintConfig", + "description": "Print config", + "base": "VnModel", + "options": { + "mysql": { + "table": "salix.printConfig" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "itRecipient": { + "type": "string" + }, + "incidencesEmail": { + "type": "string" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/db/changes/10490-august/00-ACL.sql b/db/changes/10490-august/00-ACL.sql index 871305709..1c773da89 100644 --- a/db/changes/10490-august/00-ACL.sql +++ b/db/changes/10490-august/00-ACL.sql @@ -23,4 +23,6 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp ('Supplier', 'campaignMetricsEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'), ('Travel', 'extraCommunityPdf', 'READ', 'ALLOW', 'ROLE', 'employee'), ('Travel', 'extraCommunityEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'), - ('Entry', 'entryOrderPdf', 'READ', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file + ('Entry', 'entryOrderPdf', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('OsTicket', 'osTicketReportEmail', 'WRITE', 'ALLOW', 'ROLE', 'system'), + ('Item', 'buyerWasteEmail', 'WRITE', 'ALLOW', 'ROLE', 'system'); \ No newline at end of file diff --git a/db/changes/10490-august/00-itemConfig.sql b/db/changes/10490-august/00-itemConfig.sql new file mode 100644 index 000000000..b148aa094 --- /dev/null +++ b/db/changes/10490-august/00-itemConfig.sql @@ -0,0 +1,5 @@ +ALTER TABLE `vn`.`itemConfig` + ADD id int null PRIMARY KEY first; + +ALTER TABLE `vn`.`itemConfig` + ADD wasteRecipients VARCHAR(50) NOT NULL comment 'Weekly waste report schedule recipients'; diff --git a/db/changes/10490-august/00-printConfig.sql b/db/changes/10490-august/00-printConfig.sql new file mode 100644 index 000000000..c5af09ac9 --- /dev/null +++ b/db/changes/10490-august/00-printConfig.sql @@ -0,0 +1,10 @@ +create table `salix`.`printConfig` +( + id int auto_increment, + itRecipient varchar(50) null comment 'IT recipients for report mailing', + incidencesEmail varchar(50) null comment 'CAU destinatary email', + constraint printConfig_pk + primary key (id) +) + comment 'Print service config'; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 997ebf92f..c496a5da0 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -13,6 +13,10 @@ INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`) VALUES ('DEFAULT_TOKEN', '1209600', util.VN_CURDATE(), 66); +INSERT INTO `salix`.`printConfig` (`id`, `itRecipient`, `incidencesEmail`) + VALUES + (1, 'it@gotamcity.com', 'incidences@gotamcity.com'); + INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`) VALUES ('1', '6'); diff --git a/loopback/server/boot/print.js b/loopback/server/boot/print.js index c2ef243b7..7558c3ef8 100644 --- a/loopback/server/boot/print.js +++ b/loopback/server/boot/print.js @@ -1,3 +1,3 @@ module.exports = function(app) { require('vn-print').boot(app); -}; \ No newline at end of file +}; diff --git a/loopback/server/datasources.json b/loopback/server/datasources.json index 5dade9c2e..5ca920f2e 100644 --- a/loopback/server/datasources.json +++ b/loopback/server/datasources.json @@ -19,8 +19,16 @@ "waitForConnections": true }, "osticket": { - "connector": "memory", - "timezone": "local" + "connector": "vn-mysql", + "database": "osticket", + "debug": false, + "host": "swarm.verdnatura.es", + "port": "40003", + "username": "osticket", + "password": "gfKmwsHJ2Q5H3Aem", + "connectTimeout": 180000, + "acquireTimeout": 60000, + "waitForConnections": true }, "tempStorage": { "name": "tempStorage", diff --git a/modules/item/back/methods/item/buyerWasteEmail.js b/modules/item/back/methods/item/buyerWasteEmail.js index f548b39c0..7f340de0f 100644 --- a/modules/item/back/methods/item/buyerWasteEmail.js +++ b/modules/item/back/methods/item/buyerWasteEmail.js @@ -4,55 +4,25 @@ module.exports = Self => { Self.remoteMethodCtx('buyerWasteEmail', { description: 'Sends the buyer waste email', accessType: 'WRITE', - accepts: [ - { - arg: 'id', - type: 'number', - required: true, - description: 'The client id', - http: {source: 'path'} - }, - { - arg: 'recipient', - type: 'string', - description: 'The recipient email', - required: true, - }, - { - arg: 'replyTo', - type: 'string', - description: 'The sender email to reply to', - required: false - }, - { - arg: 'recipientId', - type: 'number', - description: 'The recipient id to send to the recipient preferred language', - required: false - } - ], + accepts: [], returns: { type: ['object'], root: true }, http: { - path: '/:id/buyer-waste-email', + path: '/buyer-waste-email', verb: 'POST' } }); - Self.clientDebtStatementEmail = async ctx => { - const args = Object.assign({}, ctx.args); - const params = { - recipient: args.recipient, + Self.buyerWasteEmail = async ctx => { + const models = Self.app.models; + const itemConfig = await models.ItemConfig.findOne(); + + const email = new Email('buyer-week-waste', { + recipient: itemConfig.wasteRecipients, lang: ctx.req.getLocale() - }; - - delete args.ctx; - for (const param in args) - params[param] = args[param]; - - const email = new Email('buyer-week-waste', params); + }); return email.send(); }; diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index c31f472be..9737d26fc 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -23,6 +23,9 @@ "ItemCategory": { "dataSource": "vn" }, + "ItemConfig": { + "dataSource": "vn" + }, "ItemFamily": { "dataSource": "vn" }, diff --git a/modules/item/back/models/item-config.json b/modules/item/back/models/item-config.json new file mode 100644 index 000000000..364879986 --- /dev/null +++ b/modules/item/back/models/item-config.json @@ -0,0 +1,21 @@ +{ + "name": "ItemConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "itemConfig" + } + }, + "properties": { + "isItemTagTriggerDisabled": { + "type": "boolean" + }, + "monthToDeactivate": { + "type": "boolean" + }, + "wasteRecipients": { + "type": "string", + "description": "Buyers waste report recipients" + } + } +} \ No newline at end of file diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 457cce4f2..381033a1e 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -15,6 +15,7 @@ module.exports = Self => { require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); require('../methods/item/activeBuyers')(Self); + require('../methods/item/buyerWasteEmail')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/print/core/database.js b/print/core/database.js index f442cd4ed..43c271ad7 100644 --- a/print/core/database.js +++ b/print/core/database.js @@ -2,21 +2,22 @@ const mysql = require('mysql2'); const config = require('./config.js'); const fs = require('fs-extra'); const path = require('path'); -const PoolConnection = mysql.PoolConnection; module.exports = { - init(pool) { - if (!this.pool) { - // const datasources = config.datasources; - // const pool = mysql.createPoolCluster(); + defaultDataSource: 'vn', - // for (let datasource of datasources) - // pool.add(datasource.name, datasource.options); + init(dataSource) { + if (!this.connections) { + this.connections = []; - this.pool = pool; + const dataSources = ['vn', 'osticket']; + for (const name of dataSources) + this.connections[name] = dataSource[name].connector.client; + + this.pool = this.connections[this.defaultDataSource]; } - return this.pool; + return this.connections; }, /** @@ -25,15 +26,8 @@ module.exports = { * * @return {Object} - Pool connection */ - getConnection(name = 'default') { - let pool = this.pool; - return new Promise((resolve, reject) => { - pool.getConnection(name, function(error, connection) { - if (error) return reject(error); - - resolve(connection); - }); - }); + getConnection(name = this.defaultDataSource) { + return this.connections[name]; }, /** @@ -44,9 +38,12 @@ module.exports = { * * @return {Object} - Result promise */ - rawSql(query, params) { + rawSql(query, params, connection) { return new Promise((resolve, reject) => { - this.pool.query(query, params, (error, rows) => { + let db = this.getConnection(); + if (connection) db = connection; + + db.query(query, params, (error, rows) => { if (error) return reject(error); resolve(rows); }); @@ -71,23 +68,25 @@ module.exports = { * Returns the first row from a given raw sql * @param {String} query - The raw SQL query * @param {Object} params - Parameterized values + * @param {Object} connection - Optional pool connection * * @return {Object} - Result promise */ - findOne(query, params) { - return this.rawSql(query, params).then(([row]) => row); + findOne(query, params, connection) { + return this.rawSql(query, params, connection) + .then(([row]) => row); }, /** * Returns the first row from a given SQL file * @param {String} queryName - The SQL file name * @param {Object} params - Parameterized values + * @param {Object} connection - Optional pool connection * * @return {Object} - Result promise */ - findOneFromDef(queryName, params) { - console.log(path.resolve('queryName')); - return this.rawSqlFromDef(queryName, params) + findOneFromDef(queryName, params, connection) { + return this.rawSqlFromDef(queryName, params, connection) .then(([row]) => row); }, @@ -95,11 +94,12 @@ module.exports = { * Returns the first property from a given raw sql * @param {String} query - The raw SQL query * @param {Object} params - Parameterized values + * @param {Object} connection - Optional pool connection * * @return {Object} - Result promise */ - findValue(query, params) { - return this.findOne(query, params).then(row => { + findValue(query, params, connection) { + return this.findOne(query, params, connection).then(row => { return Object.values(row)[0]; }); }, @@ -108,13 +108,13 @@ module.exports = { * Returns the first property from a given SQL file * @param {String} queryName - The SQL file name * @param {Object} params - Parameterized values + * @param {Object} connection - Optional pool connection * * @return {Object} - Result promise */ - findValueFromDef(queryName, params) { - return this.findOneFromDef(queryName, params).then(row => { - return Object.values(row)[0]; - }); + findValueFromDef(queryName, params, connection) { + return this.findOneFromDef(queryName, params, connection) + .then(row => Object.values(row)[0]); }, /** diff --git a/print/index.js b/print/index.js index c25df6ae1..89ab33aa4 100644 --- a/print/index.js +++ b/print/index.js @@ -8,13 +8,8 @@ const componentsPath = path.resolve(__dirname, './core/components'); module.exports = { async boot(app) { // Init database instance - const conn = app.dataSources.vn.connector.client; - conn.query('SELECT 1', function(error, rows) { - if (error) return error; - console.log(rows); - }); - // console.log(app.dataSource.vn.connector.executeStmt('SELECT 1')); - require('./core/database').init(conn); + + require('./core/database').init(app.dataSources); require('./core/smtp').init(); require('./core/mixins'); require('./core/filters'); @@ -24,11 +19,11 @@ module.exports = { componentsDir.forEach(componentName => { const componentDir = path.join(componentsPath, '/', componentName); const assetsDir = `${componentDir}/assets`; - + app.use(`/api/${componentName}/assets`, express.static(assetsDir)); }); - /** + /** * Serve static files */ const templatesDir = fs.readdirSync(templatesPath); diff --git a/print/templates/email/osticket-report/assets/css/import.js b/print/templates/email/osticket-report/assets/css/import.js index c742fdf90..7360587f7 100644 --- a/print/templates/email/osticket-report/assets/css/import.js +++ b/print/templates/email/osticket-report/assets/css/import.js @@ -1,9 +1,13 @@ -const Stylesheet = require(`${appPath}/core/stylesheet`); +const Stylesheet = require(`vn-print/core/stylesheet`); + +const path = require('path'); +const vnPrintPath = path.resolve('print'); module.exports = new Stylesheet([ - `${appPath}/common/css/spacing.css`, - `${appPath}/common/css/misc.css`, - `${appPath}/common/css/layout.css`, - `${appPath}/common/css/email.css`, + `${vnPrintPath}/common/css/spacing.css`, + `${vnPrintPath}/common/css/misc.css`, + `${vnPrintPath}/common/css/layout.css`, + `${vnPrintPath}/common/css/email.css`, `${__dirname}/style.css`]) .mergeStyles(); + diff --git a/print/templates/email/osticket-report/osticket-report.js b/print/templates/email/osticket-report/osticket-report.js index 45fadd4f1..48e2202f8 100755 --- a/print/templates/email/osticket-report/osticket-report.js +++ b/print/templates/email/osticket-report/osticket-report.js @@ -1,4 +1,4 @@ -const Component = require(`${appPath}/core/component`); +const Component = require(`vn-print/core/component`); const emailHeader = new Component('email-header'); const emailFooter = new Component('email-footer');