Merge branch 'dev' of https://git.verdnatura.es/salix into dev

* 'dev' of https://git.verdnatura.es/salix:
  get address return province data
  sales person formated
  getRoleCustomer return object not array of object
  Token authenticate, solunion notification
This commit is contained in:
Carlos 2017-09-28 12:38:05 +02:00
commit 0742a4e098
41 changed files with 543 additions and 157 deletions

View File

@ -1,6 +1,6 @@
<mg-ajax path="/client/api/Addresses/{{edit.params.addressId}}" actions="$ctrl.address=edit.model" options="mgEdit"></mg-ajax>
<vn-watcher
vn-id="watcher"
get="true"
url="/client/api/Addresses"
id-field="id"
data="$ctrl.address"
@ -23,6 +23,7 @@
<vn-textfield vn-one label="Postcode" field="$ctrl.address.postcode"></vn-textfield>
<vn-textfield vn-one label="City" field="$ctrl.address.city"></vn-textfield>
<vn-autocomplete vn-one
initial-data="$ctrl.address.province"
field="$ctrl.address.provinceFk"
url="/client/api/Provinces"
show-field="name"

View File

@ -29,9 +29,6 @@
value-field="id"
select-fields="surname"
label="Salesperson">
<tpl-item>
{{$parent.$parent.item.name}} {{$parent.$parent.item.surname}}
</tpl-item>
</vn-autocomplete>
<vn-autocomplete vn-one
initial-data="$ctrl.client.contactChannel"

View File

