feat: refs #7644 Optimized entry labels report #2831

Merged
guillermo merged 3 commits from 7644-buyLabelChunk into master 2024-08-05 09:53:34 +00:00
10 changed files with 149 additions and 40 deletions

View File

@ -368,5 +368,6 @@
"Payment method is required": "El método de pago es obligatorio",
"Cannot send mail": "Não é possível enviar o email",
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos",
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo"
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo",
"The entry not have stickers": "La entrada no tiene etiquetas"
}

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.remoteMethodCtx('buyLabel', {
description: 'Returns the entry buys labels',
description: 'Returns the entry buy labels',
accessType: 'READ',
accepts: [
{

View File

@ -0,0 +1,58 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('print', {
description: 'Print stickers of all entries',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The entry id',
http: {source: 'path'}
}
],
returns: [
{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'String',
http: {target: 'header'}
}, {
arg: 'Content-Disposition',
type: 'String',
http: {target: 'header'}
}
],
http: {
path: '/:id/print',
verb: 'GET'
},
accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.print = async function(ctx, id, options) {
const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
// Importación dinámica porque no admite commonjs
const PDFMerger = ((await import('pdf-merger-js')).default);
const merger = new PDFMerger();
const buys = await models.Buy.find({where: {entryFk: id}}, myOptions);
for (const buy of buys) {
if (buy.stickers < 1) continue;
ctx.args.id = buy.id;
const pdfBuffer = await models.Entry.buyLabel(ctx, myOptions);
await merger.add(new Uint8Array(pdfBuffer[0]));
}
if (!merger._doc) throw new UserError('The entry not have stickers');
return [await merger.saveAsBuffer(), 'application/pdf', `filename="entry-${id}.pdf"`];
};
};

View File

@ -10,6 +10,7 @@ module.exports = Self => {
require('../methods/entry/addFromPackaging')(Self);
require('../methods/entry/addFromBuy')(Self);
require('../methods/entry/buyLabel')(Self);
require('../methods/entry/print')(Self);
Self.observe('before save', async function(ctx, options) {
if (ctx.isNewInstance) return;

View File

@ -43,6 +43,7 @@
"mysql": "2.18.1",
"node-ssh": "^11.0.0",
"object.pick": "^1.3.0",
"pdf-merger-js": "^5.1.2",
"puppeteer": "21.11.0",
"read-chunk": "^3.2.0",
"require-yaml": "0.0.1",
@ -80,10 +81,10 @@
"gulp-merge-json": "^1.3.1",
"gulp-nodemon": "^2.5.0",
"gulp-print": "^2.0.1",
"gulp-wrap": "^0.15.0",
"gulp-yaml": "^1.0.1",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.1.4",
"gulp-wrap": "^0.15.0",
"gulp-yaml": "^1.0.1",
"html-loader": "^0.4.5",
"html-loader-jest": "^0.2.1",
"html-webpack-plugin": "^5.5.1",

View File

@ -95,6 +95,9 @@ dependencies:
object.pick:
specifier: ^1.3.0
version: 1.3.0
pdf-merger-js:
specifier: ^5.1.2
version: 5.1.2
puppeteer:
specifier: 21.11.0
version: 21.11.0(typescript@5.4.4)
@ -2090,6 +2093,18 @@ packages:
rimraf: 3.0.2
dev: true
/@pdf-lib/standard-fonts@1.0.0:
resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==}
dependencies:
pako: 1.0.11
dev: false
/@pdf-lib/upng@1.0.1:
resolution: {integrity: sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==}
dependencies:
pako: 1.0.11
dev: false
/@pkgjs/parseargs@0.11.0:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@ -4486,6 +4501,11 @@ packages:
engines: {node: '>=14'}
dev: true
/commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
dev: false
/commander@2.17.1:
resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
dev: true
@ -11323,6 +11343,24 @@ packages:
pinkie-promise: 2.0.1
dev: true
/pdf-lib@1.17.1:
resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==}
dependencies:
'@pdf-lib/standard-fonts': 1.0.0
'@pdf-lib/upng': 1.0.1
pako: 1.0.11
tslib: 1.14.1
dev: false
/pdf-merger-js@5.1.2:
resolution: {integrity: sha512-RCBjLQILZ8UA4keO/Ip2/gjUuxigMMoK7mO5eJg6zjlnyymboFnRTgzKwOs/FiU9ornS2m72Qr95oARX1C24fw==}
engines: {node: '>=14'}
hasBin: true
dependencies:
commander: 11.1.0
pdf-lib: 1.17.1
dev: false
/pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
dev: false
@ -13836,6 +13874,10 @@ packages:
resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==}
dev: false
/tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: false
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}

View File

@ -86,7 +86,7 @@
<td>
<div class="cell">
<span class="lbl">{{$t('boxNum')}}</span>
{{`${buy.labelNum} / ${maxLabelNum}`}}
{{`${buy.labelNum} / ${buy.maxLabelNum}`}}
</div>
</td>
</tr>

View File

@ -1,5 +1,6 @@
const vnReport = require('../../../core/mixins/vn-report.js');
const {DOMImplementation, XMLSerializer} = require('xmldom');
const {models} = require('vn-loopback/server/server');
const jsBarcode = require('jsbarcode');
const moment = require('moment');
@ -7,8 +8,8 @@ module.exports = {
name: 'buy-label',
mixins: [vnReport],
async serverPrefetch() {
guillermo marked this conversation as resolved Outdated
Outdated
Review

Dalt de tot on estan els altres require, posar:
const { models } = require('vn-loopback/server/server');

Dalt de tot on estan els altres require, posar: `const { models } = require('vn-loopback/server/server');`
this.buys = await this.rawSqlFromDef('buys', [this.id, this.id]);
this.maxLabelNum = Math.max(...this.buys.map(buy => buy.labelNum));
const buy = await models.Buy.findById(this.id, null);
this.buys = await this.rawSqlFromDef('buy', [buy.entryFk, buy.entryFk, buy.entryFk, this.id]);
const date = new Date();
this.weekNum = moment(date).isoWeek();
this.dayNum = moment(date).day();

View File

@ -0,0 +1,38 @@
WITH RECURSIVE numbers AS (
SELECT 1 n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < (
SELECT MAX(stickers)
FROM buy
WHERE entryFk = ?
)
),
labels AS (
SELECT ROW_NUMBER() OVER(ORDER BY b.id, num.n) labelNum,
i.name,
i.`size`,
i.category,
ink.id color,
o.code,
b.packing,
b.`grouping`,
i.stems,
b.id,
b.itemFk,
p.name producer,
IF(i2.id, i2.comment, i.comment) comment
FROM buy b
JOIN item i ON i.id = b.itemFk
LEFT JOIN producer p ON p.id = i.producerFk
LEFT JOIN ink ON ink.id = i.inkFk
LEFT JOIN origin o ON o.id = i.originFk
LEFT JOIN item i2 ON i2.id = b.itemOriginalFk
JOIN numbers num
WHERE b.entryFk = ?
AND num.n <= b.stickers
)
SELECT *, (SELECT SUM(stickers) FROM buy WHERE entryFk = ?) maxLabelNum
FROM labels
WHERE id = ?

View File

@ -1,33 +0,0 @@
WITH RECURSIVE numbers AS (
SELECT 1 n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < (
SELECT MAX(stickers)
FROM buy
WHERE entryFk = ?
)
)
SELECT ROW_NUMBER() OVER(ORDER BY b.id, num.n) labelNum,
i.name,
i.`size`,
i.category,
ink.id color,
o.code,
b.packing,
b.`grouping`,
i.stems,
b.id,
b.itemFk,
p.name producer,
IF(i2.id, i2.comment, i.comment) comment
FROM buy b
JOIN item i ON i.id = b.itemFk
LEFT JOIN producer p ON p.id = i.producerFk
LEFT JOIN ink ON ink.id = i.inkFk
LEFT JOIN origin o ON o.id = i.originFk
LEFT JOIN item i2 ON i2.id = b.itemOriginalFk
JOIN numbers num
WHERE b.entryFk = ?
AND num.n <= b.stickers