Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7283-itemSectionsMigration
gitea/salix/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Jorge Penadés 2024-08-06 08:47:23 +02:00
commit eaea1f3559
17 changed files with 224 additions and 53 deletions

View File

@ -0,0 +1,12 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_afterDelete`
AFTER DELETE ON `ACL`
FOR EACH ROW
BEGIN
INSERT INTO ACL
SET `action` = 'delete',
`changedModel` = 'Acl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_beforeInsert`
BEFORE INSERT ON `ACL`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_beforeUpdate`
BEFORE UPDATE ON `ACL`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -11,24 +11,29 @@ BEGIN
*/
DECLARE vSaleFk INT;
DECLARE vHasProblem INT;
DECLARE vIsProblemCalcNeeded BOOL;
DECLARE vDone BOOL;
DECLARE vSaleList CURSOR FOR SELECT saleFk, hasProblem FROM tmp.sale;
DECLARE vSaleList CURSOR FOR
SELECT saleFk, hasProblem, isProblemCalcNeeded
FROM tmp.sale;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vSaleList;
l: LOOP
SET vDone = FALSE;
FETCH vSaleList INTO vSaleFk, vHasProblem;
FETCH vSaleList INTO vSaleFk, vHasProblem, vIsProblemCalcNeeded;
IF vDone THEN
LEAVE l;
END IF;
UPDATE sale
SET problem = CONCAT(
IF(vHasProblem,
CONCAT(problem, ',', vProblemCode),
REPLACE(problem, vProblemCode , '')))
SET problem = IF (vIsProblemCalcNeeded,
CONCAT(
IF(vHasProblem,
CONCAT(problem, ',', vProblemCode),
REPLACE(problem, vProblemCode , ''))),
NULL)
WHERE id = vSaleFk;
END LOOP;
CLOSE vSaleList;

View File

@ -12,24 +12,28 @@ BEGIN
*/
DECLARE vTicketFk INT;
DECLARE vHasProblem INT;
DECLARE vIsProblemCalcNeeded BOOL;
DECLARE vDone BOOL;
DECLARE vTicketList CURSOR FOR SELECT ticketFk, hasProblem FROM tmp.ticket;
DECLARE vTicketList CURSOR FOR
SELECT ticketFk, hasProblem, isProblemCalcNeeded
FROM tmp.ticket;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vTicketList;
l: LOOP
SET vDone = FALSE;
FETCH vTicketList INTO vTicketFk, vHasProblem;
FETCH vTicketList INTO vTicketFk, vHasProblem, vIsProblemCalcNeeded;
IF vDone THEN
LEAVE l;
END IF;
UPDATE ticket
SET problem = CONCAT(
IF(vHasProblem,
SET problem = IF(vIsProblemCalcNeeded,
CONCAT(IF(vHasProblem,
CONCAT(problem, ',', vProblemCode),
REPLACE(problem, vProblemCode , '')))
REPLACE(problem, vProblemCode , ''))),
NULL)
WHERE id = vTicketFk;
END LOOP;
CLOSE vTicketList;

View File

@ -0,0 +1,25 @@
CREATE OR REPLACE TABLE `salix`.`ACLLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`originFk` int(11) DEFAULT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`action` set('insert','update','delete','select') NOT NULL,
`creationDate` timestamp NULL DEFAULT current_timestamp(),
`description` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`changedModel` enum('Acl') NOT NULL DEFAULT 'Acl',
`oldInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`oldInstance`)),
`newInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`newInstance`)),
`changedModelId` int(11) NOT NULL,
`changedModelValue` varchar(45) DEFAULT NULL,
`summaryId` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `logRateuserFk` (`userFk`),
KEY `ACLLog_changedModel` (`changedModel`,`changedModelId`,`creationDate`),
KEY `ACLLog_originFk` (`originFk`,`creationDate`),
CONSTRAINT `aclUserFk` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
ALTER TABLE salix.ACL
ADD editorFk int(10) unsigned DEFAULT NULL NULL;
ALTER TABLE vn.ticket
CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER risk;

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

@ -83,12 +83,12 @@ module.exports = Self => {
for (const sale of sales) {
const originalSale = map.get(sale.id);
if (sale.quantity == originalSale.quantity) {
if (sale.quantity == originalSale?.quantity) {
query = `UPDATE sale
SET ticketFk = ?
WHERE id = ?`;
await Self.rawSql(query, [ticketId, sale.id], myOptions);
} else if (sale.quantity != originalSale.quantity) {
} else if (sale.quantity != originalSale?.quantity) {
await transferPartialSale(
ticketId, originalSale, sale, myOptions);
}

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() {
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