Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4090-global_invoincing
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Vicent Llopis 2022-11-11 07:47:29 +01:00
commit 9d06f5c0f0
146 changed files with 43538 additions and 3845 deletions

12
.vscode/settings.json vendored
View File

@ -2,7 +2,13 @@
{
// Carácter predeterminado de final de línea.
"files.eol": "\n",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
"eslint.validate": [
"javascript",
"json"
]
}

View File

@ -1,32 +1,43 @@
FROM debian:stretch-slim
FROM debian:bullseye-slim
ENV TZ Europe/Madrid
ARG DEBIAN_FRONTEND=noninteractive
# NodeJs
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
ca-certificates \
gnupg2 \
libfontconfig lftp \
&& apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
&& curl -sL https://deb.nodesource.com/setup_14.x | bash - \
&& curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g npm@8.19.2
# Puppeteer
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
nodejs \
&& apt-get purge -y --auto-remove \
gnupg2 \
libfontconfig lftp xvfb gconf-service libasound2 libatk1.0-0 libc6 \
libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 \
libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 \
libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \
libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 \
libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \
&& rm -rf /var/lib/apt/lists/* \
&& npm -g install pm2
# Salix
WORKDIR /salix
COPY print/package.json print/package-lock.json print/
RUN npm --prefix ./print install --omit=dev ./print
COPY package.json package-lock.json ./
COPY loopback/package.json loopback/
COPY print/package.json print/
RUN npm install --only=prod
RUN npm --prefix ./print install --only=prod ./print
RUN npm install --omit=dev
COPY loopback loopback
COPY back back

View File

@ -47,20 +47,22 @@ module.exports = Self => {
for (let dms of dmsToDelete) {
const pathHash = DmsContainer.getHash(dms.id);
const dmsContainer = await DmsContainer.container(pathHash);
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
try {
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
await fs.unlink(dstFile);
} catch (err) {
continue;
if (err.code != 'ENOENT')
throw err;
}
await dms.destroy(myOptions);
const dstFolder = path.join(dmsContainer.client.root, pathHash);
try {
await fs.rmdir(dstFolder);
} catch (err) {
continue;
}
await dms.destroy(myOptions);
}
};
};

View File

@ -1,4 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('InvoiceIn', 'invoiceInPdf', 'READ', 'ALLOW', 'ROLE', 'administrative'),
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -47,12 +47,8 @@ module.exports = class Docker {
if (ci) network = `--network="${networkName}"`;
log('Starting container...');
const container = await this.execP(`
docker run \
${network} \
--env RUN_CHOWN=${runChown} \
-d ${dockerArgs} salix-db
`);
const container = await this.execP(
`docker run ${network} --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
this.id = container.stdout.trim();
try {

View File

@ -918,7 +918,7 @@ INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
(3, 'Perdida', 'LOST');
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `itemFk`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
VALUES
(1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 15, 1, 18, 'UR9000006041', 94, 1, 'pc1'),
(2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 16, 2, 18, 'UR9000006041', 94, 1, NULL),

View File

@ -27518,7 +27518,7 @@ CREATE TABLE `expedition` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`agencyModeFk` int(11) NOT NULL,
`ticketFk` int(10) NOT NULL,
`isBox` int(11) DEFAULT 1 COMMENT 'Este campo realmente en un campo itemFk, haciendo referencia al artículo que nos va a facturar el proveedor de transporte.\nSe debería llamar freightItemFk',
`freightItemFk` int(11) DEFAULT 1 COMMENT 'Este campo realmente en un campo itemFk, haciendo referencia al artículo que nos va a facturar el proveedor de transporte.\nSe debería llamar freightItemFk',
`created` timestamp NULL DEFAULT current_timestamp(),
`isRefund__` bit(1) DEFAULT b'0' COMMENT 'Deprecado 01/06/2022',
`isPickUp__` bit(1) DEFAULT b'0' COMMENT 'Deprecado 01/06/2022',
@ -27534,7 +27534,7 @@ CREATE TABLE `expedition` (
`hasNewRoute` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`),
KEY `index1` (`agencyModeFk`),
KEY `index2` (`isBox`),
KEY `index2` (`freightItemFk`),
KEY `index3` (`created`),
KEY `index4` (`ticketFk`),
KEY `expedition_fk3_idx` (`packagingFk`),
@ -27567,7 +27567,7 @@ BEGIN
DECLARE vShipFk INT;
IF NEW.isBox > 0 THEN
IF NEW.freightItemFk > 0 THEN
UPDATE ticket SET packages = nz(packages) + 1 WHERE id = NEW.ticketFk;
@ -27638,7 +27638,7 @@ DELIMITER ;;
BEGIN
UPDATE ticket t
SET packages = (SELECT COUNT(counter)-1
FROM expedition e WHERE e.ticketFk = OLD.ticketFk and e.isBox)
FROM expedition e WHERE e.ticketFk = OLD.ticketFk and e.freightItemFk)
WHERE t.id = OLD.ticketFk;
END */;;
@ -36287,7 +36287,7 @@ CREATE TABLE `sorter` (
`created` datetime NOT NULL,
`routeFk` int(10) unsigned NOT NULL,
`ticketFk` int(10) NOT NULL,
`isBox` int(11) DEFAULT 1,
`freightItemFk` int(11) DEFAULT 1,
`itemFk` int(11) DEFAULT NULL,
`width` decimal(10,2) DEFAULT 0.00,
`depth` decimal(10,2) DEFAULT 0.00,
@ -44956,7 +44956,7 @@ BEGIN
SELECT SUM((t.zonePrice - t.zoneBonus) * ebv.ratio) INTO deliveryPrice
FROM vn.ticket t
LEFT JOIN expedition e ON e.ticketFk = t.id
JOIN expeditionBoxVol ebv ON ebv.boxFk = e.isBox
JOIN expeditionBoxVol ebv ON ebv.boxFk = e.freightItemFk
WHERE t.id = vTicketFk;
END IF;
@ -46492,7 +46492,7 @@ BEGIN
LEFT JOIN item i ON i.id = b.itemFk
LEFT JOIN itemType it ON it.id = i.typeFk
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
LEFT JOIN packaging p ON p.id = b.packageFk AND NOT p.isBox
LEFT JOIN packaging p ON p.id = b.packageFk AND NOT p.freightItemFk
JOIN volumeConfig vc ON TRUE
WHERE b.id = vSelf;
@ -53229,7 +53229,7 @@ BEGIN
INNER JOIN vn.ticketState ts ON ts.ticketFk = exp.ticketFk
LEFT JOIN vn.address a ON t.addressFk = a.id
LEFT JOIN vn.warehouse w ON t.warehouseFk = w.id
WHERE t.routeFk = vRouteFk AND exp.isBox > 0;
WHERE t.routeFk = vRouteFk AND exp.freightItemFk > 0;
END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -53760,7 +53760,7 @@ BEGIN
GROUP BY sub.ticketFk
) sub2 ON sub2.ticketFk = t.id
LEFT JOIN expeditionStateType est ON est.id = e.stateTypeFk
WHERE t.routeFk = vRouteFk AND e.isBox <> FALSE
WHERE t.routeFk = vRouteFk AND e.freightItemFk <> FALSE
ORDER BY r.created, t.priority DESC;
END ;;
DELIMITER ;