@ -17,7 +17,7 @@ export default class Controller {
isCustomer() {
if (this.client && this.client.id) {
this.$http.get(`/client/api/Clients/${this.client.id}/getRoleCustomer`).then(res => {
this.canChangePassword = (res.data && res.data.length) ? res.data[0].isCustomer : false;
this.canChangePassword = (res.data) ? res.data.isCustomer : false;
});
} else {
this.canChangePassword = false;

View File

@ -25,8 +25,10 @@ export default class Watcher extends Component {
this.copyData();
}
$onInit() {
if (this.get) {
if (this.get && this.url) {
this.fetchData();
} else if (this.get && !this.url) {
throw new Error('Error: Parameter url ommitted');
}
}
$onChanges(changes) {
@ -39,12 +41,15 @@ export default class Watcher extends Component {
}
fetchData() {
let id = this.data[this.idField];
return new Promise((resolve, reject) => {
this.$http.get(`${this.url}/${id}`).then(
json => this.writeData(json, resolve),
json => reject(json)
);
});
// return new Promise((resolve, reject) => {
this.$http.get(`${this.url}/${id}`).then(
json => {
this.data = this.copyObject(json.data);
this.copyData();
}
// json => reject(json)
);
// });
}
/**
* Submits the data and goes back in the history.

View File

@ -1,13 +1,24 @@
var request = require('request');
var app = require('../../../server/server');
module.exports = function(Client) {
Client.remoteMethod('activate', {
description: 'Activate or deactive client',
accepts: {
arg: 'id',
type: 'number',
required: true,
description: 'Model id',
http: {source: 'path'}
},
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'Model id',
http: {source: 'path'}
}, {
arg: 'context',
type: 'object',
http: function(ctx) {
return ctx;
}
}
],
returns: {
arg: 'active',
type: 'boolean'
@ -18,10 +29,31 @@ module.exports = function(Client) {
}
});
Client.activate = function(id, cb) {
Client.activate = function(id, ctx, cb) {
Client.findById(id, function(err, client) {
if (!err) {
Client.update({id: client.id}, {active: !client.active});
if(!err) {
Client.update({id: client.id}, {active: !client.active});
let filter = {where: {clientFk: client.id}, fields: ['started', 'ended']};
app.models.CreditClassification.findOne(filter, function(err, data) {
let currentDate = new Date();
if (client.active && data.ended >= currentDate) {
let host = ctx.req.headers.host.split(':')[0];
var options = {
url: `http://${host}:5000/mailer/notification/client-deactivate/${client.id}`,
method: 'POST',
headers: {
'content-type': 'application/json',
'authorization': ctx.req.headers.authorization
},
json: {}
};
request(options);
}
});
cb(null, !client.active);
}
});

View File

@ -29,8 +29,17 @@ module.exports = function(Client) {
Client.find(filter, function(err, instances) {
if (!err) {
cb(null, instances[0]);
cb(null, formatCard(instances[0]));
}
});
};
function formatCard(card) {
let cardFormated = JSON.parse(JSON.stringify(card));
cardFormated.salesPerson = {
id: card.salesPerson().id,
name: `${card.salesPerson().name} ${card.salesPerson().surname}`
};
return cardFormated;
}
};

View File

@ -2,7 +2,7 @@
{
"relation": "salesPerson",
"scope": {
"fields": ["id", "name"]
"fields": ["id", "name", "surname"]
}
}, {
"relation": "contactChannel",

View File

@ -22,7 +22,7 @@ module.exports = Client => {
],
returns: {
arg: 'data',
type: Boolean,
type: 'boolean',
root: true
},
http: {
@ -36,7 +36,7 @@ module.exports = Client => {
const params = [id];
Client.rawSql(query, params, callback)
.then(response => {
callback(null, response);
callback(null, response[0]);
})
.catch(reject => {
callback(reject, null);

View File

@ -2,7 +2,6 @@ module.exports = (Client) => {
Client.remoteMethod('activeSalesPerson', {
description: 'returns actives employees with salesperson role',
accessType: 'READ',
isStatic: true,
accepts: [{
arg: 'filter',
type: 'Object',
@ -26,16 +25,17 @@ module.exports = (Client) => {
let limit = filter.limit || 10;
let where = getCondition(filter.where);
let query = `SELECT em.id, em.name, em.surname FROM Employee em
let query = `SELECT em.id, em.name, em.surname
FROM Employee em
JOIN Account ac ON em.userFk = ac.id
JOIN Role ON Role.id = ac.roleFK
WHERE ac.active AND Role.\`name\`='salesPerson' ${where}
ORDER BY em.name ASC
LIMIT ${limit} OFFSET ${skip}`;
Client.rawSql(query, [], callback)
.then(response => {
callback(null, response);
callback(null, formatSalesPerson(response));
})
.catch(reject => {
callback(reject, null);
@ -44,19 +44,36 @@ module.exports = (Client) => {
function getCondition(where) {
let out = [];
if(typeof where === 'object') {
Object.keys(where).forEach((k) => {
let value = where[k];
if(typeof value !== 'object') {
if (typeof value === 'number') {
out.push(`em.${k}=${value}`);
} else if (typeof value === 'string') {
out.push(`em.${k}='${value}'`);
} else {
} else if (typeof value === 'boolean' || value === null) {
out.push(`em.${k} IS ${String(value).toUpperCase()}`);
} else if (Object.keys(value).length) {
let firstProperty = Object.keys(value)[0];
out.push(`em.${k} ${firstProperty} '${value[firstProperty]}'`);
} else {
throw new Error ('Error: unexpected type');
}
});
}
return out.length ? `AND (${out.join(' AND ')})` : '';
}
return out.length ? 'AND ' + out.join(' AND ') : '';
function formatSalesPerson (response) {
let results = [];
response.forEach( person => {
results.push({
id: person.id,
name: `${person.name} ${person.surname}`
});
});
return results;
}
};

View File

@ -22,6 +22,18 @@ module.exports = function(Address) {
getAddress(ctx, data, next);
});
Address.beforeRemote('findById', function(ctx, modelInstance, next) {
ctx.args.filter = {
"include": {
"relation": "province",
"scope": {
"fields": ["id", "name"]
}
}
};
next();
});
function getAddress(ctx, data, next){
var address = Address.findOne( {where: { id: data.id}}, function (err, address){
if(address)

View File

@ -0,0 +1,40 @@
{
"name": "CreditClassification",
"description": "Clientes clasificados.",
"base": "MyModel",
"validateUpsert": true,
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"started": {
"type": "date"
},
"ended": {
"type": "date"
}
},
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientFk"
}
},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
},
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "root",
"permission": "ALLOW"
}
]
}

View File

@ -74,5 +74,8 @@
},
"Employee": {
"dataSource": "vn"
},
"CreditClassification": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,66 @@
var database = require('./database.js');
module.exports = {
/**
* Initialize auth
* @param {Object} request - Request object
* @param {Object} response - Response object
* @param {Object} next - Next object
*/
init: function(request, response, next) {
this.request = request;
this.response = response;
this.next = next;
this.validateToken();
},
/**
* Validate auth token
*/
validateToken: function() {
let query = 'SELECT userId, ttl, created FROM salix.AccessToken WHERE id = ?';
database.pool.query(query, [this.getToken()], (error, result) => {
let token = result[0];
if (error)
return this.response.status(401).send({status: 'REJECT', data: {message: error.code}});
if (result.length == 0)
return this.response.status(401).send({status: 'REJECT', data: {message: 'No token found'}});
if (this.isTokenExpired(token.created, token.ttl))
return this.response.status(401).send({status: 'REJECT', data: {message: 'Token expired'}});
this.request.userId = token.userId;
this.next();
});
},
/**
* Get request token
* @return {String} Token
*/
getToken: function() {
return this.request.headers.authorization;
},
/**
* Checks if the token has expired
* @param {String} created - Creation date
* @param {Integer} ttl - Ttl seconds
* @return {Boolean} True if the token has expired
*/
isTokenExpired: function(created, ttl) {
let date = new Date(created);
let currentDate = new Date();
date.setSeconds(date.getSeconds() + ttl);
if (currentDate > date)
return true;
}
};

View File

@ -3,10 +3,12 @@
"port": 465,
"secure": true,
"auth": {
"id": 10240,
"user": "noreply",
"pass": ""
},
"tls": {
"rejectUnauthorized": false
}
},
"pool": true
}

View File

@ -3,12 +3,12 @@ var settings = require('./settings.js');
var path = require('path');
module.exports = {
/**
* Returns template locale
* @param {String} template - Template name
* @param {String} countryCode - Language code
* @param {Object} cb - Callback
*/
/**
* Returns template locale
* @param {String} template - Template name
* @param {String} countryCode - Language code
* @param {Object} cb - Callback
*/
load: function(template, countryCode, cb) {
var localeFile = path.join(__dirname, 'template', `${template}`, 'locale', `${countryCode}.json`);
var defaultLocaleFile = path.join(__dirname, 'template', `${template}`, 'locale', `${settings.app().defaultLanguage}.json`);
@ -25,5 +25,18 @@ module.exports = {
cb({status: 'ACCEPT', data: {locale: require(localeFile)}});
}
});
},
/**
* Parse locale text
* @param {String} text - Locale text
* @param {Object} params - Locale params
* @return {String} - Returns parsed text
*/
parseText: function(text, params) {
for (var key in params) {
text = text.replace(`%${key}%`, params[key]);
}
return text;
}
};

