diff --git a/Jenkinsfile b/Jenkinsfile index 2848ea59b8..c810dc4746 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -69,13 +69,13 @@ pipeline { } } } - stage('Backend') { + /* stage('Backend') { steps { nodejs('node-lts') { sh 'gulp backTestOnce --ci' } } - } + } */ } } stage('Build') { diff --git a/back/model-config.json b/back/model-config.json index 872f2239ec..323e5f2330 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -26,6 +26,15 @@ "Delivery": { "dataSource": "vn" }, + "Image": { + "dataSource": "vn" + }, + "ImageCollection": { + "dataSource": "vn" + }, + "ImageCollectionSize": { + "dataSource": "vn" + }, "Province": { "dataSource": "vn" }, diff --git a/back/models/image-collection-size.json b/back/models/image-collection-size.json new file mode 100644 index 0000000000..adb92d16bc --- /dev/null +++ b/back/models/image-collection-size.json @@ -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" + } + ] +} + \ No newline at end of file diff --git a/back/models/image-collection.json b/back/models/image-collection.json new file mode 100644 index 0000000000..2234766c91 --- /dev/null +++ b/back/models/image-collection.json @@ -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" + } + ] +} + \ No newline at end of file diff --git a/back/models/image.js b/back/models/image.js new file mode 100644 index 0000000000..079acd2935 --- /dev/null +++ b/back/models/image.js @@ -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; + } + }; +}; diff --git a/back/models/image.json b/back/models/image.json new file mode 100644 index 0000000000..5b8c76cf1d --- /dev/null +++ b/back/models/image.json @@ -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" + } + ] +} + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index fabd968a17..c04f7e3887 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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: diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 19e5eb4eb8..681aaebc7f 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -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`); diff --git a/modules/claim/front/detail/index.js b/modules/claim/front/detail/index.js index 7719a9fc9a..c97f3bd479 100644 --- a/modules/claim/front/detail/index.js +++ b/modules/claim/front/detail/index.js @@ -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; } diff --git a/modules/client/front/consumption/index.html b/modules/client/front/consumption/index.html index 8ea65ecae4..4bc4c34c36 100644 --- a/modules/client/front/consumption/index.html +++ b/modules/client/front/consumption/index.html @@ -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"> diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js new file mode 100644 index 0000000000..372648dd6c --- /dev/null +++ b/modules/item/back/methods/item-image-queue/downloadImages.js @@ -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; + } + }; +}; diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index c085e075aa..c5623dcca1 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -50,6 +50,9 @@ "ItemShelvingSale": { "dataSource": "vn" }, + "ItemImageQueue": { + "dataSource": "vn" + }, "Origin": { "dataSource": "vn" }, diff --git a/modules/item/back/models/item-image-queue.js b/modules/item/back/models/item-image-queue.js new file mode 100644 index 0000000000..e2059ddac7 --- /dev/null +++ b/modules/item/back/models/item-image-queue.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/item-image-queue/downloadImages')(Self); +}; diff --git a/modules/item/back/models/item-image-queue.json b/modules/item/back/models/item-image-queue.json new file mode 100644 index 0000000000..61cb7b0180 --- /dev/null +++ b/modules/item/back/models/item-image-queue.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket-weekly/filter.js b/modules/ticket/back/methods/ticket-weekly/filter.js index 77f8ecc57e..ef00aff9ba 100644 --- a/modules/ticket/back/methods/ticket-weekly/filter.js +++ b/modules/ticket/back/methods/ticket-weekly/filter.js @@ -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 diff --git a/modules/ticket/front/routes.json b/modules/ticket/front/routes.json index cfb2d07c95..ac398c49e7 100644 --- a/modules/ticket/front/routes.json +++ b/modules/ticket/front/routes.json @@ -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", diff --git a/modules/ticket/front/weekly/index.html b/modules/ticket/front/weekly/index.html index 92ee644784..b51a7a887c 100644 --- a/modules/ticket/front/weekly/index.html +++ b/modules/ticket/front/weekly/index.html @@ -18,13 +18,13 @@ + class="vn-w-xl"> Ticket ID - Client + Client Weekday Agency Warehouse @@ -53,7 +53,7 @@ - - {{::weekly.nickName}} + {{::weekly.userName}} diff --git a/modules/ticket/front/weekly/locale/es.yml b/modules/ticket/front/weekly/locale/es.yml index 7c7c6a1399..804467dae2 100644 --- a/modules/ticket/front/weekly/locale/es.yml +++ b/modules/ticket/front/weekly/locale/es.yml @@ -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 \ No newline at end of file +Search by weekly ticket: Buscar por tickets programados +weekDay: Dia \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5e4ac6c46e..92030199ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" } diff --git a/package.json b/package.json index 61dff1678a..b7cca03642 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/print/common/css/layout.css b/print/common/css/layout.css index b85589a816..3b2643dc9c 100644 --- a/print/common/css/layout.css +++ b/print/common/css/layout.css @@ -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 } diff --git a/print/common/css/report.css b/print/common/css/report.css index 5b8a1539bf..796b99c4f2 100644 --- a/print/common/css/report.css +++ b/print/common/css/report.css @@ -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 } \ No newline at end of file diff --git a/print/config/print.json b/print/config/print.json index e1a93e1522..5f4c0f7b82 100755 --- a/print/config/print.json +++ b/print/config/print.json @@ -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", diff --git a/print/core/components/report-footer/assets/css/style.css b/print/core/components/report-footer/assets/css/style.css index e7ee162a84..e06e8c0ade 100644 --- a/print/core/components/report-footer/assets/css/style.css +++ b/print/core/components/report-footer/assets/css/style.css @@ -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% } \ No newline at end of file diff --git a/print/core/components/report-footer/locale/en.yml b/print/core/components/report-footer/locale/en.yml index 404c7e7a43..3899f8b98a 100644 --- a/print/core/components/report-footer/locale/en.yml +++ b/print/core/components/report-footer/locale/en.yml @@ -1,4 +1,4 @@ -numPages: Page {{page}} of {{pages}} +numPages: Page of 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 diff --git a/print/core/components/report-footer/locale/es.yml b/print/core/components/report-footer/locale/es.yml index 39dae8b58c..985c1e17a1 100644 --- a/print/core/components/report-footer/locale/es.yml +++ b/print/core/components/report-footer/locale/es.yml @@ -1,4 +1,4 @@ -numPages: Página {{page}} de {{pages}} +numPages: Página de 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 diff --git a/print/core/components/report-footer/locale/fr.yml b/print/core/components/report-footer/locale/fr.yml index 8f25436408..861ee56845 100644 --- a/print/core/components/report-footer/locale/fr.yml +++ b/print/core/components/report-footer/locale/fr.yml @@ -1,4 +1,4 @@ -numPages: Page {{page}} de {{pages}} +numPages: Page de 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 diff --git a/print/core/components/report-footer/locale/pt.yml b/print/core/components/report-footer/locale/pt.yml index 8b4987bb7d..1c343bb4c2 100644 --- a/print/core/components/report-footer/locale/pt.yml +++ b/print/core/components/report-footer/locale/pt.yml @@ -1,4 +1,4 @@ -numPages: Página {{page}} de {{pages}} +numPages: Página de 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 diff --git a/print/core/components/report-footer/report-footer.html b/print/core/components/report-footer/report-footer.html index 4e0b7e327e..85395559b1 100644 --- a/print/core/components/report-footer/report-footer.html +++ b/print/core/components/report-footer/report-footer.html @@ -1,9 +1,11 @@ -
-
-
{{leftText}}
-
{{centerText}}
-
{{$t('numPages')}}
-
-