View File

@ -3,7 +3,7 @@
ng-transclude="prepend"
class="prepend">
</div>
<div class="infix">
<div class="infix" >
<div class="fix prefix"></div>
<div class="control">
<section
@ -13,8 +13,7 @@
</section>
<input
type="file"
accept="{{$ctrl.accept}}"
style="display: none;">
accept="{{$ctrl.accept}}">
</input>
</div>
<div class="fix suffix"></div>

View File

@ -4,4 +4,13 @@
.value {
cursor: pointer;
}
.control {
& > input[type=file] {
opacity: 0;
}
& > section {
position: absolute;
bottom: 0;
}
}
}

View File

@ -24,10 +24,11 @@
}
},
"node_modules/@uirouter/angularjs": {
"version": "1.0.29",
"license": "MIT",
"version": "1.0.30",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
"dependencies": {
"@uirouter/core": "6.0.7"
"@uirouter/core": "6.0.8"
},
"engines": {
"node": ">=4.0.0"
@ -37,15 +38,18 @@
}
},
"node_modules/@uirouter/core": {
"version": "6.0.7",
"license": "MIT",
"version": "6.0.8",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/angular": {
"version": "1.8.2",
"license": "MIT"
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==",
"deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward."
},
"node_modules/angular-animate": {
"version": "1.8.2",
@ -62,8 +66,9 @@
}
},
"node_modules/angular-translate": {
"version": "2.18.4",
"license": "MIT",
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
"dependencies": {
"angular": "^1.8.0"
},
@ -72,10 +77,11 @@
}
},
"node_modules/angular-translate-loader-partial": {
"version": "2.18.4",
"license": "MIT",
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
"dependencies": {
"angular-translate": "~2.18.4"
"angular-translate": "~2.19.0"
}
},
"node_modules/argparse": {
@ -119,8 +125,9 @@
}
},
"node_modules/moment": {
"version": "2.29.1",
"license": "MIT",
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"engines": {
"node": "*"
}
@ -164,16 +171,22 @@
},
"dependencies": {
"@uirouter/angularjs": {
"version": "1.0.29",
"version": "1.0.30",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
"requires": {
"@uirouter/core": "6.0.7"
"@uirouter/core": "6.0.8"
}
},
"@uirouter/core": {
"version": "6.0.7"
"version": "6.0.8",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
},
"angular": {
"version": "1.8.2"
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
},
"angular-animate": {
"version": "1.8.2"
@ -185,15 +198,19 @@
}
},
"angular-translate": {
"version": "2.18.4",
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
"requires": {
"angular": "^1.8.0"
}
},
"angular-translate-loader-partial": {
"version": "2.18.4",
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
"requires": {
"angular-translate": "~2.18.4"
"angular-translate": "~2.19.0"
}
},
"argparse": {
@ -222,7 +239,9 @@
}
},
"moment": {
"version": "2.29.1"
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"oclazyload": {
"version": "0.6.3"

View File

@ -239,5 +239,6 @@
"This route does not exists": "Esta ruta no existe",
"Claim pickup order sent": "Reclamación Orden de recogida enviada [({{claimId}})]({{{claimUrl}}}) al cliente *{{clientName}}*",
"You don't have grant privilege": "No tienes privilegios para dar privilegios",
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario"
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario",
"Empty data source": "Origen de datos vacio"
}

View File

@ -0,0 +1,40 @@
const {Email} = require('vn-print');
module.exports = Self => {
Self.remoteMethodCtx('balanceCompensationEmail', {
description: 'Sends the debit balances compensation email with an attached PDF',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'Number',
required: true,
description: 'The receipt id',
http: { source: 'path' }
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: '/:id/balance-compensation-email',
verb: 'POST'
}
});
Self.balanceCompensationEmail = async (ctx, id) => {
const models = Self.app.models;
const receipt = await models.Receipt.findById(id, {fields: ['clientFk']});
const client = await models.Client.findById(receipt.clientFk, {fields:['email']});
const email = new Email('balance-compensation', {
lang: ctx.req.getLocale(),
recipient: client.email+',administracion@verdnatura.es',
id
});
return email.send();
};
};

View File

@ -0,0 +1,50 @@
const { Report } = require('vn-print');
module.exports = Self => {
Self.remoteMethodCtx('balanceCompensationPdf', {
description: 'Returns the the debit balances compensation pdf',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The receipt id',
http: { source: 'path' }
}
],
returns: [
{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'String',
http: {target: 'header'}
}, {
arg: 'Content-Disposition',
type: 'String',
http: {target: 'header'}
}
],
http: {
path: '/:id/balance-compensation-pdf',
verb: 'GET'
}
});
Self.balanceCompensationPdf = async(ctx, id) => {
const args = Object.assign({}, ctx.args);
const params = {lang: ctx.req.getLocale()};
delete args.ctx;
for (const param in args)
params[param] = args[param];
const report = new Report('balance-compensation', params);
const stream = await report.toPdfStream();
return [stream, 'application/pdf', `filename="doc-${id}.pdf"`];
};
};

View File