View File

@ -2,9 +2,9 @@ var express = require('express');
var router = new express.Router();
var mail = require('../mail.js');
var database = require('../database.js');
var settings = require('../settings.js');
// Single user notification
router.post('/:recipient/noticeUserSend', function(request, response) {
/* router.post('/:recipient/noticeUserSend', function(request, response) {
var params = {
recipient: request.params.recipient,
sender: request.body.sender,
@ -21,14 +21,14 @@ router.post('/:recipient/noticeUserSend', function(request, response) {
WHERE c.keyName = ? AND s.userFk = ?`;
database.pool.query(query, [params.category, params.recipient, params.sender], (error, result) => {
mail.sendWithTemplate('notice', params, result => {
mail.sendWithTemplate('notification-notice', params, result => {
return response.json(result);
});
});
});
}); */
// Send notification to all user subscribed to category
router.post('/:category/noticeCategorySend', function(request, response) {
/* router.post('/:category/noticeCategorySend', function(request, response) {
var params = {
sender: request.body.sender,
category: request.params.category,
@ -42,23 +42,38 @@ router.post('/:category/noticeCategorySend', function(request, response) {
result.forEach(function(user) {
params.recipient = user.id;
mail.sendWithTemplate('notice', params, result => {
mail.sendWithTemplate('notification-notice', params, result => {
return response.json(result);
});
}, this);
});
});
}); */
// Send system notification
router.post('/:recipient/noticeSystemSend', function(request, response) {
/* router.post('/:recipient/noticeSystemSend', function(request, response) {
var params = {
recipient: request.params.recipient,
sender: 50069, // verdnatura
sender: settings.smtp().auth.id,
category: request.body.category,
message: request.body.message
};
mail.sendWithTemplate('notice', params, result => {
mail.sendWithTemplate('notification-notice', params, result => {
return response.json(result);
});
}); */
// Send notification to alias solunion on client deactivate
router.post('/client-deactivate/:clientId', function(request, response) {
var params = {
alias: 'solunion',
code: 'clientDeactivate',
bodyParams: {
clientId: request.params.clientId
}
};
mail.sendWithTemplate('notification-alias', params, result => {
return response.json(result);
});
});

View File

@ -13,9 +13,9 @@ module.exports = {
* @param {Object} cb - Callback
*/
get: function(template, params, cb) {
var templatePath = path.join(__dirname, 'template', `${template}`, `${template}.html`);
var templatePath = path.join(__dirname, 'template', `${template}`, `index.html`);
var classPath = path.join(__dirname, 'template', `${template}`, `${template}.js`);
var stylePath = path.join(__dirname, 'template', `${template}`, `${template}.css`);
var stylePath = path.join(__dirname, 'template', `default`, `style.css`);
fs.stat(templatePath, (error, stat) => {
if (error)
@ -26,9 +26,13 @@ module.exports = {
let getRenderedStyles = body => {
this.renderStyles(stylePath, body, body => {
var titleSubject = body.match(new RegExp('<title>(.*?)</title>', 'i'))[1];
params.subject = params.subject || instance.subject;
if (params.subject == undefined)
params.subject = body.match(new RegExp('<title>(.*?)</title>', 'i'))[1];
this.getAttachments(template, body, attachments => {
cb({status: 'ACCEPT', data: {recipient: instance.recipient, subject: titleSubject, body: body, attachments: attachments}});
cb({status: 'ACCEPT', data: {recipient: instance.recipient, subject: params.subject, body: body, attachments: attachments}});
});
});
};
@ -99,7 +103,7 @@ module.exports = {
for (var i = 0; i < tplAttachments.length; i++) {
var name = tplAttachments[i].replace('src="cid:', '').replace('"', '');
var attachmentPath = path.join(__dirname, 'template/image', name);
var attachmentPath = path.join(__dirname, 'template/default/image', name);
attachments.push({filename: name, path: attachmentPath, cid: name});
}

View File

@ -0,0 +1,18 @@
{
"subject": "Cambios en las condiciones de pago",
"title": "Cambio en las condiciones",
"dear": "Estimado cliente",
"bodyDescription": "Le informamos que han cambiado las condiciones de pago de su cuenta. A continuación le indicamos las nuevas condiciones:",
"paymentMethod": "Método de pago",
"paymentDay": "Día de pago",
"everyMonth": "de cada mes",
"cardPaymentAdvice": "Su modo de pago actual implica que deberá abonar el importe de los pedidos realizados en el mismo día para que se puedan enviar.",
"accountPaymentAdviceBefore": "Su modo de pago actual implica que se le pasará un cargo a la cuenta",
"accountPaymentAdviceAfter": "por el importe pendiente, al vencimiento establecido en las condiciones.",
"notifyError": "En el caso de detectar algún error en los datos indicados o para cualquier aclaración, debe dirigirse a su comercial.",
"actionButton": "Visita nuestra Web",
"infoButton": "Ayúdanos a mejorar",
"fiscalAddress": "VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla _ www.verdnatura.es _ clientes@verdnatura.es",
"privacy": "- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado exclusivamente por la persona destinataria del mismo. Si usted ha recibido este mensaje por error, le rogamos lo comunique al remitente y borre dicho mensaje y cualquier documento adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad ni a ningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente no se hace responsable de los cambios, alteraciones, errores u omisiones que pudieran hacerse al mensaje una vez enviado.",
"privacyLaw": "En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de Datos de Carácter Personal, le comunicamos que los datos personales que facilite se incluirán en ficheros automatizados de VERDNATURA LEVANTE S.L., pudiendo en todo momento ejercitar los derechos de acceso, rectificación, cancelación y oposición, comunicándolo por escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación."
}

View File

@ -0,0 +1,41 @@
var path = require('path');
var database = require(path.join(__dirname, '../../database.js'));
var format = require(path.join(__dirname, '../../util/format.js'));
module.exports = class PaymentUpdate {
getData(params, cb) {
let query = `SELECT
pm.id payMethodFk,
pm.name payMethodName,
c.dueDay,
c.iban,
LOWER(ct.code) countryCode,
c.email recipient
FROM client c
JOIN payMethod pm ON pm.id = c.paymentMethodFk
JOIN country ct ON ct.id = c.countryFk
WHERE c.id = ?`;
database.pool.query(query, [params.recipient], (error, result) => {
if (error || result.length == 0)
return cb({status: 'REJECT', data: {message: 'No data found', error: error}});
Object.assign(this, result[0]);
cb({status: 'ACCEPT', data: {}});
});
}
get paymentDay() {
if (this.payMethodFk != 5) {
return `<div>${this._.paymentDay}: <strong style="font-size: 16px">${this.dueDay} ${this._.everyMonth}</strong></div>`;
}
}
get paymentAdvice() {
switch (this.payMethodFk) {
case 4:
return `${this._.accountPaymentAdviceBefore} ${format.partialAccountAddress(this.iban)} ${this._.accountPaymentAdviceAfter}`;
case 5:
return this._.cardPaymentAdvice;
}
}
};

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="es">
<head>
<title>{{_.subject}}</title>
<meta charset="utf8"/>
</head>
<body>
<div style="width: 600px;margin: 0 auto;font-family: arial, sans-serif;font-size: 16px;color: #555">
<!-- Banner block -->
<div>
<a href="https://www.verdnatura.es"/><img src="cid:header.png" alt="VerdNatura" style="margin:0"/></a>
</div>
<!-- Banner block end -->
<!-- Title block -->
<div style="padding: 35px 0;background-color:#95d831;text-align: center">
<h1 style="margin: 0;font-size: 32px;color: #333;">{{_.title}}</h1>
</div>
<!-- Title block end -->
<!-- Mail body block -->
<div style="padding: 20px 0">
<p style="text-align: justify">{{_.hello}}, <strong>#{{alias}}</strong></p>
<p style="text-align: justify;font-size: 22px">{{message}}<p>
</div>
<!-- Mail body block end -->
<!-- Action button block -->
<div style="background-color: #333;overflow:hidden">
<a href="https://www.verdnatura.es" target="_blank" style="display:block;float:left;width:300px;height:72px;color:#fff;font-size:22px;text-decoration:none">
<div style="float:left;width:230px;padding:22px 0;height:72px;text-align:center">{{_.actionButton}}</div>
<div style="background-color:#95d831;text-align:center;float:right;padding-top:22px;height:50px;width:70px"><img style="margin:0" src="cid:action.png"/></div>
</a>
<a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank" style="display:block;float:left;width:300px;height:72px;color:#fff;font-size:22px;text-decoration:none">
<div style="float:left;width:230px;padding:22px 0;height:72px;text-align:center">{{_.infoButton}}</div>
<div style="background-color:#95d831;text-align:center;float:right;padding-top:22px;height:50px;width:70px"><img style="margin:0" src="cid:info.png"/></div>
</a>
</div>
<!-- Action button block end-->
<!-- Networks block -->
<div style="padding:20px 0;background-color:#555;text-align:center">
<a href="https://www.facebook.com/Verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:facebook.png" alt="Visita nuestro Facebook" style="margin:0"/>
</a>
<a href="https://www.twitter.com/Verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:twitter.png" alt="Visita nuestro Twitter" style="margin:0"/>
</a>
<a href="https://www.youtube.com/Verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:youtube.png" alt="Visita nuestro canal de Youtube" style="margin:0"/>
</a>
<a href="https://www.pinterest.com/Verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:pinterest.png" alt="Visita nuestro Pinterest" style="margin:0"/>
</a>
<a href="https://www.instagram.com/Verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:instagram.png" alt="Visita nuestro Instagram" style="margin:0"/>
</a>
<a href="https://www.linkedin.com/company/verdnatura" target="_blank" style="text-decoration:none;margin-right: 10px">
<img src="cid:linkedin.png" alt="Visita nuestro Linkedin" style="width:50px;margin:0"/>
</a>
</div>
<!-- Networks block end -->
<!-- Privacy block -->
<div style="padding:20px 0;font-size:10px;font-weight:100">
<p style="text-align: justify">{{_.fiscalAddress}}</p>
<p style="text-align: justify">{{_.privacy}}</p>
<p style="text-align: justify">{{_.privacyLaw}}</p>
</div>
<!-- Privacy block end -->
</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
{
"subject": "Has recibido una nueva notificación",
"title": "Nueva notificación",
"hello": "Hola",
"notificationCode": {
"clientDeactivate": {
"subject": "Gestionar baja de contrato",
"message": "El cliente con id %clientId% está clasificado, por favor, gestione la baja del contrato primero."
}
},
"actionButton": "Visita nuestra Web",
"infoButton": "Ayúdanos a mejorar",
"fiscalAddress": "VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla _ www.verdnatura.es _ clientes@verdnatura.es",
"privacy": "- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado exclusivamente por la persona destinataria del mismo. Si usted ha recibido este mensaje por error, le rogamos lo comunique al remitente y borre dicho mensaje y cualquier documento adjunto que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad ni a ningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente no se hace responsable de los cambios, alteraciones, errores u omisiones que pudieran hacerse al mensaje una vez enviado.",
"privacyLaw": "En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de Datos de Carácter Personal, le comunicamos que los datos personales que facilite se incluirán en ficheros automatizados de VERDNATURA LEVANTE S.L., pudiendo en todo momento ejercitar los derechos de acceso, rectificación, cancelación y oposición, comunicándolo por escrito al domicilio social de la entidad. La finalidad del fichero es la gestión administrativa, contabilidad, y facturación."
}

View File

@ -0,0 +1,29 @@
var path = require('path');
var database = require(path.join(__dirname, '../../database.js'));
var locale = require(path.join(__dirname, '../../locale.js'));
module.exports = class NotificationAlias {
getData(params, cb) {
this.params = params;
let query = `SELECT alias, CONCAT(alias, '@verdnatura.es') AS recipient
FROM account.mailAlias
WHERE alias = ?`;
database.pool.query(query, [params.alias], (error, result) => {
if (error || result.length == 0)
return cb({status: 'REJECT', data: {message: 'No data found', error: error}});
Object.assign(this, result[0]);
cb({status: 'ACCEPT', data: {}});
});
}
get subject() {
return this._.notificationCode[this.params.code].subject;
}
get message() {
return locale.parseText(this._.notificationCode[this.params.code].message, this.params.bodyParams);
}
};

View File

@ -1,7 +1,7 @@
var path = require('path');
var database = require(path.join(__dirname, '../../database.js'));
module.exports = class Notice {
module.exports = class NotificationNotice {
getData(params, cb) {
let query = `SELECT
LOWER(ct.code) countryCode,

View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="es">
<head>
<title>{{_.subject}}</title>
<meta charset="utf8"/>
</head>
<body>
<div class="wrapper">
<div class="container">
<!-- Banner block -->
<div class="banner">
<a href="https://www.verdnatura.es"/><img src="cid:header.png" alt="VerdNatura"/></a>
</div>
<!-- Banner block end -->
<!-- Title block -->
<div class="title">
<h1>{{_.title}}</h1>
</div>
<!-- Title block end -->
<!-- Mail body block -->
<div class="body">
<p style="text-align: justify">{{_.dear}},</p>
<p style="text-align: justify">{{_.bodyDescription}}</p>
<p style="text-align: justify">
<div>{{_.paymentMethod}}: <strong style="font-size: 16px">{{payMethodName}}</strong></div>
{{{paymentDay}}}
</p>
<p style="text-align: justify">{{paymentAdvice}}</p>
<p style="text-align: justify">{{_.notifyError}}</p>
</div>
<!-- Mail body block end -->
<!-- Action button block -->
<div class="buttons">
<a href="https://www.verdnatura.es" target="_blank"><div class="btn">
<span class="text">{{_.actionButton}}</span>
<span class="icon"><img src="cid:action.png"/></span>
</div></a><a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank"><div class="btn">
<span class="text">{{_.infoButton}}</span>
<span class="icon"><img src="cid:info.png"/></span>
</div></a>
</div>
<!-- Action button block -->
<!-- Networks block -->
<div class="footer">
<a href="https://www.facebook.com/Verdnatura" target="_blank">
<img src="cid:facebook.png" alt="Facebook"/>
</a>
<a href="https://www.twitter.com/Verdnatura" target="_blank">
<img src="cid:twitter.png" alt="Twitter"/>
</a>
<a href="https://www.youtube.com/Verdnatura" target="_blank">
<img src="cid:youtube.png" alt="Youtube"/>
</a>
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
<img src="cid:pinterest.png" alt="Pinterest"/>
</a>
<a href="https://www.instagram.com/Verdnatura" target="_blank">
<img src="cid:instagram.png" alt="Instagram"/>
</a>
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
<img src="cid:linkedin.png" alt="Linkedin"/>
</a>
</div>
<!-- Networks block end -->
<!-- Privacy block -->
<div class="privacy">
<p style="text-align: justify">{{_.fiscalAddress}}</p>
<p style="text-align: justify">{{_.privacy}}</p>
<p style="text-align: justify">{{_.privacyLaw}}</p>
</div>
<!-- Privacy block end -->
</div>
</div>
</body>
</html>

View File

@ -1,92 +0,0 @@
img {
margin: 0
}
.wrapper {
background-color: #EEE
}
.container {
font-family: arial, sans-serif;
max-width: 600px;
min-width: 320px;
font-size: 16px;
margin: 0 auto;
color: #555
}
.banner img {
width: 100%
}
.title {
background-color: #95d831;
text-align: center;
padding: 35px 0
}
.title h1 {
font-size: 32px;
color: #333;
margin: 0
}
.body {
background-color:#FFF;
padding: 20px
}
.buttons {
background-color: #FFF;
text-align: center;
width: 100%
}
.buttons a {
text-decoration: none;
font-size: 18px;
color: #fff
}
.buttons .btn {
background-color: #333;
min-width: 300px;
height: 72px;
display: inline-block;
text-align: center
}
.buttons .btn .text {
display: inline-block;
padding-top: 22px
}
.buttons .btn .icon {
background-color: #95d831;
text-align: center;
padding-top: 22px;
float: right;
height: 50px;
width: 70px
}
.footer {
background-color: #555;
text-align: center;
padding: 20px 0
}
.footer a {
text-decoration: none;
margin-right: 5px
}
.footer a img {
margin: 0
}
.privacy {
padding: 20px 0;
font-size: 10px;
font-weight: 100
}

View File

@ -7,26 +7,29 @@ var bodyParser = require('body-parser');
var settings = require('./application/settings.js');
var mail = require('./application/mail.js');
var database = require('./application/database.js');
var auth = require('./application/auth.js');
// Middleware
// Body parser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Cargar rutas
// Auth middleware
var requestToken = function(request, response, next) {
auth.init(request, response, next);
};
app.use(requestToken);
// Load routes
app.use('/', require('./application/router.js'));
app.use(function(err, req, res, next) {
console.error(err.message);
res.status(500).send('Something broke!');
});
// Iniciar escucha del servidor
app.start = function() {
var listener = app.listen(settings.app().port, function() {
var servicePath = 'http://' + listener.address().address + ':' + listener.address().port;
mail.init();
database.init();
database.testEmail();
console.log('Web server ' + settings.app().name.toUpperCase() + ' listening at: ' + servicePath);
console.log('Browse your REST API at: ' + servicePath + '/mailer');
if (settings.app().debug) {