Merge branch '1466-print_refactor' of verdnatura/salix into dev
gitea/salix/dev This commit looks good
Details
LGTM
|
@ -1460,7 +1460,7 @@ INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `amountUnpaid`, `pay
|
|||
(1, 'Cobro web', 100.50, 0.00, CURDATE(), 9, 1, 101, CURDATE(), 442, 1),
|
||||
(2, 'Cobro web', 200.50, 0.00, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 9, 1, 101, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 442, 1),
|
||||
(3, 'Cobro en efectivo', 300.00, 100.00, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 9, 1, 102, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 442, 0),
|
||||
(4, 'Cobro en efectivo', -400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0);
|
||||
(4, 'Cobro en efectivo', 400.00, -50.00, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 9, 1, 103, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 442, 0);
|
||||
|
||||
INSERT INTO `vn2008`.`workerTeam`(`id`, `team`, `user`)
|
||||
VALUES
|
||||
|
|
|
@ -47,6 +47,7 @@ TABLES=(
|
|||
claimResult
|
||||
ticketUpdateAction
|
||||
state
|
||||
sample
|
||||
)
|
||||
dump_tables ${TABLES[@]}
|
||||
|
||||
|
@ -56,7 +57,6 @@ TABLES=(
|
|||
businessReasonEnd
|
||||
container
|
||||
department
|
||||
escritos
|
||||
Grupos
|
||||
iva_group_codigo
|
||||
tarifa_componentes
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module.exports = function(app) {
|
||||
require('../../../print/server.js')(app);
|
||||
require('../../../print/boot.js')(app);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Serializes an object to a query params
|
||||
*
|
||||
* @param {Object} obj The params object
|
||||
* @return {String} Serialized params
|
||||
*/
|
||||
exports.httpParamSerializer = function(obj) {
|
||||
let query = '';
|
||||
for (let param in obj) {
|
||||
if (query != '')
|
||||
query += '&';
|
||||
query += `${param}=${obj[param]}`;
|
||||
}
|
||||
|
||||
return query;
|
||||
};
|
|
@ -35,7 +35,7 @@ class Controller {
|
|||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['salesPersonFk', 'name'],
|
||||
fields: ['salesPersonFk', 'name', 'email'],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $state, $http, $translate, vnApp, aclService) {
|
||||
constructor($scope, $state, $http, $translate, vnApp, aclService, $httpParamSerializer) {
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.$http = $http;
|
||||
this.$translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.aclService = aclService;
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
this.moreOptions = [
|
||||
{callback: this.showPickupOrder, name: 'Show Pickup order'},
|
||||
{callback: this.confirmPickupOrder, name: 'Send Pickup order'},
|
||||
|
@ -60,7 +61,12 @@ class Controller {
|
|||
}
|
||||
|
||||
showPickupOrder() {
|
||||
let url = `report/rpt-claim-pickup-order?claimFk=${this.claim.id}`;
|
||||
const params = {
|
||||
clientId: this.claim.clientFk,
|
||||
claimId: this.claim.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/claim-pickup-order?${serializedParams}`;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
|
@ -70,7 +76,14 @@ class Controller {
|
|||
|
||||
sendPickupOrder(response) {
|
||||
if (response === 'accept') {
|
||||
this.$http.post(`email/claim-pickup-order`, {claimFk: this.claim.id}).then(
|
||||
const params = {
|
||||
recipient: this.claim.client.email,
|
||||
clientId: this.claim.clientFk,
|
||||
claimId: this.claim.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
const url = `email/claim-pickup-order?${serializedParams}`;
|
||||
this.$http.get(url).then(
|
||||
() => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
|
||||
);
|
||||
}
|
||||
|
@ -90,7 +103,7 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$state', '$http', '$translate', 'vnApp', 'aclService'];
|
||||
Controller.$inject = ['$scope', '$state', '$http', '$translate', 'vnApp', 'aclService', '$httpParamSerializer'];
|
||||
|
||||
ngModule.component('vnClaimDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Item Component vnClaimDescriptor', () => {
|
||||
let $httpParamSerializer;
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('claim'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => {
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, _$httpParamSerializer_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
controller = $componentController('vnClaimDescriptor');
|
||||
controller.claim = {id: 2};
|
||||
controller.claim = {id: 2, clientFk: 101, client: {email: 'client@email'}};
|
||||
}));
|
||||
|
||||
describe('showPickupOrder()', () => {
|
||||
it('should open a new window showing a pickup order PDF document', () => {
|
||||
let expectedPath = 'report/rpt-claim-pickup-order?claimFk=2';
|
||||
const params = {
|
||||
clientId: controller.claim.clientFk,
|
||||
claimId: controller.claim.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
let expectedPath = `api/report/claim-pickup-order?${serializedParams}`;
|
||||
spyOn(window, 'open');
|
||||
controller.showPickupOrder();
|
||||
|
||||
|
@ -38,8 +45,15 @@ describe('Item Component vnClaimDescriptor', () => {
|
|||
it('should make a query and call vnApp.showMessage() if the response is accept', () => {
|
||||
spyOn(controller.vnApp, 'showMessage');
|
||||
|
||||
$httpBackend.when('POST', `email/claim-pickup-order`, {claimFk: 2}).respond();
|
||||
$httpBackend.expect('POST', `email/claim-pickup-order`, {claimFk: 2}).respond();
|
||||
const params = {
|
||||
recipient: 'client@email',
|
||||
clientId: controller.claim.clientFk,
|
||||
claimId: controller.claim.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/claim-pickup-order?${serializedParams}`).respond();
|
||||
$httpBackend.expect('GET', `email/claim-pickup-order?${serializedParams}`).respond();
|
||||
controller.sendPickupOrder('accept');
|
||||
$httpBackend.flush();
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ let request = require('request-promise-native');
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
let getFinalState = require('vn-loopback/util/hook').getFinalState;
|
||||
let isMultiple = require('vn-loopback/util/hook').isMultiple;
|
||||
const httpParamSerializer = require('vn-loopback/util/http').httpParamSerializer;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
module.exports = Self => {
|
||||
// Methods
|
||||
|
@ -239,15 +241,18 @@ module.exports = Self => {
|
|||
});
|
||||
}
|
||||
|
||||
const options = {
|
||||
method: 'POST',
|
||||
uri: 'http://127.0.0.1:3000/api/email/payment-update',
|
||||
body: {
|
||||
clientFk: instance.id
|
||||
},
|
||||
json: true
|
||||
// Send email to client
|
||||
|
||||
if (!instance.email) return;
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const headers = loopBackContext.active.http.req.headers;
|
||||
const params = {
|
||||
clientId: instance.id,
|
||||
recipient: instance.email
|
||||
};
|
||||
await request(options);
|
||||
const serializedParams = httpParamSerializer(params);
|
||||
const query = `${headers.origin}/api/email/payment-update?${serializedParams}`;
|
||||
await request.get(query);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
<mg-ajax path="ClientSamples" options="vnPost"></mg-ajax>
|
||||
<vn-crud-model auto-load="true"
|
||||
url="Companies"
|
||||
data="companiesData"
|
||||
order="code">
|
||||
</vn-crud-model>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.clientSample"
|
||||
|
@ -8,9 +13,13 @@
|
|||
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
vn-id="sampleType"
|
||||
<vn-textfield vn-one
|
||||
label="Recipient"
|
||||
ng-model="$ctrl.clientSample.recipient">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one vn-id="sampleType"
|
||||
ng-model="$ctrl.clientSample.typeFk"
|
||||
model="ClientSample.typeFk"
|
||||
fields="['code','hasCompany']"
|
||||
|
@ -19,11 +28,10 @@
|
|||
value-field="id"
|
||||
label="Sample">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.clientSample.companyFk"
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.companyId"
|
||||
model="ClientSample.companyFk"
|
||||
url="Companies"
|
||||
data="companiesData"
|
||||
show-field="code"
|
||||
value-field="id"
|
||||
label="Company"
|
||||
|
@ -41,5 +49,9 @@
|
|||
<vn-dialog
|
||||
vn-id="show-preview"
|
||||
on-open="$ctrl.onPreviewOpen()">
|
||||
<tpl-body></tpl-body>
|
||||
<tpl-body class="client-sample-dialog">
|
||||
<div class="loading">
|
||||
<vn-spinner enable="true"></vn-spinner>
|
||||
</div>
|
||||
</tpl-body>
|
||||
</vn-dialog>
|
||||
|
|
|
@ -1,33 +1,84 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $state, $http, vnApp, $translate) {
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.$stateParams = $state.params;
|
||||
this.$http = $http;
|
||||
class Controller extends Component {
|
||||
constructor($element, $, vnApp, $httpParamSerializer, vnConfig) {
|
||||
super($element, $);
|
||||
this.vnApp = vnApp;
|
||||
this.$translate = $translate;
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
this.vnConfig = vnConfig;
|
||||
this.clientSample = {
|
||||
clientFk: this.$stateParams.id
|
||||
clientFk: this.$params.id,
|
||||
companyFk: vnConfig.companyFk
|
||||
};
|
||||
}
|
||||
|
||||
jsonToQuery(json) {
|
||||
let query = '';
|
||||
for (let param in json) {
|
||||
if (query != '')
|
||||
query += '&';
|
||||
query += `${param}=${json[param]}`;
|
||||
}
|
||||
get client() {
|
||||
return this._client;
|
||||
}
|
||||
|
||||
return query;
|
||||
set client(value) {
|
||||
this._client = value;
|
||||
|
||||
if (value)
|
||||
this.clientSample.recipient = value.email;
|
||||
}
|
||||
|
||||
get companyId() {
|
||||
if (!this.clientSample.companyFk)
|
||||
this.clientSample.companyFk = this.vnConfig.companyFk;
|
||||
return this.clientSample.companyFk;
|
||||
}
|
||||
|
||||
set companyId(value) {
|
||||
this.clientSample.companyFk = value;
|
||||
}
|
||||
|
||||
showPreview() {
|
||||
let sampleType = this.$scope.sampleType.selection;
|
||||
let params = {clientFk: this.$stateParams.id};
|
||||
let sampleType = this.$.sampleType.selection;
|
||||
|
||||
if (!sampleType)
|
||||
return this.vnApp.showError(this.$translate.instant('Choose a sample'));
|
||||
|
||||
if (sampleType.hasCompany && !this.clientSample.companyFk)
|
||||
return this.vnApp.showError(this.$translate.instant('Choose a company'));
|
||||
|
||||
const params = {
|
||||
clientId: this.$params.id,
|
||||
recipient: this.clientSample.recipient,
|
||||
isPreview: true
|
||||
};
|
||||
|
||||
if (sampleType.hasCompany)
|
||||
params.companyId = this.clientSample.companyFk;
|
||||
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
const query = `email/${sampleType.code}?${serializedParams}`;
|
||||
this.$http.get(query).then(res => {
|
||||
this.$.showPreview.show();
|
||||
let dialog = document.body.querySelector('div.vn-dialog');
|
||||
let body = dialog.querySelector('tpl-body');
|
||||
let scroll = dialog.querySelector('div:first-child');
|
||||
|
||||
body.innerHTML = res.data;
|
||||
scroll.scrollTop = 0;
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.check();
|
||||
this.$.watcher.realSubmit().then(() =>
|
||||
this.sendSample()
|
||||
);
|
||||
}
|
||||
|
||||
sendSample() {
|
||||
let sampleType = this.$.sampleType.selection;
|
||||
let params = {
|
||||
clientId: this.$params.id,
|
||||
recipient: this.clientSample.recipient
|
||||
};
|
||||
|
||||
if (!sampleType)
|
||||
return this.vnApp.showError(this.$translate.instant('Choose a sample'));
|
||||
|
@ -36,50 +87,22 @@ class Controller {
|
|||
return this.vnApp.showError(this.$translate.instant('Choose a company'));
|
||||
|
||||
if (sampleType.hasCompany)
|
||||
params.companyFk = this.clientSample.companyFk;
|
||||
params.companyId = this.clientSample.companyFk;
|
||||
|
||||
let query = `email/${sampleType.code}?${this.jsonToQuery(params)}`;
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
const query = `email/${sampleType.code}?${serializedParams}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
let dialog = this.$scope.showPreview.element;
|
||||
let body = dialog.querySelector('tpl-body');
|
||||
let scroll = dialog.querySelector('div:first-child');
|
||||
|
||||
body.innerHTML = res.data;
|
||||
this.$scope.showPreview.show();
|
||||
|
||||
scroll.scrollTop = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$scope.watcher.check();
|
||||
this.$scope.watcher.realSubmit().then(() =>
|
||||
this.sendSample()
|
||||
);
|
||||
}
|
||||
|
||||
sendSample() {
|
||||
let sampleType = this.$scope.sampleType.selection;
|
||||
let params = {clientFk: this.$stateParams.id};
|
||||
|
||||
if (sampleType.hasCompany)
|
||||
params.companyFk = this.clientSample.companyFk;
|
||||
|
||||
|
||||
let query = `email/${sampleType.code}?${this.jsonToQuery(params)}`;
|
||||
this.$http.post(query).then(res => {
|
||||
if (res) {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
|
||||
this.$state.go('client.card.sample.index');
|
||||
}
|
||||
this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
|
||||
this.$state.go('client.card.sample.index');
|
||||
});
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];
|
||||
Controller.$inject = ['$element', '$scope', 'vnApp', '$httpParamSerializer', 'vnConfig'];
|
||||
|
||||
ngModule.component('vnClientSampleCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
client: '<'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,14 +2,16 @@ import './index';
|
|||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientSampleCreate', () => {
|
||||
let $httpParamSerializer;
|
||||
let $scope;
|
||||
let $element;
|
||||
let $httpBackend;
|
||||
let $state;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('client'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, _$state_) => {
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, _$state_, _$httpParamSerializer_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$scope.sampleType = {};
|
||||
$scope.watcher = {
|
||||
|
@ -35,30 +37,24 @@ describe('Client', () => {
|
|||
$state = _$state_;
|
||||
$state.params.id = 101;
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnClientSampleCreate', {$scope, $state});
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
$element = angular.element('<vn-client-sample-create></vn-client-sample-create>');
|
||||
controller = $componentController('vnClientSampleCreate', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('jsonToQuery()', () => {
|
||||
it(`should convert a JSON object with clientFk property to query params`, () => {
|
||||
let myObject = {clientFk: 101};
|
||||
let result = controller.jsonToQuery(myObject);
|
||||
|
||||
expect(result).toEqual('clientFk=101');
|
||||
});
|
||||
|
||||
it(`should convert a JSON object with clientFk and companyFk properties to query params`, () => {
|
||||
let myObject = {clientFk: 101, companyFk: 442};
|
||||
let result = controller.jsonToQuery(myObject);
|
||||
|
||||
expect(result).toEqual('clientFk=101&companyFk=442');
|
||||
});
|
||||
});
|
||||
|
||||
describe('showPreview()', () => {
|
||||
it(`should perform a query (GET) and open a sample preview`, () => {
|
||||
spyOn(controller.$scope.showPreview, 'show');
|
||||
spyOn(controller.$.showPreview, 'show');
|
||||
const element = document.createElement('div');
|
||||
document.body.querySelector = () => {
|
||||
return {
|
||||
querySelector: () => {
|
||||
return element;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
controller.$scope.sampleType.selection = {
|
||||
controller.$.sampleType.selection = {
|
||||
hasCompany: false,
|
||||
code: 'MyReport'
|
||||
};
|
||||
|
@ -69,18 +65,32 @@ describe('Client', () => {
|
|||
|
||||
let event = {preventDefault: () => {}};
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?clientFk=101`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?clientFk=101`);
|
||||
const params = {
|
||||
clientId: 101,
|
||||
isPreview: true
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`);
|
||||
controller.showPreview(event);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$scope.showPreview.show).toHaveBeenCalledWith();
|
||||
expect(controller.$.showPreview.show).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should perform a query (GET) with companyFk param and open a sample preview`, () => {
|
||||
spyOn(controller.$scope.showPreview, 'show');
|
||||
spyOn(controller.$.showPreview, 'show');
|
||||
const element = document.createElement('div');
|
||||
document.body.querySelector = () => {
|
||||
return {
|
||||
querySelector: () => {
|
||||
return element;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
controller.$scope.sampleType.selection = {
|
||||
controller.$.sampleType.selection = {
|
||||
hasCompany: true,
|
||||
code: 'MyReport'
|
||||
};
|
||||
|
@ -92,12 +102,19 @@ describe('Client', () => {
|
|||
|
||||
let event = {preventDefault: () => {}};
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?clientFk=101&companyFk=442`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?clientFk=101&companyFk=442`);
|
||||
const params = {
|
||||
clientId: 101,
|
||||
companyId: 442,
|
||||
isPreview: true
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`);
|
||||
controller.showPreview(event);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$scope.showPreview.show).toHaveBeenCalledWith();
|
||||
expect(controller.$.showPreview.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -114,7 +131,7 @@ describe('Client', () => {
|
|||
it(`should perform a query (GET) and call go() method`, () => {
|
||||
spyOn(controller.$state, 'go');
|
||||
|
||||
controller.$scope.sampleType.selection = {
|
||||
controller.$.sampleType.selection = {
|
||||
hasCompany: false,
|
||||
code: 'MyReport'
|
||||
};
|
||||
|
@ -123,8 +140,13 @@ describe('Client', () => {
|
|||
clientFk: 101
|
||||
};
|
||||
|
||||
$httpBackend.when('POST', `email/MyReport?clientFk=101`).respond(true);
|
||||
$httpBackend.expect('POST', `email/MyReport?clientFk=101`);
|
||||
const params = {
|
||||
clientId: 101
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`);
|
||||
controller.sendSample();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
@ -134,7 +156,7 @@ describe('Client', () => {
|
|||
it(`should perform a query (GET) with companyFk param and call go() method`, () => {
|
||||
spyOn(controller.$state, 'go');
|
||||
|
||||
controller.$scope.sampleType.selection = {
|
||||
controller.$.sampleType.selection = {
|
||||
hasCompany: true,
|
||||
code: 'MyReport'
|
||||
};
|
||||
|
@ -144,8 +166,14 @@ describe('Client', () => {
|
|||
companyFk: 442
|
||||
};
|
||||
|
||||
$httpBackend.when('POST', `email/MyReport?clientFk=101&companyFk=442`).respond(true);
|
||||
$httpBackend.expect('POST', `email/MyReport?clientFk=101&companyFk=442`);
|
||||
const params = {
|
||||
clientId: 101,
|
||||
companyId: 442
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true);
|
||||
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`);
|
||||
controller.sendSample();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
|
|
@ -1,36 +1,34 @@
|
|||
vn-client-sample-create {
|
||||
vn-dialog {
|
||||
& > div {
|
||||
padding: 0 !important
|
||||
div.vn-dialog {
|
||||
tpl-body.client-sample-dialog {
|
||||
width: 800px;
|
||||
|
||||
.container, .container h1 {
|
||||
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||
font-size: 1em !important;
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
margin: auto
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0
|
||||
}
|
||||
|
||||
footer p {
|
||||
font-size: 10px !important;
|
||||
line-height: 10px
|
||||
}
|
||||
}
|
||||
|
||||
tpl-body {
|
||||
min-width: 800px;
|
||||
|
||||
.title h1 {
|
||||
font-size: 2em !important;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.container, .container h1 {
|
||||
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||
font-size: 1em !important;
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
margin: auto
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0
|
||||
}
|
||||
|
||||
footer p {
|
||||
font-size: 10px !important;
|
||||
line-height: 10px
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.title h1 {
|
||||
font-size: 2em !important;
|
||||
margin: 0
|
||||
}
|
||||
.loading {
|
||||
text-align: center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,24 @@ export default class Controller {
|
|||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['userFk'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id'],
|
||||
include: {
|
||||
relation: 'emailUser',
|
||||
scope: {
|
||||
fields: ['email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($, $http, vnApp, $translate, aclService) {
|
||||
constructor($, $http, vnApp, $translate, aclService, $httpParamSerializer) {
|
||||
this.$http = $http;
|
||||
this.vnApp = vnApp;
|
||||
this.$translate = $translate;
|
||||
this.$ = $;
|
||||
this.aclService = aclService;
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
this.moreOptions = [
|
||||
{callback: this.showRouteReport, name: 'Show route report'},
|
||||
{callback: this.sendRouteReport, name: 'Send route report'},
|
||||
|
@ -36,13 +37,26 @@ class Controller {
|
|||
}
|
||||
|
||||
showRouteReport() {
|
||||
let url = `report/rpt-route?routeFk=${this.route.id}`;
|
||||
const user = this.route.worker.user;
|
||||
const params = {
|
||||
clientId: user.id,
|
||||
routeId: this.route.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/driver-route?${serializedParams}`;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
sendRouteReport() {
|
||||
let url = `email/driver-route?routeFk=${this.route.id}`;
|
||||
this.$http.post(url).then(() => {
|
||||
const user = this.route.worker.user;
|
||||
const params = {
|
||||
recipient: user.emailUser.email,
|
||||
clientId: user.id,
|
||||
routeId: this.route.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
const url = `email/driver-route?${serializedParams}`;
|
||||
this.$http.get(url).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Report sent'));
|
||||
});
|
||||
}
|
||||
|
@ -62,7 +76,7 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate', 'aclService'];
|
||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate', 'aclService', '$httpParamSerializer'];
|
||||
|
||||
ngModule.component('vnRouteDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -15,7 +15,15 @@ class Controller {
|
|||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked', 'credit'],
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked',
|
||||
'credit',
|
||||
'email'
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
|
||||
<vn-confirm
|
||||
vn-id="confirm-delivery-note"
|
||||
on-response="$ctrl.sendDeliveryNote($response)"
|
||||
on-accept="$ctrl.sendDeliveryNote()"
|
||||
question="Send Delivery Note"
|
||||
message="Are you sure you want to send it?">
|
||||
</vn-confirm>
|
|
@ -2,9 +2,10 @@ import ngModule from '../module';
|
|||
import Component from 'core/lib/component';
|
||||
|
||||
class Controller extends Component {
|
||||
constructor($element, $, aclService) {
|
||||
constructor($element, $, aclService, $httpParamSerializer) {
|
||||
super($element, $);
|
||||
this.aclService = aclService;
|
||||
this.$httpParamSerializer = $httpParamSerializer;
|
||||
this.moreOptions = [
|
||||
{name: 'Add turn', callback: this.showAddTurnDialog},
|
||||
{name: 'Show Delivery Note', callback: this.showDeliveryNote},
|
||||
|
@ -198,10 +199,27 @@ class Controller extends Component {
|
|||
}
|
||||
|
||||
showDeliveryNote() {
|
||||
let url = `report/rpt-delivery-note?ticketFk=${this.ticket.id}`;
|
||||
const params = {
|
||||
clientId: this.ticket.client.id,
|
||||
ticketId: this.ticket.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
let url = `api/report/delivery-note?${serializedParams}`;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
sendDeliveryNote() {
|
||||
const params = {
|
||||
recipient: this.ticket.client.email,
|
||||
clientId: this.ticket.client.id,
|
||||
ticketId: this.ticket.id
|
||||
};
|
||||
const serializedParams = this.$httpParamSerializer(params);
|
||||
this.$http.get(`email/delivery-note?${serializedParams}`).then(
|
||||
() => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
|
||||
);
|
||||
}
|
||||
|
||||
showSMSDialog() {
|
||||
const address = this.ticket.address;
|
||||
this.newSMS = {
|
||||
|
@ -272,17 +290,9 @@ class Controller extends Component {
|
|||
confirmDeliveryNote() {
|
||||
this.$.confirmDeliveryNote.show();
|
||||
}
|
||||
|
||||
sendDeliveryNote(response) {
|
||||
if (response === 'accept') {
|
||||
this.$http.post(`email/delivery-note`, {ticketFk: this.ticket.id}).then(
|
||||
() => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', 'aclService'];
|
||||
Controller.$inject = ['$element', '$scope', 'aclService', '$httpParamSerializer'];
|
||||
|
||||
ngModule.component('vnTicketDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Ticket Component vnTicketDescriptor', () => {
|
||||
let $httpParamSerializer;
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
let $state;
|
||||
|
||||
beforeEach(ngModule('ticket'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, $compile, _$state_) => {
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, $compile, _$state_, _$httpParamSerializer_) => {
|
||||
let $element = $compile(`<vn-autocomplete></vn-autocomplete>`)($rootScope);
|
||||
$state = _$state_;
|
||||
$state.getCurrentPath = () => {
|
||||
|
@ -17,8 +18,9 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
];
|
||||
};
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
controller = $componentController('vnTicketDescriptor', {$element});
|
||||
controller._ticket = {id: 2, invoiceOut: {id: 1}};
|
||||
controller._ticket = {id: 2, invoiceOut: {id: 1}, client: {id: 101, email: 'client@email'}};
|
||||
controller.cardReload = ()=> {
|
||||
return true;
|
||||
};
|
||||
|
@ -82,7 +84,12 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
|
||||
describe('showDeliveryNote()', () => {
|
||||
it('should open a new window showing a delivery note PDF document', () => {
|
||||
let expectedPath = 'report/rpt-delivery-note?ticketFk=2';
|
||||
const params = {
|
||||
clientId: controller.ticket.client.id,
|
||||
ticketId: controller.ticket.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
let expectedPath = `api/report/delivery-note?${serializedParams}`;
|
||||
spyOn(window, 'open');
|
||||
controller.showDeliveryNote();
|
||||
|
||||
|
@ -90,6 +97,26 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('sendDeliveryNote()', () => {
|
||||
it('should make a query and call vnApp.showMessage()', () => {
|
||||
spyOn(controller.vnApp, 'showMessage');
|
||||
|
||||
const params = {
|
||||
recipient: 'client@email',
|
||||
clientId: controller.ticket.client.id,
|
||||
ticketId: controller.ticket.id
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(params);
|
||||
|
||||
$httpBackend.when('GET', `email/delivery-note?${serializedParams}`).respond();
|
||||
$httpBackend.expect('GET', `email/delivery-note?${serializedParams}`).respond();
|
||||
controller.sendDeliveryNote();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Notification sent!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeInvoice()', () => {
|
||||
it('should make a query and call $state.reload() method if the response is accept', () => {
|
||||
spyOn(controller.$state, 'reload');
|
||||
|
|
|
@ -13500,7 +13500,7 @@
|
|||
"dependencies": {
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
const express = require('express');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const templatesPath = path.resolve(__dirname, './templates');
|
||||
const componentsPath = path.resolve(__dirname, './core/components');
|
||||
|
||||
module.exports = app => {
|
||||
global.appPath = __dirname;
|
||||
|
||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||
|
||||
// Extended locale intl polyfill
|
||||
const IntlPolyfill = require('intl');
|
||||
Intl.NumberFormat = IntlPolyfill.NumberFormat;
|
||||
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
|
||||
|
||||
// Init database instance
|
||||
require('./core/database').init();
|
||||
// Init SMTP Instance
|
||||
require('./core/smtp').init();
|
||||
//
|
||||
require('./core/mixins');
|
||||
require('./core/filters');
|
||||
require('./core/directives');
|
||||
// Init router
|
||||
require('./core/router')(app);
|
||||
|
||||
/**
|
||||
* Serve component static files
|
||||
*/
|
||||
const componentsDir = fs.readdirSync(componentsPath);
|
||||
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);
|
||||
templatesDir.forEach(directory => {
|
||||
const templateTypeDir = path.join(templatesPath, '/', directory);
|
||||
const templates = fs.readdirSync(templateTypeDir);
|
||||
|
||||
templates.forEach(templateName => {
|
||||
const templateDir = path.join(templatesPath, '/', directory, '/', templateName);
|
||||
const assetsDir = `${templateDir}/assets`;
|
||||
|
||||
app.use(`/api/${templateName}/assets`, express.static(assetsDir));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -1,40 +1,30 @@
|
|||
/**
|
||||
* Email only stylesheet
|
||||
*
|
||||
*/
|
||||
body {
|
||||
background-color: #EEE;
|
||||
color: #555;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.grid {
|
||||
background-color: #EEE
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
min-width: 320px;
|
||||
margin: 0 auto;
|
||||
color: #555
|
||||
}
|
||||
|
||||
.main {
|
||||
background-color: #FFF;
|
||||
padding: 20px
|
||||
}
|
||||
|
||||
.main a {
|
||||
.grid a {
|
||||
color: #8dba25
|
||||
}
|
||||
|
||||
.main h1 {
|
||||
color: #999
|
||||
.grid-block {
|
||||
min-width: 320px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
width: 600px
|
||||
}
|
||||
|
||||
.main h3 {
|
||||
font-size: 16px
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: #95d831;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
padding: 35px 0
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
font-size: 32px;
|
||||
h1 {
|
||||
font-weight: 100;
|
||||
font-size: 1.5em;
|
||||
color: #333;
|
||||
margin: 0
|
||||
}
|
||||
|
|
|
@ -1,10 +1,34 @@
|
|||
.container {
|
||||
/**
|
||||
* CSS layout elements
|
||||
*
|
||||
*/
|
||||
|
||||
.grid {
|
||||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||
font-size: 16px
|
||||
font-size: 16px;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.grid-row {
|
||||
background-color: transparent
|
||||
}
|
||||
|
||||
.grid-block {
|
||||
box-sizing: border-box;
|
||||
min-height: 40px
|
||||
}
|
||||
|
||||
.grid-block.empty {
|
||||
height: 40px
|
||||
}
|
||||
|
||||
.grid-block.white {
|
||||
background-color: #FFF
|
||||
}
|
||||
|
||||
.columns {
|
||||
overflow: hidden
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.columns .size100 {
|
||||
|
@ -18,6 +42,7 @@
|
|||
}
|
||||
|
||||
.columns .size50 {
|
||||
box-sizing: border-box;
|
||||
width: 50%;
|
||||
float: left
|
||||
}
|
||||
|
@ -173,7 +198,7 @@ table {
|
|||
}
|
||||
|
||||
.panel .row-oriented td, .panel .row-oriented th {
|
||||
padding: 10px 0
|
||||
padding: 8px 10px
|
||||
}
|
||||
|
||||
.row-oriented > tbody > tr > td {
|
||||
|
@ -199,8 +224,8 @@ table {
|
|||
margin-left: -1px;
|
||||
margin-right: 1px;
|
||||
margin-top: 10px;
|
||||
padding: 5px 0;
|
||||
color: #999;
|
||||
padding: 5px 0
|
||||
}
|
||||
|
||||
.line .vertical-aligned {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* CSS misc classes
|
||||
*
|
||||
*/
|
||||
.uppercase {
|
||||
text-transform: uppercase
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
/**
|
||||
* Report only stylesheet
|
||||
*
|
||||
*/
|
||||
body {
|
||||
zoom: 0.55
|
||||
zoom: 0.53
|
||||
}
|
||||
|
||||
.title {
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
/**
|
||||
* CSS spacing classes
|
||||
*
|
||||
* vn-[p|m][t|r|b|l|a|x|y]-[none|auto|xs|sm|md|lg|xl]
|
||||
* T D S
|
||||
*
|
||||
* T - type
|
||||
* - values: p (padding), m (margin)
|
||||
*
|
||||
* D - direction
|
||||
* - values:
|
||||
* t (top), r (right), b (bottom), l (left),
|
||||
* a (all), x (both left & right), y (both top & bottom)
|
||||
*
|
||||
* S - size
|
||||
* - values:
|
||||
* none,
|
||||
* auto (ONLY for specific margins: vn-ml-*, vn-mr-*, vn-mx-*),
|
||||
* xs (extra small),
|
||||
* sm (small),
|
||||
* md (medium),
|
||||
* lg (large),
|
||||
* xl (extra large)
|
||||
*/
|
||||
|
||||
/* ++++++++++++++++++++++++++++++++++++++++++++++++ Padding */
|
||||
|
||||
.vn-pa-none {
|
||||
padding: 0;
|
||||
}
|
||||
.vn-pl-none {
|
||||
padding-left: 0;
|
||||
}
|
||||
.vn-pr-none {
|
||||
padding-right: 0;
|
||||
}
|
||||
.vn-pt-none {
|
||||
padding-top: 0;
|
||||
}
|
||||
.vn-pb-none {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.vn-py-none {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.vn-px-none {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.vn-pa-xs {
|
||||
padding: 4px;
|
||||
}
|
||||
.vn-pl-xs {
|
||||
padding-left: 4px;
|
||||
}
|
||||
.vn-pr-xs {
|
||||
padding-right: 4px;
|
||||
}
|
||||
.vn-pt-xs {
|
||||
padding-top: 4px;
|
||||
}
|
||||
.vn-pb-xs {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.vn-py-xs {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.vn-px-xs {
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
/* Small */
|
||||
|
||||
.vn-pa-sm {
|
||||
padding: 8px;
|
||||
}
|
||||
.vn-pl-sm {
|
||||
padding-left: 8px;
|
||||
}
|
||||
.vn-pr-sm {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.vn-pt-sm {
|
||||
padding-top: 8px;
|
||||
}
|
||||
.vn-pb-sm {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.vn-py-sm {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.vn-px-sm {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
/* Medium */
|
||||
|
||||
.vn-pa-md {
|
||||
padding: 16px;
|
||||
}
|
||||
.vn-pl-md {
|
||||
padding-left: 16px;
|
||||
}
|
||||
.vn-pr-md {
|
||||
padding-right: 16px;
|
||||
}
|
||||
.vn-pt-md {
|
||||
padding-top: 16px;
|
||||
}
|
||||
.vn-pb-md {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.vn-py-md {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.vn-px-md {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
/* Large */
|
||||
|
||||
.vn-pa-lg {
|
||||
padding: 32px;
|
||||
}
|
||||
.vn-pl-lg {
|
||||
padding-left: 32px;
|
||||
}
|
||||
.vn-pr-lg {
|
||||
padding-right: 32px;
|
||||
}
|
||||
.vn-pt-lg {
|
||||
padding-top: 32px;
|
||||
}
|
||||
.vn-pb-lg {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
.vn-py-lg {
|
||||
padding-top: 32px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
.vn-px-lg {
|
||||
padding-left: 32px;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
/* Extra large */
|
||||
|
||||
.vn-pa-xl {
|
||||
padding: 100px;
|
||||
}
|
||||
.vn-pl-xl {
|
||||
padding-left: 100px;
|
||||
}
|
||||
.vn-pr-xl {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.vn-pt-xl {
|
||||
padding-top: 100px;
|
||||
}
|
||||
.vn-pb-xl {
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.vn-py-xl {
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.vn-px-xl {
|
||||
padding-left: 100px;
|
||||
padding-right: 100px;
|
||||
}
|
||||
|
||||
/* ++++++++++++++++++++++++++++++++++++++++++++++++ Margin */
|
||||
|
||||
/* None */
|
||||
|
||||
.vn-ma-none {
|
||||
padding: 0;
|
||||
}
|
||||
.vn-ml-none {
|
||||
padding-left: 0;
|
||||
}
|
||||
.vn-mr-none {
|
||||
padding-right: 0;
|
||||
}
|
||||
.vn-mt-none {
|
||||
padding-top: 0;
|
||||
}
|
||||
.vn-mb-none {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.vn-my-none {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.vn-mx-none {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Auto */
|
||||
|
||||
.vn-ml-none {
|
||||
padding-left: auto;
|
||||
}
|
||||
.vn-mr-none {
|
||||
padding-right: auto;
|
||||
}
|
||||
.vn-mx-none {
|
||||
padding-left: auto;
|
||||
padding-right: auto;
|
||||
}
|
||||
|
||||
/* Extra small */
|
||||
|
||||
.vn-ma-xs {
|
||||
margin: 4px;
|
||||
}
|
||||
.vn-mt-xs {
|
||||
margin-top: 4px;
|
||||
}
|
||||
.vn-ml-xs {
|
||||
margin-left: 4px;
|
||||
}
|
||||
.vn-mr-xs {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.vn-mb-xs {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.vn-my-xs {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.vn-mx-xs {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* Small */
|
||||
|
||||
.vn-ma-sm {
|
||||
margin: 8px;
|
||||
}
|
||||
.vn-mt-sm {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.vn-ml-sm {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.vn-mr-sm {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.vn-mb-sm {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.vn-my-sm {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.vn-mx-sm {
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* Medium */
|
||||
|
||||
.vn-ma-md {
|
||||
margin: 16px;
|
||||
}
|
||||
.vn-mt-md {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.vn-ml-md {
|
||||
margin-left: 16px;
|
||||
}
|
||||
.vn-mr-md {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.vn-mb-md {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.vn-my-md {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.vn-mx-md {
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
/* Large */
|
||||
|
||||
.vn-ma-lg {
|
||||
margin: 32px;
|
||||
}
|
||||
.vn-mt-lg {
|
||||
margin-top: 32px;
|
||||
}
|
||||
.vn-ml-lg {
|
||||
margin-left: 32px;
|
||||
}
|
||||
.vn-mr-lg {
|
||||
margin-right: 32px;
|
||||
}
|
||||
.vn-mb-lg {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.vn-my-lg {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.vn-mx-lg {
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
/* Extra large */
|
||||
|
||||
.vn-ma-xl {
|
||||
margin: 100px;
|
||||
}
|
||||
.vn-mt-xl {
|
||||
margin-top: 100px;
|
||||
}
|
||||
.vn-ml-xl {
|
||||
margin-left: 100px;
|
||||
}
|
||||
.vn-mr-xl {
|
||||
margin-right: 100px;
|
||||
}
|
||||
.vn-mb-xl {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
.vn-my-xl {
|
||||
margin-top: 100px;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
.vn-mx-xl {
|
||||
margin-left: 100px;
|
||||
margin-right: 100px;
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
{
|
||||
"app": {
|
||||
"host": "http://localhost:5000",
|
||||
"port": 3000,
|
||||
"defaultLanguage": "es",
|
||||
"senderMail": "nocontestar@verdnatura.es",
|
||||
"senderName": "Verdnatura"
|
||||
},
|
||||
"i18n": {
|
||||
"locale": "es",
|
||||
"fallbackLocale": "es",
|
||||
"silentTranslationWarn": true
|
||||
},
|
||||
"pdf": {
|
||||
"format": "A4",
|
||||
"border": "1.5cm",
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
[
|
||||
{"type": "email", "name": "client-welcome"},
|
||||
{"type": "email", "name": "printer-setup"},
|
||||
{"type": "email", "name": "payment-update"},
|
||||
{"type": "email", "name": "letter-debtor-st"},
|
||||
{"type": "email", "name": "letter-debtor-nd"},
|
||||
{"type": "email", "name": "claim-pickup-order"},
|
||||
{"type": "email", "name": "sepa-core"},
|
||||
{"type": "email", "name": "client-lcr"},
|
||||
{"type": "email", "name": "driver-route"},
|
||||
{"type": "email", "name": "delivery-note"},
|
||||
{"type": "report", "name": "rpt-delivery-note"},
|
||||
{"type": "report", "name": "rpt-claim-pickup-order"},
|
||||
{"type": "report", "name": "rpt-letter-debtor"},
|
||||
{"type": "report", "name": "rpt-sepa-core"},
|
||||
{"type": "report", "name": "rpt-receipt"},
|
||||
{"type": "report", "name": "rpt-zone"},
|
||||
{"type": "report", "name": "rpt-route"},
|
||||
{"type": "report", "name": "rpt-lcr"},
|
||||
{"type": "report", "name": "rpt-item-label"},
|
||||
{"type": "static", "name": "email-header"},
|
||||
{"type": "static", "name": "email-footer"},
|
||||
{"type": "static", "name": "report-header"},
|
||||
{"type": "static", "name": "report-footer"}
|
||||
]
|
|
@ -0,0 +1,104 @@
|
|||
const Vue = require('vue');
|
||||
const VueI18n = require('vue-i18n');
|
||||
const renderer = require('vue-server-renderer').createRenderer();
|
||||
Vue.use(VueI18n);
|
||||
|
||||
const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
const juice = require('juice');
|
||||
const path = require('path');
|
||||
const config = require('./config');
|
||||
|
||||
class Component {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `./components/${this.name}`;
|
||||
}
|
||||
|
||||
get template() {
|
||||
const templatePath = `${this.path}/${this.name}.html`;
|
||||
const fullPath = path.resolve(__dirname, templatePath);
|
||||
|
||||
return fs.readFileSync(fullPath, 'utf8');
|
||||
}
|
||||
|
||||
get locale() {
|
||||
if (!this._locale)
|
||||
this.getLocale();
|
||||
|
||||
return this._locale;
|
||||
}
|
||||
|
||||
getLocale() {
|
||||
const mergedLocale = {messages: {}};
|
||||
const localePath = path.resolve(__dirname, `${this.path}/locale`);
|
||||
|
||||
if (!fs.existsSync(localePath))
|
||||
return mergedLocale;
|
||||
|
||||
const localeDir = fs.readdirSync(localePath);
|
||||
localeDir.forEach(locale => {
|
||||
const fullPath = path.join(localePath, '/', locale);
|
||||
const yamlLocale = fs.readFileSync(fullPath, 'utf8');
|
||||
const jsonLocale = yaml.safeLoad(yamlLocale);
|
||||
const localeName = locale.replace('.yml', '');
|
||||
|
||||
mergedLocale.messages[localeName] = jsonLocale;
|
||||
});
|
||||
|
||||
this._locale = mergedLocale;
|
||||
}
|
||||
|
||||
get stylesheet() {
|
||||
let mergedStyles = '';
|
||||
const stylePath = path.resolve(__dirname, `${this.path}/assets/css`);
|
||||
|
||||
if (!fs.existsSync(stylePath))
|
||||
return mergedStyles;
|
||||
|
||||
return require(`${stylePath}/import`);
|
||||
}
|
||||
|
||||
get attachments() {
|
||||
const attachmentsPath = `${this.path}/attachments.json`;
|
||||
const fullPath = path.resolve(__dirname, attachmentsPath);
|
||||
|
||||
if (!fs.existsSync(fullPath))
|
||||
return [];
|
||||
|
||||
return require(fullPath);
|
||||
}
|
||||
|
||||
build() {
|
||||
const fullPath = path.resolve(__dirname, this.path);
|
||||
if (!fs.existsSync(fullPath))
|
||||
throw new Error(`Sample "${this.name}" not found`);
|
||||
|
||||
const component = require(`${this.path}/${this.name}`);
|
||||
component.i18n = this.locale;
|
||||
component.attachments = this.attachments;
|
||||
component.template = juice.inlineContent(this.template, this.stylesheet, {
|
||||
inlinePseudoElements: true
|
||||
});
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
async render() {
|
||||
const component = this.build();
|
||||
const i18n = new VueI18n(config.i18n);
|
||||
const app = new Vue({
|
||||
i18n: i18n,
|
||||
render: h => h(component, {
|
||||
props: this.args
|
||||
})
|
||||
});
|
||||
|
||||
return renderer.renderToString(app);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Component;
|
|
@ -0,0 +1,9 @@
|
|||
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||
|
||||
module.exports = new Stylesheet([
|
||||
`${appPath}/common/css/spacing.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/email.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
|
@ -0,0 +1,22 @@
|
|||
div {
|
||||
display: inline-block;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: #F5F5F5;
|
||||
border: 1px solid #CCC;
|
||||
display: flex;
|
||||
vertical-align: middle;
|
||||
box-sizing: border-box;
|
||||
min-width: 150px;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
color: #8dba25
|
||||
}
|
||||
|
||||
a > div.icon {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
color: #555
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg>
|
After Width: | Height: | Size: 371 B |
|
@ -0,0 +1,6 @@
|
|||
<div class="vn-mx-xs" v-if="attachment.component">
|
||||
<a target="_blank" class="vn-py-sm vn-px-md" v-bind:href="path">
|
||||
<div class="text">{{attachment.filename}}</div>
|
||||
<div class="icon vn-pl-md">▼</div>
|
||||
</a>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
module.exports = {
|
||||
name: 'attachment',
|
||||
computed: {
|
||||
path() {
|
||||
const filename = this.attachment.filename;
|
||||
const component = this.attachment.component;
|
||||
if (this.attachment.cid)
|
||||
return `/api/${component}/assets/files/${filename}`;
|
||||
else
|
||||
return `/api/report/${component}?${this.getHttpParams()}`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getHttpParams() {
|
||||
const props = this.args;
|
||||
let query = '';
|
||||
for (let param in props) {
|
||||
if (query != '')
|
||||
query += '&';
|
||||
query += `${param}=${props[param]}`;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
attachment: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
args: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||
|
||||
module.exports = new Stylesheet([
|
||||
`${appPath}/common/css/spacing.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/email.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
|
@ -1,21 +1,11 @@
|
|||
@media (max-width: 400px) {
|
||||
.buttons a {
|
||||
display: block;
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.buttons a {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
width: 50%
|
||||
}
|
||||
|
||||
.buttons .btn {
|
||||
|
@ -23,18 +13,20 @@
|
|||
text-align: center
|
||||
}
|
||||
|
||||
.buttons .btn .text {
|
||||
display: inline-block;
|
||||
padding: 22px 0
|
||||
}
|
||||
|
||||
.buttons .btn .icon {
|
||||
background-color: #95d831;
|
||||
box-sizing: border-box;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 16.5px 0;
|
||||
float: right;
|
||||
width: 70px
|
||||
color: #333;
|
||||
float: left
|
||||
}
|
||||
|
||||
|
||||
.buttons .btn .text {
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.networks {
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{
|
||||
"filename": "facebook.png",
|
||||
"path": "/assets/images/facebook.png",
|
||||
"cid": "facebook.png"
|
||||
},
|
||||
{
|
||||
"filename": "twitter.png",
|
||||
"path": "/assets/images/twitter.png",
|
||||
"cid": "twitter.png"
|
||||
},
|
||||
{
|
||||
"filename": "youtube.png",
|
||||
"path": "/assets/images/youtube.png",
|
||||
"cid": "youtube.png"
|
||||
},
|
||||
{
|
||||
"filename": "pinterest.png",
|
||||
"path": "/assets/images/pinterest.png",
|
||||
"cid": "pinterest.png"
|
||||
},
|
||||
{
|
||||
"filename": "instagram.png",
|
||||
"path": "/assets/images/instagram.png",
|
||||
"cid": "instagram.png"
|
||||
},
|
||||
{
|
||||
"filename": "linkedin.png",
|
||||
"path": "/assets/images/linkedin.png",
|
||||
"cid": "linkedin.png"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,53 @@
|
|||
<footer>
|
||||
<!-- Action button block -->
|
||||
<div class="buttons">
|
||||
<div class="columns">
|
||||
<div class="size50">
|
||||
<a href="https://www.verdnatura.es" target="_blank">
|
||||
<div class="btn">
|
||||
<!-- <span class="icon vn-pa-sm"><img v-bind:src="getEmailSrc('action.png')"/></span> -->
|
||||
<span class="text vn-pa-sm">{{ $t('buttons.webAcccess')}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="size50">
|
||||
<a href="https://goo.gl/forms/j8WSL151ZW6QtlT72" target="_blank">
|
||||
<div class="btn">
|
||||
<!-- <span class="icon vn-pa-sm"><img v-bind:src="getEmailSrc('info.png')"/></span> -->
|
||||
<span class="text vn-pa-sm">{{ $t('buttons.info')}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Networks block -->
|
||||
<div class="networks">
|
||||
<a href="https://www.facebook.com/Verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('facebook.png')" alt="Facebook"/>
|
||||
</a>
|
||||
<a href="https://www.twitter.com/Verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('twitter.png')" alt="Twitter"/>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/Verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('youtube.png')" alt="Youtube"/>
|
||||
</a>
|
||||
<a href="https://www.pinterest.com/Verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('pinterest.png')" alt="Pinterest"/>
|
||||
</a>
|
||||
<a href="https://www.instagram.com/Verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('instagram.png')" alt="Instagram"/>
|
||||
</a>
|
||||
<a href="https://www.linkedin.com/company/verdnatura" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('linkedin.png')" alt="Linkedin"/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Privacy block -->
|
||||
<div class="privacy">
|
||||
<p>{{$t('privacy.fiscalAddress')}}</p>
|
||||
<p>{{$t('privacy.disclaimer')}}</p>
|
||||
<p>{{$t('privacy.law')}}</p>
|
||||
</div>
|
||||
<!-- Privacy block end -->
|
||||
</footer>
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
name: 'email-footer',
|
||||
props: ['isPreview', 'locale']
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
buttons:
|
||||
webAcccess: Visita nuestra Web
|
||||
info: Ayúdanos a mejorar
|
||||
privacy:
|
||||
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla
|
||||
· www.verdnatura.es · clientes@verdnatura.es
|
||||
disclaimer: '- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado
|
||||
exclusivamente por la persona destinataria del mismo. Si has recibido este mensaje
|
||||
por error, te rogamos lo comuniques al remitente y borres 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.'
|
||||
law: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de
|
||||
Datos de Carácter Personal, te comunicamos que los datos personales que facilites
|
||||
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.
|
|
@ -0,0 +1,19 @@
|
|||
buttons:
|
||||
webAcccess: Visitez notre site web
|
||||
info: Aidez-nous à améliorer
|
||||
privacy:
|
||||
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla
|
||||
· www.verdnatura.es · clientes@verdnatura.es
|
||||
disclaimer: '- AVIS - Ce message est privé et confidentiel et doit être utilisé.exclusivamente
|
||||
por la persona destinataria del mismo. Si has recibido este mensajepor error,
|
||||
te rogamos lo comuniques al remitente y borres dicho mensaje y cualquier documentoadjunto
|
||||
que pudiera contener. Verdnatura Levante SL no renuncia a la confidencialidad
|
||||
ni aningún privilegio por causa de transmisión errónea o mal funcionamiento. Igualmente
|
||||
no se haceresponsable de los cambios, alteraciones, errores u omisiones que pudieran
|
||||
hacerse al mensaje una vez enviado.'
|
||||
law: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección de
|
||||
Datos de Carácter Personal, te comunicamos que los datos personales que facilites
|
||||
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 porescrito al domicilio social de la entidad. La finalidad del fichero
|
||||
es la gestión administrativa, contabilidad, y facturación.
|
|
@ -0,0 +1,9 @@
|
|||
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||
|
||||
module.exports = new Stylesheet([
|
||||
`${appPath}/common/css/spacing.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/email.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
|
@ -0,0 +1,19 @@
|
|||
header .logo {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
header .logo img {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
header .topbar {
|
||||
background-color: #95d831;
|
||||
height: 25px
|
||||
}
|
||||
|
||||
.topbar:after {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
content: ' ';
|
||||
clear: both;
|
||||
}
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="500"
|
||||
height="68.596313"
|
||||
viewBox="0 0 499.99999 68.596313"
|
||||
enable-background="new 0 0 226.229 31.038"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="verdnatura-white.svg"><metadata
|
||||
id="metadata61"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs59" /><sodipodi:namedview
|
||||
pagecolor="#333333"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1013"
|
||||
id="namedview57"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5909426"
|
||||
inkscape:cx="268.25598"
|
||||
inkscape:cy="112.75218"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" /><g
|
||||
id="Background"
|
||||
transform="translate(2.2478643e-6,43.261169)" /><g
|
||||
id="Guides"
|
||||
transform="translate(2.2478643e-6,43.261169)" /><g
|
||||
id="g883"
|
||||
transform="matrix(2.2101465,0,0,2.2101465,0,-594.44542)"><g
|
||||
transform="translate(0,268.962)"
|
||||
style="fill:#ffffff"
|
||||
id="g9"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path11"
|
||||
d="M 10.417,30.321 0,0 h 8.233 l 4.26,15.582 0.349,1.276 c 0.521,1.866 0.918,3.431 1.191,4.693 0.15,-0.618 0.335,-1.345 0.555,-2.182 0.219,-0.837 0.528,-1.935 0.925,-3.293 L 19.981,0 h 8.19 l -10.5,30.321 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g13"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#8ed300;fill-opacity:1;fill-rule:evenodd"
|
||||
id="path15"
|
||||
d="m 139.809,19.787 c -0.665,0.357 -1.748,0.686 -3.25,0.988 -0.727,0.137 -1.283,0.254 -1.667,0.35 -0.95,0.247 -1.661,0.563 -2.134,0.947 -0.472,0.384 -0.799,0.899 -0.979,1.544 -0.223,0.796 -0.155,1.438 0.204,1.925 0.359,0.488 0.945,0.731 1.757,0.731 1.252,0 2.375,-0.36 3.369,-1.081 0.994,-0.721 1.653,-1.665 1.98,-2.831 z m 5.106,10.534 h -7.458 c 0.017,-0.356 0.048,-0.726 0.094,-1.11 l 0.159,-1.192 c -1.318,1.026 -2.627,1.786 -3.927,2.279 -1.299,0.493 -2.643,0.739 -4.031,0.739 -2.158,0 -3.7,-0.593 -4.625,-1.779 -0.925,-1.187 -1.106,-2.788 -0.542,-4.804 0.519,-1.851 1.431,-3.356 2.737,-4.515 1.307,-1.159 3.021,-1.972 5.142,-2.438 1.169,-0.247 2.641,-0.515 4.413,-0.803 2.646,-0.412 4.082,-1.016 4.304,-1.812 l 0.151,-0.539 c 0.182,-0.65 0.076,-1.145 -0.317,-1.483 -0.393,-0.339 -1.071,-0.508 -2.033,-0.508 -1.045,0 -1.934,0.214 -2.666,0.643 -0.731,0.428 -1.289,1.058 -1.673,1.887 h -6.748 c 1.065,-2.53 2.64,-4.413 4.723,-5.65 2.083,-1.237 4.724,-1.856 7.923,-1.856 1.991,0 3.602,0.241 4.833,0.722 1.231,0.481 2.095,1.209 2.59,2.185 0.339,0.701 0.483,1.536 0.432,2.504 -0.052,0.969 -0.377,2.525 -0.978,4.669 l -2.375,8.483 c -0.284,1.014 -0.416,1.812 -0.396,2.395 0.02,0.583 0.188,0.962 0.503,1.141 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g17"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#8ed300;fill-opacity:1;fill-rule:evenodd"
|
||||
id="path19"
|
||||
d="m 185.7,30.321 6.27,-22.393 h 7.049 l -1.097,3.918 c 1.213,-1.537 2.502,-2.659 3.867,-3.366 1.365,-0.707 2.951,-1.074 4.758,-1.101 l -2.03,7.25 c -0.304,-0.042 -0.608,-0.072 -0.912,-0.093 -0.303,-0.02 -0.592,-0.03 -0.867,-0.03 -1.126,0 -2.104,0.168 -2.932,0.504 -0.829,0.336 -1.561,0.854 -2.197,1.555 -0.406,0.467 -0.789,1.136 -1.149,2.007 -0.361,0.872 -0.814,2.282 -1.359,4.232 l -2.104,7.516 H 185.7 Z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g21"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#8ed300;fill-opacity:1;fill-rule:evenodd"
|
||||
id="path23"
|
||||
d="m 217.631,19.787 c -0.664,0.357 -1.748,0.686 -3.25,0.988 -0.727,0.137 -1.282,0.254 -1.667,0.35 -0.95,0.247 -1.661,0.563 -2.134,0.947 -0.472,0.384 -0.799,0.899 -0.979,1.544 -0.223,0.796 -0.155,1.438 0.205,1.925 0.359,0.488 0.945,0.731 1.757,0.731 1.252,0 2.375,-0.36 3.369,-1.081 0.994,-0.721 1.654,-1.665 1.98,-2.831 z m 5.106,10.534 h -7.458 c 0.017,-0.356 0.048,-0.726 0.094,-1.11 l 0.159,-1.192 c -1.318,1.026 -2.627,1.786 -3.927,2.279 -1.299,0.493 -2.643,0.739 -4.031,0.739 -2.158,0 -3.7,-0.593 -4.625,-1.779 -0.926,-1.187 -1.106,-2.788 -0.542,-4.804 0.519,-1.851 1.431,-3.356 2.737,-4.515 1.306,-1.159 3.02,-1.972 5.142,-2.438 1.169,-0.247 2.641,-0.515 4.413,-0.803 2.647,-0.412 4.082,-1.016 4.304,-1.812 l 0.151,-0.539 c 0.182,-0.65 0.077,-1.145 -0.317,-1.483 -0.393,-0.339 -1.071,-0.508 -2.033,-0.508 -1.045,0 -1.934,0.214 -2.666,0.643 -0.731,0.428 -1.289,1.058 -1.672,1.887 h -6.748 c 1.065,-2.53 2.64,-4.413 4.723,-5.65 2.083,-1.237 4.724,-1.856 7.923,-1.856 1.99,0 3.601,0.241 4.833,0.722 1.232,0.481 2.095,1.209 2.591,2.185 0.339,0.701 0.483,1.536 0.431,2.504 -0.051,0.969 -0.377,2.525 -0.978,4.669 l -2.375,8.483 c -0.284,1.014 -0.416,1.812 -0.396,2.395 0.02,0.583 0.188,0.962 0.503,1.141 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g25"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#8ed300;fill-opacity:1;fill-rule:evenodd"
|
||||
id="path27"
|
||||
d="m 188.386,7.928 -6.269,22.393 h -7.174 l 0.864,-3.085 c -1.227,1.246 -2.476,2.163 -3.746,2.751 -1.27,0.588 -2.625,0.882 -4.067,0.882 -2.471,0 -4.154,-0.634 -5.048,-1.901 -0.895,-1.268 -0.993,-3.149 -0.294,-5.644 l 4.31,-15.396 h 7.338 l -3.508,12.53 c -0.516,1.842 -0.641,3.109 -0.375,3.803 0.266,0.694 0.967,1.041 2.105,1.041 1.275,0 2.323,-0.422 3.142,-1.267 0.819,-0.845 1.497,-2.223 2.031,-4.133 l 3.353,-11.974 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g29"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#8ed300;fill-opacity:1;fill-rule:evenodd"
|
||||
id="path31"
|
||||
d="m 149.937,12.356 1.239,-4.428 h 2.995 l 1.771,-6.326 h 7.338 l -1.771,6.326 h 3.753 l -1.24,4.428 h -3.753 l -2.716,9.702 c -0.416,1.483 -0.498,2.465 -0.247,2.946 0.25,0.48 0.905,0.721 1.964,0.721 l 0.549,-0.011 0.39,-0.031 -1.31,4.678 c -0.811,0.148 -1.596,0.263 -2.354,0.344 -0.758,0.081 -1.48,0.122 -2.167,0.122 -2.543,0 -4.108,-0.621 -4.695,-1.863 -0.587,-1.242 -0.313,-3.887 0.82,-7.936 l 2.428,-8.672 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
style="fill:#ffffff"
|
||||
id="g33"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path35"
|
||||
d="m 73.875,18.896 c -0.561,2.004 -0.616,3.537 -0.167,4.601 0.449,1.064 1.375,1.595 2.774,1.595 1.399,0 2.605,-0.524 3.62,-1.574 1.015,-1.05 1.806,-2.59 2.375,-4.622 0.526,-1.879 0.556,-3.334 0.09,-4.363 -0.466,-1.029 -1.393,-1.543 -2.778,-1.543 -1.304,0 -2.487,0.528 -3.551,1.585 -1.064,1.057 -1.852,2.496 -2.363,4.321 z M 96.513,0 88.024,30.321 h -7.337 l 0.824,-2.944 c -1.166,1.22 -2.369,2.121 -3.61,2.703 -1.241,0.582 -2.583,0.874 -4.025,0.874 -2.802,0 -4.772,-1.081 -5.912,-3.243 -1.139,-2.162 -1.218,-4.993 -0.238,-8.493 0.988,-3.528 2.668,-6.404 5.042,-8.627 2.374,-2.224 4.927,-3.336 7.661,-3.336 1.47,0 2.695,0.296 3.676,0.887 0.981,0.591 1.681,1.465 2.099,2.62 L 89.217,0 Z" /><g
|
||||
style="fill:#ffffff"
|
||||
id="g37"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path39"
|
||||
d="m 73.875,18.896 c -0.561,2.004 -0.616,3.537 -0.167,4.601 0.449,1.064 1.375,1.595 2.774,1.595 1.399,0 2.605,-0.524 3.62,-1.574 1.015,-1.05 1.806,-2.59 2.375,-4.622 0.526,-1.879 0.556,-3.334 0.09,-4.363 -0.466,-1.029 -1.393,-1.543 -2.778,-1.543 -1.304,0 -2.487,0.528 -3.551,1.585 -1.064,1.057 -1.852,2.496 -2.363,4.321 z M 96.513,0 88.024,30.321 h -7.337 l 0.824,-2.944 c -1.166,1.22 -2.369,2.121 -3.61,2.703 -1.241,0.582 -2.583,0.874 -4.025,0.874 -2.802,0 -4.772,-1.081 -5.912,-3.243 -1.139,-2.162 -1.218,-4.993 -0.238,-8.493 0.988,-3.528 2.668,-6.404 5.042,-8.627 2.374,-2.224 4.927,-3.336 7.661,-3.336 1.47,0 2.695,0.296 3.676,0.887 0.981,0.591 1.681,1.465 2.099,2.62 L 89.217,0 Z" /></g></g><g
|
||||
transform="translate(0,268.962)"
|
||||
style="fill:#ffffff"
|
||||
id="g41"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path43"
|
||||
d="M 46.488,30.321 52.757,7.928 h 7.049 l -1.098,3.918 C 59.921,10.309 61.21,9.187 62.576,8.48 63.942,7.773 68.591,7.406 70.398,7.379 l -2.03,7.25 c -0.304,-0.042 -0.608,-0.072 -0.911,-0.093 -0.304,-0.02 -0.592,-0.03 -0.867,-0.03 -1.126,0 -5.167,0.168 -5.997,0.504 -0.829,0.336 -1.561,0.854 -2.196,1.555 -0.406,0.467 -0.789,1.136 -1.149,2.007 -0.361,0.872 -0.814,2.282 -1.36,4.232 l -2.104,7.516 h -7.296 z" /></g><g
|
||||
transform="translate(0,268.962)"
|
||||
style="fill:#ffffff"
|
||||
id="g45"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path47"
|
||||
d="m 32.673,16.742 8.351,-0.021 c 0.375,-1.436 0.308,-2.558 -0.201,-3.365 -0.509,-0.807 -1.402,-1.211 -2.68,-1.211 -1.209,0 -2.285,0.397 -3.229,1.19 -0.944,0.793 -1.69,1.93 -2.241,3.407 z m 6.144,6.536 h 7.043 c -1.347,2.456 -3.172,4.356 -5.477,5.7 -2.305,1.345 -4.885,2.017 -7.74,2.017 -3.473,0 -5.923,-1.054 -7.351,-3.161 -1.427,-2.107 -1.632,-4.98 -0.613,-8.618 1.038,-3.707 2.875,-6.641 5.512,-8.803 2.637,-2.163 5.678,-3.244 9.123,-3.244 3.555,0 6.04,1.099 7.456,3.298 1.417,2.198 1.582,5.234 0.498,9.109 l -0.239,0.814 -0.167,0.484 H 31.721 c -0.441,1.575 -0.438,2.777 0.01,3.606 0.448,0.829 1.332,1.244 2.65,1.244 0.975,0 1.836,-0.206 2.583,-0.617 0.747,-0.411 1.366,-1.021 1.853,-1.829 z" /><g
|
||||
style="fill:#ffffff"
|
||||
id="g49"><path
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path51"
|
||||
d="m 32.673,16.742 8.351,-0.021 c 0.375,-1.436 0.308,-2.558 -0.201,-3.365 -0.509,-0.807 -1.402,-1.211 -2.68,-1.211 -1.209,0 -2.285,0.397 -3.229,1.19 -0.944,0.793 -1.69,1.93 -2.241,3.407 z m 6.144,6.536 h 7.043 c -1.347,2.456 -3.172,4.356 -5.477,5.7 -2.305,1.345 -4.885,2.017 -7.74,2.017 -3.473,0 -5.923,-1.054 -7.351,-3.161 -1.427,-2.107 -1.632,-4.98 -0.613,-8.618 1.038,-3.707 2.875,-6.641 5.512,-8.803 2.637,-2.163 5.678,-3.244 9.123,-3.244 3.555,0 6.04,1.099 7.456,3.298 1.417,2.198 1.582,5.234 0.498,9.109 l -0.239,0.814 -0.167,0.484 H 31.721 c -0.441,1.575 -0.438,2.777 0.01,3.606 0.448,0.829 1.332,1.244 2.65,1.244 0.975,0 1.836,-0.206 2.583,-0.617 0.747,-0.411 1.366,-1.021 1.853,-1.829 z" /></g></g><g
|
||||
transform="translate(0,268.962)"
|
||||
id="g53"><path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#8ed300;fill-opacity:1"
|
||||
id="path55"
|
||||
d="m 112.881,30.643 -6.404,-18.639 -6.455,18.639 h -7.254 l 9.565,-30.321 h 8.19 l 4.434,15.582 0.35,1.276 c 0.521,1.866 0.917,3.431 1.191,4.693 l 0.555,-2.182 c 0.219,-0.837 0.528,-1.935 0.925,-3.293 l 4.468,-16.076 h 8.19 l -10.501,30.321 z" /></g></g></svg>
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
{
|
||||
"filename": "logo-black.png",
|
||||
"path": "/assets/images/logo-black.png",
|
||||
"cid": "logo-black.png"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
<header>
|
||||
<div class="logo">
|
||||
<a href="https://www.verdnatura.es" target="_blank">
|
||||
<img v-bind:src="getEmailSrc('logo-black.png')" alt="VerdNatura"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="topbar"></div>
|
||||
</header>
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
name: 'email-header',
|
||||
props: ['locale']
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
const CssReader = require(`${appPath}/lib/cssReader`);
|
||||
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||
|
||||
module.exports = new CssReader([
|
||||
module.exports = new Stylesheet([
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/report.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
|
@ -0,0 +1,10 @@
|
|||
numPages: Página {{page}} de {{pages}}
|
||||
law:
|
||||
phytosanitary: 'VERDNATURA LEVANTE SL - Pasaporte Fitosanitario R.P. Generalitat
|
||||
Valenciana - Nº Comerciante: ES17462130'
|
||||
privacy: 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.
|
|
@ -0,0 +1,10 @@
|
|||
numPages: Page {{page}} de {{pages}}
|
||||
law:
|
||||
phytosanitary: 'VERDNATURA LEVANTE SL - Passeport Phytosanitaire R.P. Generalitat
|
||||
Valenciana - Numéro d''opérateur: ES17462130'
|
||||
privacy: Conformément aux dispositions de la loi organique 15/1999 sur la protection
|
||||
des données personnelles, nous vous informons que les données personnelles que
|
||||
vous fournissez seront incluses dans des dossiers. VERDNATURA LEVANTE S.L., vous
|
||||
pouvez à tout moment, exercer les droits d'accès, de rectification, d'annulation
|
||||
et d'opposition, en communiquant par écrit au siège social de la société. Le dossier
|
||||
a pour objet la gestion administrative, la comptabilité et la facturation.
|
|
@ -0,0 +1,10 @@
|
|||
numPages: Página {{page}} de {{pages}}
|
||||
law:
|
||||
phytosanitary: 'VERDNATURA LEVANTE S.L - Passaporte Fitossanitário R.P. Generalitat
|
||||
Valenciana - Nº Comerciante: ES17462130'
|
||||
privacy: Em cumprimento do disposto na lei Orgânica 15/1999, de Protecção de Dados
|
||||
de Carácter Pessoal, comunicamos que os dados pessoais que facilite se incluirão
|
||||
nos ficheiros automatizados de VERDNATURA LEVANTE S.L., podendo em todo momento
|
||||
exercer os direitos de acesso, rectificação, cancelação e oposição, comunicando
|
||||
por escrito ao domicílio social da entidade. A finalidade do ficheiro é a gestão
|
||||
administrativa, contabilidade e facturação.
|
|
@ -1,7 +1,7 @@
|
|||
<footer>
|
||||
<section class="page">
|
||||
<section :if="leftText">{{leftText}}</section>
|
||||
<section :if="centerText" class="uppercase">{{centerText}}</section>
|
||||
<section v-if="leftText">{{leftText}}</section>
|
||||
<section v-if="centerText" class="uppercase">{{centerText}}</section>
|
||||
<section class="number">{{$t('numPages')}}</section>
|
||||
</section>
|
||||
<p class="phytosanitary">{{$t('law.phytosanitary')}}</p>
|
|
@ -1,8 +1,4 @@
|
|||
module.exports = {
|
||||
name: 'report-footer',
|
||||
created() {
|
||||
if (this.locale)
|
||||
this.$i18n.locale = this.locale;
|
||||
},
|
||||
props: ['leftText', 'centerText', 'locale']
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
const CssReader = require(`${appPath}/lib/cssReader`);
|
||||
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||
|
||||
module.exports = new CssReader([
|
||||
module.exports = new Stylesheet([
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/report.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" x="0px" y="0px" width="226.229px" height="31.038px" viewBox="0 0 226.229 31.038" enable-background="new 0 0 226.229 31.038" xml:space="preserve" id="svg2" inkscape:version="0.48.1 r9760" sodipodi:docname="logo.svg"><metadata id="metadata61"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs59"/><sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1366" inkscape:window-height="710" id="namedview57" showgrid="false" inkscape:zoom="4.0755163" inkscape:cx="138.56745" inkscape:cy="16.509992" inkscape:window-x="0" inkscape:window-y="26" inkscape:window-maximized="1" inkscape:current-layer="svg2"/>
|
||||
<g id="Background">
|
||||
</g>
|
||||
<g id="Guides">
|
||||
</g>
|
||||
<g id="Foreground">
|
||||
<g id="g7">
|
||||
<g id="g9">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.417,30.321L0,0h8.233l4.26,15.582l0.349,1.276 c0.521,1.866,0.918,3.431,1.191,4.693c0.15-0.618,0.335-1.345,0.555-2.182c0.219-0.837,0.528-1.935,0.925-3.293L19.981,0h8.19 L17.671,30.321H10.417z" id="path11"/>
|
||||
</g>
|
||||
<g id="g13">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#A0CE67" d="M139.809,19.787c-0.665,0.357-1.748,0.686-3.25,0.988 c-0.727,0.137-1.283,0.254-1.667,0.35c-0.95,0.247-1.661,0.563-2.134,0.947c-0.472,0.384-0.799,0.899-0.979,1.544 c-0.223,0.796-0.155,1.438,0.204,1.925c0.359,0.488,0.945,0.731,1.757,0.731c1.252,0,2.375-0.36,3.369-1.081 c0.994-0.721,1.653-1.665,1.98-2.831L139.809,19.787z M144.915,30.321h-7.458c0.017-0.356,0.048-0.726,0.094-1.11l0.159-1.192 c-1.318,1.026-2.627,1.786-3.927,2.279c-1.299,0.493-2.643,0.739-4.031,0.739c-2.158,0-3.7-0.593-4.625-1.779 c-0.925-1.187-1.106-2.788-0.542-4.804c0.519-1.851,1.431-3.356,2.737-4.515c1.307-1.159,3.021-1.972,5.142-2.438 c1.169-0.247,2.641-0.515,4.413-0.803c2.646-0.412,4.082-1.016,4.304-1.812l0.151-0.539c0.182-0.65,0.076-1.145-0.317-1.483 c-0.393-0.339-1.071-0.508-2.033-0.508c-1.045,0-1.934,0.214-2.666,0.643c-0.731,0.428-1.289,1.058-1.673,1.887h-6.748 c1.065-2.53,2.64-4.413,4.723-5.65s4.724-1.856,7.923-1.856c1.991,0,3.602,0.241,4.833,0.722s2.095,1.209,2.59,2.185 c0.339,0.701,0.483,1.536,0.432,2.504c-0.052,0.969-0.377,2.525-0.978,4.669l-2.375,8.483c-0.284,1.014-0.416,1.812-0.396,2.395 s0.188,0.962,0.503,1.141L144.915,30.321z" id="path15" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
<g id="g17">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#A0CE67" d="M185.7,30.321l6.27-22.393h7.049l-1.097,3.918 c1.213-1.537,2.502-2.659,3.867-3.366c1.365-0.707,2.951-1.074,4.758-1.101l-2.03,7.25c-0.304-0.042-0.608-0.072-0.912-0.093 c-0.303-0.02-0.592-0.03-0.867-0.03c-1.126,0-2.104,0.168-2.932,0.504c-0.829,0.336-1.561,0.854-2.197,1.555 c-0.406,0.467-0.789,1.136-1.149,2.007c-0.361,0.872-0.814,2.282-1.359,4.232l-2.104,7.516H185.7z" id="path19" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
<g id="g21">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#A0CE67" d="M217.631,19.787c-0.664,0.357-1.748,0.686-3.25,0.988 c-0.727,0.137-1.282,0.254-1.667,0.35c-0.95,0.247-1.661,0.563-2.134,0.947c-0.472,0.384-0.799,0.899-0.979,1.544 c-0.223,0.796-0.155,1.438,0.205,1.925c0.359,0.488,0.945,0.731,1.757,0.731c1.252,0,2.375-0.36,3.369-1.081 c0.994-0.721,1.654-1.665,1.98-2.831L217.631,19.787z M222.737,30.321h-7.458c0.017-0.356,0.048-0.726,0.094-1.11l0.159-1.192 c-1.318,1.026-2.627,1.786-3.927,2.279c-1.299,0.493-2.643,0.739-4.031,0.739c-2.158,0-3.7-0.593-4.625-1.779 c-0.926-1.187-1.106-2.788-0.542-4.804c0.519-1.851,1.431-3.356,2.737-4.515c1.306-1.159,3.02-1.972,5.142-2.438 c1.169-0.247,2.641-0.515,4.413-0.803c2.647-0.412,4.082-1.016,4.304-1.812l0.151-0.539c0.182-0.65,0.077-1.145-0.317-1.483 c-0.393-0.339-1.071-0.508-2.033-0.508c-1.045,0-1.934,0.214-2.666,0.643c-0.731,0.428-1.289,1.058-1.672,1.887h-6.748 c1.065-2.53,2.64-4.413,4.723-5.65s4.724-1.856,7.923-1.856c1.99,0,3.601,0.241,4.833,0.722s2.095,1.209,2.591,2.185 c0.339,0.701,0.483,1.536,0.431,2.504c-0.051,0.969-0.377,2.525-0.978,4.669l-2.375,8.483c-0.284,1.014-0.416,1.812-0.396,2.395 c0.02,0.583,0.188,0.962,0.503,1.141L222.737,30.321z" id="path23" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
<g id="g25">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#A0CE67" d="M188.386,7.928l-6.269,22.393h-7.174l0.864-3.085 c-1.227,1.246-2.476,2.163-3.746,2.751s-2.625,0.882-4.067,0.882c-2.471,0-4.154-0.634-5.048-1.901 c-0.895-1.268-0.993-3.149-0.294-5.644l4.31-15.396h7.338l-3.508,12.53c-0.516,1.842-0.641,3.109-0.375,3.803 s0.967,1.041,2.105,1.041c1.275,0,2.323-0.422,3.142-1.267c0.819-0.845,1.497-2.223,2.031-4.133l3.353-11.974H188.386z" id="path27" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
<g id="g29">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#A0CE67" d="M149.937,12.356l1.239-4.428h2.995l1.771-6.326h7.338 l-1.771,6.326h3.753l-1.24,4.428h-3.753l-2.716,9.702c-0.416,1.483-0.498,2.465-0.247,2.946c0.25,0.48,0.905,0.721,1.964,0.721 l0.549-0.011l0.39-0.031l-1.31,4.678c-0.811,0.148-1.596,0.263-2.354,0.344c-0.758,0.081-1.48,0.122-2.167,0.122 c-2.543,0-4.108-0.621-4.695-1.863c-0.587-1.242-0.313-3.887,0.82-7.936l2.428-8.672H149.937z" id="path31" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
<g id="g33">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M73.875,18.896c-0.561,2.004-0.616,3.537-0.167,4.601 s1.375,1.595,2.774,1.595c1.399,0,2.605-0.524,3.62-1.574s1.806-2.59,2.375-4.622c0.526-1.879,0.556-3.334,0.09-4.363 c-0.466-1.029-1.393-1.543-2.778-1.543c-1.304,0-2.487,0.528-3.551,1.585S74.386,17.071,73.875,18.896z M96.513,0l-8.489,30.321 h-7.337l0.824-2.944c-1.166,1.22-2.369,2.121-3.61,2.703s-2.583,0.874-4.025,0.874c-2.802,0-4.772-1.081-5.912-3.243 c-1.139-2.162-1.218-4.993-0.238-8.493c0.988-3.528,2.668-6.404,5.042-8.627c2.374-2.224,4.927-3.336,7.661-3.336 c1.47,0,2.695,0.296,3.676,0.887c0.981,0.591,1.681,1.465,2.099,2.62L89.217,0H96.513z" id="path35"/>
|
||||
<g id="g37">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M73.875,18.896c-0.561,2.004-0.616,3.537-0.167,4.601s1.375,1.595,2.774,1.595 c1.399,0,2.605-0.524,3.62-1.574s1.806-2.59,2.375-4.622c0.526-1.879,0.556-3.334,0.09-4.363 c-0.466-1.029-1.393-1.543-2.778-1.543c-1.304,0-2.487,0.528-3.551,1.585S74.386,17.071,73.875,18.896z M96.513,0l-8.489,30.321 h-7.337l0.824-2.944c-1.166,1.22-2.369,2.121-3.61,2.703s-2.583,0.874-4.025,0.874c-2.802,0-4.772-1.081-5.912-3.243 c-1.139-2.162-1.218-4.993-0.238-8.493c0.988-3.528,2.668-6.404,5.042-8.627c2.374-2.224,4.927-3.336,7.661-3.336 c1.47,0,2.695,0.296,3.676,0.887c0.981,0.591,1.681,1.465,2.099,2.62L89.217,0H96.513z" id="path39"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g41">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.488,30.321l6.269-22.393h7.049l-1.098,3.918 c1.213-1.537,2.502-2.659,3.868-3.366s6.015-1.074,7.822-1.101l-2.03,7.25c-0.304-0.042-0.608-0.072-0.911-0.093 c-0.304-0.02-0.592-0.03-0.867-0.03c-1.126,0-5.167,0.168-5.997,0.504c-0.829,0.336-1.561,0.854-2.196,1.555 c-0.406,0.467-0.789,1.136-1.149,2.007c-0.361,0.872-0.814,2.282-1.36,4.232l-2.104,7.516H46.488z" id="path43"/>
|
||||
</g>
|
||||
<g id="g45">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M32.673,16.742l8.351-0.021 c0.375-1.436,0.308-2.558-0.201-3.365s-1.402-1.211-2.68-1.211c-1.209,0-2.285,0.397-3.229,1.19S33.224,15.265,32.673,16.742z M38.817,23.278h7.043c-1.347,2.456-3.172,4.356-5.477,5.7c-2.305,1.345-4.885,2.017-7.74,2.017 c-3.473,0-5.923-1.054-7.351-3.161c-1.427-2.107-1.632-4.98-0.613-8.618c1.038-3.707,2.875-6.641,5.512-8.803 c2.637-2.163,5.678-3.244,9.123-3.244c3.555,0,6.04,1.099,7.456,3.298c1.417,2.198,1.582,5.234,0.498,9.109l-0.239,0.814 l-0.167,0.484H31.721c-0.441,1.575-0.438,2.777,0.01,3.606c0.448,0.829,1.332,1.244,2.65,1.244c0.975,0,1.836-0.206,2.583-0.617 S38.33,24.086,38.817,23.278z" id="path47"/>
|
||||
<g id="g49">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.673,16.742l8.351-0.021c0.375-1.436,0.308-2.558-0.201-3.365 s-1.402-1.211-2.68-1.211c-1.209,0-2.285,0.397-3.229,1.19S33.224,15.265,32.673,16.742z M38.817,23.278h7.043 c-1.347,2.456-3.172,4.356-5.477,5.7c-2.305,1.345-4.885,2.017-7.74,2.017c-3.473,0-5.923-1.054-7.351-3.161 c-1.427-2.107-1.632-4.98-0.613-8.618c1.038-3.707,2.875-6.641,5.512-8.803c2.637-2.163,5.678-3.244,9.123-3.244 c3.555,0,6.04,1.099,7.456,3.298c1.417,2.198,1.582,5.234,0.498,9.109l-0.239,0.814l-0.167,0.484H31.721 c-0.441,1.575-0.438,2.777,0.01,3.606c0.448,0.829,1.332,1.244,2.65,1.244c0.975,0,1.836-0.206,2.583-0.617 S38.33,24.086,38.817,23.278z" id="path51"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g53">
|
||||
<path fill="#A0CE67" d="M112.881,30.643l-6.404-18.639l-6.455,18.639h-7.254l9.565-30.321h8.19l4.434,15.582l0.35,1.276 c0.521,1.866,0.917,3.431,1.191,4.693l0.555-2.182c0.219-0.837,0.528-1.935,0.925-3.293l4.468-16.076h8.19l-10.501,30.321 H112.881z" id="path55" style="fill:#8ed300;fill-opacity:1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.5 KiB |
|
@ -0,0 +1,5 @@
|
|||
company:
|
||||
fiscalAddress: VERDNATURA LEVANTE S.L., B97367486 Avda. Espioca, 100, 46460 Silla
|
||||
- www.verdnatura.es - clientes@verdnatura.es
|
||||
registry: 'CIF: B97367486 Registro Mercantil de Valencia, Tomo 8041, Libro 5334,
|
||||
Folio 160, Sección 8, Hoja V 102076'
|
|
@ -0,0 +1,5 @@
|
|||
company:
|
||||
fiscalAddress: VERDNATURA LEVANTE S.L., B97367486 Avda. Espioca, 100, 46460 Silla
|
||||
- www.verdnatura.es - clientes@verdnatura.es
|
||||
registry: 'CIF: B97367486 Registro Mercantil de Valencia, Tomo 8041, Libro 5334,
|
||||
Folio 160, Sección 8, Hoja V 102076'
|
|
@ -1,5 +1,5 @@
|
|||
<header>
|
||||
<img :src="embeded['/assets/images/report-logo.svg']" alt="Verdnatura"/>
|
||||
<img v-bind:src="getReportSrc('report-logo.svg')" alt="Verdnatura"/>
|
||||
<section>{{$t('company.fiscalAddress')}}</section>
|
||||
<section>{{$t('company.registry')}}</section>
|
||||
</header>
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
name: 'report-header',
|
||||
props: ['isPreview', 'locale']
|
||||
};
|
|
@ -14,19 +14,6 @@ for (let configFile of configFiles) {
|
|||
Object.assign(config, require(configFile));
|
||||
}
|
||||
|
||||
/* let proxyConf = {};
|
||||
let proxyFiles = [
|
||||
'../../nginx/config.yml',
|
||||
`${configPath}/config.yml`,
|
||||
`${configPath}/config.${env}.yml`
|
||||
];
|
||||
|
||||
for (let proxyFile of proxyFiles) {
|
||||
if (fs.existsSync(proxyFile))
|
||||
Object.assign(proxyConf, require(proxyFile));
|
||||
} */
|
||||
|
||||
// config.proxy = proxyConf;
|
||||
config.env = env;
|
||||
|
||||
module.exports = config;
|
|
@ -0,0 +1,24 @@
|
|||
const mysql = require('mysql2/promise');
|
||||
const config = require('./config.js');
|
||||
|
||||
module.exports = {
|
||||
init() {
|
||||
if (!this.pool) {
|
||||
this.pool = mysql.createPool(config.mysql);
|
||||
this.pool.on('connection', connection => {
|
||||
connection.config.namedPlaceholders = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
find(query, params) {
|
||||
return this.pool.query(query, params).then(([rows]) => {
|
||||
return rows;
|
||||
});
|
||||
},
|
||||
findOne(query, params) {
|
||||
return this.find(query, params).then(([rows]) => rows);
|
||||
},
|
||||
findFromDef() {
|
||||
|
||||
}
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
// Import global directives
|
||||
require('./pin');
|
|
@ -0,0 +1,9 @@
|
|||
// DIRECTIVES NOT WORKING
|
||||
const Vue = require('vue');
|
||||
Vue.directive('pin', {
|
||||
bind: function(el, binding, vnode) {
|
||||
el.style.position = 'fixed';
|
||||
el.style.top = binding.value + 'px';
|
||||
el.style.backgroundColor = 'red';
|
||||
}
|
||||
});
|
|
@ -0,0 +1,93 @@
|
|||
const path = require('path');
|
||||
const smtp = require('./smtp');
|
||||
const Component = require('./component');
|
||||
const Report = require('./report');
|
||||
const db = require('./database');
|
||||
const config = require('./config');
|
||||
|
||||
if (!process.env.OPENSSL_CONF)
|
||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||
|
||||
class Email extends Component {
|
||||
constructor(name, args) {
|
||||
super(name);
|
||||
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `../templates/email/${this.name}`;
|
||||
}
|
||||
|
||||
|
||||
async getSubject() {
|
||||
if (!this.lang) await this.getLang();
|
||||
const locale = this.locale.messages;
|
||||
const userLocale = locale[this.lang];
|
||||
|
||||
if (!userLocale) {
|
||||
const fallbackLocale = config.i18n.fallbackLocale;
|
||||
|
||||
return locale[fallbackLocale].subject;
|
||||
}
|
||||
|
||||
return userLocale.subject;
|
||||
}
|
||||
|
||||
async getLang() {
|
||||
const clientId = this.args.clientId;
|
||||
const lang = await db.findOne(`
|
||||
SELECT lang FROM account.user
|
||||
WHERE id = ?`, [clientId]).then(rows => {
|
||||
return rows.lang;
|
||||
});
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
async send() {
|
||||
const instance = this.build();
|
||||
const rendered = await this.render();
|
||||
const attachments = [];
|
||||
const getAttachments = async(componentPath, files) => {
|
||||
for (file of files) {
|
||||
const fileCopy = Object.assign({}, file);
|
||||
if (fileCopy.cid) {
|
||||
const templatePath = `${componentPath}/${file.path}`;
|
||||
const fullFilePath = path.resolve(__dirname, templatePath);
|
||||
|
||||
fileCopy.path = path.resolve(__dirname, fullFilePath);
|
||||
} else {
|
||||
const reportName = fileCopy.filename.replace('.pdf', '');
|
||||
const report = new Report(reportName, this.args);
|
||||
fileCopy.content = await report.toPdfStream();
|
||||
}
|
||||
|
||||
attachments.push(fileCopy);
|
||||
}
|
||||
};
|
||||
|
||||
if (instance.components) {
|
||||
const components = instance.components;
|
||||
for (let componentName in components) {
|
||||
const component = components[componentName];
|
||||
const componentPath = `./components/${componentName}`;
|
||||
await getAttachments(componentPath, component.attachments);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.attachments)
|
||||
await getAttachments(this.path, this.attachments);
|
||||
|
||||
const localeSubject = await this.getSubject();
|
||||
const options = {
|
||||
to: this.args.recipient,
|
||||
subject: localeSubject,
|
||||
html: rendered,
|
||||
attachments: attachments
|
||||
};
|
||||
|
||||
return smtp.send(options);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Email;
|
|
@ -0,0 +1,9 @@
|
|||
const Vue = require('vue');
|
||||
const config = require('../config');
|
||||
const defaultLocale = config.i18n.locale;
|
||||
|
||||
Vue.filter('currency', function(value, currency = 'EUR', locale = defaultLocale) {
|
||||
return new Intl.NumberFormat(locale, {
|
||||
style: 'currency', currency
|
||||
}).format(parseFloat(value));
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
const Vue = require('vue');
|
||||
const strftime = require('strftime');
|
||||
|
||||
Vue.filter('date', function(value, specifiers) {
|
||||
return strftime(specifiers, value);
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
// Import global filters
|
||||
require('./date');
|
||||
require('./currency');
|
||||
require('./percentage');
|
|
@ -0,0 +1,11 @@
|
|||
const Vue = require('vue');
|
||||
const config = require('../config');
|
||||
const defaultLocale = config.i18n.locale;
|
||||
|
||||
Vue.filter('percentage', function(value, minFraction = 2, maxFraction = 2, locale = defaultLocale) {
|
||||
return new Intl.NumberFormat(locale, {
|
||||
style: 'percent',
|
||||
minimumFractionDigits: minFraction,
|
||||
maximumFractionDigits: maxFraction
|
||||
}).format(parseFloat(value));
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
const Vue = require('vue');
|
||||
const config = require('../config');
|
||||
|
||||
const imageSrc = {
|
||||
methods: {
|
||||
getEmailSrc(image) {
|
||||
let src = `cid:${image}`;
|
||||
|
||||
if (this.isPreview === 'true')
|
||||
src = `/api/${this.$options.name}/assets/images/${image}`;
|
||||
|
||||
return src;
|
||||
},
|
||||
getReportSrc(image) {
|
||||
const assetsPath = `${config.app.host}/api/${this.$options.name}`;
|
||||
const imagePath = `${assetsPath}/assets/images/${image}`;
|
||||
|
||||
return imagePath;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Vue.mixin(imageSrc);
|
|
@ -0,0 +1,4 @@
|
|||
// Import global mixins
|
||||
require('./image-src');
|
||||
require('./user-locale');
|
||||
require('./prop-validator');
|
|
@ -0,0 +1,26 @@
|
|||
const Vue = require('vue');
|
||||
const validator = {
|
||||
created() {
|
||||
const props = this.$options.props;
|
||||
const invalidProps = [];
|
||||
|
||||
for (prop in props) {
|
||||
const isObject = typeof props[prop] === 'object';
|
||||
const isRequired = props[prop].required;
|
||||
const isNotDefined = this[prop] === undefined;
|
||||
|
||||
if (isObject && isRequired && isNotDefined)
|
||||
invalidProps.push(prop);
|
||||
}
|
||||
|
||||
if (invalidProps.length > 0) {
|
||||
const required = invalidProps.join(', ');
|
||||
|
||||
throw new Error(`Required params not found [${required}]`);
|
||||
}
|
||||
},
|
||||
props: ['isPreview']
|
||||
};
|
||||
|
||||
|
||||
Vue.mixin(validator);
|
|
@ -0,0 +1,24 @@
|
|||
const Vue = require('vue');
|
||||
const db = require('../database');
|
||||
const userLocale = {
|
||||
async serverPrefetch() {
|
||||
if (this.clientId)
|
||||
this.locale = await this.getLocale(this.clientId);
|
||||
|
||||
if (this.locale)
|
||||
this.$i18n.locale = this.locale;
|
||||
},
|
||||
methods: {
|
||||
getLocale(clientId) {
|
||||
return db.findOne(`
|
||||
SELECT lang FROM account.user
|
||||
WHERE id = ?`, [clientId]).then(rows => {
|
||||
return rows.lang;
|
||||
});
|
||||
}
|
||||
},
|
||||
props: ['clientId']
|
||||
};
|
||||
|
||||
|
||||
Vue.mixin(userLocale);
|
|
@ -0,0 +1,38 @@
|
|||
const fs = require('fs');
|
||||
const pdf = require('html-pdf');
|
||||
const path = require('path');
|
||||
const config = require('./config');
|
||||
const Component = require('./component');
|
||||
|
||||
if (!process.env.OPENSSL_CONF)
|
||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||
|
||||
class Report extends Component {
|
||||
constructor(name, args) {
|
||||
super(name);
|
||||
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `../templates/reports/${this.name}`;
|
||||
}
|
||||
|
||||
async toPdfStream() {
|
||||
const template = await this.render();
|
||||
let options = config.pdf;
|
||||
|
||||
const optionsPath = `${this.path}/options.json`;
|
||||
const fullPath = path.resolve(__dirname, optionsPath);
|
||||
if (fs.existsSync(fullPath))
|
||||
options = Object.assign(options, require(optionsPath));
|
||||
|
||||
return new Promise(resolve => {
|
||||
pdf.create(template, options).toStream((err, stream) => {
|
||||
resolve(stream);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Report;
|
|
@ -0,0 +1,51 @@
|
|||
const Report = require('./report');
|
||||
const Email = require('./email');
|
||||
|
||||
module.exports = app => {
|
||||
app.get(`/api/report/:name`, async(req, res, next) => {
|
||||
const args = req.query;
|
||||
const requiredArgs = ['clientId'];
|
||||
|
||||
const hasRequiredArgs = requiredArgs.every(arg => {
|
||||
return args[arg];
|
||||
});
|
||||
|
||||
if (!hasRequiredArgs)
|
||||
res.json({message: 'Required params recipient, clientId'});
|
||||
|
||||
try {
|
||||
const report = new Report(req.params.name, args);
|
||||
const stream = await report.toPdfStream();
|
||||
res.setHeader('Content-type', 'application/pdf');
|
||||
stream.pipe(res);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
});
|
||||
|
||||
app.get(`/api/email/:name`, async(req, res, next) => {
|
||||
const args = req.query;
|
||||
const requiredArgs = ['recipient', 'clientId'];
|
||||
|
||||
const hasRequiredArgs = requiredArgs.every(arg => {
|
||||
return args[arg];
|
||||
});
|
||||
|
||||
if (!hasRequiredArgs)
|
||||
res.json({message: 'Required params recipient, clientId'});
|
||||
|
||||
try {
|
||||
const email = new Email(req.params.name, args);
|
||||
if (args.isPreview === 'true') {
|
||||
const rendered = await email.render();
|
||||
|
||||
res.send(rendered);
|
||||
} else {
|
||||
await email.send();
|
||||
res.status(200).json({message: 'Sent'});
|
||||
}
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
});
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
const nodemailer = require('nodemailer');
|
||||
const config = require('./config.js');
|
||||
const config = require('./config');
|
||||
|
||||
module.exports = {
|
||||
init() {
|
||||
|
@ -11,7 +11,7 @@ module.exports = {
|
|||
options.from = `${config.app.senderName} <${config.app.senderMail}>`;
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!config.smtp.user)
|
||||
if (!config.smtp.auth.user)
|
||||
return Promise.resolve(true);
|
||||
|
||||
options.to = config.app.senderMail;
|
|
@ -1,6 +1,6 @@
|
|||
const fs = require('fs-extra');
|
||||
|
||||
class CssReader {
|
||||
class Stylesheet {
|
||||
constructor(files) {
|
||||
this.files = files;
|
||||
this.css = [];
|
||||
|
@ -15,4 +15,4 @@ class CssReader {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = CssReader;
|
||||
module.exports = Stylesheet;
|
|
@ -1,9 +0,0 @@
|
|||
const mysql = require('mysql2/promise');
|
||||
const config = require('./config.js');
|
||||
|
||||
module.exports = {
|
||||
init() {
|
||||
if (!this.pool)
|
||||
this.pool = mysql.createPool(config.mysql);
|
||||
},
|
||||
};
|
|
@ -1,152 +0,0 @@
|
|||
const Vue = require('vue');
|
||||
const VueI18n = require('vue-i18n');
|
||||
const renderer = require('vue-server-renderer').createRenderer();
|
||||
const fs = require('fs-extra');
|
||||
const juice = require('juice');
|
||||
const smtp = require('./smtp');
|
||||
const fallbackLocale = 'es';
|
||||
|
||||
if (!process.env.OPENSSL_CONF)
|
||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
module.exports = {
|
||||
|
||||
path: `${appPath}/report`,
|
||||
|
||||
/**
|
||||
* Renders a report component
|
||||
*
|
||||
* @param {String} name - Report name
|
||||
* @param {Object} ctx - Request context
|
||||
*/
|
||||
async render(name, ctx) {
|
||||
const component = require(`${this.path}/${name}`);
|
||||
const result = await this.preFetch(component, ctx);
|
||||
const i18n = new VueI18n({
|
||||
locale: 'es',
|
||||
fallbackLocale
|
||||
});
|
||||
const app = new Vue({i18n,
|
||||
render: h => h(result.component)});
|
||||
|
||||
return renderer.renderToString(app).then(renderedHtml => {
|
||||
return {
|
||||
html: renderedHtml,
|
||||
data: result.mergedData,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Prefetch all component data from asyncData method
|
||||
*
|
||||
* @param {Object} orgComponent - Component object
|
||||
* @param {Object} ctx - Request context
|
||||
*/
|
||||
async preFetch(orgComponent, ctx) {
|
||||
let component = Object.create(orgComponent);
|
||||
let mergedData = {attachments: []};
|
||||
let asyncData = {};
|
||||
let data = {};
|
||||
let params = {};
|
||||
|
||||
if (Object.keys(ctx.body).length > 0)
|
||||
params = ctx.body;
|
||||
|
||||
if (Object.keys(ctx.query).length > 0)
|
||||
params = ctx.query;
|
||||
|
||||
await this.attachAssets(component);
|
||||
|
||||
if (orgComponent.hasOwnProperty('data'))
|
||||
data = orgComponent.data();
|
||||
|
||||
if (orgComponent.hasOwnProperty('asyncData')) {
|
||||
asyncData = await orgComponent.asyncData(ctx, params);
|
||||
|
||||
if (asyncData.locale) {
|
||||
let locale = component.i18n.messages[asyncData.locale];
|
||||
|
||||
if (!locale)
|
||||
locale = component.i18n.messages[fallbackLocale];
|
||||
|
||||
mergedData.subject = locale.subject;
|
||||
}
|
||||
}
|
||||
|
||||
mergedData = Object.assign(mergedData, data, asyncData);
|
||||
|
||||
component.data = function data() {
|
||||
return mergedData;
|
||||
};
|
||||
|
||||
if (data.hasOwnProperty('files')) {
|
||||
const files = data.files;
|
||||
files.forEach(file => {
|
||||
const componentPath = `${this.path}/${orgComponent.name}`;
|
||||
let fileSrc = componentPath + file;
|
||||
|
||||
if (file.slice(0, 4) === 'http' || file.slice(0, 5) === 'https')
|
||||
fileSrc = file;
|
||||
|
||||
const fileName = file.split('/').pop();
|
||||
mergedData.attachments.push({
|
||||
filename: fileName,
|
||||
path: fileSrc,
|
||||
cid: file,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const components = orgComponent.components;
|
||||
|
||||
if (components) {
|
||||
const promises = [];
|
||||
const childNames = [];
|
||||
component.components = {};
|
||||
|
||||
Object.keys(components).forEach(childName => {
|
||||
childNames.push(childName);
|
||||
promises.push(this.preFetch(components[childName], ctx));
|
||||
});
|
||||
|
||||
await Promise.all(promises).then(results => {
|
||||
results.forEach((result, i) => {
|
||||
result.mergedData.attachments.forEach(atth => {
|
||||
mergedData.attachments.push(atth);
|
||||
});
|
||||
|
||||
component.components[childNames[i]] = result.component;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {component, mergedData};
|
||||
},
|
||||
|
||||
async attachAssets(component) {
|
||||
const localePath = `${this.path}/${component.name}/locale.js`;
|
||||
const templatePath = `${this.path}/${component.name}/index.html`;
|
||||
const stylePath = `${this.path}/${component.name}/assets/css/index.js`;
|
||||
|
||||
const template = await fs.readFile(templatePath, 'utf8');
|
||||
const css = require(stylePath);
|
||||
|
||||
component.i18n = require(localePath);
|
||||
component.template = juice.inlineContent(template, css);
|
||||
},
|
||||
|
||||
async toEmail(name, ctx) {
|
||||
const rendered = await this.render(name, ctx);
|
||||
const data = rendered.data;
|
||||
const options = {
|
||||
to: data.recipient,
|
||||
subject: data.subject,
|
||||
html: rendered.html,
|
||||
attachments: data.attachments,
|
||||
};
|
||||
return smtp.send(options);
|
||||
},
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
module.exports = class UserException extends Error {
|
||||
/**
|
||||
* UserException
|
||||
* @param {String} message - Error message
|
||||
*/
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
||||
this.httpStatusCode = 400;
|
||||
this.name = 'UserException';
|
||||
}
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = {
|
||||
methods: {
|
||||
uFirst: (text) => {
|
||||
return text;
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,119 +0,0 @@
|
|||
const Vue = require('vue');
|
||||
const VueI18n = require('vue-i18n');
|
||||
const renderer = require('vue-server-renderer').createRenderer();
|
||||
const fs = require('fs-extra');
|
||||
const pdf = require('html-pdf');
|
||||
const juice = require('juice');
|
||||
const config = require('./config');
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
if (!process.env.OPENSSL_CONF)
|
||||
process.env.OPENSSL_CONF = '/etc/ssl/';
|
||||
|
||||
module.exports = {
|
||||
|
||||
path: `${appPath}/report`,
|
||||
|
||||
/**
|
||||
* Renders a report component
|
||||
*
|
||||
* @param {String} name - Report name
|
||||
* @param {Object} ctx - Request context
|
||||
*/
|
||||
async render(name, ctx) {
|
||||
const component = require(`${this.path}/${name}`);
|
||||
const result = await this.preFetch(component, ctx);
|
||||
const i18n = new VueI18n({
|
||||
locale: 'es',
|
||||
fallbackLocale: 'es',
|
||||
silentTranslationWarn: true
|
||||
});
|
||||
const app = new Vue({i18n,
|
||||
render: h => h(result.component)});
|
||||
|
||||
return renderer.renderToString(app);
|
||||
},
|
||||
|
||||
/**
|
||||
* Prefetch all component data from asyncData method
|
||||
*
|
||||
* @param {Object} orgComponent - Component object
|
||||
* @param {Object} ctx - Request context
|
||||
*/
|
||||
async preFetch(orgComponent, ctx) {
|
||||
let component = Object.create(orgComponent);
|
||||
let mergedData = {};
|
||||
let asyncData = {};
|
||||
let data = {};
|
||||
let params = {};
|
||||
|
||||
if (Object.keys(ctx.body).length > 0)
|
||||
params = ctx.body;
|
||||
|
||||
if (Object.keys(ctx.query).length > 0)
|
||||
params = ctx.query;
|
||||
|
||||
await this.attachAssets(component);
|
||||
|
||||
if (orgComponent.hasOwnProperty('data'))
|
||||
data = orgComponent.data();
|
||||
|
||||
if (orgComponent.hasOwnProperty('asyncData'))
|
||||
asyncData = await orgComponent.asyncData(ctx, params);
|
||||
|
||||
mergedData = Object.assign(mergedData, data, asyncData);
|
||||
|
||||
component.data = function data() {
|
||||
return mergedData;
|
||||
};
|
||||
|
||||
const components = orgComponent.components;
|
||||
if (components) {
|
||||
const promises = [];
|
||||
const childNames = [];
|
||||
component.components = {};
|
||||
|
||||
Object.keys(components).forEach(childName => {
|
||||
childNames.push(childName);
|
||||
promises.push(this.preFetch(components[childName], ctx));
|
||||
});
|
||||
|
||||
await Promise.all(promises).then(results => {
|
||||
results.forEach((result, i) => {
|
||||
component.components[childNames[i]] = result.component;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {component};
|
||||
},
|
||||
|
||||
async attachAssets(component) {
|
||||
const localePath = `${this.path}/${component.name}/locale`;
|
||||
const templatePath = `${this.path}/${component.name}/index.html`;
|
||||
const stylePath = `${this.path}/${component.name}/assets/css/index`;
|
||||
|
||||
const template = await fs.readFile(templatePath, 'utf8');
|
||||
const css = require(stylePath);
|
||||
const cssOptions = {inlinePseudoElements: true};
|
||||
|
||||
component.i18n = require(localePath);
|
||||
component.template = juice.inlineContent(template, css, cssOptions);
|
||||
},
|
||||
|
||||
async toPdf(name, ctx) {
|
||||
const html = await this.render(name, ctx);
|
||||
let options = config.pdf;
|
||||
|
||||
const optionsPath = `${this.path}/${name}/options.json`;
|
||||
if (fs.existsSync(optionsPath))
|
||||
options = Object.assign(options, require(optionsPath));
|
||||
|
||||
return new Promise(resolve => {
|
||||
pdf.create(html, options).toStream((err, stream) => {
|
||||
resolve(stream);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,64 +0,0 @@
|
|||
const reportEngine = require('./reportEngine.js');
|
||||
const emailEngine = require('./emailEngine');
|
||||
const express = require('express');
|
||||
const routes = require(`../config/routes.json`);
|
||||
|
||||
module.exports = app => {
|
||||
this.path = `${appPath}/report`;
|
||||
|
||||
/**
|
||||
* Enables a report
|
||||
*
|
||||
* @param {String} name - Report state path
|
||||
*/
|
||||
function registerReport(name) {
|
||||
if (!name) throw new Error('Report name required');
|
||||
|
||||
app.get(`/api/report/${name}`, (request, response, next) => {
|
||||
reportEngine.toPdf(name, request).then(stream => {
|
||||
response.setHeader('Content-type', 'application/pdf');
|
||||
stream.pipe(response);
|
||||
}).catch(e => {
|
||||
next(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a email
|
||||
*
|
||||
* @param {String} name - Report state path
|
||||
*/
|
||||
function registerEmail(name) {
|
||||
if (!name) throw new Error('Email name required');
|
||||
|
||||
app.get(`/api/email/${name}`, (request, response, next) => {
|
||||
emailEngine.render(name, request).then(rendered => {
|
||||
response.send(rendered.html);
|
||||
}).catch(e => {
|
||||
next(e);
|
||||
});
|
||||
});
|
||||
|
||||
app.post(`/api/email/${name}`, (request, response, next) => {
|
||||
emailEngine.toEmail(name, request).then(() => {
|
||||
response.status(200).json({status: 200});
|
||||
}).catch(e => {
|
||||
next(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
routes.forEach(route => {
|
||||
if (route.type === 'email')
|
||||
registerEmail(route.name);
|
||||
else if (route.type === 'report')
|
||||
registerReport(route.name);
|
||||
|
||||
const staticPath = this.path + `/${route.name}/assets`;
|
||||
app.use(`/api/assets`, express.static(staticPath));
|
||||
});
|
||||
};
|
|
@ -21,9 +21,20 @@
|
|||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
|
@ -39,12 +50,9 @@
|
|||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
|
||||
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.10"
|
||||
}
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
|
||||
"integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
|
@ -80,21 +88,24 @@
|
|||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"optional": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"cheerio": {
|
||||
|
@ -120,6 +131,44 @@
|
|||
"lodash.some": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
|
||||
|
@ -129,9 +178,9 @@
|
|||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
|
||||
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
|
@ -200,9 +249,9 @@
|
|||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz",
|
||||
"integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ=="
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
|
@ -213,13 +262,12 @@
|
|||
}
|
||||
},
|
||||
"datauri": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/datauri/-/datauri-1.1.0.tgz",
|
||||
"integrity": "sha512-0q+cTTKx7q8eDteZRIQLTFJuiIsVing17UbWTPssY4JLSMaYsk/VKpNulBDo9NSgQWcvlPrkEHW8kUO67T/7mQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/datauri/-/datauri-2.0.0.tgz",
|
||||
"integrity": "sha512-zS2HSf9pI5XPlNZgIqJg/wCJpecgU/HA6E/uv2EfaWnW1EiTGLfy/EexTIsC9c99yoCOTXlqeeWk4FkCSuO3/g==",
|
||||
"requires": {
|
||||
"image-size": "^0.6.2",
|
||||
"mimer": "^0.3.2",
|
||||
"semver": "^5.5.0"
|
||||
"image-size": "^0.7.3",
|
||||
"mimer": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
|
@ -231,6 +279,11 @@
|
|||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
|
@ -242,24 +295,22 @@
|
|||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"denque": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.0.tgz",
|
||||
"integrity": "sha512-gh513ac7aiKrAgjiIBWZG0EASyDF9p4JMWwKA8YU5s9figrL5SRNEMT6FDynsegakuhWd1wVqTvqvqAoDxw7wQ=="
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
|
||||
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
|
||||
},
|
||||
"dijkstrajs": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
|
||||
"integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
||||
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
|
||||
"requires": {
|
||||
"domelementtype": "~1.1.1",
|
||||
"entities": "~1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
|
||||
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
|
||||
}
|
||||
"domelementtype": "^1.3.0",
|
||||
"entities": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
|
@ -293,6 +344,11 @@
|
|||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
|
@ -309,6 +365,11 @@
|
|||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
@ -350,6 +411,14 @@
|
|||
"pend": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
|
@ -383,6 +452,11 @@
|
|||
"is-property": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
|
@ -418,6 +492,11 @@
|
|||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"hash-sum": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
|
||||
|
@ -447,16 +526,16 @@
|
|||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
|
||||
"integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.0",
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.0.6"
|
||||
"readable-stream": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
|
@ -470,23 +549,33 @@
|
|||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz",
|
||||
"integrity": "sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"image-size": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
|
||||
"integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA=="
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
|
||||
"integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"intl": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz",
|
||||
"integrity": "sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"is-property": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
|
@ -519,6 +608,15 @@
|
|||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
|
@ -559,9 +657,9 @@
|
|||
}
|
||||
},
|
||||
"juice": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/juice/-/juice-5.1.0.tgz",
|
||||
"integrity": "sha512-SRfLv0y7xwAKnsd6HWS9aSF0+a9ozXEatKlXHiiTvozdZu0Vwz9dDk7NEpy/N2icFTnhYtk1Du3rPNtH7fFVHw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/juice/-/juice-5.2.0.tgz",
|
||||
"integrity": "sha512-0l6GZmT3efexyaaay3SchKT5kG311N59TEFP5lfvEy0nz9SNqjx311plJ3b4jze7arsmDsiHQLh/xnAuk0HFTQ==",
|
||||
"requires": {
|
||||
"cheerio": "^0.22.0",
|
||||
"commander": "^2.15.1",
|
||||
|
@ -569,7 +667,7 @@
|
|||
"deep-extend": "^0.6.0",
|
||||
"mensch": "^0.3.3",
|
||||
"slick": "^1.12.2",
|
||||
"web-resource-inliner": "^4.2.1"
|
||||
"web-resource-inliner": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"kew": {
|
||||
|
@ -587,10 +685,14 @@
|
|||
"graceful-fs": "^4.1.9"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
|
@ -633,9 +735,9 @@
|
|||
"integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM="
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
|
||||
"integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ=="
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"lodash.pick": {
|
||||
"version": "4.4.0",
|
||||
|
@ -658,20 +760,20 @@
|
|||
"integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0="
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
|
||||
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
|
||||
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "~3.0.0",
|
||||
"lodash._reinterpolate": "^3.0.0",
|
||||
"lodash.templatesettings": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.templatesettings": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
|
||||
"integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
|
||||
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "~3.0.0"
|
||||
"lodash._reinterpolate": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.unescape": {
|
||||
|
@ -690,12 +792,11 @@
|
|||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"requires": {
|
||||
"pseudomap": "^1.0.2",
|
||||
"yallist": "^2.1.2"
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"mensch": {
|
||||
|
@ -717,9 +818,9 @@
|
|||
}
|
||||
},
|
||||
"mimer": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mimer/-/mimer-0.3.2.tgz",
|
||||
"integrity": "sha512-N6NcgDQAevhP/02DQ/epK6daLy4NKrIHyTlJcO6qBiYn98q+Y4a/knNsAATCe1xLS2F0nEmJp+QYli2s8vKwyQ=="
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimer/-/mimer-1.0.0.tgz",
|
||||
"integrity": "sha512-4ZJvCzfcwsBgPbkKXUzGoVZMWjv8IDIygkGzVc7uUYhgnK0t2LmGxxjdgH1i+pn0/KQfB5F/VKUJlfyTSOFQjg=="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
|
@ -743,15 +844,15 @@
|
|||
"optional": true
|
||||
},
|
||||
"mysql2": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz",
|
||||
"integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.7.0.tgz",
|
||||
"integrity": "sha512-xTWWQPjP5rcrceZQ7CSTKR/4XIDeH/cRkNH/uzvVGQ7W5c7EJ0dXeJUusk7OKhIoHj7uFKUxDVSCfLIl+jluog==",
|
||||
"requires": {
|
||||
"denque": "^1.4.0",
|
||||
"denque": "^1.4.1",
|
||||
"generate-function": "^2.3.1",
|
||||
"iconv-lite": "^0.4.24",
|
||||
"iconv-lite": "^0.5.0",
|
||||
"long": "^4.0.0",
|
||||
"lru-cache": "^4.1.3",
|
||||
"lru-cache": "^5.1.1",
|
||||
"named-placeholders": "^1.1.2",
|
||||
"seq-queue": "^0.0.5",
|
||||
"sqlstring": "^2.3.1"
|
||||
|
@ -763,6 +864,22 @@
|
|||
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
|
||||
"requires": {
|
||||
"lru-cache": "^4.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"requires": {
|
||||
"pseudomap": "^1.0.2",
|
||||
"yallist": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||
}
|
||||
}
|
||||
},
|
||||
"nice-try": {
|
||||
|
@ -788,6 +905,32 @@
|
|||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
|
||||
"integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
|
@ -863,6 +1006,11 @@
|
|||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pngjs": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
|
||||
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
|
@ -890,15 +1038,33 @@
|
|||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"qrcode": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.2.tgz",
|
||||
"integrity": "sha512-eR6RgxFYPDFH+zFLTJKtoNP/RlsHANQb52AUmQ2bGDPMuUw7jJb0F+DNEgx7qQGIElrbFxWYMc0/B91zLZPF9Q==",
|
||||
"requires": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"isarray": "^2.0.1",
|
||||
"pngjs": "^3.3.0",
|
||||
"yargs": "^13.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
|
||||
"integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
|
||||
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
|
@ -941,10 +1107,20 @@
|
|||
"throttleit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
|
||||
"integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
|
||||
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
|
@ -960,9 +1136,9 @@
|
|||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"seq-queue": {
|
||||
"version": "0.0.5",
|
||||
|
@ -970,9 +1146,14 @@
|
|||
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4="
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz",
|
||||
"integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw=="
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
|
||||
"integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
|
@ -997,6 +1178,11 @@
|
|||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"sqlstring": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
||||
|
@ -1023,12 +1209,44 @@
|
|||
"resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.0.tgz",
|
||||
"integrity": "sha1-s/D6QZKVICpaKJ9ta+n0kJphcZM="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
|
||||
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
|
@ -1040,9 +1258,12 @@
|
|||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"throttleit": {
|
||||
"version": "1.0.0",
|
||||
|
@ -1109,9 +1330,9 @@
|
|||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
},
|
||||
"valid-data-url": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.6.tgz",
|
||||
"integrity": "sha512-FXg2qXMzfAhZc0y2HzELNfUeiOjPr+52hU1DNBWiJJ2luXD+dD1R9NA48Ug5aj0ibbxroeGDc/RJv6ThiGgkDw=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-2.0.0.tgz",
|
||||
"integrity": "sha512-dyCZnv3aCey7yfTgIqdZanKl7xWAEEKCbgmR7SKqyK6QT/Z07ROactrgD1eA37C69ODRj7rNOjzKWVPh0EUjBA=="
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
|
@ -1124,19 +1345,19 @@
|
|||
}
|
||||
},
|
||||
"vue": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.7.tgz",
|
||||
"integrity": "sha512-g7ADfQ82QU+j6F/bVDioVQf2ccIMYLuR4E8ev+RsDBlmwRkhGO3HhgF4PF9vpwjdPpxyb1zzLur2nQ2oIMAMEg=="
|
||||
"version": "2.6.10",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
|
||||
"integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
|
||||
},
|
||||
"vue-i18n": {
|
||||
"version": "8.8.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.8.2.tgz",
|
||||
"integrity": "sha512-P09ZN2S0mX1AmhSR/+wP2owP3izGVx1pSoDFcOXTLya5xvP95dG7kc9LQUnboPgSzK/JKe9FkYmoYdDTKDjPSw=="
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.15.0.tgz",
|
||||
"integrity": "sha512-juJ/avAP39bOMycC+qQDLJ8U9z9LtLF/9PsRoJLBSfsYZo9bqYntyyX5QPicwlb1emJKjgxhZ3YofHiQcXBu0Q=="
|
||||
},
|
||||
"vue-server-renderer": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.7.tgz",
|
||||
"integrity": "sha512-CVtGR+bE63y4kyIeOcCEF2UNKquSquFQAsTHZ5R1cGM4L4Z0BXgAUEcngTOy8kN+tubt3c1zpRvbrok/bHKeDg==",
|
||||
"version": "2.6.10",
|
||||
"resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz",
|
||||
"integrity": "sha512-UYoCEutBpKzL2fKCwx8zlRtRtwxbPZXKTqbl2iIF4yRZUNO/ovrHyDAJDljft0kd+K0tZhN53XRHkgvCZoIhug==",
|
||||
"requires": {
|
||||
"chalk": "^1.1.3",
|
||||
"hash-sum": "^1.0.2",
|
||||
|
@ -1146,21 +1367,46 @@
|
|||
"resolve": "^1.2.0",
|
||||
"serialize-javascript": "^1.3.0",
|
||||
"source-map": "0.5.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||
}
|
||||
}
|
||||
},
|
||||
"web-resource-inliner": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.2.1.tgz",
|
||||
"integrity": "sha512-fOWnBQHVX8zHvEbECDTxtYL0FXIIZZ5H3LWoez8mGopYJK7inEru1kVMDzM1lVdeJBNEqUnNP5FBGxvzuMcwwQ==",
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.3.3.tgz",
|
||||
"integrity": "sha512-Qk19pohqZs3SoFUW4ZlOHlM8hsOnXhTpCrQ16b1qtJtKzJgO7NZLGP+/lcb2g3hWDQD39/LE/JYOn1Sjy7tn1A==",
|
||||
"requires": {
|
||||
"async": "^2.1.2",
|
||||
"chalk": "^1.1.3",
|
||||
"datauri": "^1.0.4",
|
||||
"async": "^3.1.0",
|
||||
"chalk": "^2.4.2",
|
||||
"datauri": "^2.0.0",
|
||||
"htmlparser2": "^3.9.2",
|
||||
"lodash.unescape": "^4.0.1",
|
||||
"request": "^2.78.0",
|
||||
"valid-data-url": "^0.1.4",
|
||||
"xtend": "^4.0.0"
|
||||
"safer-buffer": "^2.1.2",
|
||||
"valid-data-url": "^2.0.0",
|
||||
"xtend": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
|
@ -1171,15 +1417,84 @@
|
|||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
|
||||
"integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
|
||||
"requires": {
|
||||
"cliui": "^5.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
|
||||
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
"dependencies": {
|
||||
"fs-extra": "^7.0.1",
|
||||
"html-pdf": "^2.2.0",
|
||||
"juice": "^5.0.1",
|
||||
"mysql2": "^1.6.5",
|
||||
"intl": "^1.2.5",
|
||||
"js-yaml": "^3.13.1",
|
||||
"juice": "^5.2.0",
|
||||
"mysql2": "^1.7.0",
|
||||
"nodemailer": "^4.7.0",
|
||||
"qrcode": "^1.4.2",
|
||||
"strftime": "^0.10.0",
|
||||
"vue": "^2.6.7",
|
||||
"vue-i18n": "^8.8.2",
|
||||
"vue-server-renderer": "^2.6.7"
|
||||
"vue": "^2.6.10",
|
||||
"vue-i18n": "^8.15.0",
|
||||
"vue-server-renderer": "^2.6.10"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<title>{{ $t('subject') }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="container">
|
||||
<!-- Header component -->
|
||||
<email-header></email-header>
|
||||
<!-- End header component -->
|
||||
<section class="main">
|
||||
<!-- Title block -->
|
||||
<div class="title">
|
||||
<h1>{{ $t('title') }}</h1>
|
||||
</div>
|
||||
<!-- Title block end -->
|
||||
|
||||
<p>{{$t('description.dear')}},</p>
|
||||
<p>{{$t('description.instructions')}}</p>
|
||||
|
||||
<!-- <h1>{{$t('sections.howToBuy.title')}}</h1>
|
||||
<p>{{$t('sections.howToBuy.description')}}</p>
|
||||
<ol>
|
||||
<li v-for="requeriment in $t('sections.howToBuy.requeriments')">
|
||||
<span v-html="requeriment"></span>
|
||||
</li>
|
||||
</ol>
|
||||
<p>{{$t('sections.howToBuy.stock')}}</p>
|
||||
<p>{{$t('sections.howToBuy.delivery')}}</p> -->
|
||||
</section>
|
||||
<!-- Footer component -->
|
||||
<email-footer :locale="locale"></email-footer>
|
||||
<!-- End footer component -->
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
|
@ -1,53 +0,0 @@
|
|||
const UserException = require(`${appPath}/lib/exceptions/userException`);
|
||||
const reportEngine = require(`${appPath}/lib/reportEngine`);
|
||||
const database = require(`${appPath}/lib/database`);
|
||||
const emailHeader = require('../email-header');
|
||||
const emailFooter = require('../email-footer');
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'claim-pickup-order',
|
||||
async asyncData(ctx, params) {
|
||||
const promises = [];
|
||||
const data = {
|
||||
isPreview: ctx.method === 'GET',
|
||||
};
|
||||
|
||||
if (!params.claimFk)
|
||||
throw new UserException('No claim id specified');
|
||||
|
||||
promises.push(reportEngine.toPdf('rpt-claim-pickup-order', ctx));
|
||||
promises.push(this.methods.fetchClient(params.claimFk));
|
||||
|
||||
return Promise.all(promises).then(result => {
|
||||
const stream = result[0];
|
||||
const [[client]] = result[1];
|
||||
|
||||
Object.assign(data, client);
|
||||
Object.assign(data, {attachments: [{filename: 'claim-pickup-order.pdf', content: stream}]});
|
||||
|
||||
return data;
|
||||
});
|
||||
},
|
||||
created() {
|
||||
if (this.locale)
|
||||
this.$i18n.locale = this.locale;
|
||||
},
|
||||
methods: {
|
||||
fetchClient(claimFk) {
|
||||
return database.pool.query(`
|
||||
SELECT
|
||||
c.id,
|
||||
u.lang locale,
|
||||
c.email recipient
|
||||
FROM claim cl
|
||||
JOIN client c ON c.id = cl.clientFk
|
||||
JOIN account.user u ON u.id = c.id
|
||||
WHERE cl.id = ?`, [claimFk]);
|
||||
},
|
||||
},
|
||||
components: {
|
||||
emailHeader,
|
||||
emailFooter,
|
||||
},
|
||||
};
|
|
@ -1,25 +0,0 @@
|
|||
module.exports = {
|
||||
messages: {
|
||||
es: {
|
||||
subject: 'Orden de recogida',
|
||||
title: 'Orden de recogida',
|
||||
description: {
|
||||
dear: 'Estimado cliente',
|
||||
instructions: 'Aqui tienes tu orden de recogida.'
|
||||
},
|
||||
sections: {
|
||||
howToBuy: {
|
||||
title: 'Cómo hacer un pedido',
|
||||
description: `Para realizar un pedido en nuestra web,
|
||||
debes configurarlo indicando:`,
|
||||
requeriments: [
|
||||
'Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si lo prefieres recoger en alguno de nuestros almacenes.',
|
||||
'La fecha en la que quieres recibir el pedido (se preparará el día anterior).',
|
||||
'La dirección de entrega o el almacén donde quieres recoger el pedido.'],
|
||||
stock: 'En nuestra web y aplicaciones puedes visualizar el stock disponible de flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que dicho stock puede variar en función de la fecha seleccionada al configurar el pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.',
|
||||
delivery: 'El reparto se realiza de lunes a sábado según la zona en la que te encuentres. Por regla general, los pedidos que se entregan por agencia, deben estar confirmados y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos), aunque esto puede variar si el pedido se envía a través de nuestro reparto y según la zona.',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|