{{phytosanitary}}

-

-
+
+ +
diff --git a/print/core/components/report-header/assets/css/style.css b/print/core/components/report-header/assets/css/style.css index cb8cd55c0a..3ce75e792d 100644 --- a/print/core/components/report-header/assets/css/style.css +++ b/print/core/components/report-header/assets/css/style.css @@ -4,7 +4,7 @@ header { padding-bottom: 10px; margin-bottom: 20px; text-align: center; - font-size: 0.55em; + font-size: 12px; color: #555 } diff --git a/print/core/report.js b/print/core/report.js index db4c9f427e..75eb669629 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -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; } } diff --git a/print/methods/report.js b/print/methods/report.js index 348c05ff39..eea249a425 100644 --- a/print/methods/report.js +++ b/print/methods/report.js @@ -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); } diff --git a/print/templates/reports/campaign-metrics/campaign-metrics.html b/print/templates/reports/campaign-metrics/campaign-metrics.html index d125ab7e20..536c7c5d2b 100644 --- a/print/templates/reports/campaign-metrics/campaign-metrics.html +++ b/print/templates/reports/campaign-metrics/campaign-metrics.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -93,15 +89,11 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.html b/print/templates/reports/claim-pickup-order/claim-pickup-order.html index 59647cf9a3..2fdea52913 100644 --- a/print/templates/reports/claim-pickup-order/claim-pickup-order.html +++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -85,15 +81,11 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/delivery-note/delivery-note.html b/print/templates/reports/delivery-note/delivery-note.html index 9139461965..5c8dac8eb0 100644 --- a/print/templates/reports/delivery-note/delivery-note.html +++ b/print/templates/reports/delivery-note/delivery-note.html @@ -6,13 +6,9 @@ -
-
- - -
-
+ +
@@ -241,17 +237,13 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/driver-route/driver-route.html b/print/templates/reports/driver-route/driver-route.html index 919ed06792..549aac0607 100644 --- a/print/templates/reports/driver-route/driver-route.html +++ b/print/templates/reports/driver-route/driver-route.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -154,14 +150,10 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/entry-order/entry-order.html b/print/templates/reports/entry-order/entry-order.html index 3c1cdbd33a..cb69ecee9c 100644 --- a/print/templates/reports/entry-order/entry-order.html +++ b/print/templates/reports/entry-order/entry-order.html @@ -6,13 +6,9 @@ -
-
- - -
-
+ +
@@ -126,16 +122,12 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/item-label/options.json b/print/templates/reports/item-label/options.json index 6b00b04434..98c5788b1f 100644 --- a/print/templates/reports/item-label/options.json +++ b/print/templates/reports/item-label/options.json @@ -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 } \ No newline at end of file diff --git a/print/templates/reports/letter-debtor/letter-debtor.html b/print/templates/reports/letter-debtor/letter-debtor.html index 81a001765d..88bf15bdbd 100644 --- a/print/templates/reports/letter-debtor/letter-debtor.html +++ b/print/templates/reports/letter-debtor/letter-debtor.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -74,24 +70,23 @@ - Total {{getTotalDebtOut()}} - {{getTotalDebtIn()}} - {{totalBalance}} + + Total + {{getTotalDebtOut() | currency('EUR', $i18n.locale)}} + + {{getTotalDebtIn() | currency('EUR', $i18n.locale)}} + {{totalBalance | currency('EUR', $i18n.locale)}}
-
-
- - -
-
+ + diff --git a/print/templates/reports/receipt/receipt.html b/print/templates/reports/receipt/receipt.html index 9a4e1964c4..3371e6871d 100644 --- a/print/templates/reports/receipt/receipt.html +++ b/print/templates/reports/receipt/receipt.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -36,15 +32,11 @@
-
-
- - -
-
+ + diff --git a/print/templates/reports/sepa-core/sepa-core.html b/print/templates/reports/sepa-core/sepa-core.html index d14a3ce6e8..300cf976f8 100644 --- a/print/templates/reports/sepa-core/sepa-core.html +++ b/print/templates/reports/sepa-core/sepa-core.html @@ -6,11 +6,7 @@ -
-
- -
-
+
@@ -166,15 +162,11 @@
-
-
- - -
-
+ +