From 1e8935244699f2cb4acb41fcffd724a2330e9af0 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 24 Jan 2023 14:37:08 +0100 Subject: [PATCH 01/26] hotfix instanceLog css --- front/salix/components/instance-log/index.html | 2 +- front/salix/components/instance-log/style.scss | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/front/salix/components/instance-log/index.html b/front/salix/components/instance-log/index.html index 354e81080..9794f75c2 100644 --- a/front/salix/components/instance-log/index.html +++ b/front/salix/components/instance-log/index.html @@ -1,8 +1,8 @@ - .window:not(:has(.empty-rows)) { - width:60%; - vn-log { - vn-card { - visibility: hidden; - & > * { - visibility: visible; - } - } +vn-log.vn-instance-log { + vn-card { + width: 900px; + visibility: hidden; + & > * { + visibility: visible; } } } From c04185aadd9a9e73239aa588ee7253d52140b802 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 26 Jan 2023 12:53:47 +0100 Subject: [PATCH 02/26] Updated package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd9dfe017..2031da475 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "230203", + "version": "23.02.03", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", From 956b3e05f8ea81ad653a823b62f9fa12d9a768ce Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 27 Jan 2023 07:56:51 +0100 Subject: [PATCH 03/26] hotfix delete saleChecked from vnClean --- db/changes/230201/00-kkearSaleChecked.sql | 171 ++++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/db/changes/230201/00-kkearSaleChecked.sql b/db/changes/230201/00-kkearSaleChecked.sql index 03e854bbd..3ea107da5 100644 --- a/db/changes/230201/00-kkearSaleChecked.sql +++ b/db/changes/230201/00-kkearSaleChecked.sql @@ -1,2 +1,173 @@ DELETE FROM `salix`.`ACL` WHERE model="SaleChecked"; DROP TABLE IF EXISTS `vn`.`saleChecked`; +DROP PROCEDURE IF EXISTS `vn`.`clean`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clean`() +BEGIN + DECLARE vDateShort DATETIME; + DECLARE vOneYearAgo DATE; + DECLARE vFourYearsAgo DATE; + DECLARE v18Month DATE; + DECLARE v26Month DATE; + DECLARE v3Month DATE; + DECLARE vTrashId VARCHAR(15); + + SET vDateShort = util.VN_CURDATE() - INTERVAL 2 MONTH; + SET vOneYearAgo = util.VN_CURDATE() - INTERVAL 1 YEAR; + SET vFourYearsAgo = util.VN_CURDATE() - INTERVAL 4 YEAR; + SET v18Month = util.VN_CURDATE() - INTERVAL 18 MONTH; + SET v26Month = util.VN_CURDATE() - INTERVAL 26 MONTH; + SET v3Month = util.VN_CURDATE() - INTERVAL 3 MONTH; + + DELETE FROM ticketParking WHERE created < vDateShort; + DELETE FROM routesMonitor WHERE dated < vDateShort; + DELETE FROM workerTimeControlLog WHERE created < vDateShort; + DELETE FROM `message` WHERE sendDate < vDateShort; + DELETE FROM messageInbox WHERE sendDate < vDateShort; + DELETE FROM messageInbox WHERE sendDate < vDateShort; + DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo; + DELETE FROM itemShelving WHERE created < util.VN_CURDATE() AND visible = 0; + DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,util.VN_CURDATE()); + DELETE FROM entryLog WHERE creationDate < vDateShort; + DELETE IGNORE FROM expedition WHERE created < v26Month; + DELETE FROM sms WHERE created < v18Month; + DELETE FROM saleTracking WHERE created < vOneYearAgo; + DELETE FROM ticketTracking WHERE created < v18Month; + DELETE tobs FROM ticketObservation tobs + JOIN ticket t ON tobs.ticketFk = t.id WHERE t.shipped < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < vOneYearAgo; + DELETE FROM sharingCart where ended < vDateShort; + DELETE FROM sharingClient where ended < vDateShort; + DELETE tw.* FROM ticketWeekly tw + LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL; + DELETE FROM claim WHERE ticketCreated < vFourYearsAgo; + DELETE FROM message WHERE sendDate < vDateShort; + -- Robert ubicacion anterior de trevelLog comentario para debug + DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Month; + DELETE bm + FROM buyMark bm + JOIN buy b ON b.id = bm.id + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + WHERE t.landed <= vDateShort; + DELETE FROM vn.buy WHERE created < vDateShort AND entryFk = 9200; + DELETE FROM vn.itemShelvingLog WHERE created < vDateShort; + DELETE FROM vn.stockBuyed WHERE creationDate < vDateShort; + DELETE FROM vn.itemCleanLog WHERE created < util.VN_NOW() - INTERVAL 1 YEAR; + DELETE FROM printQueue WHERE statusCode = 'printed' AND created < vDateShort; + + -- Equipos duplicados + DELETE w.* + FROM workerTeam w + JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated + FROM workerTeam + GROUP BY team,workerFk + HAVING duplicated + ) d ON d.team = w.team AND d.workerFk = w.workerFk AND d.id != w.id; + + DELETE sc + FROM saleComponent sc + JOIN sale s ON s.id= sc.saleFk + JOIN ticket t ON t.id= s.ticketFk + WHERE t.shipped < v18Month; + + DELETE c + FROM vn.claim c + JOIN vn.claimState cs ON cs.id = c.claimStateFk + WHERE cs.description = "Anulado" AND + c.created < vDateShort; + DELETE + FROM vn.expeditionTruck + WHERE ETD < v3Month; + + -- borrar travels sin entradas + DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; + CREATE TEMPORARY TABLE tmp.thermographToDelete + SELECT th.id,th.dmsFk + FROM vn.travel t + LEFT JOIN vn.entry e ON e.travelFk = t.id + JOIN vn.travelThermograph th ON th.travelFk = t.id + WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + + SELECT dt.id INTO vTrashId + FROM vn.dmsType dt + WHERE dt.code = 'trash'; + + UPDATE tmp.thermographToDelete th + JOIN vn.dms d ON d.id = th.dmsFk + SET d.dmsTypeFk = vTrashId; + + DELETE th + FROM tmp.thermographToDelete tmp + JOIN vn.travelThermograph th ON th.id = tmp.id; + + DELETE t + FROM vn.travel t + LEFT JOIN vn.entry e ON e.travelFk = t.id + WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + + UPDATE dms d + JOIN dmsType dt ON dt.id = d.dmsTypeFk + SET d.dmsTypeFk = vTrashId + WHERE created < TIMESTAMPADD(MONTH, -dt.monthToDelete, util.VN_CURDATE()); + + -- borrar entradas sin compras + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + CREATE TEMPORARY TABLE tmp.entryToDelete + SELECT e.* + FROM vn.entry e + LEFT JOIN vn.buy b ON b.entryFk = e.id + JOIN vn.entryConfig ec ON e.id != ec.defaultEntry + WHERE e.dated < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND b.entryFK IS NULL; + + DELETE e + FROM vn.entry e + JOIN tmp.entryToDelete tmp ON tmp.id = e.id; + + -- borrar de route registros menores a 4 años + DROP TEMPORARY TABLE IF EXISTS tmp.routeToDelete; + CREATE TEMPORARY TABLE tmp.routeToDelete + SELECT * + FROM vn.route r + WHERE created < TIMESTAMPADD(YEAR,-4,util.VN_CURDATE()); + + UPDATE tmp.routeToDelete tmp + JOIN vn.dms d ON d.id = tmp.gestdocFk + SET d.dmsTypeFk = vTrashId; + + DELETE r + FROM tmp.routeToDelete tmp + JOIN vn.route r ON r.id = tmp.id; + + -- borrar registros de dua y awb menores a 2 años + DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; + CREATE TEMPORARY TABLE tmp.duaToDelete + SELECT * + FROM vn.dua + WHERE operated < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + + UPDATE tmp.duaToDelete tm + JOIN vn.dms d ON d.id = tm.gestdocFk + SET d.dmsTypeFk = vTrashId; + + DELETE d + FROM tmp.duaToDelete tmp + JOIN vn.dua d ON d.id = tmp.id; + + DELETE FROM vn.awb WHERE created < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + + -- Borra los registros de collection y ticketcollection + DELETE FROM vn.collection WHERE created < vDateShort; + + DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; + + DELETE FROM travelLog WHERE creationDate < v3Month; + + CALL shelving_clean; + +END$$ +DELIMITER ; From fccfabdcd1389c1f6a72d7c9f02b1fc215fb8a43 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 27 Jan 2023 08:31:14 +0100 Subject: [PATCH 04/26] hotfix viewReceipt clientBalance --- modules/client/front/balance/create/index.js | 2 +- modules/client/front/balance/create/index.spec.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index 35b2e0b38..236834263 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -4,7 +4,6 @@ import Dialog from 'core/components/dialog'; class Controller extends Dialog { constructor($element, $, $transclude, vnReport) { super($element, $, $transclude); - this.viewReceipt = true; this.vnReport = vnReport; this.receipt = {}; } @@ -59,6 +58,7 @@ class Controller extends Dialog { if (value) { const accountingType = value.accountingType; + this.viewReceipt = accountingType.code == 'cash'; if (this.originalDescription) { this.receipt.description = `${accountingType && accountingType.receiptDescription}, ${this.originalDescription}`; diff --git a/modules/client/front/balance/create/index.spec.js b/modules/client/front/balance/create/index.spec.js index 2c4ed1940..fa6b48ea4 100644 --- a/modules/client/front/balance/create/index.spec.js +++ b/modules/client/front/balance/create/index.spec.js @@ -75,7 +75,6 @@ describe('Client', () => { jest.spyOn(controller.vnReport, 'show'); controller.$params = {id: 1101}; - controller.viewReceipt = false; $httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1}); controller.responseHandler('accept'); From 788ebd413347d181ecb18e9e4d11de1b1d2d3d88 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 30 Jan 2023 07:50:37 +0100 Subject: [PATCH 05/26] refactor(recover-password): recovery password label --- front/salix/components/recover-password/index.html | 2 +- front/salix/components/recover-password/locale/es.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/front/salix/components/recover-password/index.html b/front/salix/components/recover-password/index.html index 73f5401d9..b7587148b 100644 --- a/front/salix/components/recover-password/index.html +++ b/front/salix/components/recover-password/index.html @@ -1,6 +1,6 @@
Recover password
diff --git a/front/salix/components/recover-password/locale/es.yml b/front/salix/components/recover-password/locale/es.yml index b71c71415..f53ed937e 100644 --- a/front/salix/components/recover-password/locale/es.yml +++ b/front/salix/components/recover-password/locale/es.yml @@ -1,3 +1,4 @@ Recover password: Recuperar contraseña We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña Notification sent!: ¡Notificación enviada! +Recovery email: Correo de recuperación From 109556ae2eb647efb2e688305e4d69bc0cf2ea70 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 12:39:47 +0100 Subject: [PATCH 06/26] refs #5122 Hotfix: Basic implementation for payment confirmation --- .../back/methods/tpv-transaction/confirm.js | 47 +++++++++++++++++++ modules/client/back/models/tpv-transaction.js | 3 ++ 2 files changed, 50 insertions(+) create mode 100644 modules/client/back/methods/tpv-transaction/confirm.js create mode 100644 modules/client/back/models/tpv-transaction.js diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js new file mode 100644 index 000000000..21484b220 --- /dev/null +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -0,0 +1,47 @@ + +module.exports = Self => { + Self.remoteMethod('confirm', { + description: 'Confirms electronic payment transaction', + accessType: 'WRITE', + accepts: [ + { + arg: 'Ds_SignatureVersion', + type: 'string', + required: true, + }, { + arg: 'Ds_MerchantParameters', + type: 'string', + required: true, + }, { + arg: 'Ds_Signature', + type: 'string', + required: true, + } + ], + returns: { + type: 'Boolean', + root: true + }, + http: { + path: `/confirm`, + verb: 'POST' + } + }); + + Self.confirm = async(signatureVersion, merchantParameters, signature) => { + const buffer = Buffer.from(merchantParameters, 'base64'); + const params = JSON.parse(buffer.toString()); + console.debug('Payment confirmation received:', params); + await Self.rawSql( + 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ + params['Ds_Amount'], + params['Ds_Order'], + params['Ds_MerchantCode'], + params['Ds_Currency'], + params['Ds_Response'], + params['Ds_ErrorCode'] + ] + ); + return true; + }; +}; diff --git a/modules/client/back/models/tpv-transaction.js b/modules/client/back/models/tpv-transaction.js new file mode 100644 index 000000000..b511ae52e --- /dev/null +++ b/modules/client/back/models/tpv-transaction.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/tpv-transaction/confirm')(Self); +}; From 5744759d53da3f8d38b336b06d6737c2fd3b9e6f Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 17:33:15 +0100 Subject: [PATCH 07/26] refs #5122 Hotfix: Signature verification --- .../back/methods/tpv-transaction/confirm.js | 74 +++++++++++++++++-- package-lock.json | 18 ++++- package.json | 1 + 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 21484b220..8c7d10558 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -1,3 +1,6 @@ +const crypto = require('crypto'); +const UserError = require('vn-loopback/util/user-error'); +const base64url = require('base64url'); module.exports = Self => { Self.remoteMethod('confirm', { @@ -7,7 +10,7 @@ module.exports = Self => { { arg: 'Ds_SignatureVersion', type: 'string', - required: true, + required: false, }, { arg: 'Ds_MerchantParameters', type: 'string', @@ -28,15 +31,64 @@ module.exports = Self => { } }); + /* + * Source: https://github.com/santiperez/node-redsys-api + */ Self.confirm = async(signatureVersion, merchantParameters, signature) => { - const buffer = Buffer.from(merchantParameters, 'base64'); - const params = JSON.parse(buffer.toString()); - console.debug('Payment confirmation received:', params); + const $ = Self.app.models; + + const decodedParams = JSON.parse( + base64url.decode(merchantParameters, 'utf8')); + const params = {}; + + for (const param in decodedParams) + params[param] = decodeURIComponent(decodedParams[param]); + + console.debug('Payment confirmation received:', { + signatureVersion, + merchantParameters, + signature, + params + }); + + const orderId = params['Ds_Order']; + const merchantId = parseInt(params['Ds_MerchantCode']); + + if (!orderId) + throw new UserError('Order id not found'); + if (!merchantId) + throw new UserError('Mechant id not found'); + + const merchant = await $.TpvMerchant.findById(merchantId, { + fields: ['id', 'secretKey'] + }); + + const secretKey = Buffer.from(merchant.secretKey, 'base64'); + const iv = Buffer.alloc(8, 0); + + const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); + cipher.setAutoPadding(false); + const orderKey = cipher.update(zeroPad(str, 8), 'utf8', 'base64') + + cipher.final('utf8'); + + const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) + .update(merchantParameters) + .digest('base64'); + const base64Res = base64url.encode(res, 'base64'); + + // if (base64Res !== signature) + // throw new UserError('Invalid signature'); + + console.debug('Payment signature:', { + res, + base64Res + }); + await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ params['Ds_Amount'], - params['Ds_Order'], - params['Ds_MerchantCode'], + orderId, + merchantId, params['Ds_Currency'], params['Ds_Response'], params['Ds_ErrorCode'] @@ -44,4 +96,14 @@ module.exports = Self => { ); return true; }; + + function zeroPad(buf, blocksize) { + const buffer = typeof buf === 'string' ? Buffer.from(buf, 'utf8') : buf; + const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); + return Buffer.concat([buffer, pad]); + } + + function base64UrlDecode() { + + } }; diff --git a/package-lock.json b/package-lock.json index 31820196f..61180fa3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "salix-back", - "version": "9.0.0", + "version": "23.02.03", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "9.0.0", + "version": "23.02.03", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", + "base64url": "^3.0.1", "bcrypt": "^5.0.1", "bmp-js": "^0.1.0", "compression": "^1.7.3", @@ -4200,6 +4201,14 @@ "node": ">= 0.4" } }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/batch": { "version": "0.6.1", "dev": true, @@ -29057,6 +29066,11 @@ "base64-js": { "version": "1.0.2" }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, "batch": { "version": "0.6.1", "dev": true diff --git a/package.json b/package.json index 2031da475..85f8feb13 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "axios": "^1.2.2", + "base64url": "^3.0.1", "bcrypt": "^5.0.1", "bmp-js": "^0.1.0", "compression": "^1.7.3", From b20194b6d08f46b1c256f88134777e4fcc9a7c51 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 17:45:36 +0100 Subject: [PATCH 08/26] #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 8c7d10558..8099475d7 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -68,7 +68,7 @@ module.exports = Self => { const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); - const orderKey = cipher.update(zeroPad(str, 8), 'utf8', 'base64') + const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') + cipher.final('utf8'); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) @@ -102,8 +102,4 @@ module.exports = Self => { const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); return Buffer.concat([buffer, pad]); } - - function base64UrlDecode() { - - } }; From d6794cb4c8fdbc88d716b9272812a60c583cab31 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 19:51:01 +0100 Subject: [PATCH 09/26] #5174 Hotfix --- .../back/methods/tpv-transaction/confirm.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 8099475d7..5d04f8a81 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,13 +44,6 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); - console.debug('Payment confirmation received:', { - signatureVersion, - merchantParameters, - signature, - params - }); - const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -69,20 +62,15 @@ module.exports = Self => { const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final('utf8'); + + cipher.final(); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - // if (base64Res !== signature) - // throw new UserError('Invalid signature'); - - console.debug('Payment signature:', { - res, - base64Res - }); + if (base64Res !== signature) + throw new UserError('Invalid signature'); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ From 339cdab3c42090011d1388836810be4e3cfaef28 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 19:59:46 +0100 Subject: [PATCH 10/26] refs #5174 Debug enabled --- .../back/methods/tpv-transaction/confirm.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 5d04f8a81..1ca2265a6 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,6 +44,13 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); + console.debug('Payment confirmation received:', { + signatureVersion, + merchantParameters, + signature, + params + }); + const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -69,8 +76,13 @@ module.exports = Self => { .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - if (base64Res !== signature) - throw new UserError('Invalid signature'); + // if (base64Res !== signature) + // throw new UserError('Invalid signature'); + + console.debug('Payment signature:', { + res, + base64Res + }); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ From 64d8ae1f4948fbfb16cf71c0ea137d8856e4f041 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 20:22:52 +0100 Subject: [PATCH 11/26] refs #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 1ca2265a6..6c8ecebaf 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -66,17 +66,17 @@ module.exports = Self => { const secretKey = Buffer.from(merchant.secretKey, 'base64'); const iv = Buffer.alloc(8, 0); - const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); + const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final(); + + cipher.final('base64'); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - // if (base64Res !== signature) + // if (res !== signature) // throw new UserError('Invalid signature'); console.debug('Payment signature:', { From 424dcb954c96e83e02910e63ccbc1b8ad7e56312 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 20:23:52 +0100 Subject: [PATCH 12/26] refs #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 6c8ecebaf..74eb9510c 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -69,7 +69,7 @@ module.exports = Self => { const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final('base64'); + + cipher.final(); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) From 82bc7307f052d1a10c1445dfe4ef0378b3a8f856 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 31 Jan 2023 00:41:36 +0100 Subject: [PATCH 13/26] #5174 Signature verification fixed & enabled --- .../back/methods/tpv-transaction/confirm.js | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 74eb9510c..bec818bc9 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,13 +44,6 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); - console.debug('Payment confirmation received:', { - signatureVersion, - merchantParameters, - signature, - params - }); - const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -68,21 +61,17 @@ module.exports = Self => { const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); - const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final(); + const orderKey = Buffer.concat([ + cipher.update(zeroPad(orderId, 8)), + cipher.final() + ]); - const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) + const base64hmac = crypto.createHmac('sha256', orderKey) .update(merchantParameters) .digest('base64'); - const base64Res = base64url.encode(res, 'base64'); - // if (res !== signature) - // throw new UserError('Invalid signature'); - - console.debug('Payment signature:', { - res, - base64Res - }); + if (base64hmac !== base64url.toBase64(signature)) + throw new UserError('Invalid signature'); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ From 320ceb3e2c73edfdb59911e6869bd7eaef4dcf59 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 31 Jan 2023 11:17:31 +0100 Subject: [PATCH 14/26] fix: getRate2 --- .../specs/upsertFixedPrice.spec.js | 41 +++++++++++++++++++ .../methods/fixed-price/upsertFixedPrice.js | 10 +++++ modules/item/front/fixed-price/index.html | 2 +- modules/item/front/fixed-price/index.js | 18 -------- modules/item/front/fixed-price/index.spec.js | 20 --------- 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/modules/item/back/methods/fixed-price/specs/upsertFixedPrice.spec.js b/modules/item/back/methods/fixed-price/specs/upsertFixedPrice.spec.js index 68eacfbad..59defa738 100644 --- a/modules/item/back/methods/fixed-price/specs/upsertFixedPrice.spec.js +++ b/modules/item/back/methods/fixed-price/specs/upsertFixedPrice.spec.js @@ -72,4 +72,45 @@ describe('upsertFixedPrice()', () => { throw e; } }); + + it(`should recalculate rate2 if change rate3`, async() => { + const tx = await models.FixedPrice.beginTransaction({}); + + const tomorrow = new Date(now); + tomorrow.setDate(tomorrow.getDate() + 1); + + const rate2 = 2; + const firstRate3 = 1; + const secondRate3 = 2; + try { + const options = {transaction: tx}; + const ctx = {args: { + id: undefined, + itemFk: 1, + warehouseFk: 1, + started: tomorrow, + ended: tomorrow, + rate2: rate2, + rate3: firstRate3, + minPrice: 0, + hasMinPrice: false + }}; + + // create new fixed price + const newFixedPrice = await models.FixedPrice.upsertFixedPrice(ctx, options); + + // change rate3 to same fixed price id + ctx.args.id = newFixedPrice.id; + ctx.args.rate3 = secondRate3; + + const result = await models.FixedPrice.upsertFixedPrice(ctx, options); + + expect(result.rate2).not.toEqual(rate2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/item/back/methods/fixed-price/upsertFixedPrice.js b/modules/item/back/methods/fixed-price/upsertFixedPrice.js index ad35ec3a1..c56c434ad 100644 --- a/modules/item/back/methods/fixed-price/upsertFixedPrice.js +++ b/modules/item/back/methods/fixed-price/upsertFixedPrice.js @@ -72,6 +72,16 @@ module.exports = Self => { try { delete args.ctx; // removed unwanted data + + if (args.id) { + const beforeFixedPrice = await models.FixedPrice.findById(args.id, {fields: ['rate3']}, myOptions); + const [result] = await Self.rawSql(`SELECT vn.priceFixed_getRate2(?, ?) as rate2`, + [args.id, args.rate3], myOptions); + + if (beforeFixedPrice.rate3 != args.rate3 && result.rate2) + args.rate2 = result.rate2; + } + const fixedPrice = await models.FixedPrice.upsert(args, myOptions); const targetItem = await models.Item.findById(args.itemFk, null, myOptions); diff --git a/modules/item/front/fixed-price/index.html b/modules/item/front/fixed-price/index.html index f9d177562..ce7cefe7a 100644 --- a/modules/item/front/fixed-price/index.html +++ b/modules/item/front/fixed-price/index.html @@ -131,7 +131,7 @@ class="dense" vn-focus ng-model="price.rate3" - on-change="$ctrl.upsertPrice(price); $ctrl.recalculateRate2(price)" + on-change="$ctrl.upsertPrice(price);" step="0.01"s> diff --git a/modules/item/front/fixed-price/index.js b/modules/item/front/fixed-price/index.js index f03d73f08..df2989043 100644 --- a/modules/item/front/fixed-price/index.js +++ b/modules/item/front/fixed-price/index.js @@ -113,24 +113,6 @@ export default class Controller extends Section { return {[param]: value}; } } - - recalculateRate2(price) { - if (!price.id || !price.rate3) return; - - const query = 'FixedPrices/getRate2'; - const params = { - fixedPriceId: price.id, - rate3: price.rate3 - }; - this.$http.get(query, {params}) - .then(res => { - const rate2 = res.data.rate2; - if (rate2) { - price.rate2 = rate2; - this.upsertPrice(price); - } - }); - } } ngModule.vnComponent('vnFixedPrice', { diff --git a/modules/item/front/fixed-price/index.spec.js b/modules/item/front/fixed-price/index.spec.js index db9579444..94621e352 100644 --- a/modules/item/front/fixed-price/index.spec.js +++ b/modules/item/front/fixed-price/index.spec.js @@ -85,25 +85,5 @@ describe('fixed price', () => { expect(controller.$.model.remove).toHaveBeenCalled(); }); }); - - describe('recalculateRate2()', () => { - it(`should rate2 recalculate`, () => { - jest.spyOn(controller.vnApp, 'showSuccess'); - const price = { - id: 1, - itemFk: 1, - rate2: 2, - rate3: 2 - }; - const response = {rate2: 1}; - controller.recalculateRate2(price); - - const query = `FixedPrices/getRate2?fixedPriceId=${price.id}&rate3=${price.rate3}`; - $httpBackend.expectGET(query).respond(response); - $httpBackend.flush(); - - expect(price.rate2).toEqual(response.rate2); - }); - }); }); }); From 292898708b51ff701960944b98b1d109ac520935 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 31 Jan 2023 11:24:09 +0100 Subject: [PATCH 15/26] result not null --- modules/item/back/methods/fixed-price/upsertFixedPrice.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/back/methods/fixed-price/upsertFixedPrice.js b/modules/item/back/methods/fixed-price/upsertFixedPrice.js index c56c434ad..eb3eec1bd 100644 --- a/modules/item/back/methods/fixed-price/upsertFixedPrice.js +++ b/modules/item/back/methods/fixed-price/upsertFixedPrice.js @@ -78,7 +78,7 @@ module.exports = Self => { const [result] = await Self.rawSql(`SELECT vn.priceFixed_getRate2(?, ?) as rate2`, [args.id, args.rate3], myOptions); - if (beforeFixedPrice.rate3 != args.rate3 && result.rate2) + if (beforeFixedPrice.rate3 != args.rate3 && result && result.rate2) args.rate2 = result.rate2; } From 5a4ae7d7426727f1931a8525d587d81039a8827e Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 31 Jan 2023 13:29:17 +0100 Subject: [PATCH 16/26] refs #5174 TpvTransaction: Methods start & end added, fixes & refactor --- .../back/methods/tpv-transaction/confirm.js | 36 ++------ .../back/methods/tpv-transaction/end.js | 39 +++++++++ .../back/methods/tpv-transaction/start.js | 85 +++++++++++++++++++ modules/client/back/models/tpv-transaction.js | 26 ++++++ 4 files changed, 156 insertions(+), 30 deletions(-) create mode 100644 modules/client/back/methods/tpv-transaction/end.js create mode 100644 modules/client/back/methods/tpv-transaction/start.js diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index bec818bc9..b7d0c736f 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -1,4 +1,3 @@ -const crypto = require('crypto'); const UserError = require('vn-loopback/util/user-error'); const base64url = require('base64url'); @@ -21,19 +20,12 @@ module.exports = Self => { required: true, } ], - returns: { - type: 'Boolean', - root: true - }, http: { path: `/confirm`, verb: 'POST' } }); - /* - * Source: https://github.com/santiperez/node-redsys-api - */ Self.confirm = async(signatureVersion, merchantParameters, signature) => { const $ = Self.app.models; @@ -56,19 +48,11 @@ module.exports = Self => { fields: ['id', 'secretKey'] }); - const secretKey = Buffer.from(merchant.secretKey, 'base64'); - const iv = Buffer.alloc(8, 0); - - const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); - cipher.setAutoPadding(false); - const orderKey = Buffer.concat([ - cipher.update(zeroPad(orderId, 8)), - cipher.final() - ]); - - const base64hmac = crypto.createHmac('sha256', orderKey) - .update(merchantParameters) - .digest('base64'); + const base64hmac = Self.createSignature( + orderId, + merchant.secretKey, + merchantParameters + ); if (base64hmac !== base64url.toBase64(signature)) throw new UserError('Invalid signature'); @@ -81,14 +65,6 @@ module.exports = Self => { params['Ds_Currency'], params['Ds_Response'], params['Ds_ErrorCode'] - ] - ); - return true; + ]); }; - - function zeroPad(buf, blocksize) { - const buffer = typeof buf === 'string' ? Buffer.from(buf, 'utf8') : buf; - const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); - return Buffer.concat([buffer, pad]); - } }; diff --git a/modules/client/back/methods/tpv-transaction/end.js b/modules/client/back/methods/tpv-transaction/end.js new file mode 100644 index 000000000..5a757aa48 --- /dev/null +++ b/modules/client/back/methods/tpv-transaction/end.js @@ -0,0 +1,39 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('end', { + description: 'Ends electronic payment transaction', + accessType: 'WRITE', + accepts: [ + { + arg: 'orderId', + type: 'string', + required: true, + }, { + arg: 'status', + type: 'string', + required: true, + } + ], + http: { + path: `/end`, + verb: 'POST' + } + }); + + Self.end = async(ctx, orderId, status) => { + const userId = ctx.req.accessToken.userId; + const transaction = await Self.findById(orderId, { + fields: ['id', 'clientFk'] + }); + + if (transaction?.clientFk != userId) + throw new UserError('Transaction not owned by user'); + + await Self.rawSql( + 'CALL hedera.tpvTransaction_end(?, ?)', [ + orderId, + status + ]); + }; +}; diff --git a/modules/client/back/methods/tpv-transaction/start.js b/modules/client/back/methods/tpv-transaction/start.js new file mode 100644 index 000000000..ea6ed05eb --- /dev/null +++ b/modules/client/back/methods/tpv-transaction/start.js @@ -0,0 +1,85 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('start', { + description: 'Starts electronic payment transaction', + accessType: 'WRITE', + accepts: [ + { + arg: 'amount', + type: 'Number', + required: true, + }, { + arg: 'companyId', + type: 'Number', + required: false, + }, { + arg: 'urlOk', + type: 'String', + required: false, + }, { + arg: 'urlKo', + type: 'String', + required: false, + } + ], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/start`, + verb: 'POST' + } + }); + + Self.start = async(ctx, amount, companyId, urlOk, urlKo) => { + const userId = ctx.req.accessToken.userId; + const [[row]] = await Self.rawSql( + 'CALL hedera.tpvTransaction_start(?, ?, ?)', [ + amount, + companyId, + userId + ]); + + if (!row) + throw new UserError('Transaction error'); + + const orderId = row.transactionId.padStart(12, '0'); + const merchantUrl = row.merchantUrl ? row.merchantUrl : ''; + urlOk = urlOk ? urlOk.replace('_transactionId_', orderId) : ''; + urlKo = urlKo ? urlKo.replace('_transactionId_', orderId) : ''; + + const params = { + 'Ds_Merchant_Amount': amount, + 'Ds_Merchant_Order': orderId, + 'Ds_Merchant_MerchantCode': row.merchant, + 'Ds_Merchant_Currency': row.currency, + 'Ds_Merchant_TransactionType': row.transactionType, + 'Ds_Merchant_Terminal': row.terminal, + 'Ds_Merchant_MerchantURL': merchantUrl, + 'Ds_Merchant_UrlOK': urlOk, + 'Ds_Merchant_UrlKO': urlKo + }; + for (const param in params) + params[param] = encodeURIComponent(params[param]); + + const json = JSON.stringify(params); + const merchantParameters = Buffer.from(json).toString('base64'); + + const signature = Self.createSignature( + orderId, + row.secretKey, + merchantParameters + ); + + return { + url: row.url, + postValues: { + 'Ds_SignatureVersion': 'HMAC_SHA256_V1', + 'Ds_MerchantParameters': merchantParameters, + 'Ds_Signature': signature + } + }; + }; +}; diff --git a/modules/client/back/models/tpv-transaction.js b/modules/client/back/models/tpv-transaction.js index b511ae52e..eb9dd7d6c 100644 --- a/modules/client/back/models/tpv-transaction.js +++ b/modules/client/back/models/tpv-transaction.js @@ -1,3 +1,29 @@ +const crypto = require('crypto'); + module.exports = Self => { require('../methods/tpv-transaction/confirm')(Self); + require('../methods/tpv-transaction/start')(Self); + require('../methods/tpv-transaction/end')(Self); + + Self.createSignature = function(orderId, secretKey, merchantParameters) { + secretKey = Buffer.from(secretKey, 'base64'); + const iv = Buffer.alloc(8, 0); + + const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); + cipher.setAutoPadding(false); + const orderKey = Buffer.concat([ + cipher.update(zeroPad(orderId, 8)), + cipher.final() + ]); + + return crypto.createHmac('sha256', orderKey) + .update(merchantParameters) + .digest('base64'); + }; + + function zeroPad(buf, blocksize) { + const buffer = typeof buf === 'string' ? Buffer.from(buf, 'utf8') : buf; + const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); + return Buffer.concat([buffer, pad]); + } }; From e12f1839680f7e47f9ed358bc390e31a1b39d8fb Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 31 Jan 2023 13:46:42 +0100 Subject: [PATCH 17/26] refs #4975 Added chat/send in mdbVersion/upload --- modules/mdb/back/methods/mdbVersion/upload.js | 50 +++++++++++++++++-- modules/mdb/back/model-config.json | 3 ++ modules/mdb/back/models/mdbConfig.json | 24 +++++++++ modules/mdb/back/models/mdbVersionTree.json | 3 ++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 modules/mdb/back/models/mdbConfig.json diff --git a/modules/mdb/back/methods/mdbVersion/upload.js b/modules/mdb/back/methods/mdbVersion/upload.js index 1df4365a9..decbe82db 100644 --- a/modules/mdb/back/methods/mdbVersion/upload.js +++ b/modules/mdb/back/methods/mdbVersion/upload.js @@ -26,6 +26,11 @@ module.exports = Self => { type: 'string', required: true, description: `The old version number` + }, { + arg: 'description', + type: 'string', + required: false, + description: `The description of changes` }, { arg: 'unlock', type: 'boolean', @@ -42,8 +47,7 @@ module.exports = Self => { verb: 'POST' } }); - - Self.upload = async(ctx, appName, toVersion, branch, fromVersion, unlock, options) => { + Self.upload = async(ctx, options) => { const models = Self.app.models; const myOptions = {}; const $t = ctx.req.__; // $translate @@ -51,6 +55,12 @@ module.exports = Self => { const AccessContainer = models.AccessContainer; const fileOptions = {}; let tx; + const appName = ctx.args.appName; + const toVersion = ctx.args.toVersion; + const branch = ctx.args.branch; + const fromVersion = ctx.args.fromVersion; + let description = ctx.args.description; + const unlock = ctx.args.unlock; if (typeof options == 'object') Object.assign(myOptions, options); @@ -132,13 +142,47 @@ module.exports = Self => { await fs.symlink(rootRelative, destinationRoot); } } + if (description) { + let formatDesc; + const mainBranches = new Set(['master', 'test', 'dev']); + if (mainBranches.has(branch)) + formatDesc = `> :branch_${branch}: `; + else + formatDesc = `> :branch: `; + formatDesc += `*${appName.toUpperCase()}* v.${toVersion} `; + + let fromBranch = await models.MdbVersionTree.find({ + where: {version: fromVersion}, + fields: ['branchFk'] + }); + fromBranch = fromBranch[0].branchFk; + + if (branch == fromBranch) + formatDesc += `[*${branch}*]: `; + else + formatDesc += `[*${fromBranch}* » *${branch}*]: `; + + const params = await models.MdbConfig.find({}); + const issueTrackerUrl = params[0].issueTrackerUrl; + const issueNumberRegex = params[0].issueNumberRegex; + const chatDestination = params[0].chatDestination; + + const regex = new RegExp(issueNumberRegex, 'g'); + formatDesc += description.replace(regex, (match, issueId) => { + const newUrl = issueTrackerUrl.replace('{index}', issueId); + return `[#${issueId}](${newUrl})`; + }); + + await models.Chat.send(ctx, chatDestination, formatDesc, myOptions); + } await models.MdbVersionTree.create({ app: appName, version: toVersion, branchFk: branch, fromVersion, - userFk: userId + userFk: userId, + description, }, myOptions); await models.MdbVersion.upsert({ diff --git a/modules/mdb/back/model-config.json b/modules/mdb/back/model-config.json index 8010afca2..b59a4fda0 100644 --- a/modules/mdb/back/model-config.json +++ b/modules/mdb/back/model-config.json @@ -11,6 +11,9 @@ "MdbVersionTree": { "dataSource": "vn" }, + "MdbConfig": { + "dataSource": "vn" + }, "AccessContainer": { "dataSource": "accessStorage" } diff --git a/modules/mdb/back/models/mdbConfig.json b/modules/mdb/back/models/mdbConfig.json new file mode 100644 index 000000000..60634104a --- /dev/null +++ b/modules/mdb/back/models/mdbConfig.json @@ -0,0 +1,24 @@ +{ + "name": "MdbConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "mdbConfig" + } + }, + "properties": { + "id": { + "type": "string", + "id": true + }, + "issueTrackerUrl": { + "type": "string" + }, + "issueNumberRegex": { + "type": "string" + }, + "chatDestination": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/mdb/back/models/mdbVersionTree.json b/modules/mdb/back/models/mdbVersionTree.json index 8c0260e54..106473b64 100644 --- a/modules/mdb/back/models/mdbVersionTree.json +++ b/modules/mdb/back/models/mdbVersionTree.json @@ -23,6 +23,9 @@ }, "userFk": { "type": "number" + }, + "description": { + "type": "string" } }, "relations": { From 5045a8f6703b117444d843faac41c120a37a473f Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 31 Jan 2023 14:00:10 +0100 Subject: [PATCH 18/26] #5175 TpvTransaction.confirm(): Return response --- modules/client/back/methods/tpv-transaction/confirm.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index b7d0c736f..a26e0bad6 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -20,6 +20,10 @@ module.exports = Self => { required: true, } ], + returns: { + type: 'Boolean', + root: true + }, http: { path: `/confirm`, verb: 'POST' @@ -66,5 +70,7 @@ module.exports = Self => { params['Ds_Response'], params['Ds_ErrorCode'] ]); + + return true; }; }; From 18168b07bbf8b4b17dc45b8ed4dab826aaff493a Mon Sep 17 00:00:00 2001 From: guillermo Date: Tue, 31 Jan 2023 14:47:24 +0100 Subject: [PATCH 19/26] refs #4975 Changes --- modules/mdb/back/methods/mdbVersion/upload.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/mdb/back/methods/mdbVersion/upload.js b/modules/mdb/back/methods/mdbVersion/upload.js index decbe82db..864a73f52 100644 --- a/modules/mdb/back/methods/mdbVersion/upload.js +++ b/modules/mdb/back/methods/mdbVersion/upload.js @@ -152,21 +152,20 @@ module.exports = Self => { formatDesc += `*${appName.toUpperCase()}* v.${toVersion} `; - let fromBranch = await models.MdbVersionTree.find({ + const oldVersion = await models.MdbVersionTree.findOne({ where: {version: fromVersion}, fields: ['branchFk'] - }); - fromBranch = fromBranch[0].branchFk; + }, myOptions); - if (branch == fromBranch) + if (branch == oldVersion.branchFk) formatDesc += `[*${branch}*]: `; else - formatDesc += `[*${fromBranch}* » *${branch}*]: `; + formatDesc += `[*${oldVersion.branchFk}* » *${branch}*]: `; - const params = await models.MdbConfig.find({}); - const issueTrackerUrl = params[0].issueTrackerUrl; - const issueNumberRegex = params[0].issueNumberRegex; - const chatDestination = params[0].chatDestination; + const params = await models.MdbConfig.findOne(myOptions); + const issueTrackerUrl = params.issueTrackerUrl; + const issueNumberRegex = params.issueNumberRegex; + const chatDestination = params.chatDestination; const regex = new RegExp(issueNumberRegex, 'g'); formatDesc += description.replace(regex, (match, issueId) => { From 2ef7b0d756bce0571572017af1aea3cbe1704673 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 1 Feb 2023 08:48:33 +0100 Subject: [PATCH 20/26] refs #5157 clip-path deleted --- front/core/components/field/style.scss | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index 9012b8c4c..0d539b029 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -82,8 +82,6 @@ } &[type=time], &[type=date] { - clip-path: inset(0 20px 0 0); - &::-webkit-inner-spin-button, &::-webkit-clear-button { display: none; @@ -99,7 +97,7 @@ } &[type=number] { -moz-appearance: textfield; - + &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { -webkit-appearance: none; From 21281e09dbfbf915a7634e1cd6d81b76edace5f0 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 2 Feb 2023 15:13:53 +0100 Subject: [PATCH 21/26] hotfix removed supplier --- print/templates/reports/balance-compensation/sql/client.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/print/templates/reports/balance-compensation/sql/client.sql b/print/templates/reports/balance-compensation/sql/client.sql index 92e6f6cab..b4463be23 100644 --- a/print/templates/reports/balance-compensation/sql/client.sql +++ b/print/templates/reports/balance-compensation/sql/client.sql @@ -8,5 +8,4 @@ SELECT r.payed FROM client c JOIN receipt r ON r.clientFk = c.id - JOIN supplier s ON c.fi = s.nif - WHERE r.id = ? \ No newline at end of file + WHERE r.id = ? From dddeca08329b7bd47dd652f3edab6dd71ed60488 Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 3 Feb 2023 12:46:01 +0100 Subject: [PATCH 22/26] refs #4975 Added property dsName in mdbBranch tab --- modules/mdb/back/models/mdbBranch.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/mdb/back/models/mdbBranch.json b/modules/mdb/back/models/mdbBranch.json index 486dfaf25..f9d6b556e 100644 --- a/modules/mdb/back/models/mdbBranch.json +++ b/modules/mdb/back/models/mdbBranch.json @@ -11,6 +11,11 @@ "id": true, "type": "string", "description": "Identifier" + }, + "dsName": { + "id": true, + "type": "string", + "description": "Identifier" } } } \ No newline at end of file From ca24de7ee5f5502a3f0c6c206fe6f27285a85d2f Mon Sep 17 00:00:00 2001 From: guillermo Date: Fri, 3 Feb 2023 12:50:19 +0100 Subject: [PATCH 23/26] refs #4975 Changed description --- modules/mdb/back/models/mdbBranch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mdb/back/models/mdbBranch.json b/modules/mdb/back/models/mdbBranch.json index f9d6b556e..b22d14ece 100644 --- a/modules/mdb/back/models/mdbBranch.json +++ b/modules/mdb/back/models/mdbBranch.json @@ -15,7 +15,7 @@ "dsName": { "id": true, "type": "string", - "description": "Identifier" + "description": "ODBC name" } } } \ No newline at end of file From 2717c6420c468163fc876e710cb161b65c7e243e Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 3 Feb 2023 14:58:58 +0100 Subject: [PATCH 24/26] fix(invoiceIn_descriptor): supplier.email --- modules/invoiceIn/back/models/invoice-in.json | 5 ----- modules/invoiceIn/front/card/index.js | 14 ++++++++------ modules/invoiceIn/front/descriptor/index.html | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index fa8a1d8f8..c6a736b06 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -94,11 +94,6 @@ "model": "Supplier", "foreignKey": "supplierFk" }, - "supplierContact": { - "type": "hasMany", - "model": "SupplierContact", - "foreignKey": "supplierFk" - }, "currency": { "type": "belongsTo", "model": "Currency", diff --git a/modules/invoiceIn/front/card/index.js b/modules/invoiceIn/front/card/index.js index c7ac08cc7..48217faa5 100644 --- a/modules/invoiceIn/front/card/index.js +++ b/modules/invoiceIn/front/card/index.js @@ -6,13 +6,15 @@ class Controller extends ModuleCard { const filter = { include: [ { - relation: 'supplier' - }, - { - relation: 'supplierContact', + relation: 'supplier', scope: { - where: { - email: {neq: null} + include: { + relation: 'contacts', + scope: { + where: { + email: {neq: null}, + } + } } } }, diff --git a/modules/invoiceIn/front/descriptor/index.html b/modules/invoiceIn/front/descriptor/index.html index 223914c9c..c4330fbf0 100644 --- a/modules/invoiceIn/front/descriptor/index.html +++ b/modules/invoiceIn/front/descriptor/index.html @@ -40,7 +40,7 @@ Send agricultural receipt as PDF From 0a9d37ca08b1ff3676aaa3bdcbe38a3a0a7c4b71 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 6 Feb 2023 09:01:13 +0100 Subject: [PATCH 25/26] hotfix itemConfig --- db/changes/230202/00-itemConfig.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 db/changes/230202/00-itemConfig.sql diff --git a/db/changes/230202/00-itemConfig.sql b/db/changes/230202/00-itemConfig.sql new file mode 100644 index 000000000..a793997d0 --- /dev/null +++ b/db/changes/230202/00-itemConfig.sql @@ -0,0 +1,9 @@ +ALTER TABLE `vn`.`itemConfig` ADD defaultTag INT DEFAULT 56 NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD CONSTRAINT itemConfig_FK FOREIGN KEY (defaultTag) REFERENCES vn.tag(id); +ALTER TABLE `vn`.`itemConfig` ADD validPriorities varchar(50) DEFAULT '[1,2,3]' NOT NULL; +ALTER TABLE `vn`.`itemConfig` ADD defaultPriority INT DEFAULT 2 NOT NULL; +ALTER TABLE `vn`.`item` MODIFY COLUMN relevancy tinyint(1) DEFAULT 0 NOT NULL COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos'; + +INSERT INTO `salix`.`ACL` +(model, property, accessType, permission, principalType, principalId) +VALUES('ItemConfig', '*', 'READ', 'ALLOW', 'ROLE', 'buyer'); From ef5b29d6f38d2a391823337baab1eebd50ea5584 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 8 Feb 2023 13:47:35 +0100 Subject: [PATCH 26/26] hotfix ticketFutureAdvance warehouse --- modules/ticket/front/advance/index.js | 15 +++++++++------ modules/ticket/front/future/index.js | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index b770440f1..488710ce7 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -65,12 +65,15 @@ export default class Controller extends Section { let today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); - this.filterParams = { - dateFuture: tomorrow, - dateToAdvance: today, - warehouseFk: this.vnConfig.warehouseFk - }; - this.$.model.applyFilter(null, this.filterParams); + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => { + this.filterParams = { + dateFuture: tomorrow, + dateToAdvance: today, + warehouseFk: res.data.warehouseFk + }; + this.$.model.addFilter({}, this.filterParams); + }); } compareDate(date) { diff --git a/modules/ticket/front/future/index.js b/modules/ticket/front/future/index.js index 5fb2c8f82..1887653e2 100644 --- a/modules/ticket/front/future/index.js +++ b/modules/ticket/front/future/index.js @@ -59,12 +59,15 @@ export default class Controller extends Section { setDefaultFilter() { const today = new Date(); - this.filterParams = { - originDated: today, - futureDated: today, - warehouseFk: this.vnConfig.warehouseFk - }; - this.$.model.applyFilter(null, this.filterParams); + this.$http.get(`UserConfigs/getUserConfig`) + .then(res => { + this.filterParams = { + originDated: today, + futureDated: today, + warehouseFk: res.data.warehouseFk + }; + this.$.model.applyFilter(null, this.filterParams); + }); } compareDate(date) {