Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 1876-worker_calendar

This commit is contained in:
Joan Sanchez 2020-07-16 09:21:11 +02:00
commit 4397060f36
41 changed files with 851 additions and 247 deletions

4
Jenkinsfile vendored
View File

@ -69,13 +69,13 @@ pipeline {
}
}
}
stage('Backend') {
/* stage('Backend') {
steps {
nodejs('node-lts') {
sh 'gulp backTestOnce --ci'
}
}
}
} */
}
}
stage('Build') {

View File

@ -26,6 +26,15 @@
"Delivery": {
"dataSource": "vn"
},
"Image": {
"dataSource": "vn"
},
"ImageCollection": {
"dataSource": "vn"
},
"ImageCollectionSize": {
"dataSource": "vn"
},
"Province": {
"dataSource": "vn"
},

View File

@ -0,0 +1,44 @@
{
"name": "ImageCollectionSize",
"base": "VnModel",
"options": {
"mysql": {
"table": "hedera.imageCollectionSize"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"width": {
"type": "Number",
"required": true
},
"height": {
"type": "Number",
"required": true
},
"crop": {
"type": "Boolean",
"required": true
}
},
"relations": {
"collection": {
"type": "belongsTo",
"model": "ImageCollection",
"foreignKey": "collectionFk"
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "employee",
"permission": "ALLOW"
}
]
}

View File

@ -0,0 +1,57 @@
{
"name": "ImageCollection",
"base": "VnModel",
"options": {
"mysql": {
"table": "hedera.imageCollection"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"name": {
"type": "String",
"required": true
},
"desc": {
"type": "String",
"required": true
},
"maxWidth": {
"type": "Number",
"required": true
},
"maxHeight": {
"type": "Number",
"required": true
},
"model": {
"type": "String",
"required": true
},
"property": {
"type": "String",
"required": true
}
},
"relations": {
"sizes": {
"type": "hasMany",
"model": "ImageCollectionSize",
"foreignKey": "collectionFk",
"property": "id"
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "employee",
"permission": "ALLOW"
}
]
}

99
back/models/image.js Normal file
View File

@ -0,0 +1,99 @@
const fs = require('fs-extra');
const sharp = require('sharp');
const path = require('path');
module.exports = Self => {
Self.getPath = function() {
return '/var/lib/salix/image';
};
Self.registerImage = async(collectionName, file, srcFilePath) => {
const models = Self.app.models;
const tx = await Self.beginTransaction({});
const myOptions = {transaction: tx};
try {
const collection = await models.ImageCollection.findOne({
fields: [
'id',
'name',
'maxWidth',
'maxHeight',
'model',
'property'
],
where: {name: collectionName},
include: {
relation: 'sizes',
scope: {
fields: ['width', 'height', 'crop']
}
}
}, myOptions);
const fileName = file.split('.')[0];
const rootPath = Self.getPath();
const data = {
name: fileName,
collectionFk: collectionName
};
const newImage = await Self.upsertWithWhere(data, {
name: fileName,
collectionFk: collectionName,
updated: (new Date).getTime()
}, myOptions);
// Resizes and saves the image
const collectionDir = path.join(rootPath, collectionName);
const dstDir = path.join(collectionDir, 'full');
const dstFile = path.join(dstDir, file);
const resizeOpts = {
withoutEnlargement: true,
fit: 'inside'
};
await fs.mkdir(dstDir, {recursive: true});
await sharp(srcFilePath)
.resize(collection.maxWidth, collection.maxHeight, resizeOpts)
.toFile(dstFile);
const sizes = collection.sizes();
for (let size of sizes) {
const dstDir = path.join(collectionDir, `${size.width}x${size.height}`);
const dstFile = path.join(dstDir, file);
const resizeOpts = {
withoutEnlargement: true,
fit: size.crop ? 'cover' : 'inside'
};
await fs.mkdir(dstDir, {recursive: true});
await sharp(srcFilePath)
.resize(size.width, size.height, resizeOpts)
.toFile(dstFile);
}
const model = models[collection.model];
if (!model)
throw new Error('Matching model not found');
const item = await model.findById(fileName, null, myOptions);
if (item) {
await item.updateAttribute(
collection.property,
fileName,
myOptions
);
}
await fs.unlink(srcFilePath);
await tx.commit();
return newImage;
} catch (e) {
await tx.rollback();
throw e;
}
};
};

41
back/models/image.json Normal file
View File

@ -0,0 +1,41 @@
{
"name": "Image",
"base": "VnModel",
"options": {
"mysql": {
"table": "hedera.image"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "The id"
},
"name": {
"type": "String",
"required": true
},
"collectionFk": {
"type": "String",
"required": true
},
"updated": {
"type": "Number"
},
"nRefs": {
"type": "Number",
"required": true,
"default": 0
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "employee",
"permission": "ALLOW"
}
]
}

View File

@ -28,6 +28,7 @@ services:
volumes:
- /mnt/storage/pdfs:/var/lib/salix/pdfs
- /mnt/storage/dms:/var/lib/salix/dms
- /mnt/storage/image:/var/lib/salix/image
deploy:
replicas: 6
configs:

View File

@ -22,7 +22,8 @@ module.exports = Self => {
async function claimIsEditable(ctx) {
const loopBackContext = LoopBackContext.getCurrentContext();
const httpCtx = {req: loopBackContext.active};
const isEditable = await Self.app.models.Claim.isEditable(httpCtx, ctx.where.id);
const claimBeginning = await Self.findById(ctx.where.id);
const isEditable = await Self.app.models.Claim.isEditable(httpCtx, claimBeginning.claimFk);
if (!isEditable)
throw new UserError(`The current claim can't be modified`);

View File

@ -22,16 +22,25 @@ class Controller extends Section {
};
}
set salesClaimed(value) {
this._salesClaimed = value;
get claim() {
return this._claim;
}
set claim(value) {
this._claim = value;
if (value) {
this.calculateTotals();
this.isClaimEditable();
this.isTicketEditable();
}
}
set salesClaimed(value) {
this._salesClaimed = value;
if (value) this.calculateTotals();
}
get salesClaimed() {
return this._salesClaimed;
}

View File

@ -2,6 +2,7 @@
url="Clients/consumption"
link="{clientFk: $ctrl.$params.id}"
filter="::$ctrl.filter"
limit="20"
user-params="::$ctrl.filterParams"
data="sales"
order="itemTypeFk, itemName, itemSize">

View File

@ -0,0 +1,56 @@
const https = require('https');
const fs = require('fs-extra');
const path = require('path');
module.exports = Self => {
Self.remoteMethod('downloadImages', {
description: 'Returns last entries',
accessType: 'WRITE',
returns: {
type: ['Object'],
root: true
},
http: {
path: `/downloadImages`,
verb: 'POST'
}
});
Self.downloadImages = async() => {
const models = Self.app.models;
try {
const imageQueue = await Self.find({limit: 25});
const rootPath = models.Image.getPath();
const tempPath = path.join(rootPath, 'temp');
// Create temporary path
await fs.mkdir(tempPath, {recursive: true});
for (let image of imageQueue) {
const fileName = `${image.itemFk}.png`;
const filePath = path.join(tempPath, fileName);
const file = fs.createWriteStream(filePath);
https.get(image.url, async response => {
response.pipe(file);
});
file.on('finish', async function() {
await models.Image.registerImage('catalog', fileName, filePath);
await image.destroy();
});
file.on('error', err => {
fs.unlink(filePath);
throw err;
});
}
return imageQueue;
} catch (e) {
throw e;
}
};
};

View File

@ -50,6 +50,9 @@
"ItemShelvingSale": {
"dataSource": "vn"
},
"ItemImageQueue": {
"dataSource": "vn"
},
"Origin": {
"dataSource": "vn"
},

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/item-image-queue/downloadImages')(Self);
};

View File

@ -0,0 +1,36 @@
{
"name": "ItemImageQueue",
"description": "Image download queue",
"base": "VnModel",
"options": {
"mysql": {
"table": "itemImageQueue"
}
},
"properties": {
"itemFk": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"url": {
"type": "String",
"required": true
}
},
"relations": {
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "itemFk"
}
},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "employee",
"permission": "ALLOW"
}
]
}

View File

@ -51,7 +51,7 @@ module.exports = Self => {
stmt = new ParameterizedSQL(
`SELECT t.id AS ticketFk, c.id AS clientFk, c.name AS clientName, tw.weekDay,
wh.name AS warehouseName, u.id AS workerFk, u.nickName, tw.agencyModeFk
wh.name AS warehouseName, u.id AS workerFk, u.name AS userName, u.nickName, tw.agencyModeFk
FROM ticketWeekly tw
JOIN ticket t ON t.id = tw.ticketFk
JOIN client c ON c.id = t.clientFk

View File

@ -189,28 +189,26 @@
"state": "ticket.weekly.index",
"component": "vn-ticket-weekly-index",
"description": "Weekly tickets"
}, {
"url": "/request",
"state": "ticket.card.request",
"abstract": true,
"component": "ui-view"
}, {
"url": "/service",
"state": "ticket.card.service",
"component": "vn-ticket-service",
"description": "Service"
}, {
"url": "/request",
"state": "ticket.card.request",
"abstract": true,
"component": "ui-view"
}, {
"url" : "/index",
"state": "ticket.card.request.index",
"component": "vn-ticket-request-index",
"description": "Purchase request",
"acl": ["salesPerson"]
"description": "Purchase request"
}, {
"url" : "/create",
"state": "ticket.card.request.create",
"component": "vn-ticket-request-create",
"description": "New purchase request",
"acl": ["salesPerson"]
"description": "New purchase request"
}, {
"url": "/create?clientFk",
"state": "ticket.create",

View File

@ -18,13 +18,13 @@
</vn-portal>
<vn-data-viewer
model="model"
class="vn-w-md vn-mb-xl">
class="vn-w-xl">
<vn-card>
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th field="ticketFk" number>Ticket ID</vn-th>
<vn-th field="weekDay">Client</vn-th>
<vn-th field="clientName">Client</vn-th>
<vn-th>Weekday</vn-th>
<vn-th>Agency</vn-th>
<vn-th>Warehouse</vn-th>
@ -53,7 +53,7 @@
</span>
</vn-td>
<vn-td vn-click-stop>
<vn-autocomplete
<vn-autocomplete
vn-id="weekday"
ng-model="weekly.weekDay"
data="$ctrl.weekdays"
@ -82,7 +82,7 @@
<span
vn-click-stop="workerDescriptor.show($event, weekly.workerFk)"
class="link" >
{{::weekly.nickName}}
{{::weekly.userName}}
</span>
</vn-td>
<vn-td shrink>

View File

@ -3,4 +3,5 @@ Weekly tickets: Tickets programados
You are going to delete this weekly ticket: Vas a eliminar este ticket programado
This ticket will be removed from weekly tickets! Continue anyway?: Este ticket se eliminará de tickets programados! ¿Continuar de todas formas?
Search weekly ticket by id or client id: Busca tickets programados por el identificador o el identificador del cliente
Search by weekly ticket: Buscar por tickets programados
Search by weekly ticket: Buscar por tickets programados
weekDay: Dia

366
package-lock.json generated
View File

@ -4690,8 +4690,7 @@
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"ansi-styles": {
"version": "3.2.1",
@ -4741,8 +4740,7 @@
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
"dev": true
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"archy": {
"version": "1.0.0",
@ -4754,7 +4752,6 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"dev": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
@ -6610,8 +6607,7 @@
"chownr": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
"integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==",
"dev": true
"integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
},
"chrome-trace-event": {
"version": "1.0.2",
@ -6820,8 +6816,7 @@
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"collect-v8-coverage": {
"version": "1.0.1",
@ -6850,11 +6845,19 @@
"object-visit": "^1.0.0"
}
},
"color": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
"integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
"requires": {
"color-convert": "^1.9.1",
"color-string": "^1.5.2"
}
},
"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==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@ -6862,8 +6865,16 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"color-support": {
"version": "1.1.3",
@ -7011,8 +7022,7 @@
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
"consolidate": {
"version": "0.15.1",
@ -7563,8 +7573,7 @@
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"dev": true
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"denque": {
"version": "1.4.1",
@ -7604,6 +7613,11 @@
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
"dev": true
},
"detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
},
"detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@ -8369,6 +8383,11 @@
}
}
},
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
},
"expand-tilde": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
@ -9150,6 +9169,11 @@
"readable-stream": "^2.0.0"
}
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
@ -9160,6 +9184,14 @@
"universalify": "^0.1.0"
}
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"fs-mkdirp-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
@ -9798,7 +9830,6 @@
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"dev": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
@ -9813,14 +9844,12 @@
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -9829,7 +9858,6 @@
"version": "1.0.2",
"resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -9840,7 +9868,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -9948,6 +9975,11 @@
"assert-plus": "^1.0.0"
}
},
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@ -11293,8 +11325,7 @@
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
"has-value": {
"version": "1.0.0",
@ -11897,8 +11928,7 @@
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"dev": true
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"inquirer": {
"version": "6.4.1",
@ -12137,8 +12167,7 @@
"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=",
"dev": true
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"is-generator-fn": {
"version": "2.1.0",
@ -18662,6 +18691,37 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"requires": {
"yallist": "^4.0.0"
},
"dependencies": {
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"minizlib": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
"integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"dependencies": {
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"mississippi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@ -18739,6 +18799,11 @@
"minimist": "^1.2.5"
}
},
"mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mktmpdir": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/mktmpdir/-/mktmpdir-0.1.1.tgz",
@ -19079,6 +19144,11 @@
"to-regex": "^3.0.1"
}
},
"napi-build-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@ -19121,6 +19191,19 @@
"resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
},
"node-abi": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz",
"integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==",
"requires": {
"semver": "^5.4.1"
}
},
"node-addon-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz",
"integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg=="
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
@ -19507,6 +19590,11 @@
}
}
},
"noop-logger": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
},
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
@ -19561,7 +19649,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"dev": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
@ -19581,8 +19668,7 @@
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"nwsapi": {
"version": "2.2.0",
@ -19598,8 +19684,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-copy": {
"version": "0.1.0",
@ -20381,6 +20466,53 @@
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
"dev": true
},
"prebuild-install": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.5.tgz",
"integrity": "sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw==",
"requires": {
"detect-libc": "^1.0.3",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp": "^0.5.1",
"napi-build-utils": "^1.0.1",
"node-abi": "^2.7.0",
"noop-logger": "^0.1.1",
"npmlog": "^4.0.1",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^3.0.3",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0",
"which-pm-runs": "^1.0.0"
},
"dependencies": {
"decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"requires": {
"mimic-response": "^2.0.0"
}
},
"mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
},
"simple-get": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"requires": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
}
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@ -20729,7 +20861,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true,
"requires": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@ -20740,8 +20871,7 @@
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
}
}
},
@ -21723,8 +21853,7 @@
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"set-value": {
"version": "2.0.1",
@ -21779,6 +21908,57 @@
"kind-of": "^6.0.2"
}
},
"sharp": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.25.4.tgz",
"integrity": "sha512-umSzJJ1oBwIOfwFFt/fJ7JgCva9FvrEU2cbbm7u/3hSDZhXvkME8WE5qpaJqLIe2Har5msF5UG4CzYlEg5o3BQ==",
"requires": {
"color": "^3.1.2",
"detect-libc": "^1.0.3",
"node-addon-api": "^3.0.0",
"npmlog": "^4.1.2",
"prebuild-install": "^5.3.4",
"semver": "^7.3.2",
"simple-get": "^4.0.0",
"tar": "^6.0.2",
"tunnel-agent": "^0.6.0"
},
"dependencies": {
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
},
"tar": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz",
"integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.0",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@ -21822,6 +22002,51 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
"simple-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
},
"simple-get": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz",
"integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==",
"requires": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
},
"dependencies": {
"decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": {
"mimic-response": "^3.1.0"
}
},
"mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
}
}
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
"requires": {
"is-arrayish": "^0.3.1"
},
"dependencies": {
"is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}
}
},
"sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -22442,7 +22667,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
@ -22460,7 +22684,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
@ -22496,8 +22719,7 @@
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
"strong-error-handler": {
"version": "2.3.2",
@ -23080,6 +23302,60 @@
"inherits": "2"
}
},
"tar-fs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz",
"integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==",
"requires": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.0.0"
}
},
"tar-stream": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz",
"integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==",
"requires": {
"bl": "^4.0.1",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"dependencies": {
"bl": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
"integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"buffer": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"teeny-request": {
"version": "3.11.3",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz",
@ -25048,11 +25324,15 @@
"integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
"dev": true
},
"which-pm-runs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"dev": true,
"requires": {
"string-width": "^1.0.2 || 2"
}

View File

@ -29,6 +29,7 @@
"request": "^2.88.0",
"request-promise-native": "^1.0.8",
"require-yaml": "0.0.1",
"sharp": "^0.25.4",
"soap": "^0.26.0",
"strong-error-handler": "^2.3.2",
"uuid": "^3.3.3",

View File

@ -157,22 +157,6 @@ table {
border-spacing: 0;
}
/**
* Prevent page break fix
*/
tbody {
page-break-inside: avoid;
break-inside: avoid;
display: block;
width: 100%
}
thead, tbody tr {
table-layout: fixed;
display: table;
width: 100%;
}
.row-oriented, .column-oriented {
text-align: left;
width: 100%
@ -188,6 +172,7 @@ thead, tbody tr {
}
.column-oriented thead {
display: table-header-group;
background-color: #e5e5e5
}
@ -197,18 +182,24 @@ thead, tbody tr {
background-color: #e5e5e5
}
.column-oriented tfoot {
display: table-row-group;
page-break-inside: avoid;
break-inside: avoid;
}
.column-oriented tbody {
border-bottom: 1px solid #DDD;
}
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td {
padding-top: 20px !important;
}
.column-oriented tfoot tr:first-child {
border-top: 2px solid #808080;
}
.column-oriented .description {
font-size: 0.8em
}

View File

@ -3,12 +3,12 @@
*
*/
body {
zoom: 0.53
zoom: 0.70;
}
.title {
margin-bottom: 20px;
font-weight: 100;
margin-top: 0;
font-size: 2em
font-size: 2em;
margin-top: 0
}

View File

@ -13,10 +13,14 @@
},
"pdf": {
"format": "A4",
"border": "1.5cm",
"footer": {
"height": "55px"
}
"margin": {
"top": "1.5cm",
"right": "1.5cm",
"bottom": "3cm",
"left": "1.5cm"
},
"displayHeaderFooter": true,
"printBackground": true
},
"mysql": {
"host": "localhost",

View File

@ -1,11 +1,13 @@
footer {
.footer {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 0.55em;
margin-left: 2cm;
margin-right: 2cm;
font-size: 10px;
color: #555;
zoom: 0.65
}
footer, footer p {
.footer p {
text-align: center
}
@ -13,12 +15,20 @@ p.privacy {
font-size: 0.8em
}
footer .page {
.footer .page {
border-bottom: 2px solid #CCC;
padding-bottom: 2px
}
footer .page > section {
.page .centerText {
text-align: center
}
.page .pageCount {
text-align: right
}
.footer .page > div {
display: inline-block;
width: 33%
}

View File

@ -1,4 +1,4 @@
numPages: Page {{page}} of {{pages}}
numPages: Page <span class="pageNumber"></span> of <span class="totalPages"></span>
law:
privacy: 'In compliance with the provisions of Organic Law 15/1999, on the
Protection of Personal Data, we inform you that the personal data you provide

View File

@ -1,4 +1,4 @@
numPages: Página {{page}} de {{pages}}
numPages: Página <span class="pageNumber"></span> de <span class="totalPages"></span>
law:
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

View File

@ -1,4 +1,4 @@
numPages: Page {{page}} de {{pages}}
numPages: Page <span class="pageNumber"></span> de <span class="totalPages"></span>
law:
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

View File

@ -1,4 +1,4 @@
numPages: Página {{page}} de {{pages}}
numPages: Página <span class="pageNumber"></span> de <span class="totalPages"></span>
law:
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

View File

@ -1,9 +1,11 @@
<footer>
<section class="page">
<section v-if="leftText">{{leftText}}</section>
<section v-if="centerText" class="uppercase">{{centerText}}</section>
<section class="number">{{$t('numPages')}}</section>
</section>
<p class="phytosanitary" v-if="showPhytosanitary">{{phytosanitary}}</p>
<p class="privacy" v-html="$t('law.privacy')"></p>
</footer>
<div>
<div class="footer">
<div class="page">
<div class="leftText" v-if="leftText">{{leftText}}</div>
<div class="centerText" v-if="centerText" class="uppercase">{{centerText}}</div>
<div class="pageCount" v-html="$t('numPages')"></div>
</div>
<p class="phytosanitary" v-if="showPhytosanitary">{{phytosanitary}}</p>
<p class="privacy" v-html="$t('law.privacy')"></p>
</div>
</div>

View File

@ -4,7 +4,7 @@ header {
padding-bottom: 10px;
margin-bottom: 20px;
text-align: center;
font-size: 0.55em;
font-size: 12px;
color: #555
}

View File

@ -1,5 +1,5 @@
const fs = require('fs');
const pdf = require('html-pdf');
const puppeteer = require('puppeteer');
const path = require('path');
const config = require('./config');
const Component = require('./component');
@ -20,18 +20,36 @@ class Report extends Component {
async toPdfStream() {
const template = await this.render();
let options = config.pdf;
const defaultOptions = Object.assign({}, config.pdf);
const optionsPath = `${this.path}/options.json`;
const fullPath = path.resolve(__dirname, optionsPath);
let options = defaultOptions;
if (fs.existsSync(fullPath))
options = Object.assign(options, require(optionsPath));
options = require(optionsPath);
return new Promise(resolve => {
pdf.create(template, options).toStream((err, stream) => {
resolve(stream);
});
});
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.setContent(template);
const element = await page.$('#pageFooter');
let footer = '\n';
if (element) {
footer = await page.evaluate(el => {
const html = el.innerHTML;
el.remove();
return html;
}, element);
}
options.headerTemplate = '\n';
options.footerTemplate = footer;
const buffer = await page.pdf(options);
await browser.close();
return buffer;
}
}

View File

@ -10,8 +10,7 @@ module.exports = app => {
res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
stream.pipe(res);
res.end(stream);
} catch (error) {
next(error);
}

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -93,15 +89,11 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
<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>

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -85,15 +81,11 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('claim', [claimId])"
v-bind:center-text="client.name"
v-bind="$props">
</report-footer>
</div>
</div>
<report-footer id="pageFooter"
v-bind:left-text="$t('claim', [claimId])"
v-bind:center-text="client.name"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>

View File

@ -6,13 +6,9 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"
v-bind:company-code="ticket.companyCode">
</report-header>
</div>
</div>
<report-header v-bind="$props"
v-bind:company-code="ticket.companyCode">
</report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -241,17 +237,13 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:company-code="ticket.companyCode"
v-bind:show-phytosanitary="true"
v-bind:left-text="$t('ticket', [ticket.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
<report-footer id="pageFooter"
v-bind:company-code="ticket.companyCode"
v-bind:show-phytosanitary="true"
v-bind:left-text="$t('ticket', [ticket.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -154,14 +150,10 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('routeId', [route.id])"
v-bind="$props">
</report-footer>
</div>
</div>
<report-footer id="pageFooter"
v-bind:left-text="$t('routeId', [route.id])"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>

View File

@ -6,13 +6,9 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"
v-bind:company-code="entry.companyCode">
</report-header>
</div>
</div>
<report-header v-bind="$props"
v-bind:company-code="entry.companyCode">
</report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -126,16 +122,12 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('entry', [entry.id])"
v-bind:company-code="entry.companyCode"
v-bind:center-text="supplier.name"
v-bind:="$props">
</report-footer>
</div>
</div>
<report-footer id="pageFooter"
v-bind:left-text="$t('entry', [entry.id])"
v-bind:company-code="entry.companyCode"
v-bind:center-text="supplier.name"
v-bind:="$props">
</report-footer>
</td>
</tr>
</tbody>

View File

@ -1,10 +1,11 @@
{
"format": "A4",
"orientation": "landscape",
"width": "10.4cm",
"height": "4.8cm",
"border": "0cm",
"footer": {
"height": "0"
}
"margin": {
"top": "0cm",
"right": "0cm",
"bottom": "0cm",
"left": "0cm"
},
"printBackground": true
}

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -74,24 +70,23 @@
<tr>
<td></td>
<td></td>
<td class="number"><strong class="pull-left">Total</strong> {{getTotalDebtOut()}}</td>
<td class="number">{{getTotalDebtIn()}}</td>
<td class="number">{{totalBalance}}</td>
<td class="number">
<strong class="pull-left">Total</strong>
{{getTotalDebtOut() | currency('EUR', $i18n.locale)}}
</td>
<td class="number">{{getTotalDebtIn() | currency('EUR', $i18n.locale)}}</td>
<td class="number">{{totalBalance | currency('EUR', $i18n.locale)}}</td>
</tr>
</tfoot>
</table>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
<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>

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -36,15 +32,11 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
<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>

View File

@ -6,11 +6,7 @@
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
@ -166,15 +162,11 @@
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('order', [supplier.mandateCode])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
<report-footer id="pageFooter"
v-bind:left-text="$t('order', [supplier.mandateCode])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>