@ -2,6 +2,8 @@ const LoopBackContext = require('loopback-context');
module.exports = function(Self) {
require('../methods/receipt/filter')(Self);
require('../methods/receipt/balanceCompensationEmail')(Self);
require('../methods/receipt/balanceCompensationPdf')(Self);
require('../methods/receipt/receiptPdf')(Self);
Self.validateBinded('amountPaid', isNotZero, {

View File

@ -121,9 +121,22 @@
</vn-icon-button>
</a>
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
<vn-td center shrink ng-if="!balance.isInvoice">
<vn-icon-button
vn-dialog="send_compensation"
icon="outgoing_mail"
title="{{'Send compensation' | translate}}">
</vn-icon-button>
</vn-td>
<vn-confirm
vn-id="send_compensation"
on-accept="$ctrl.sendEmail(balance)"
question="Notify compensation"
message="Send compensation">
</vn-confirm>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
</div>

View File

@ -2,8 +2,9 @@ import ngModule from '../../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
constructor($element, $, vnEmail) {
super($element, $);
this.vnEmail = vnEmail;
this.filter = {
include: {
relation: 'company',
@ -54,45 +55,49 @@ class Controller extends Section {
}
})).then(() => this.getBalances());
}
getCurrentBalance() {
const clientRisks = this.$.riskModel.data;
const selectedCompany = this.companyId;
const currentBalance = clientRisks.find(balance => {
return balance.companyFk === selectedCompany;
});
return currentBalance && currentBalance.amount;
}
getBalances() {
const balances = this.$.model.data;
balances.forEach((balance, index) => {
if (index === 0)
balance.balance = this.getCurrentBalance();
balance.balance = this.getCurrentBalance();
if (index > 0) {
let previousBalance = balances[index - 1];
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
}
});
}
showInvoiceOutDescriptor(event, balance) {
if (!balance.isInvoice) return;
if (event.defaultPrevented) return;
this.$.invoiceOutDescriptor.show(event.target, balance.id);
}
changeDescription(balance) {
const params = {description: balance.description};
const endpoint = `Receipts/${balance.id}`;
this.$http.patch(endpoint, params)
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
}
sendEmail(balance) {
return this.vnEmail.send(`Receipts/${balance.id}/balance-compensation-email`);
}
}
Controller.$inject = ['$element', '$scope'];
Controller.$inject = ['$element', '$scope', 'vnEmail'];
ngModule.vnComponent('vnClientBalanceIndex', {
template: require('./index.html'),

View File

@ -8,4 +8,6 @@ Havings: Haber
Balance: Balance
Total by company: Total por empresa
Download PDF: Descargar PDF
BILL: N/FRA {{ref}}
Send compensation: Enviar compensación
BILL: N/FRA {{ref}}
Notify compensation: ¿Desea informar de la compensación al cliente por correo?

View File

@ -91,7 +91,7 @@
url="Packagings"
show-field="id"
value-field="id"
where="{isBox: true}"
where="{freightItemFk: true}"
ng-model="buy.packageFk"
on-change="$ctrl.saveBuy(buy)">
</vn-autocomplete>

View File

@ -32,7 +32,7 @@ module.exports = Self => {
`SELECT
e.id,
e.ticketFk,
e.isBox,
e.freightItemFk,
e.workerFk,
i1.name packageItemName,
e.counter,
@ -51,7 +51,7 @@ module.exports = Self => {
FROM vn.expedition e
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
LEFT JOIN vn.item i2 ON i2.id = e.itemFk
INNER JOIN vn.item i1 ON i1.id = e.isBox
INNER JOIN vn.item i1 ON i1.id = e.freightItemFk
LEFT JOIN vn.packaging p ON p.id = e.packagingFk
LEFT JOIN vn.item i3 ON i3.id = p.itemFk
LEFT JOIN account.user u ON u.id = e.workerFk

View File

@ -0,0 +1,50 @@
const {Report} = require('vn-print');
module.exports = Self => {
Self.remoteMethodCtx('collectionLabel', {
description: 'Returns the collection label',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
},
],
returns: [
{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'String',
http: {target: 'header'}
}, {
arg: 'Content-Disposition',
type: 'String',
http: {target: 'header'}
}
],
http: {
path: '/:id/collection-label',
verb: 'GET'
}
});
Self.collectionLabel = async(ctx, id) => {
const args = Object.assign({}, ctx.args);
const params = {lang: ctx.req.getLocale()};
delete args.ctx;
for (const param in args)
params[param] = args[param];
const report = new Report('collection-label', params);
const stream = await report.toPdfStream();
return [stream, 'application/pdf', `filename="doc-${id}.pdf"`];
};
};

View File

@ -16,7 +16,7 @@
"type": "number",
"description": "Identifier"
},
"isBox": {
"freightItemFk": {
"type": "number"
},
"created": {
@ -55,7 +55,7 @@
"freightItem": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "isBox"
"foreignKey": "freightItemFk"
},
"packaging": {
"type": "belongsTo",

View File

@ -33,4 +33,5 @@ module.exports = function(Self) {
require('../methods/ticket/closeByTicket')(Self);
require('../methods/ticket/closeByAgency')(Self);
require('../methods/ticket/closeByRoute')(Self);
require('../methods/ticket/collectionLabel')(Self);
};

40216
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@
"puppeteer": "^18.0.5",
"read-chunk": "^3.2.0",
"require-yaml": "0.0.1",
"sharp": "^0.31.0",
"sharp": "^0.31.2",
"smbhash": "0.0.1",
"strong-error-handler": "^2.3.2",
"uuid": "^3.3.3",
@ -80,7 +80,7 @@
"html-loader-jest": "^0.2.1",
"html-webpack-plugin": "^4.0.0-beta.11",
"identity-obj-proxy": "^3.0.0",
"jasmine": "^4.1.0",
"jasmine": "^4.5.0",
"jasmine-reporters": "^2.4.0",
"jasmine-spec-reporter": "^7.0.0",
"jest": "^26.0.1",

View File

@ -0,0 +1,11 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/email.css`])
.mergeStyles();

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width" />
<meta name="format-detection" content="telephone=no" />
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<slot name="header">
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
</slot>
<slot></slot>
<slot name="footer">
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
</slot>
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,12 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
name: 'email-body',
};

View File

@ -3,7 +3,7 @@
<div class="buttons">
<div class="columns">
<div class="size50">
<a href="https://www.verdnatura.es" target="_blank">
<a href="https://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>

View File

@ -2,7 +2,7 @@ buttons:
webAcccess: Visit our website
info: Help us to improve
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESI
· www.verdnatura.es · clientes@verdnatura.es
· verdnatura.es · clientes@verdnatura.es
disclaimer: '- NOTICE - This message is private and confidential, and should be used
exclusively by the person receiving it. If you have received this message by mistake,
please notify the sender and delete that message and any attached documents that it may contain.

View File

@ -2,7 +2,7 @@ buttons:
webAcccess: Visita nuestra Web
info: Ayúdanos a mejorar
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESI
· www.verdnatura.es · clientes@verdnatura.es
· 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

View File

@ -2,7 +2,7 @@ buttons:
webAcccess: Visitez notre site web
info: Aidez-nous à améliorer
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESI
· www.verdnatura.es · clientes@verdnatura.es
· verdnatura.es · clientes@verdnatura.es
disclaimer: "- AVIS - Ce message est privé et confidentiel et doit être utilisé
exclusivement par le destinataire. Si vous avez reçu ce message par erreur,
veuillez en informer l'expéditeur et supprimer ce message ainsi que tous les

View File

@ -2,7 +2,7 @@ buttons:
webAcccess: Visite o nosso site
info: Ajude-nos a melhorar
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESI
· www.verdnatura.es · clientes@verdnatura.es
· verdnatura.es · clientes@verdnatura.es
disclaimer: '- AVISO - Esta mensagem é privada e confidencial e deve ser usada exclusivamente
pela pessoa que a recebe. Se você recebeu esta mensagem por engano, notifique o remetente e
exclua essa mensagem e todos os documentos anexos que ela possa conter.

View File

@ -1,7 +1,7 @@
<header>
<div class="logo">
<a href="https://www.verdnatura.es" target="_blank">
<img v-bind:src="getEmailSrc('logo-black.png')" alt="VerdNatura"/>
<a href="https://verdnatura.es" target="_blank">
<img v-bind:src="getEmailSrc('logo-black.png')" alt="VerdNatura" />
</a>
</div>
<div class="topbar"></div>

View File

@ -0,0 +1,10 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/report.css`,
`${vnPrintPath}/common/css/misc.css`])
.mergeStyles();

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<slot name="header">
<report-header v-bind="$props"></report-header>
</slot>
<slot></slot>
<slot name="footer">
<report-footer id="pageFooter" v-bind="$props"></report-footer>
</slot>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,12 @@
const Component = require(`vn-print/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
module.exports = {
name: 'report-body',
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
};

View File

@ -1,2 +1,2 @@
company:
contactData: www.verdnatura.es - clientes@verdnatura.es
contactData: verdnatura.es - clientes@verdnatura.es

View File

@ -1,2 +1,2 @@
company:
contactData: www.verdnatura.es - clientes@verdnatura.es
contactData: verdnatura.es - clientes@verdnatura.es

View File

@ -1,2 +1,2 @@
company:
contactData: www.verdnatura.es - clientes@verdnatura.es
contactData: verdnatura.es - clientes@verdnatura.es

View File

@ -1,2 +1,2 @@
company:
contactData: · www.verdnatura.es · clientes@verdnatura.es
contactData: · verdnatura.es · clientes@verdnatura.es

View File

@ -32,7 +32,7 @@ class Email extends Component {
const rendered = await this.render();
const attachments = [];
const getAttachments = async(componentPath, files) => {
for (file of files) {
for (const file of files) {
const fileCopy = Object.assign({}, file);
const fileName = fileCopy.filename;
@ -54,15 +54,22 @@ class Email extends Component {
}
};
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);
async function getSubcomponentAttachments(instance) {
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 (component.components)
await getSubcomponentAttachments(component)
}
}
}
await getSubcomponentAttachments(instance)
if (this.attachments)
await getAttachments(this.path, this.attachments);

View File

@ -0,0 +1,11 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/email.css`])
.mergeStyles();

View File

@ -0,0 +1,6 @@
[
{
"filename": "balance-compensation.pdf",
"component": "balance-compensation"
}
]

View File

@ -0,0 +1,17 @@
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<p>{{$t('description.instructions')}} {{client.name}}</p>
<p>{{$t('description.attached')}}</p>
<p>{{$t('description.response')}}</p>
<p>{{$t('description.regards')}}</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -0,0 +1,36 @@
const Component = require(`vn-print/core/component`);
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
name: 'balance-compensation',
async serverPrefetch() {
this.client = await this.fetchClient(this.id);
},
methods: {
fetchClient(id) {
return this.findOneFromDef('client', [id]);
},
},
components: {
'email-body': emailBody.build(),
'attachment': attachment.build()
},
data() {
return {
attachments: [
{
filename: 'balance-compensation.pdf',
type: 'pdf',
path: `Receipts/${this.id}/balance-compensation-pdf`
}
]
};
},
props: {
id: {
type: Number,
required: true
}
}
};

View File

@ -0,0 +1,6 @@
subject: Compensación VerdNatura SL
description:
instructions: Buenos días,
attached: Adjuntamos escrito para su confirmación
response: Rogamos su respuesta a la mayor brevedad
regards: Un saludo

View File

@ -0,0 +1,5 @@
SELECT
c.name
FROM client c
JOIN receipt r ON r.clientFk = c.id
WHERE r.id = ?;

View File

@ -1,76 +1,37 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [dated])"></p>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('buyer')}}</th>
<th class="number">{{$t('percentage')}}</th>
<th class="number">{{$t('dwindle')}}</th>
<th class="number">{{$t('total')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="waste in wastes" v-bind:key="waste.buyer">
<td class="font gray">{{waste.buyer}}</td>
<td class="number">{{(waste.percentage / 100) | percentage(2, 2, $i18n.locale)}}</td>
<td class="number">{{waste.dwindle | currency('EUR', $i18n.locale)}}</td>
<td class="number">{{waste.total | currency('EUR', $i18n.locale)}}</td>
</tr>
</tbody>
</table>
<p v-html="$t('wasteDetailLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a href="https://salix.verdnatura.es/#!/item/waste/index" target="_blank">
https://salix.verdnatura.es/#!/item/waste/index
</a>
</div>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [dated])"></p>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('buyer')}}</th>
<th class="number">{{$t('percentage')}}</th>
<th class="number">{{$t('dwindle')}}</th>
<th class="number">{{$t('total')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="waste in wastes" v-bind:key="waste.buyer">
<td class="font gray">{{waste.buyer}}</td>
<td class="number">{{(waste.percentage / 100) | percentage(2, 2, $i18n.locale)}}</td>
<td class="number">{{waste.dwindle | currency('EUR', $i18n.locale)}}</td>
<td class="number">{{waste.total | currency('EUR', $i18n.locale)}}</td>
</tr>
</tbody>
</table>
<p v-html="$t('wasteDetailLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a href="https://salix.verdnatura.es/#!/item/waste/index" target="_blank">
https://salix.verdnatura.es/#!/item/waste/index
</a>
</div>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'buyer-week-waste',
@ -23,8 +22,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build()
},
props: {}
};

View File

@ -1,46 +1,9 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [minDate, maxDate])"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [minDate, maxDate])"></p>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'campaign-metrics',
@ -16,8 +15,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -1,47 +1,10 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title', [id]) }}</h1>
<p>{{ $t('description.dear') }},</p>
<p v-html="instructions"></p>
<p>{{ $t('description.conclusion') }}</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title', [id]) }}</h1>
<p>{{ $t('description.dear') }},</p>
<p v-html="instructions"></p>
<p>{{ $t('description.conclusion') }}</p>
</div>
</div>
</email-body>

View File

@ -1,12 +1,10 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'claim-pickup-order',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
async serverPrefetch() {
this.ticket = await this.fetchTicket(this.id);

View File

@ -0,0 +1,6 @@
[
{
"filename": "client-debt-statement.pdf",
"component": "client-debt-statement"
}
]

View File

@ -1,55 +1,15 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
<!-- Preview block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,13 +1,11 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
name: 'client-debt-statement',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
data() {

View File

@ -1,92 +1,56 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dearClient')}},</p>
<p v-html="$t('clientData')"></p>
<p>
<div>{{$t('clientId')}}: <strong>{{client.id}}</strong></div>
<div>{{$t('user')}}: <strong>{{client.userName}}</strong></div>
<div>{{$t('password')}}: <strong>********</strong>
(<a href="https://verdnatura.es">{{$t('passwordResetText')}}</a>)
</div>
</p>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dearClient')}},</p>
<p v-html="$t('clientData')"></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>
<h1>{{$t('sections.howToPay.title')}}</h1>
<p>{{$t('sections.howToPay.description')}}</p>
<ul>
<li v-for="option in $t('sections.howToPay.options')">
<span v-html="option"></span>
</li>
</ul>
<p>
<div>{{$t('clientId')}}: <strong>{{client.id}}</strong></div>
<div>{{$t('user')}}: <strong>{{client.userName}}</strong></div>
<div>{{$t('password')}}: <strong>********</strong>
(<a href="https://verdnatura.es">{{$t('passwordResetText')}}</a>)
</div>
</p>
<h1>{{$t('sections.toConsider.title')}}</h1>
<p>{{$t('sections.toConsider.description')}}</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>
<h4>{{$t('sections.claimsPolicy.title')}}</h4>
<p>{{$t('sections.claimsPolicy.description')}}</p>
<h1>{{$t('sections.howToPay.title')}}</h1>
<p>{{$t('sections.howToPay.description')}}</p>
<ul>
<li v-for="option in $t('sections.howToPay.options')">
<span v-html="option"></span>
</li>
</ul>
<p v-html="$t('help')"></p>
<p>
<section v-if="client.salesPersonName">
{{$t('salesPersonName')}}: <strong>{{client.salesPersonName}}</strong>
</section>
<section v-if="client.salesPersonPhone">
{{$t('salesPersonPhone')}}: <strong>{{client.salesPersonPhone}}</strong>
</section>
<section v-if="client.salesPersonEmail">
{{$t('salesPersonEmail')}}:
<strong><a v-bind:href="`mailto: ${client.salesPersonEmail}`" target="_blank">{{client.salesPersonEmail}}</strong>
</section>
</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<h1>{{$t('sections.toConsider.title')}}</h1>
<p>{{$t('sections.toConsider.description')}}</p>
<h4>{{$t('sections.claimsPolicy.title')}}</h4>
<p>{{$t('sections.claimsPolicy.description')}}</p>
<p v-html="$t('help')"></p>
<p>
<section v-if="client.salesPersonName">
{{$t('salesPersonName')}}: <strong>{{client.salesPersonName}}</strong>
</section>
<section v-if="client.salesPersonPhone">
{{$t('salesPersonPhone')}}: <strong>{{client.salesPersonPhone}}</strong>
</section>
<section v-if="client.salesPersonEmail">
{{$t('salesPersonEmail')}}:
<strong><a v-bind:href="`mailto: ${client.salesPersonEmail}`"
target="_blank">{{client.salesPersonEmail}}</strong>
</section>
</p>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'client-welcome',
@ -13,8 +12,7 @@ module.exports = {
},
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -1,8 +1,8 @@
subject: Bienvenido a Verdnatura
title: "¡Te damos la bienvenida!"
dearClient: Estimado cliente
clientData: 'Tus datos para poder comprar en la web de Verdnatura (<a href="https://www.verdnatura.es"
title="Visitar Verdnatura" target="_blank" style="color: #8dba25">https://www.verdnatura.es</a>)
clientData: 'Tus datos para poder comprar en la web de Verdnatura (<a href="https://verdnatura.es"
title="Visitar Verdnatura" target="_blank" style="color: #8dba25">https://verdnatura.es</a>)
o en nuestras aplicaciones para <a href="https://goo.gl/3hC2mG" title="App Store"
target="_blank" style="color: #8dba25">iOS</a> y <a href="https://goo.gl/8obvLc"
title="Google Play" target="_blank" style="color: #8dba25">Android</a>, son'

View File

@ -1,55 +1,15 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
<!-- Preview block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,13 +1,11 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
name: 'credit-request',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
data() {

View File

@ -2,4 +2,8 @@
border: 2px dashed #8dba25;
border-radius: 3px;
text-align: center
}
a {
color: #8dba25
}

View File

@ -1,69 +1,24 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
<style type="text/css">
a {
color: #8dba25
}
</style>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}}</p>
<p v-html="$t('description', [id])"></p>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-px-ml">
<p>{{$t('copyLink')}}</p>
<div class="external-link vn-pa-sm vn-m-md">
https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={{id}}
</div>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}}</p>
<p v-html="$t('description', [id])"></p>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-px-ml">
<p>{{$t('copyLink')}}</p>
<div class="external-link vn-pa-sm vn-m-md">
https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={{id}}
</div>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
</email-body>

View File

@ -1,12 +1,10 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'delivery-note-link',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -2,7 +2,7 @@ subject: Your delivery note
title: Your delivery note
dear: Dear client
description: The delivery note from the order <strong>{0}</strong> is now available. <br/>
You can download it by clicking <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">this link</a>.
You can download it by clicking <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">this link</a>.
copyLink: 'As an alternative, you can copy the following link in your browser:'
poll: If you wish, you can answer our satisfaction survey to
help us provide better service. Your opinion is very important for us!

View File

@ -2,7 +2,7 @@ subject: Tu albarán
title: Tu albarán
dear: Estimado cliente
description: Ya está disponible el albarán correspondiente al pedido <strong>{0}</strong>. <br/>
Puedes verlo haciendo clic <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">en este enlace</a>.
Puedes verlo haciendo clic <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">en este enlace</a>.
copyLink: 'Como alternativa, puedes copiar el siguiente enlace en tu navegador:'
poll: Si lo deseas, puedes responder a nuestra encuesta de satisfacción para
ayudarnos a prestar un mejor servicio. ¡Tu opinión es muy importante para nosotros!

View File

@ -2,7 +2,7 @@ subject: Votre bon de livraison
title: Votre bon de livraison
dear: Cher client,
description: Le bon de livraison correspondant à la commande <strong>{0}</strong> est maintenant disponible.<br/>
Vous pouvez le voir en cliquant <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}" target="_blank">sur ce lien</a>.
Vous pouvez le voir en cliquant <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}" target="_blank">sur ce lien</a>.
copyLink: 'Vous pouvez également copier le lien suivant dans votre navigateur:'
poll: Si vous le souhaitez, vous pouvez répondre à notre questionaire de satisfaction
pour nous aider à améliorer notre service. Votre avis est très important pour nous!

View File

@ -2,7 +2,7 @@ subject: Sua nota de entrega
title: Sua nota de entrega
dear: Estimado cliente
description: Já está disponível sua nota de entrega correspondente a encomenda numero <strong>{0}</strong>. <br/>
Para ver-lo faça um clique <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">neste link</a>.
Para ver-lo faça um clique <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">neste link</a>.
copyLink: 'Como alternativa, podes copiar o siguinte link no teu navegador:'
poll: Si o deseja, podes responder nosso questionário de satiscação para ajudar-nos a prestar-vos um melhor serviço. Tua opinião é muito importante para nós!
help: Cualquer dúvida que surja, no hesites em consultar-la, <strong>Estamos aqui para

View File

@ -1,49 +1,12 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [id])"></p>
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [id])"></p>
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
</email-body>

View File

@ -1,12 +1,10 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'delivery-note',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -1,45 +1,8 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.instructions')}}</p>
</div>
</div>
</email-body>

View File

@ -1,12 +1,10 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'driver-route',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -1,57 +1,17 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<p>{{$t('description.conclusion')}}</p>
</div>
</div>
<!-- Attachments block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<p>{{$t('description.conclusion')}}</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
@ -17,8 +16,7 @@ module.exports = {
};
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
props: {

View File

@ -1,49 +1,12 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [invoice.ref, invoice.ticketFk])"></p>
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [invoice.ref, invoice.ticketFk])"></p>
<p v-html="$t('poll')"></p>
<p v-html="$t('help')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
</email-body>

View File

@ -1,7 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'invoice',
async serverPrefetch() {
@ -13,8 +11,7 @@ module.exports = {
},
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
reference: {

View File

@ -1,47 +1,10 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description')"></p>
<p v-html="$t('conclusion')"></p>
</div>
</div>
</email-body>

View File

@ -1,11 +1,8 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'invoiceIn',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
}
};

View File

@ -1,88 +1,48 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p>{{ $t('sections.introduction.description') }}</p>
<p>{{ $t('sections.introduction.terms') }}</p>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p>{{ $t('sections.introduction.description') }}</p>
<p>{{ $t('sections.introduction.terms') }}</p>
<p>
{{ $t('sections.payMethod.description') }}:
<ol>
<li v-for="option in $t('sections.payMethod.options')">
{{ option }}
</li>
</ol>
</p>
<p>
{{ $t('sections.payMethod.description') }}:
<ol>
<li v-for="option in $t('sections.payMethod.options')">
{{ option }}
</li>
</ol>
</p>
<p>
{{ $t('sections.legalAction.description') }}:
<ol type="a">
<li v-for="option in $t('sections.legalAction.options')">
{{ option }}
</li>
</ol>
</p>
<p>
{{ $t('sections.legalAction.description') }}:
<ol type="a">
<li v-for="option in $t('sections.legalAction.options')">
{{ option }}
</li>
</ol>
</p>
<p v-html="$t('contactPhone')"></p>
<p v-html="$t('conclusion')"></p>
<p v-html="$t('contactPhone')"></p>
<p v-html="$t('conclusion')"></p>
<p>
<div class="row">
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
</div>
</p>
</div>
</div>
<!-- Block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<p>
<div class="row">
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
</div>
</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
@ -28,8 +27,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
props: {

View File

@ -1,71 +1,31 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p>{{ $t('sections.introduction.description') }}</p>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p>{{ $t('sections.introduction.description') }}</p>
<p>{{ $t('checkExtract') }}</p>
<p>{{ $t('checkValidData') }}</p>
<p>{{ $t('payMethod') }}</p>
<p>{{ $t('conclusion') }}</p>
<p>{{ $t('checkExtract') }}</p>
<p>{{ $t('checkValidData') }}</p>
<p>{{ $t('payMethod') }}</p>
<p>{{ $t('conclusion') }}</p>
<p>
<div class="row">
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
</div>
</p>
</div>
</div>
<!-- Block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<p>
<div class="row">
<div class="text">{{debtor.bankName}}</div>
<div class="control">{{debtor.iban}}</div>
<div class="description">
<div class="line"><span>{{$t('transferAccount') }}</span></div>
</div>
</div>
</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
module.exports = {
@ -28,8 +27,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
props: {

View File

@ -1,99 +1,59 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [started, ended])"></p>
<p v-html="$t('totalResolved', [resolvedTickets])"></p>
<p v-html="$t('grafanaLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a v-bind:href="'https://grafana.verdnatura.es/d/2kaHDi9Mk/osticket?orgId=1&from=' + startedTime + '&to=' + endedTime" target="_blank">
https://grafana.verdnatura.es/d/2kaHDi9Mk/osticket?orgId=1&from={{startedTime}}&to={{endedTime}}
</a>
</div>
<p v-html="$t('redmineLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a href="https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112" target="_blank">
https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112
</a>
</div>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml" v-for="technician in technicians">
<div class="table-title clearfix">
<h2>{{technician.name}} (<strong>{{technician.tickets.length}}</strong>)</h2>
</div>
<table class="column-oriented">
<thead>
<tr>
<th width="5%">{{$t('author')}}</th>
<th width="15%">{{$t('dated')}}</th>
<th width="25%">{{$t('ticketSubject')}}</th>
<th width="30%">{{$t('ticketDescription')}}</th>
<th width="20%">{{$t('resolution')}}</th>
</tr>
</thead>
<tbody v-for="ticket in technician.tickets">
<tr>
<td>{{ticket.author}}</td>
<td class="font light-gray">
<div v-bind:title="$t('opened')">
&#128275; {{ticket.created | date('%d-%m-%Y %H:%M')}}
</div>
<div v-bind:title="$t('closed')">
&#128274; {{ticket.closed | date('%d-%m-%Y %H:%M')}}
</div>
</td>
<td>
<a v-bind:href="'https://cau.verdnatura.es/scp/tickets.php?id=' + ticket.ticket_id">
{{ticket.number}} - {{ticket.subject}}
</a>
</td>
<td class="message" v-html="ticket.description"></td>
<td class="message" v-html="ticket.resolution"></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [started, ended])"></p>
<p v-html="$t('totalResolved', [resolvedTickets])"></p>
<p v-html="$t('grafanaLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a
v-bind:href="'https://grafana.verdnatura.es/d/2kaHDi9Mk/osticket?orgId=1&from=' + startedTime + '&to=' + endedTime"
target="_blank"
>
https://grafana.verdnatura.es/d/2kaHDi9Mk/osticket?orgId=1&from={{startedTime}}&to={{endedTime}}
</a>
</div>
<p v-html="$t('redmineLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a href="https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112" target="_blank">
https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112
</a>
</div>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-pa-ml" v-for="technician in technicians">
<div class="table-title clearfix">
<h2>{{technician.name}} (<strong>{{technician.tickets.length}}</strong>)</h2>
</div>
<table class="column-oriented">
<thead>
<tr>
<th width="5%">{{$t('author')}}</th>
<th width="15%">{{$t('dated')}}</th>
<th width="25%">{{$t('ticketSubject')}}</th>
<th width="30%">{{$t('ticketDescription')}}</th>
<th width="20%">{{$t('resolution')}}</th>
</tr>
</thead>
<tbody v-for="ticket in technician.tickets">
<tr>
<td>{{ticket.author}}</td>
<td class="font light-gray">
<div v-bind:title="$t('opened')">&#128275; {{ticket.created | date('%d-%m-%Y %H:%M')}}</div>
<div v-bind:title="$t('closed')">&#128274; {{ticket.closed | date('%d-%m-%Y %H:%M')}}</div>
</td>
<td>
<a v-bind:href="'https://cau.verdnatura.es/scp/tickets.php?id=' + ticket.ticket_id">
{{ticket.number}} - {{ticket.subject}}
</a>
</td>
<td class="message" v-html="ticket.description"></td>
<td class="message" v-html="ticket.resolution"></td>
</tr>
</tbody>
</table>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'osticket-report',
@ -61,8 +60,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {}
};

View File

@ -1,66 +1,28 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p v-html="`${$t('sections.introduction.description')}:`"></p>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{ $t('sections.introduction.title') }},</p>
<p v-html="`${$t('sections.introduction.description')}:`"></p>
<p>
<section>
<span>{{ $t('sections.pay.method') }}:</span>
<strong>{{payMethod.name}}</strong>
</section>
<section v-if="payMethod.code != 'card'">
<span>{{ $t('sections.pay.day') }}:</span>
<strong>{{ $t('sections.pay.dueDay', [payMethod.dueDay]) }}</strong>
</section>
</p>
<p>
<section>
<span>{{ $t('sections.pay.method') }}:</span>
<strong>{{payMethod.name}}</strong>
</section>
<section v-if="payMethod.code != 'card'">
<span>{{ $t('sections.pay.day') }}:</span>
<strong>{{ $t('sections.pay.dueDay', [payMethod.dueDay]) }}</strong>
</section>
</p>
<p v-if="payMethod.code == 'bankDraft'"
v-html="$t('sections.pay.accountImplicates', [accountAddress])">
</p>
<p v-else-if="payMethod.code == 'card'">
{{ $t('sections.pay.cardImplicates') }}
</p>
<p v-if="payMethod.code == 'bankDraft'" v-html="$t('sections.pay.accountImplicates', [accountAddress])">
</p>
<p v-else-if="payMethod.code == 'card'">
{{ $t('sections.pay.cardImplicates') }}
</p>
<p>{{ $t('notifyAnError') }}</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<p>{{ $t('notifyAnError') }}</p>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'payment-update',
@ -21,8 +20,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build(),
},
props: {
id: {

View File

@ -1,90 +1,49 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<p v-html="$t('description.followGuide')"></p>
<p v-html="$t('description.downloadFrom')"></p>
<p v-html="$t('description.downloadDriver')"></p>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<p>{{$t('description.instructions')}}</p>
<p v-html="$t('description.followGuide')"></p>
<p v-html="$t('description.downloadFrom')"></p>
<p v-html="$t('description.downloadDriver')"></p>
<h1>{{$t('sections.QLabel.title')}}</h1>
<p>{{$t('sections.QLabel.description')}}:</p>
<ol>
<li v-for="step in $t('sections.QLabel.steps')">
<span v-html="step"></span>
</li>
</ol>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{$t('sections.help.title')}}</h1>
<p>{{$t('sections.help.description')}}</p>
<p v-html="$t('sections.help.remoteSupport')"></p>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<div v-if="client.salesPersonName">
{{$t('salesPersonName')}}: <strong>{{client.salesPersonName}}</strong>
</div>
<div v-if="client.salesPersonPhone">
{{$t('salesPersonPhone')}}: <strong>{{client.salesPersonPhone}}</strong>
</div>
<div v-if="client.salesPersonEmail">
{{$t('salesPersonEmail')}}:
<strong><a v-bind:href="`mailto:${client.salesPersonEmail}`" target="_blank">{{client.salesPersonEmail}}</strong>
</div>
</div>
</div>
<!-- Block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<h1>{{$t('sections.QLabel.title')}}</h1>
<p>{{$t('sections.QLabel.description')}}:</p>
<ol>
<li v-for="step in $t('sections.QLabel.steps')">
<span v-html="step"></span>
</li>
</ol>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{$t('sections.help.title')}}</h1>
<p>{{$t('sections.help.description')}}</p>
<p v-html="$t('sections.help.remoteSupport')"></p>
</div>
</div>
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<div v-if="client.salesPersonName">
{{$t('salesPersonName')}}: <strong>{{client.salesPersonName}}</strong>
</div>
<div v-if="client.salesPersonPhone">
{{$t('salesPersonPhone')}}: <strong>{{client.salesPersonPhone}}</strong>
</div>
<div v-if="client.salesPersonEmail">
{{$t('salesPersonEmail')}}:
<strong><a v-bind:href="`mailto:${client.salesPersonEmail}`"
target="_blank">{{client.salesPersonEmail}}</strong>
</div>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments" v-bind:key="attachment.filename"
v-bind:attachment="attachment" v-bind:args="$props">
</attachment>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
const attachment = new Component('attachment');
const attachments = require('./attachments.json');
@ -18,8 +17,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'email-body': emailBody.build(),
'attachment': attachment.build()
},
props: {

View File

@ -1,57 +1,21 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<div v-html="$t('description.instructions')"></div>
<p>{{$t('description.conclusion')}}</p>
</div>
</div>
<!-- Attachments block -->
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props">
</attachment>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('description.dear')}},</p>
<div v-html="$t('description.instructions')"></div>
<p>{{$t('description.conclusion')}}</p>
</div>
</div>
<div class="grid-row" v-if="isPreview">
<div class="grid-block vn-pa-ml">
<attachment
v-for="attachment in attachments"
v-bind:key="attachment.filename"
v-bind:attachment="attachment"
v-bind:args="$props"
>
</attachment>
</div>
</div>
</email-body>

View File

@ -1,7 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const attachment = new Component('attachment');
const emailBody = new Component('email-body');
const attachments = require('./attachments.json');
module.exports = {
@ -10,9 +8,7 @@ module.exports = {
return {attachments};
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build(),
'attachment': attachment.build()
'email-body': emailBody.build()
},
props: {
id: {

View File

@ -1,46 +1,9 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [minDate, maxDate])"></p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p v-html="$t('description', [minDate, maxDate])"></p>
</div>
</div>
</email-body>

View File

@ -1,6 +1,5 @@
const Component = require(`vn-print/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
const emailBody = new Component('email-body');
module.exports = {
name: 'supplier-campaign-metrics',
@ -16,8 +15,7 @@ module.exports = {
}
},
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
'email-body': emailBody.build()
},
props: {
id: {

View File

@ -0,0 +1,31 @@
<report-body v-bind="$props">
<div class="grid-row">
<div class="grid-block">
<div class="columns">
<div class="size50">
<p style="text-align: right">{{$t('Place')}} {{currentDate()}}</p>
<h3 style="text-align: center; margin-top: 8%">{{$t('Compensation') | uppercase}}</h3>
<p style="margin-top: 8%">{{$t('In one hand')}}:</p>
<p style="text-align: justify">
{{company.name}} {{$t('CIF')}} {{company.nif}} {{$t('Home')}} {{company.street}},
{{company.city}}.
</p>
<p style="margin-top: 5%">{{$t('In other hand')}}:</p>
<p style="text-align: justify">
{{$t('Sr')}} {{client.name}} {{$t('NIF')}} {{client.fi}} {{$t('Home')}} {{client.street}},
{{client.city}}.
</p>
<h4 style="text-align: center; margin-top: 10%">{{$t('Agree') | uppercase}}</h4>
<p style="margin-top: 8%; text-align: justify">
{{$t('Date')}} {{client.payed | date('%d-%m-%Y')}} {{$t('Compensate')}} {{client.amountPaid}} €
{{$t('From client')}} {{client.name}} {{$t('Toclient')}} {{company.name}}.
</p>
<p style="margin-top: 8%">
{{$t('Reception')}} <span style="color: blue">administracion@verdnatura.es</span>
</p>
<div style="margin-top: 8%"><small>{{$t('Greetings')}}</small></div>
</div>
</div>
</div>
</div>
</report-body>

View File

@ -0,0 +1,34 @@
const Component = require(`vn-print/core/component`);
const reportBody = new Component('report-body');
module.exports = {
name: 'balance-compensation',
async serverPrefetch() {
this.client = await this.fetchClient(this.id);
this.company = await this.fetchCompany(this.id);
},
methods: {
fetchClient(id) {
return this.findOneFromDef('client', [id]);
},
fetchCompany(id) {
return this.findOneFromDef('company', [id]);
},
currentDate() {
const current = new Date();
const date = `${current.getDate()}/${current.getMonth() + 1}/${current.getFullYear()}`;
return date;
}
},
components: {
'report-body': reportBody.build()
},
props: {
id: {
type: Number,
required: true,
description: 'The receipt id'
}
}
};

View File

@ -0,0 +1,12 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,16 @@
reportName: compensacion-saldo
Place: Algemesí, a
Compensation: Compensación de saldos deudores y acreedores
In one hand: De una parte
CIF: con CIF
NIF: con NIF
Home: y domicilio sito en
In other hand: De la otra
Sr: Don/Doña
Agree: Acuerdan
Date: En fecha de
Compensate: se ha compensado el saldo de
From client: del cliente/proveedor
To client: con el cliente/proveedor
Reception: Por favor, rogamos confirmen la recepción de esta compensación al email
Greetings: Saludos cordiales,

View File

@ -0,0 +1,12 @@
SELECT
c.name,
c.socialName,
c.street,
c.fi,
c.city,
r.amountPaid,
r.payed
FROM client c
JOIN receipt r ON r.clientFk = c.id
JOIN supplier s ON c.fi = s.nif
WHERE r.id = ?

View File

@ -0,0 +1,8 @@
SELECT
s.name,
s.nif,
s.street,
s.city
FROM supplier s
JOIN receipt r ON r.companyFk = s.id
WHERE r.id = ?;

View File

@ -1,95 +1,72 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Header block -->
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<div class="columns">
<div class="size50">
<h1 class="title uppercase">{{$t('title')}}</h1>
<div class="size75">
<table class="row-oriented report-info">
<tbody>
<tr>
<td class="font gray">{{$t('Client')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray">{{$t('From')}}</td>
<th>{{from | date('%d-%m-%Y')}}</th>
</tr>
<tr>
<td class="font gray">{{$t('To')}}</td>
<th>{{to | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
</div>
</div>
<div class="size50">
<div class="panel">
<div class="header">{{$t('clientData')}}</div>
<div class="body">
<h3 class="uppercase">{{client.socialName}}</h3>
<div>
{{client.street}}
</div>
<div>
{{client.postcode}}, {{client.city}} ({{client.province}})
</div>
<div>
{{client.country}}
</div>
</div>
</div>
</div>
</div>
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('Code')}}</th>
<th class="number">{{$t('Quantity')}}</th>
<th width="50%">{{$t('Concept')}}</th>
</tr>
</thead>
<tbody v-for="sale in sales">
<tr>
<td>{{sale.itemFk | zerofill('000000')}}</td>
<td class="number">{{Math.trunc(sale.subtotal)}}</td>
<td width="50%">{{sale.concept}}</td>
</tr>
<tr class="description font light-gray">
<td colspan="7">
<span v-if="sale.value5">
<strong>{{sale.tag5}}</strong> {{sale.value5}}
</span>
<span v-if="sale.value6">
<strong>{{sale.tag6}}</strong> {{sale.value6}}
</span>
<span v-if="sale.value7">
<strong>{{sale.tag7}}</strong> {{sale.value7}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
<report-body v-bind="$props">
<div class="grid-row">
<div class="grid-block">
<div class="columns">
<div class="size50">
<h1 class="title uppercase">{{$t('title')}}</h1>
<div class="size75">
<table class="row-oriented report-info">
<tbody>
<tr>
<td class="font gray">{{$t('Client')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray">{{$t('From')}}</td>
<th>{{from | date('%d-%m-%Y')}}</th>
</tr>
<tr>
<td class="font gray">{{$t('To')}}</td>
<th>{{to | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
</div>
</div>
<div class="size50">
<div class="panel">
<div class="header">{{$t('clientData')}}</div>
<div class="body">
<h3 class="uppercase">{{client.socialName}}</h3>
<div>{{client.street}}</div>
<div>{{client.postcode}}, {{client.city}} ({{client.province}})</div>
<div>{{client.country}}</div>
</div>
<!-- Footer block -->
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>
</table>
</body>
</html>
</div>
</div>
</div>
<table class="column-oriented">
<thead>
<tr>
<th>{{$t('Code')}}</th>
<th class="number">{{$t('Quantity')}}</th>
<th width="50%">{{$t('Concept')}}</th>
</tr>
</thead>
<tbody v-for="sale in sales">
<tr>
<td>{{sale.itemFk | zerofill('000000')}}</td>
<td class="number">{{Math.trunc(sale.subtotal)}}</td>
<td width="50%">{{sale.concept}}</td>
</tr>
<tr class="description font light-gray">
<td colspan="7">
<span v-if="sale.value5"> <strong>{{sale.tag5}}</strong> {{sale.value5}} </span>
<span v-if="sale.value6"> <strong>{{sale.tag6}}</strong> {{sale.value6}} </span>
<span v-if="sale.value7"> <strong>{{sale.tag7}}</strong> {{sale.value7}} </span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<template v-slot:footer>
<report-footer
id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props"
>
</report-footer>
</template>
</report-body>

View File

@ -1,5 +1,5 @@
const Component = require(`vn-print/core/component`);
const reportHeader = new Component('report-header');
const reportBody = new Component('report-body');
const reportFooter = new Component('report-footer');
module.exports = {
@ -20,7 +20,7 @@ module.exports = {
},
},
components: {
'report-header': reportHeader.build(),
'report-body': reportBody.build(),
'report-footer': reportFooter.build()
},
props: {

Some files were not shown because too many files have changed in this diff Show More