From f832c1d9eceba58e63530197e54a6716809f2a09 Mon Sep 17 00:00:00 2001 From: pablone Date: Sun, 15 Oct 2023 11:08:33 +0200 Subject: [PATCH 01/21] refs #5979 getUrl --- back/methods/collection/getTickets.js | 21 ++++---------- loopback/common/methods/application/getUrl.js | 29 +++++++++++++++++++ loopback/common/models/application.js | 1 + loopback/common/models/application.json | 8 ++++- .../back/methods/claim/claimPickupEmail.js | 7 ++--- .../claim/back/methods/claim/updateClaim.js | 9 +++--- .../back/methods/sale/updateQuantity.js | 7 +++-- 7 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 loopback/common/methods/application/getUrl.js diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 445fc070d3..8509edadf5 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const origin = ctx.req.headers.origin; + const url = Self.app.models.Application.getUrl(); const $t = ctx.req.__; const myOptions = {}; @@ -36,7 +36,6 @@ module.exports = Self => { myOptions.userId = userId; const promises = []; - const [tickets] = await Self.rawSql(`CALL vn.collection_getTickets(?)`, [id], myOptions); const sales = await Self.rawSql(` SELECT s.ticketFk, @@ -46,11 +45,11 @@ module.exports = Self => { i.longName, i.size, ic.color, - o.code origin, + o.code url, ish.packing, ish.grouping, s.isAdded, - s.originalQuantity, + s.urlalQuantity, s.quantity saleQuantity, iss.quantity reservedQuantity, SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, @@ -74,7 +73,7 @@ module.exports = Self => { LEFT JOIN shelving sh ON sh.code = ish.shelvingFk LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk - LEFT JOIN origin o ON o.id = i.originFk + LEFT JOIN url o ON o.id = i.urlFk WHERE tc.collectionFk = ? GROUP BY ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); @@ -86,24 +85,19 @@ module.exports = Self => { if (tickets && tickets.length) { for (const ticket of tickets) { const ticketId = ticket.ticketFk; - - // SEND ROCKET if (ticket.observaciones != '') { for (observation of ticket.observaciones.split(' ')) { if (['#', '@'].includes(observation.charAt(0))) { promises.push(Self.app.models.Chat.send(ctx, observation, $t('The ticket is in preparation', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/summary`, + ticketUrl: `${url}/#!/ticket/${ticketId}/summary`, salesPersonId: ticket.salesPersonFk }))); } } } - - // SET COLLECTION if (sales && sales.length) { - // GET BARCODES const barcodes = await Self.rawSql(` SELECT s.id saleFk, b.code, c.id FROM vn.sale s @@ -114,13 +108,10 @@ module.exports = Self => { WHERE s.ticketFk = ? AND tr.landed >= util.VN_CURDATE() - INTERVAL 1 YEAR`, [ticketId], myOptions); - - // BINDINGS ticket.sales = []; for (const sale of sales) { if (sale.ticketFk === ticketId) { sale.Barcodes = []; - if (barcodes && barcodes.length) { for (const barcode of barcodes) { if (barcode.saleFk === sale.saleFk) { @@ -131,7 +122,6 @@ module.exports = Self => { } } } - ticket.sales.push(sale); } } @@ -140,7 +130,6 @@ module.exports = Self => { } } await Promise.all(promises); - return collection; }; }; diff --git a/loopback/common/methods/application/getUrl.js b/loopback/common/methods/application/getUrl.js new file mode 100644 index 0000000000..57aed0b848 --- /dev/null +++ b/loopback/common/methods/application/getUrl.js @@ -0,0 +1,29 @@ +module.exports = Self => { + Self.remoteMethodCtx('getUrl', { + description: 'Returns the colling app name', + accepts: [ + { + arg: 'appName', + type: 'string', + required: false + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: `/getUrl`, + verb: 'get' + } + }); + Self.getUrl = async(appName = 'salix') => { + const {url} = Self.app.models.Url.findOne({ + where: { + appName, + enviroment: process.env.NODE_ENV || 'development' + } + }); + return url; + }; +}; diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index 5e767fdc11..b3841d34a3 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,4 +2,5 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); + require('../methods/application/getUrl')(Self); }; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index bc72df315a..6343c3421f 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,6 +13,12 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - } + }, + { + "property": "getUrl", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } ] } diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index 1fd8eb99e3..f4cd0fc206 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -43,9 +43,8 @@ module.exports = Self => { Self.claimPickupEmail = async ctx => { const models = Self.app.models; - const userId = ctx.req.accessToken.userId; const $t = ctx.req.__; // $translate - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const args = Object.assign({}, ctx.args); const params = { @@ -70,9 +69,9 @@ module.exports = Self => { const message = $t('Claim pickup order sent', { claimId: args.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${args.id}/summary`, + claimUrl: `${url}/claim/${args.id}/summary`, }); - + console.log(message); const salesPersonId = claim.client().salesPersonFk; if (salesPersonId) await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 5486b8efff..b7ffa9ff5b 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -115,27 +115,28 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const origin = ctx.req.headers.origin; + const url = await models.Application.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${claim.id}/summary` + claimUrl: `${url}/claim/${claim.id}/summary` }); await models.Chat.sendCheckingPresence(ctx, workerId, message); } async function notifyPickUp(ctx, workerId, claim) { - const origin = ctx.req.headers.origin; const models = Self.app.models; + const url = await models.Application.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${origin}/#!/claim/${claim.id}/summary` + claimUrl: `${url}/claim/${claim.id}/summary` }); + console.log(message); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index edbc34e421..3cbd9255f6 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,16 +80,17 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await models.Application.getUrl(); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, concept: sale.concept, oldQuantity: oldQuantity, newQuantity: newQuantity, - ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}/ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}/item/${sale.itemFk}/summary` }); + await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); } From 033c02750b48106e25000fb77a35b7b48db7da77 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:24:58 +0200 Subject: [PATCH 02/21] refactor(origin): .origin por getUrl() --- back/methods/collection/getTickets.js | 8 +-- back/models/vn-user.js | 51 +------------------ db/tests/vn/ticketCalculateClon.spec.js | 3 +- loopback/common/methods/application/getUrl.js | 3 +- .../back/methods/claim/createFromSales.js | 6 +-- .../back/methods/claim/regularizeClaim.js | 6 +-- modules/client/back/models/client.js | 21 +++++--- .../client/back/models/credit-insurance.js | 4 +- .../methods/invoiceOut/makePdfAndNotify.js | 4 +- .../ticket/back/methods/sale/deleteSales.js | 6 +-- modules/ticket/back/methods/sale/reserve.js | 10 ++-- .../ticket/back/methods/sale/updatePrice.js | 8 ++- .../back/methods/sale/updateQuantity.js | 7 +-- .../back/methods/ticket-request/confirm.js | 6 +-- .../back/methods/ticket-request/deny.js | 4 +- modules/ticket/back/methods/ticket/addSale.js | 4 +- .../back/methods/ticket/componentUpdate.js | 4 +- modules/ticket/back/methods/ticket/merge.js | 6 +-- modules/ticket/back/methods/ticket/restore.js | 4 +- .../ticket/back/methods/ticket/setDeleted.js | 7 +-- .../back/methods/ticket/updateDiscount.js | 5 +- .../back/methods/worker/createAbsence.js | 4 +- .../back/methods/worker/deleteAbsence.js | 4 +- 23 files changed, 70 insertions(+), 115 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 8509edadf5..dbb286b4f6 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -45,11 +45,11 @@ module.exports = Self => { i.longName, i.size, ic.color, - o.code url, + o.code origin, ish.packing, ish.grouping, s.isAdded, - s.urlalQuantity, + s.originalQuantity, s.quantity saleQuantity, iss.quantity reservedQuantity, SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, @@ -73,7 +73,7 @@ module.exports = Self => { LEFT JOIN shelving sh ON sh.code = ish.shelvingFk LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk - LEFT JOIN url o ON o.id = i.urlFk + LEFT JOIN origin o ON o.id = i.originFk WHERE tc.collectionFk = ? GROUP BY ish.id, p.code, p2.code ORDER BY pickingOrder;`, [id], myOptions); @@ -91,7 +91,7 @@ module.exports = Self => { promises.push(Self.app.models.Chat.send(ctx, observation, $t('The ticket is in preparation', { ticketId: ticketId, - ticketUrl: `${url}/#!/ticket/${ticketId}/summary`, + ticketUrl: `${url}ticket/${ticketId}/summary`, salesPersonId: ticket.salesPersonFk }))); } diff --git a/back/models/vn-user.js b/back/models/vn-user.js index cf210b61b8..a38139bc7d 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -1,5 +1,4 @@ const vnModel = require('vn-loopback/common/models/vn-model'); -const LoopBackContext = require('loopback-context'); const {Email} = require('vn-print'); module.exports = function(Self) { @@ -90,11 +89,7 @@ module.exports = function(Self) { }; Self.on('resetPasswordRequest', async function(info) { - const loopBackContext = LoopBackContext.getCurrentContext(); - const httpCtx = {req: loopBackContext.active}; - const httpRequest = httpCtx.req.http.req; - const headers = httpRequest.headers; - const origin = headers.origin; + const url = await Self.app.models.Application.getUrl(); const defaultHash = '/reset-password?access_token=$token$'; const recoverHashes = { @@ -110,7 +105,7 @@ module.exports = function(Self) { const params = { recipient: info.email, lang: user.lang, - url: origin + '/#!' + recoverHash + url: url.slice(0, -1) + recoverHash }; const options = Object.assign({}, info.options); @@ -177,46 +172,4 @@ module.exports = function(Self) { Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls = Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls .filter(acl => acl.property != 'changePassword'); - - // FIXME: https://redmine.verdnatura.es/issues/5761 - // Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { - // if (!ctx.args || !ctx.args.data.email) return; - - // const loopBackContext = LoopBackContext.getCurrentContext(); - // const httpCtx = {req: loopBackContext.active}; - // const httpRequest = httpCtx.req.http.req; - // const headers = httpRequest.headers; - // const origin = headers.origin; - // const url = origin.split(':'); - - // class Mailer { - // async send(verifyOptions, cb) { - // const params = { - // url: verifyOptions.verifyHref, - // recipient: verifyOptions.to, - // lang: ctx.req.getLocale() - // }; - - // const email = new Email('email-verify', params); - // email.send(); - - // cb(null, verifyOptions.to); - // } - // } - - // const options = { - // type: 'email', - // to: instance.email, - // from: {}, - // redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`, - // template: false, - // mailer: new Mailer, - // host: url[1].split('/')[2], - // port: url[2], - // protocol: url[0], - // user: Self - // }; - - // await instance.verify(options); - // }); }; diff --git a/db/tests/vn/ticketCalculateClon.spec.js b/db/tests/vn/ticketCalculateClon.spec.js index 9116d805fb..665d52ed09 100644 --- a/db/tests/vn/ticketCalculateClon.spec.js +++ b/db/tests/vn/ticketCalculateClon.spec.js @@ -53,7 +53,8 @@ describe('ticket ticketCalculateClon()', () => { expect(result[orderIndex][0].ticketFk).toBeGreaterThan(newestTicketIdInFixtures); }); - it('should add the ticket to the order containing the original ticket and generate landed value if it was null', async() => { + it('should add the ticket to the order containing the original ' + + 'ticket and generate landed value if it was null', async() => { let stmts = []; let stmt; diff --git a/loopback/common/methods/application/getUrl.js b/loopback/common/methods/application/getUrl.js index 57aed0b848..4e51b0776c 100644 --- a/loopback/common/methods/application/getUrl.js +++ b/loopback/common/methods/application/getUrl.js @@ -18,7 +18,8 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { - const {url} = Self.app.models.Url.findOne({ + const {url} = await Self.app.models.Url.findOne({ + where: { appName, enviroment: process.env.NODE_ENV || 'development' diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 07bdb30aa7..7ea26f9cc8 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -94,13 +94,13 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Created claim', { claimId: newClaim.id, ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, - claimUrl: `${origin}/#!/claim/${newClaim.id}/summary`, + ticketUrl: `${url}/ticket/${ticketId}/sale`, + claimUrl: `${url}/claim/${newClaim.id}/summary`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/claim/back/methods/claim/regularizeClaim.js b/modules/claim/back/methods/claim/regularizeClaim.js index 672c94947d..4ac500e2fd 100644 --- a/modules/claim/back/methods/claim/regularizeClaim.js +++ b/modules/claim/back/methods/claim/regularizeClaim.js @@ -56,15 +56,15 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const nickname = address && address.nickname || destination.description; - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Sent units from ticket', { quantity: sale.quantity, concept: sale.concept, itemId: sale.itemFk, ticketId: sale.ticketFk, nickname: nickname, - ticketUrl: `${origin}/#!/ticket/${sale.ticketFk}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticketFk}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); } diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 8e720484ff..1b60b13296 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -250,7 +250,12 @@ module.exports = Self => { const loopBackContext = LoopBackContext.getCurrentContext(); const accessToken = {req: loopBackContext.active.accessToken}; - const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl(accessToken, 'Client', 'editVerifiedDataWithoutTaxDataCheck', 'WRITE'); + const editVerifiedDataWithoutTaxDataChecked = models.ACL.checkAccessAcl( + accessToken, + 'Client', + 'editVerifiedDataWithoutTaxDataCheck', + 'WRITE' + ); const hasChanges = orgData && changes; const isTaxDataChecked = hasChanges && (changes.isTaxDataChecked || orgData.isTaxDataChecked); @@ -263,7 +268,9 @@ module.exports = Self => { const sageTransactionTypeChanged = hasChanges && orgData.sageTransactionTypeFk != sageTransactionType; const cantEditVerifiedData = isTaxDataCheckedChanged && !editVerifiedDataWithoutTaxDataChecked; - const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !editVerifiedDataWithoutTaxDataChecked; + const cantChangeSageData = (sageTaxTypeChanged || + sageTransactionTypeChanged + ) && !editVerifiedDataWithoutTaxDataChecked; if (cantEditVerifiedData || cantChangeSageData) throw new UserError(`You don't have enough privileges`); @@ -346,8 +353,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const headers = httpRequest.headers; - const origin = headers.origin; + const url = await Self.app.models.Application.getUrl(); const salesPersonId = instance.salesPersonFk; @@ -366,7 +372,7 @@ module.exports = Self => { await email.send(); } - const fullUrl = `${origin}/#!/client/${instance.id}/billing-data`; + const fullUrl = `${url}client/${instance.id}/billing-data`; const message = $t('Changed client paymethod', { clientId: instance.id, clientName: instance.name, @@ -389,8 +395,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const headers = httpRequest.headers; - const origin = headers.origin; + const url = await Self.app.models.Application.getUrl(); const models = Self.app.models; let previousWorker = {name: $t('None')}; @@ -411,7 +416,7 @@ module.exports = Self => { currentWorker.name = worker && worker.user().nickname; } - const fullUrl = `${origin}/#!/client/${client.id}/basic-data`; + const fullUrl = `${url}client/${client.id}/basic-data`; const message = $t('Client assignment has changed', { clientId: client.id, clientName: client.name, diff --git a/modules/client/back/models/credit-insurance.js b/modules/client/back/models/credit-insurance.js index 6f656d3829..619904612c 100644 --- a/modules/client/back/models/credit-insurance.js +++ b/modules/client/back/models/credit-insurance.js @@ -57,8 +57,8 @@ module.exports = function(Self) { const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const origin = httpRequest.headers.origin; - const fullPath = `${origin}/#!/client/${client.id}/credit-insurance/index`; + const url = await Self.app.models.Application.getUrl(); + const fullPath = `${url}client/${client.id}/credit-insurance/index`; const message = $t('MESSAGE_INSURANCE_CHANGE', { clientId: client.id, clientName: client.name, diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js index a48664b302..49c7850139 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -59,10 +59,10 @@ module.exports = Self => { }; await Self.invoiceEmail(ctx, ref); } catch (err) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = ctx.req.__('Mail not sent', { clientId: client.id, - clientUrl: `${origin}/#!/claim/${id}/summary` + clientUrl: `${url}claim/${id}/summary` }); const salesPersonId = client.salesPersonFk; diff --git a/modules/ticket/back/methods/sale/deleteSales.js b/modules/ticket/back/methods/sale/deleteSales.js index 5d1463a666..c71f8d5e13 100644 --- a/modules/ticket/back/methods/sale/deleteSales.js +++ b/modules/ticket/back/methods/sale/deleteSales.js @@ -1,5 +1,3 @@ -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('deleteSales', { description: 'Deletes the selected sales', @@ -70,11 +68,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Deleted sales from ticket', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, + ticketUrl: `${url}ticket/${ticketId}/sale`, deletions: deletions }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/sale/reserve.js b/modules/ticket/back/methods/sale/reserve.js index 2dc368af69..b111a04582 100644 --- a/modules/ticket/back/methods/sale/reserve.js +++ b/modules/ticket/back/methods/sale/reserve.js @@ -1,6 +1,3 @@ - -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('reserve', { description: 'Change the state of a ticket', @@ -65,7 +62,8 @@ module.exports = Self => { promises.push(reservedSale); - changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`; + changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) + ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`; } } @@ -87,11 +85,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale reserved state', { ticketId: ticketId, - ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`, + ticketUrl: `${url}ticket/${ticketId}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 62e4ebd42e..3cae2a3333 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -1,5 +1,3 @@ -let UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('updatePrice', { description: 'Changes the price of a sale', @@ -100,7 +98,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale price', { ticketId: sale.ticket().id, itemId: sale.itemFk, @@ -108,8 +106,8 @@ module.exports = Self => { quantity: sale.quantity, oldPrice: oldPrice, newPrice: newPrice, - ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`, - itemUrl: `${origin}/#!/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); } diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 3cbd9255f6..27c1f529e2 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,15 +80,16 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await models.Application.getUrl(); + const url = await Self.app.models.Application.getUrl(); + console.log(url); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, concept: sale.concept, oldQuantity: oldQuantity, newQuantity: newQuantity, - ticketUrl: `${url}/ticket/${sale.ticket().id}/sale`, - itemUrl: `${url}/item/${sale.itemFk}/summary` + ticketUrl: `${url}ticket/${sale.ticket().id}/sale`, + itemUrl: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index 9cd7f4d682..a69fc7fd76 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -84,7 +84,7 @@ module.exports = Self => { const query = `CALL vn.sale_calculateComponent(?, NULL)`; await Self.rawSql(query, [sale.id], myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const requesterId = request.requesterFk; const message = $t('Bought units from buy request', { @@ -92,8 +92,8 @@ module.exports = Self => { concept: sale.concept, itemId: sale.itemFk, ticketId: sale.ticketFk, - url: `${origin}/#!/ticket/${sale.ticketFk}/summary`, - urlItem: `${origin}/#!/item/${sale.itemFk}/summary` + url: `${url}ticket/${sale.ticketFk}/summary`, + urlItem: `${url}item/${sale.itemFk}/summary` }); await models.Chat.sendCheckingPresence(ctx, requesterId, message, myOptions); diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 92f020083b..9ec11d755b 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -50,12 +50,12 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const requesterId = request.requesterFk; const message = $t('Deny buy request', { ticketId: request.ticketFk, - url: `${origin}/#!/ticket/${request.ticketFk}/request/index`, + url: `${url}ticket/${request.ticketFk}/request/index`, observation: params.response }); diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index cbf884273b..29e49d8e6e 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -94,11 +94,11 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t('Added sale to ticket', { ticketId: id, - ticketUrl: `${origin}/#!/ticket/${id}/sale`, + ticketUrl: `${url}ticket/${id}/sale`, addition: addition }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 8aad8959bb..fc8b3a40c8 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -237,7 +237,7 @@ module.exports = Self => { const salesPersonId = originalTicket.client().salesPersonFk; if (salesPersonId) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); let changesMade = ''; for (let change in newProperties) { @@ -249,7 +249,7 @@ module.exports = Self => { const message = $t('Changed this data from the ticket', { ticketId: args.id, - ticketUrl: `${origin}/#!/ticket/${args.id}/sale`, + ticketUrl: `${url}ticket/${args.id}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 3c0da077f3..19c7f9fa0d 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -25,7 +25,7 @@ module.exports = Self => { Self.merge = async(ctx, tickets, options) => { const httpRequest = ctx.req; const $t = httpRequest.__; - const origin = httpRequest.headers.origin; + const url = await Self.app.models.Application.getUrl(); const models = Self.app.models; const myOptions = {}; let tx; @@ -40,8 +40,8 @@ module.exports = Self => { try { for (let ticket of tickets) { - const originFullPath = `${origin}/#!/ticket/${ticket.originId}/summary`; - const destinationFullPath = `${origin}/#!/ticket/${ticket.destinationId}/summary`; + const originFullPath = `${url}ticket/${ticket.originId}/summary`; + const destinationFullPath = `${url}ticket/${ticket.destinationId}/summary`; const message = $t('Ticket merged', { originDated: dateUtil.toString(new Date(ticket.originShipped)), destinationDated: dateUtil.toString(new Date(ticket.destinationShipped)), diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 722c3294e8..0aaef0418e 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -48,10 +48,10 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; if (salesPersonId) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t(`I have restored the ticket id`, { id: id, - url: `${origin}/#!/ticket/${id}/summary` + url: `${url}ticket/${id}/summary` }); await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); } diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index fcd9972fe2..a6fd295f17 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -119,10 +119,10 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonUser = ticket.client().salesPersonUser(); if (salesPersonUser && sales.length) { - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const message = $t(`I have deleted the ticket id`, { id: id, - url: `${origin}/#!/ticket/${id}/summary` + url: `${url}ticket/${id}/summary` }); await models.Chat.send(ctx, `@${salesPersonUser.name}`, message); } @@ -146,7 +146,8 @@ module.exports = Self => { JOIN vn.sectorCollection sc ON sc.id = scsg.sectorCollectionFk JOIN vn.saleGroupDetail sgd ON sgd.saleGroupFk = sg.id JOIN vn.sale s ON s.id = sgd.saleFk - WHERE s.ticketFk = ?;`, [ticket.id], myOptions); + WHERE s.ticketFk = ?;`, [ticket.id], myOptions + ); if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index e092ee4ed4..05ade4f01b 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -165,11 +165,10 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const origin = ctx.req.headers.origin; - + const url = await Self.app.models.Application.getUrl(); const message = $t('Changed sale discount', { ticketId: id, - ticketUrl: `${origin}/#!/ticket/${id}/sale`, + ticketUrl: `${url}ticket/${id}/sale`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index cb2cf83305..10992f91ff 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -109,13 +109,13 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(args.absenceTypeId, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(id, null, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const body = $t('Created absence', { author: account.nickname, employee: subordinated.nickname, absenceType: absenceType.name, dated: formatDate(args.dated), - workerUrl: `${origin}/#!/worker/${id}/calendar` + workerUrl: `${url}worker/${id}/calendar` }); await models.Mail.create({ subject: $t('Absence change notification on the labour calendar'), diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index c315f51785..2912e6db48 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -60,13 +60,13 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(absence.dayOffTypeFk, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(labour.workerFk, null, myOptions); - const origin = ctx.req.headers.origin; + const url = await Self.app.models.Application.getUrl(); const body = $t('Deleted absence', { author: account.nickname, employee: subordinated.nickname, absenceType: absenceType.name, dated: formatDate(absence.dated), - workerUrl: `${origin}/#!/worker/${id}/calendar` + workerUrl: `${url}worker/${id}/calendar` }); await models.Mail.create({ subject: $t('Absence change notification on the labour calendar'), From afe4c676fc0a254f26795d15477fa1059b99891d Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:38:33 +0200 Subject: [PATCH 03/21] =?UTF-8?q?fix(url):=20la=20ulr=20termina=20con=20/?= =?UTF-8?q?=20no=20es=20necesario=20a=C3=B1adir=20el=20texto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/claim/back/methods/claim/claimPickupEmail.js | 2 +- modules/claim/back/methods/claim/createFromSales.js | 4 ++-- modules/claim/back/methods/claim/updateClaim.js | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index f4cd0fc206..5f33260997 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -69,7 +69,7 @@ module.exports = Self => { const message = $t('Claim pickup order sent', { claimId: args.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${args.id}/summary`, + claimUrl: `${url}claim/${args.id}/summary`, }); console.log(message); const salesPersonId = claim.client().salesPersonFk; diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 7ea26f9cc8..24ba74c6d5 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -99,8 +99,8 @@ module.exports = Self => { const message = $t('Created claim', { claimId: newClaim.id, ticketId: ticketId, - ticketUrl: `${url}/ticket/${ticketId}/sale`, - claimUrl: `${url}/claim/${newClaim.id}/summary`, + ticketUrl: `${url}ticket/${ticketId}/sale`, + claimUrl: `${url}claim/${newClaim.id}/summary`, changes: changesMade }); await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index b7ffa9ff5b..b5c576440a 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -121,22 +121,21 @@ module.exports = Self => { const message = $t(`Claim state has changed to ${state}`, { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${claim.id}/summary` + claimUrl: `${url}claim/${claim.id}/summary` }); await models.Chat.sendCheckingPresence(ctx, workerId, message); } async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Application.getUrl(); + const url = await models.Application.getUrl('lilium'); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { claimId: claim.id, clientName: claim.client().name, - claimUrl: `${url}/claim/${claim.id}/summary` + claimUrl: `${url}claim/${claim.id}/summary` }); - console.log(message); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From 4f911e644c4f03086cfcb03469fc10096b8edaa8 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 16 Oct 2023 18:43:03 +0200 Subject: [PATCH 04/21] fix: remove console.log refs #5979 --- modules/claim/back/methods/claim/claimPickupEmail.js | 1 - modules/ticket/back/methods/sale/updateQuantity.js | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index 5f33260997..aea571a61e 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -71,7 +71,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${args.id}/summary`, }); - console.log(message); const salesPersonId = claim.client().salesPersonFk; if (salesPersonId) await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index 27c1f529e2..acccc6c2f9 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -81,7 +81,6 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const url = await Self.app.models.Application.getUrl(); - console.log(url); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, From 9870a0e60adfd6bb82bfeece882a706087a5b810 Mon Sep 17 00:00:00 2001 From: pablone Date: Tue, 17 Oct 2023 13:56:49 +0200 Subject: [PATCH 05/21] feat(origin): create method url_/geturl redf #5979 --- back/methods/chat/sendCheckingPresence.js | 24 +++++++++++-------- back/models/chat.js | 9 +++++-- loopback/common/models/application.json | 5 ++++ .../methods/claim/specs/updateClaim.spec.js | 9 +++---- .../claim/back/methods/claim/updateClaim.js | 5 +++- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 274ec3a5b3..0bae87a359 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -25,22 +25,24 @@ module.exports = Self => { }); Self.sendCheckingPresence = async(ctx, recipientId, message) => { + console.log('recipientId: ', recipientId); if (!recipientId) return false; - const models = Self.app.models; - const userId = ctx.req.accessToken.userId; - const sender = await models.VnUser.findById(userId, {fields: ['id']}); - const recipient = await models.VnUser.findById(recipientId, null); + console.log('sender: ', ctx.req.accessToken.userId); + const sender = ctx.req.accessToken.userId; + console.log('sender: ', sender); + const recipient = recipientId; + console.log('recipient: ', recipient); + + console.log('recipientId == sender: ', recipientId == sender); // Prevent sending messages to yourself - if (recipientId == userId) return false; - + if (recipientId == sender) return false; if (!recipient) - throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); - + throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); if (process.env.NODE_ENV == 'test') - message = `[Test:Environment to user ${userId}] ` + message; - + message = `[Test:Environment to user ${sender}] ` + message; + console.log('chat create'); const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, @@ -51,6 +53,8 @@ module.exports = Self => { attempts: 0 }); + console.log('chat: '); + try { await Self.sendCheckingUserStatus(chat); await Self.updateChat(chat, 'sent'); diff --git a/back/models/chat.js b/back/models/chat.js index a18edbd3fb..240ec2c261 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -6,6 +6,10 @@ module.exports = Self => { require('../methods/chat/sendQueued')(Self); Self.observe('before save', async function(ctx) { + console.log('chat start 1'); + + console.log('ctx.isNewInstance: ', ctx.isNewInstance); + console.log('message: ', ctx.instance); if (!ctx.isNewInstance) return; let {message} = ctx.instance; @@ -13,14 +17,15 @@ module.exports = Self => { const parts = message.match(/(?<=\[)[a-zA-Z0-9_\-+!@#$%^&*()={};':"\\|,.<>/?\s]*(?=])/g); if (!parts) return; - + console.log('chat start 2'); const replacedParts = parts.map(part => { return part.replace(/[!$%^&*()={};':"\\,.<>/?]/g, ''); }); - + console.log('chat start 3'); for (const [index, part] of parts.entries()) message = message.replace(part, replacedParts[index]); ctx.instance.message = message; + console.log('chat end'); }); }; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index 6343c3421f..cf0653fbb1 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -19,6 +19,11 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" + },{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" } ] } diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index d367fb89f6..e7be8e9c6c 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -2,7 +2,9 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { + let url; beforeAll(async() => { + url = await app.models.Application.getUrl(); const activeCtx = { accessToken: {userId: 9}, http: { @@ -29,7 +31,6 @@ describe('Update Claim', () => { it(`should throw an error as the user doesn't have rights`, async() => { const tx = await app.models.Claim.beginTransaction({}); - let error; try { @@ -61,7 +62,7 @@ describe('Update Claim', () => { expect(error.message).toEqual(`You don't have enough privileges to change that field`); }); - it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { + fit(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { const tx = await app.models.Claim.beginTransaction({}); try { @@ -77,7 +78,7 @@ describe('Update Claim', () => { const ctx = { req: { accessToken: {userId: claimManagerId}, - headers: {origin: 'http://localhost'} + headers: {origin: url} }, args: { observation: 'valid observation', @@ -118,7 +119,7 @@ describe('Update Claim', () => { const ctx = { req: { accessToken: {userId: claimManagerId}, - headers: {origin: 'http://localhost'} + headers: {origin: url} }, args: { observation: 'valid observation', diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index b5c576440a..534f0c7abf 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -92,7 +92,6 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) notifyPickUp(ctx, salesPerson.id, claim); - // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); @@ -123,6 +122,7 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); + console.log(`${url}claim/${claim.id}/summary`); await models.Chat.sendCheckingPresence(ctx, workerId, message); } @@ -136,6 +136,9 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); + console.log('url', `${url}claim/${claim.id}/summary`); + console.log('claim client', claim.client().name); + console.log('claim id', claim.id); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From da20697052b71c724ab99abf1d798246288a4435 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 18 Oct 2023 15:19:26 +0200 Subject: [PATCH 06/21] refs #6199 feat(sale_updateQuantity): can upload --- .../05-ticket/01-sale/02_edit_sale.spec.js | 2 +- loopback/locale/en.json | 4 +- loopback/locale/es.json | 2 +- .../methods/sale/specs/updateQuantity.spec.js | 2 +- modules/ticket/back/models/sale.js | 47 ++++++++++++++----- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 6264073f63..b89254ddab 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -139,7 +139,7 @@ describe('Ticket Edit sale path', () => { await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d'); const message = await page.waitForSnackbar(); - expect(message.text).toContain('The new quantity should be smaller than the old one'); + expect(message.text).toContain('The price of the item changed'); }); it('should remove 1 from the first sale quantity', async() => { diff --git a/loopback/locale/en.json b/loopback/locale/en.json index f61226e9ee..8dfed66f62 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -14,7 +14,7 @@ "The default consignee can not be unchecked": "The default consignee can not be unchecked", "Enter an integer different to zero": "Enter an integer different to zero", "Package cannot be blank": "Package cannot be blank", - "The new quantity should be smaller than the old one": "The new quantity should be smaller than the old one", + "The price of the item changed": "The price of the item changed", "The sales of this ticket can't be modified": "The sales of this ticket can't be modified", "Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF", "You can't create an order for a frozen client": "You can't create an order for a frozen client", @@ -191,4 +191,4 @@ "Booking completed": "Booking complete", "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation", "You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets" -} \ No newline at end of file +} diff --git a/loopback/locale/es.json b/loopback/locale/es.json index dd3c92378a..525e3806f3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -35,7 +35,7 @@ "The grade must be an integer greater than or equal to zero": "El grade debe ser un entero mayor o igual a cero", "Sample type cannot be blank": "El tipo de plantilla no puede quedar en blanco", "Description cannot be blank": "Se debe rellenar el campo de texto", - "The new quantity should be smaller than the old one": "La nueva cantidad debe de ser menor que la anterior", + "The price of the item changed": "El precio del artículo cambió", "The value should not be greater than 100%": "El valor no debe de ser mayor de 100%", "The value should be a number": "El valor debe ser un numero", "This order is not editable": "Esta orden no se puede modificar", diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 0fde997fa7..74be352d17 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -49,7 +49,7 @@ describe('sale updateQuantity()', () => { error = e; } - expect(error).toEqual(new Error('The new quantity should be smaller than the old one')); + expect(error).toEqual(new Error('The price of the item changed')); }); it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index fe63072704..c1b3f3990d 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -35,7 +35,7 @@ module.exports = Self => { const ticket = await models.Ticket.findById( ticketId, { - fields: ['id', 'clientFk', 'warehouseFk', 'shipped'], + fields: ['id', 'clientFk', 'warehouseFk', 'addressFk', 'agencyModeFk', 'shipped', 'landed'], include: { relation: 'client', scope: { @@ -68,25 +68,46 @@ module.exports = Self => { if (item.family == 'EMB') return; - const itemInfo = await models.Item.getVisibleAvailable( - itemId, - ticket.warehouseFk, - ticket.shipped, - ctx.options - ); + if (newQuantity < item.minQuantity) + throw new UserError('The amount cannot be less than the minimum'); const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; - if (itemInfo.available < quantityAdded) - throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - if (newQuantity < item.minQuantity && itemInfo.available != newQuantity) - throw new UserError('The amount cannot be less than the minimum'); + if (ctx.isNewInstance || newQuantity <= oldQuantity) return; - if (!ctx.isNewInstance && newQuantity > oldQuantity) - throw new UserError('The new quantity should be smaller than the old one'); + await Self.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ + ticket.landed, + ticket.addressFk, + ticket.agencyModeFk, + itemId + ], + ctx.options); + + const [itemInfo] = await Self.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + if (itemInfo?.available < quantityAdded) + throw new UserError(`This item is not available`); + + const [saleGrouping] = await Self.rawSql(` + SELECT MAX(t.grouping), t.price newPrice + FROM tmp.ticketComponentPrice t + WHERE t.grouping <= ?`, + [quantityAdded], + ctx.options); + + await Self.rawSql(` + DROP TEMPORARY TABLE + tmp.ticketCalculateItem, + tmp.ticketComponentPrice, + tmp.ticketComponent, + tmp.ticketLot, + tmp.zoneGetShipped; + `, null, ctx.options); + + if (!saleGrouping?.newPrice || instance.price < saleGrouping.newPrice) + throw new UserError('The price of the item changed'); }); }; From 488181e1b63593ba03de4a1adb15dcbf9a0ce9e1 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:37:28 +0200 Subject: [PATCH 07/21] =?UTF-8?q?feat(getUrl):=20se=20a=C3=B1ade=20el=20me?= =?UTF-8?q?todo=20getUrl=20refs=20#5979?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/methods/collection/getTickets.js | 2 +- .../methods/application => back/methods/url}/getUrl.js | 8 +++++--- back/models/url.js | 3 +++ back/models/vn-user.js | 2 +- loopback/common/models/application.js | 1 - modules/claim/back/methods/claim/claimPickupEmail.js | 2 +- modules/claim/back/methods/claim/createFromSales.js | 2 +- modules/claim/back/methods/claim/regularizeClaim.js | 2 +- .../claim/back/methods/claim/specs/updateClaim.spec.js | 2 +- modules/claim/back/methods/claim/updateClaim.js | 4 ++-- modules/client/back/models/client.js | 4 ++-- modules/client/back/models/credit-insurance.js | 2 +- .../back/methods/invoiceOut/makePdfAndNotify.js | 2 +- modules/ticket/back/methods/sale/deleteSales.js | 2 +- modules/ticket/back/methods/sale/reserve.js | 2 +- modules/ticket/back/methods/sale/updatePrice.js | 2 +- modules/ticket/back/methods/sale/updateQuantity.js | 2 +- modules/ticket/back/methods/ticket-request/confirm.js | 2 +- modules/ticket/back/methods/ticket-request/deny.js | 2 +- modules/ticket/back/methods/ticket/addSale.js | 2 +- modules/ticket/back/methods/ticket/componentUpdate.js | 2 +- modules/ticket/back/methods/ticket/merge.js | 2 +- modules/ticket/back/methods/ticket/restore.js | 2 +- modules/ticket/back/methods/ticket/setDeleted.js | 2 +- modules/ticket/back/methods/ticket/updateDiscount.js | 2 +- modules/worker/back/methods/worker/createAbsence.js | 2 +- modules/worker/back/methods/worker/deleteAbsence.js | 2 +- 27 files changed, 34 insertions(+), 30 deletions(-) rename {loopback/common/methods/application => back/methods/url}/getUrl.js (79%) create mode 100644 back/models/url.js diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index dbb286b4f6..82fbaf8b82 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const url = Self.app.models.Application.getUrl(); + const url = Self.app.models.Url.getUrl(); const $t = ctx.req.__; const myOptions = {}; diff --git a/loopback/common/methods/application/getUrl.js b/back/methods/url/getUrl.js similarity index 79% rename from loopback/common/methods/application/getUrl.js rename to back/methods/url/getUrl.js index 4e51b0776c..f258503b16 100644 --- a/loopback/common/methods/application/getUrl.js +++ b/back/methods/url/getUrl.js @@ -1,9 +1,10 @@ module.exports = Self => { - Self.remoteMethodCtx('getUrl', { + Self.remoteMethod('getUrl', { description: 'Returns the colling app name', + accessType: 'READ', accepts: [ { - arg: 'appName', + arg: 'app', type: 'string', required: false } @@ -18,13 +19,14 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { + console.log('appName: ', appName); const {url} = await Self.app.models.Url.findOne({ - where: { appName, enviroment: process.env.NODE_ENV || 'development' } }); + console.log('url: ', url); return url; }; }; diff --git a/back/models/url.js b/back/models/url.js new file mode 100644 index 0000000000..af71ec1c49 --- /dev/null +++ b/back/models/url.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/url/getUrl')(Self); +}; diff --git a/back/models/vn-user.js b/back/models/vn-user.js index a38139bc7d..c65c625901 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -89,7 +89,7 @@ module.exports = function(Self) { }; Self.on('resetPasswordRequest', async function(info) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const defaultHash = '/reset-password?access_token=$token$'; const recoverHashes = { diff --git a/loopback/common/models/application.js b/loopback/common/models/application.js index b3841d34a3..5e767fdc11 100644 --- a/loopback/common/models/application.js +++ b/loopback/common/models/application.js @@ -2,5 +2,4 @@ module.exports = function(Self) { require('../methods/application/status')(Self); require('../methods/application/post')(Self); - require('../methods/application/getUrl')(Self); }; diff --git a/modules/claim/back/methods/claim/claimPickupEmail.js b/modules/claim/back/methods/claim/claimPickupEmail.js index aea571a61e..596102a246 100644 --- a/modules/claim/back/methods/claim/claimPickupEmail.js +++ b/modules/claim/back/methods/claim/claimPickupEmail.js @@ -44,7 +44,7 @@ module.exports = Self => { Self.claimPickupEmail = async ctx => { const models = Self.app.models; const $t = ctx.req.__; // $translate - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const args = Object.assign({}, ctx.args); const params = { diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index 24ba74c6d5..30093e43d8 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -94,7 +94,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Created claim', { claimId: newClaim.id, diff --git a/modules/claim/back/methods/claim/regularizeClaim.js b/modules/claim/back/methods/claim/regularizeClaim.js index 4ac500e2fd..a51b114ef2 100644 --- a/modules/claim/back/methods/claim/regularizeClaim.js +++ b/modules/claim/back/methods/claim/regularizeClaim.js @@ -56,7 +56,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { const nickname = address && address.nickname || destination.description; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Sent units from ticket', { quantity: sale.quantity, concept: sale.concept, diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index e7be8e9c6c..fff4d7ac65 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -4,7 +4,7 @@ const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { let url; beforeAll(async() => { - url = await app.models.Application.getUrl(); + url = await app.models.Url.getUrl(); const activeCtx = { accessToken: {userId: 9}, http: { diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 534f0c7abf..e418af9507 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -114,7 +114,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = await models.Application.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -128,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Application.getUrl('lilium'); + const url = await models.Url.getUrl('lilium'); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 1b60b13296..e16e884cc5 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -353,7 +353,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const salesPersonId = instance.salesPersonFk; @@ -395,7 +395,7 @@ module.exports = Self => { const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const models = Self.app.models; let previousWorker = {name: $t('None')}; diff --git a/modules/client/back/models/credit-insurance.js b/modules/client/back/models/credit-insurance.js index 619904612c..84bd90424c 100644 --- a/modules/client/back/models/credit-insurance.js +++ b/modules/client/back/models/credit-insurance.js @@ -57,7 +57,7 @@ module.exports = function(Self) { const httpRequest = httpCtx.req.http.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const fullPath = `${url}client/${client.id}/credit-insurance/index`; const message = $t('MESSAGE_INSURANCE_CHANGE', { clientId: client.id, diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js index 49c7850139..1de15b6661 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js +++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js @@ -59,7 +59,7 @@ module.exports = Self => { }; await Self.invoiceEmail(ctx, ref); } catch (err) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = ctx.req.__('Mail not sent', { clientId: client.id, clientUrl: `${url}claim/${id}/summary` diff --git a/modules/ticket/back/methods/sale/deleteSales.js b/modules/ticket/back/methods/sale/deleteSales.js index c71f8d5e13..0207815a94 100644 --- a/modules/ticket/back/methods/sale/deleteSales.js +++ b/modules/ticket/back/methods/sale/deleteSales.js @@ -68,7 +68,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Deleted sales from ticket', { ticketId: ticketId, diff --git a/modules/ticket/back/methods/sale/reserve.js b/modules/ticket/back/methods/sale/reserve.js index b111a04582..36db791fc2 100644 --- a/modules/ticket/back/methods/sale/reserve.js +++ b/modules/ticket/back/methods/sale/reserve.js @@ -85,7 +85,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale reserved state', { ticketId: ticketId, diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index 3cae2a3333..191fd09e3d 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -98,7 +98,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale price', { ticketId: sale.ticket().id, itemId: sale.itemFk, diff --git a/modules/ticket/back/methods/sale/updateQuantity.js b/modules/ticket/back/methods/sale/updateQuantity.js index acccc6c2f9..28754e50ce 100644 --- a/modules/ticket/back/methods/sale/updateQuantity.js +++ b/modules/ticket/back/methods/sale/updateQuantity.js @@ -80,7 +80,7 @@ module.exports = Self => { const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale quantity', { ticketId: sale.ticket().id, itemId: sale.itemFk, diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index a69fc7fd76..00310f33c3 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -84,7 +84,7 @@ module.exports = Self => { const query = `CALL vn.sale_calculateComponent(?, NULL)`; await Self.rawSql(query, [sale.id], myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const requesterId = request.requesterFk; const message = $t('Bought units from buy request', { diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 9ec11d755b..44f1e48a1e 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -50,7 +50,7 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const requesterId = request.requesterFk; const message = $t('Deny buy request', { diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index 29e49d8e6e..59f1190fa0 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -94,7 +94,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Added sale to ticket', { ticketId: id, diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index fc8b3a40c8..f7c36f1088 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -237,7 +237,7 @@ module.exports = Self => { const salesPersonId = originalTicket.client().salesPersonFk; if (salesPersonId) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); let changesMade = ''; for (let change in newProperties) { diff --git a/modules/ticket/back/methods/ticket/merge.js b/modules/ticket/back/methods/ticket/merge.js index 19c7f9fa0d..1106cef06f 100644 --- a/modules/ticket/back/methods/ticket/merge.js +++ b/modules/ticket/back/methods/ticket/merge.js @@ -25,7 +25,7 @@ module.exports = Self => { Self.merge = async(ctx, tickets, options) => { const httpRequest = ctx.req; const $t = httpRequest.__; - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const models = Self.app.models; const myOptions = {}; let tx; diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 0aaef0418e..e268c38919 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -48,7 +48,7 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonId = ticket.client().salesPersonFk; if (salesPersonId) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t(`I have restored the ticket id`, { id: id, url: `${url}ticket/${id}/summary` diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js index a6fd295f17..9a9fd9056d 100644 --- a/modules/ticket/back/methods/ticket/setDeleted.js +++ b/modules/ticket/back/methods/ticket/setDeleted.js @@ -119,7 +119,7 @@ module.exports = Self => { // Send notification to salesPerson const salesPersonUser = ticket.client().salesPersonUser(); if (salesPersonUser && sales.length) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t(`I have deleted the ticket id`, { id: id, url: `${url}ticket/${id}/summary` diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index 05ade4f01b..2e8bec27a8 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -165,7 +165,7 @@ module.exports = Self => { const salesPerson = ticket.client().salesPersonUser(); if (salesPerson) { - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const message = $t('Changed sale discount', { ticketId: id, ticketUrl: `${url}ticket/${id}/sale`, diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 10992f91ff..d628d0a2b4 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -109,7 +109,7 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(args.absenceTypeId, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(id, null, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const body = $t('Created absence', { author: account.nickname, employee: subordinated.nickname, diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index 2912e6db48..b71d077a40 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -60,7 +60,7 @@ module.exports = Self => { const absenceType = await models.AbsenceType.findById(absence.dayOffTypeFk, null, myOptions); const account = await models.VnUser.findById(userId, null, myOptions); const subordinated = await models.VnUser.findById(labour.workerFk, null, myOptions); - const url = await Self.app.models.Application.getUrl(); + const url = await Self.app.models.Url.getUrl(); const body = $t('Deleted absence', { author: account.nickname, employee: subordinated.nickname, From f8889df90354660fbeb3160e4f1a4e6416bc9a40 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:40:25 +0200 Subject: [PATCH 08/21] remove(console.log): se quitan console.log que se utilizaron para dbuggear refs #5979 --- back/methods/chat/sendCheckingPresence.js | 9 --------- back/methods/url/getUrl.js | 2 -- back/models/chat.js | 8 -------- modules/claim/back/methods/claim/updateClaim.js | 3 --- 4 files changed, 22 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 0bae87a359..7bba96d594 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -25,16 +25,10 @@ module.exports = Self => { }); Self.sendCheckingPresence = async(ctx, recipientId, message) => { - console.log('recipientId: ', recipientId); if (!recipientId) return false; const models = Self.app.models; - console.log('sender: ', ctx.req.accessToken.userId); const sender = ctx.req.accessToken.userId; - console.log('sender: ', sender); const recipient = recipientId; - console.log('recipient: ', recipient); - - console.log('recipientId == sender: ', recipientId == sender); // Prevent sending messages to yourself if (recipientId == sender) return false; @@ -42,7 +36,6 @@ module.exports = Self => { throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); if (process.env.NODE_ENV == 'test') message = `[Test:Environment to user ${sender}] ` + message; - console.log('chat create'); const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, @@ -53,8 +46,6 @@ module.exports = Self => { attempts: 0 }); - console.log('chat: '); - try { await Self.sendCheckingUserStatus(chat); await Self.updateChat(chat, 'sent'); diff --git a/back/methods/url/getUrl.js b/back/methods/url/getUrl.js index f258503b16..f30719b9f1 100644 --- a/back/methods/url/getUrl.js +++ b/back/methods/url/getUrl.js @@ -19,14 +19,12 @@ module.exports = Self => { } }); Self.getUrl = async(appName = 'salix') => { - console.log('appName: ', appName); const {url} = await Self.app.models.Url.findOne({ where: { appName, enviroment: process.env.NODE_ENV || 'development' } }); - console.log('url: ', url); return url; }; }; diff --git a/back/models/chat.js b/back/models/chat.js index 240ec2c261..882db747e3 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -6,26 +6,18 @@ module.exports = Self => { require('../methods/chat/sendQueued')(Self); Self.observe('before save', async function(ctx) { - console.log('chat start 1'); - - console.log('ctx.isNewInstance: ', ctx.isNewInstance); - console.log('message: ', ctx.instance); if (!ctx.isNewInstance) return; - let {message} = ctx.instance; if (!message) return; const parts = message.match(/(?<=\[)[a-zA-Z0-9_\-+!@#$%^&*()={};':"\\|,.<>/?\s]*(?=])/g); if (!parts) return; - console.log('chat start 2'); const replacedParts = parts.map(part => { return part.replace(/[!$%^&*()={};':"\\,.<>/?]/g, ''); }); - console.log('chat start 3'); for (const [index, part] of parts.entries()) message = message.replace(part, replacedParts[index]); ctx.instance.message = message; - console.log('chat end'); }); }; diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index e418af9507..8210f7a83e 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -136,9 +136,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); - console.log('url', `${url}claim/${claim.id}/summary`); - console.log('claim client', claim.client().name); - console.log('claim id', claim.id); await models.Chat.sendCheckingPresence(ctx, workerId, message); } }; From d3a7b4ecb996aff3f9eaae374a96ab42366aeada Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 08:41:26 +0200 Subject: [PATCH 09/21] remove: console.log from updateClaim refs #5979 --- modules/claim/back/methods/claim/updateClaim.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 8210f7a83e..7f7ccb299a 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -122,7 +122,6 @@ module.exports = Self => { clientName: claim.client().name, claimUrl: `${url}claim/${claim.id}/summary` }); - console.log(`${url}claim/${claim.id}/summary`); await models.Chat.sendCheckingPresence(ctx, workerId, message); } From 1b8f227c473152f02dd6ce0c673292838183b5c6 Mon Sep 17 00:00:00 2001 From: guillermo Date: Thu, 19 Oct 2023 11:58:15 +0200 Subject: [PATCH 10/21] ticket #125321 filter advance tickets fix --- .../ticket/front/advance-search-panel/index.js | 4 ++-- modules/ticket/front/advance/index.js | 18 ++++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/modules/ticket/front/advance-search-panel/index.js b/modules/ticket/front/advance-search-panel/index.js index 8ddbe78d4a..218fb14d3a 100644 --- a/modules/ticket/front/advance-search-panel/index.js +++ b/modules/ticket/front/advance-search-panel/index.js @@ -16,8 +16,8 @@ class Controller extends SearchPanel { this.$http.get('ItemPackingTypes', {filter}).then(res => { for (let ipt of res.data) { itemPackingTypes.push({ - code: ipt.code, - description: this.$t(ipt.description) + description: this.$t(ipt.description), + code: ipt.code }); } this.itemPackingTypes = itemPackingTypes; diff --git a/modules/ticket/front/advance/index.js b/modules/ticket/front/advance/index.js index 0cec41227a..6f8a92ebe2 100644 --- a/modules/ticket/front/advance/index.js +++ b/modules/ticket/front/advance/index.js @@ -163,26 +163,16 @@ export default class Controller extends Section { return {'futureId': value}; case 'liters': return {'liters': value}; - case 'lines': - return {'lines': value}; case 'futureLiters': return {'futureLiters': value}; + case 'lines': + return {'lines': value}; case 'futureLines': return {'futureLines': value}; case 'ipt': - return {or: - [ - {'ipt': {like: `%${value}%`}}, - {'ipt': null} - ] - }; + return {'ipt': {like: `%${value}%`}}; case 'futureIpt': - return {or: - [ - {'futureIpt': {like: `%${value}%`}}, - {'futureIpt': null} - ] - }; + return {'futureIpt': {like: `%${value}%`}}; case 'totalWithVat': return {'totalWithVat': value}; case 'futureTotalWithVat': From d9ab607126385e9cf99bab9529b8f0bfdb2a7954 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 19 Oct 2023 13:03:11 +0200 Subject: [PATCH 11/21] refs #6199 feat(sale): increase quantity if newPrice is higher --- .../collection/spec/setSaleQuantity.spec.js | 9 +- .../05-ticket/01-sale/02_edit_sale.spec.js | 8 - .../methods/sale/specs/updateQuantity.spec.js | 138 ++++++++++++++---- modules/ticket/back/models/sale.js | 35 +++-- 4 files changed, 133 insertions(+), 57 deletions(-) diff --git a/back/methods/collection/spec/setSaleQuantity.spec.js b/back/methods/collection/spec/setSaleQuantity.spec.js index 8cd73205f1..b563f5b198 100644 --- a/back/methods/collection/spec/setSaleQuantity.spec.js +++ b/back/methods/collection/spec/setSaleQuantity.spec.js @@ -18,7 +18,14 @@ describe('setSaleQuantity()', () => { it('should change quantity sale', async() => { const tx = await models.Ticket.beginTransaction({}); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); try { const options = {transaction: tx}; diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index b89254ddab..23983a9c88 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -134,14 +134,6 @@ describe('Ticket Edit sale path', () => { await page.accessToSection('ticket.card.sale'); }); - it('should try to add a higher quantity value and then receive an error', async() => { - await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); - await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d'); - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('The price of the item changed'); - }); - it('should remove 1 from the first sale quantity', async() => { await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); await page.waitForSelector(selectors.ticketSales.firstSaleQuantity); diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 74be352d17..34c58ef98c 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -24,34 +24,6 @@ describe('sale updateQuantity()', () => { }; } - it('should throw an error if the quantity is greater than it should be', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); - - const tx = await models.Sale.beginTransaction({}); - - let error; - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, 17, 31, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The price of the item changed')); - }); - it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { const saleId = 17; const buyerId = 35; @@ -64,7 +36,14 @@ describe('sale updateQuantity()', () => { }; const tx = await models.Sale.beginTransaction({}); spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: 100})))); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); try { const options = {transaction: tx}; @@ -193,6 +172,14 @@ describe('sale updateQuantity()', () => { const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); @@ -226,7 +213,15 @@ describe('sale updateQuantity()', () => { const item = await models.Item.findById(itemId, null, options); await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Item, 'getVisibleAvailable').and.returnValue((new Promise(resolve => resolve({available: newQuantity})))); + + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT ${newQuantity} as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); @@ -236,4 +231,87 @@ describe('sale updateQuantity()', () => { throw e; } }); + + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 8 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index c1b3f3990d..23cf90353f 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -31,6 +31,8 @@ module.exports = Self => { const ticketId = changes?.ticketFk || instance?.ticketFk; const itemId = changes?.itemFk || instance?.itemFk; + const oldQuantity = instance?.quantity ?? null; + const quantityAdded = newQuantity - oldQuantity; const ticket = await models.Ticket.findById( ticketId, @@ -65,20 +67,9 @@ module.exports = Self => { fields: ['family', 'minQuantity'], where: {id: itemId}, }, ctx.options); - if (item.family == 'EMB') return; - if (newQuantity < item.minQuantity) - throw new UserError('The amount cannot be less than the minimum'); - - const oldQuantity = instance?.quantity ?? null; - const quantityAdded = newQuantity - oldQuantity; - - if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - - if (ctx.isNewInstance || newQuantity <= oldQuantity) return; - - await Self.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ + await models.Sale.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ ticket.landed, ticket.addressFk, ticket.agencyModeFk, @@ -86,19 +77,27 @@ module.exports = Self => { ], ctx.options); - const [itemInfo] = await Self.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); - if (itemInfo?.available < quantityAdded) + const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + + if (!itemInfo?.available || itemInfo.available < quantityAdded) throw new UserError(`This item is not available`); - const [saleGrouping] = await Self.rawSql(` + if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; + + if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) + throw new UserError('The amount cannot be less than the minimum'); + + if (ctx.isNewInstance || newQuantity <= oldQuantity) return; + + const [saleGrouping] = await models.Sale.rawSql(` SELECT MAX(t.grouping), t.price newPrice FROM tmp.ticketComponentPrice t WHERE t.grouping <= ?`, [quantityAdded], ctx.options); - await Self.rawSql(` - DROP TEMPORARY TABLE + await models.Sale.rawSql(` + DROP TEMPORARY TABLE IF EXISTS tmp.ticketCalculateItem, tmp.ticketComponentPrice, tmp.ticketComponent, @@ -106,7 +105,7 @@ module.exports = Self => { tmp.zoneGetShipped; `, null, ctx.options); - if (!saleGrouping?.newPrice || instance.price < saleGrouping.newPrice) + if (!saleGrouping?.newPrice || saleGrouping.newPrice < instance.price) throw new UserError('The price of the item changed'); }); }; From 16f20cea70c278cc1112b6c66a77efe0022c91fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Thu, 19 Oct 2023 15:12:06 +0200 Subject: [PATCH 12/21] refs #6199 fix(sale): get minim price without grouping --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 23cf90353f..ef3dd8ef72 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -90,9 +90,10 @@ module.exports = Self => { if (ctx.isNewInstance || newQuantity <= oldQuantity) return; const [saleGrouping] = await models.Sale.rawSql(` - SELECT MAX(t.grouping), t.price newPrice + SELECT t.price newPrice FROM tmp.ticketComponentPrice t - WHERE t.grouping <= ?`, + ORDER BY (t.grouping <= ?) DESC, t.grouping ASC + LIMIT 1`, [quantityAdded], ctx.options); From 07fa01103524ddfd35dc3adaca540641a8fb4af7 Mon Sep 17 00:00:00 2001 From: pablone Date: Thu, 19 Oct 2023 18:24:03 +0200 Subject: [PATCH 13/21] fix(updateClaim): el spec daba error refs #5979 --- modules/claim/back/methods/claim/specs/updateClaim.spec.js | 2 +- modules/claim/back/methods/claim/updateClaim.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index fff4d7ac65..85ada869a9 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -62,7 +62,7 @@ describe('Update Claim', () => { expect(error.message).toEqual(`You don't have enough privileges to change that field`); }); - fit(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { + it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => { const tx = await app.models.Claim.beginTransaction({}); try { diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 7f7ccb299a..f18e3a8123 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -92,6 +92,7 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) notifyPickUp(ctx, salesPerson.id, claim); + // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); @@ -114,7 +115,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = await models.Url.getUrl(); + const url = models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -127,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = await models.Url.getUrl('lilium'); + const url = models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { From d5f98700e7da329dd24501902cd70c0d7bb57c9a Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 08:32:35 +0200 Subject: [PATCH 14/21] refs #6287 fix: ticket new correct return type --- modules/ticket/back/methods/ticket/new.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index b461fb26d3..0f5c323ed2 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -48,7 +48,7 @@ module.exports = Self => { description: `The route id filter` }], returns: { - type: 'number', + type: 'object', root: true }, http: { From 84aed7ca21c5523ea0441a46c96b7ce037080036 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 09:26:56 +0200 Subject: [PATCH 15/21] refs #6257 fix(saleQuantity): newPrice correct restricction --- .../methods/sale/specs/updateQuantity.spec.js | 180 +++++++++++------- modules/ticket/back/models/sale.js | 2 +- 2 files changed, 112 insertions(+), 70 deletions(-) diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js index 34c58ef98c..0669711e79 100644 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js @@ -232,86 +232,128 @@ describe('sale updateQuantity()', () => { } }); - it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + describe('newPrice', () => { + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; - try { - const options = {transaction: tx}; + try { + const options = {transaction: tx}; - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 8 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw error when increase quantity and the new price is lower than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + }); - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; - params = null; + it('should increase quantity when the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} } - return models.Ticket.rawSql(sqlStatement, params, options); - }); + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } + try { + const options = {transaction: tx}; - expect(error).toEqual(new Error('The price of the item changed')); + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is higher than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index ef3dd8ef72..4b7ed1043e 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -106,7 +106,7 @@ module.exports = Self => { tmp.zoneGetShipped; `, null, ctx.options); - if (!saleGrouping?.newPrice || saleGrouping.newPrice < instance.price) + if (!saleGrouping?.newPrice || saleGrouping.newPrice > instance.price) throw new UserError('The price of the item changed'); }); }; From 1eabad7f4b21ea358dce4cc39a5ea94b93666d3f Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 20 Oct 2023 12:37:44 +0200 Subject: [PATCH 16/21] refs #6257 fix(saleQuantity): add isInPreparing restriction --- .../methods/sale/specs/updateQuantity.spec.js | 359 ----------------- modules/ticket/back/models/sale.js | 2 + modules/ticket/back/models/specs/sale.spec.js | 361 ++++++++++++++++++ 3 files changed, 363 insertions(+), 359 deletions(-) delete mode 100644 modules/ticket/back/methods/sale/specs/updateQuantity.spec.js create mode 100644 modules/ticket/back/models/specs/sale.spec.js diff --git a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js b/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js deleted file mode 100644 index 0669711e79..0000000000 --- a/modules/ticket/back/methods/sale/specs/updateQuantity.spec.js +++ /dev/null @@ -1,359 +0,0 @@ -/* eslint max-len: ["error", { "code": 150 }]*/ - -const models = require('vn-loopback/server/server').models; -const LoopBackContext = require('loopback-context'); - -describe('sale updateQuantity()', () => { - const ctx = { - req: { - accessToken: {userId: 9}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - function getActiveCtx(userId) { - return { - active: { - accessToken: {userId}, - http: { - req: { - headers: {origin: 'http://localhost'} - } - } - } - }; - } - - it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { - const saleId = 17; - const buyerId = 35; - const ctx = { - req: { - accessToken: {userId: buyerId}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - const tx = await models.Sale.beginTransaction({}); - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT 100 as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - try { - const options = {transaction: tx}; - - const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); - - expect(isRoleAdvanced).toEqual(true); - - const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(originalLine.quantity).toEqual(30); - - const newQuantity = originalLine.quantity + 1; - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should update the quantity of a given sale current line', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); - - const tx = await models.Sale.beginTransaction({}); - const saleId = 25; - const newQuantity = 4; - - try { - const options = {transaction: tx}; - - const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(originalLine.quantity).toEqual(20); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw an error if the quantity is negative and it is not a refund ticket', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const saleId = 17; - const newQuantity = -10; - - const tx = await models.Sale.beginTransaction({}); - - let error; - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('You can only add negative amounts in refund tickets')); - }); - - it('should update a negative quantity when is a ticket refund', async() => { - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); - - const tx = await models.Sale.beginTransaction({}); - const saleId = 13; - const newQuantity = -10; - - try { - const options = {transaction: tx}; - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); - - expect(modifiedLine.quantity).toEqual(newQuantity); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = minQuantity - 1; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT 100 as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The amount cannot be less than the minimum')); - }); - - it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = minQuantity - 1; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY - SELECT ${newQuantity} as available;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - describe('newPrice', () => { - it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should increase quantity when the new price is lower than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should throw error when increase quantity and the new price is higher than the previous one', async() => { - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } - }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); - - const tx = await models.Sale.beginTransaction({}); - const itemId = 2; - const saleId = 17; - const minQuantity = 30; - const newQuantity = 31; - - let error; - try { - const options = {transaction: tx}; - - const item = await models.Item.findById(itemId, null, options); - await item.updateAttribute('minQuantity', minQuantity, options); - spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { - if (sqlStatement.includes('catalog_calcFromItem')) { - sqlStatement = ` - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; - CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; - params = null; - } - return models.Ticket.rawSql(sqlStatement, params, options); - }); - - await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - error = e; - } - - expect(error).toEqual(new Error('The price of the item changed')); - }); - }); -}); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 4b7ed1043e..1c86ddc0cc 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -69,6 +69,8 @@ module.exports = Self => { }, ctx.options); if (item.family == 'EMB') return; + if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'isInPreparing', '*')) return; + await models.Sale.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ ticket.landed, ticket.addressFk, diff --git a/modules/ticket/back/models/specs/sale.spec.js b/modules/ticket/back/models/specs/sale.spec.js new file mode 100644 index 0000000000..4af44c991a --- /dev/null +++ b/modules/ticket/back/models/specs/sale.spec.js @@ -0,0 +1,361 @@ +/* eslint max-len: ["error", { "code": 150 }]*/ + +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('sale model ', () => { + const ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + function getActiveCtx(userId) { + return { + active: { + accessToken: {userId}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + } + }; + } + + describe('quantity field ', () => { + it('should add quantity if the quantity is greater than it should be and is role advanced', async() => { + const saleId = 17; + const buyerId = 35; + const ctx = { + req: { + accessToken: {userId: buyerId}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + const tx = await models.Sale.beginTransaction({}); + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId)); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + try { + const options = {transaction: tx}; + + const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*'); + + expect(isRoleAdvanced).toEqual(true); + + const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(originalLine.quantity).toEqual(30); + + const newQuantity = originalLine.quantity + 1; + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should update the quantity of a given sale current line', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + + const tx = await models.Sale.beginTransaction({}); + const saleId = 25; + const newQuantity = 4; + + try { + const options = {transaction: tx}; + + const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(originalLine.quantity).toEqual(20); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error if the quantity is negative and it is not a refund ticket', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const saleId = 17; + const newQuantity = -10; + + const tx = await models.Sale.beginTransaction({}); + + let error; + try { + const options = {transaction: tx}; + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('You can only add negative amounts in refund tickets')); + }); + + it('should update a negative quantity when is a ticket refund', async() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9)); + + const tx = await models.Sale.beginTransaction({}); + const saleId = 13; + const newQuantity = -10; + + try { + const options = {transaction: tx}; + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options); + + expect(modifiedLine.quantity).toEqual(newQuantity); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw an error if the quantity is less than the minimum quantity of the item', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = minQuantity - 1; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT 100 as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The amount cannot be less than the minimum')); + }); + + it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = minQuantity - 1; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY + SELECT ${newQuantity} as available;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + describe('newPrice', () => { + it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should increase quantity when the new price is lower than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should throw error when increase quantity and the new price is higher than the previous one', async() => { + const ctx = { + req: { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1)); + + const tx = await models.Sale.beginTransaction({}); + const itemId = 2; + const saleId = 17; + const minQuantity = 30; + const newQuantity = 31; + + let error; + try { + const options = {transaction: tx}; + + const item = await models.Item.findById(itemId, null, options); + await item.updateAttribute('minQuantity', minQuantity, options); + spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => { + if (sqlStatement.includes('catalog_calcFromItem')) { + sqlStatement = ` + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available; + CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`; + params = null; + } + return models.Ticket.rawSql(sqlStatement, params, options); + }); + + await models.Sale.updateQuantity(ctx, saleId, newQuantity, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error).toEqual(new Error('The price of the item changed')); + }); + }); + }); +}); From 5c69d9c7f01e38c1e8e07e4abb9e27efc383fbe5 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 20 Oct 2023 12:53:54 +0200 Subject: [PATCH 17/21] fix: add await in async functions refs #5979 --- back/methods/collection/getTickets.js | 2 +- loopback/common/models/application.json | 6 ------ modules/claim/back/methods/claim/updateClaim.js | 10 +++++----- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js index 82fbaf8b82..f04822697c 100644 --- a/back/methods/collection/getTickets.js +++ b/back/methods/collection/getTickets.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.getTickets = async(ctx, id, print, options) => { const userId = ctx.req.accessToken.userId; - const url = Self.app.models.Url.getUrl(); + const url = await Self.app.models.Url.getUrl(); const $t = ctx.req.__; const myOptions = {}; diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index cf0653fbb1..3e6a742e2a 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,12 +13,6 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - }, - { - "property": "getUrl", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" },{ "accessType": "READ", "principalType": "ROLE", diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index f18e3a8123..d99528413c 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -91,16 +91,16 @@ module.exports = Self => { // When hasToPickUp has been changed if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) - notifyPickUp(ctx, salesPerson.id, claim); + await notifyPickUp(ctx, salesPerson.id, claim); // When claimState has been changed if (args.claimStateFk) { const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); if (newState.hasToNotify) { if (newState.code == 'incomplete') - notifyStateChange(ctx, salesPerson.id, claim, newState.code); + await notifyStateChange(ctx, salesPerson.id, claim, newState.code); if (newState.code == 'canceled') - notifyStateChange(ctx, claim.workerFk, claim, newState.code); + await notifyStateChange(ctx, claim.workerFk, claim, newState.code); } } @@ -115,7 +115,7 @@ module.exports = Self => { async function notifyStateChange(ctx, workerId, claim, state) { const models = Self.app.models; - const url = models.Url.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t(`Claim state has changed to ${state}`, { @@ -128,7 +128,7 @@ module.exports = Self => { async function notifyPickUp(ctx, workerId, claim) { const models = Self.app.models; - const url = models.Url.getUrl(); + const url = await models.Url.getUrl(); const $t = ctx.req.__; // $translate const message = $t('Claim will be picked', { From 4df39272d69b78930e2cb019baf959e6c186e9d8 Mon Sep 17 00:00:00 2001 From: pablone Date: Fri, 20 Oct 2023 13:08:39 +0200 Subject: [PATCH 18/21] remove: appiclation config refs #5979 --- loopback/common/models/application.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/loopback/common/models/application.json b/loopback/common/models/application.json index 3e6a742e2a..f790015852 100644 --- a/loopback/common/models/application.json +++ b/loopback/common/models/application.json @@ -13,11 +13,6 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW" - },{ - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" } ] } From 2edfacb91c4c14e3120b82e9c84fe10a3e995577 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 07:33:52 +0200 Subject: [PATCH 19/21] refs #5979 fix(sendCheckingPresence)! --- back/methods/chat/sendCheckingPresence.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 7bba96d594..85b66e94be 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -27,15 +27,19 @@ module.exports = Self => { Self.sendCheckingPresence = async(ctx, recipientId, message) => { if (!recipientId) return false; const models = Self.app.models; - const sender = ctx.req.accessToken.userId; - const recipient = recipientId; + + const userId = ctx.req.accessToken.userId; + const sender = await models.VnUser.findById(userId, {fields: ['id']}); + const recipient = await models.VnUser.findById(recipientId, null); // Prevent sending messages to yourself - if (recipientId == sender) return false; + if (recipientId == userId) return false; if (!recipient) - throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${sender}`); + throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); + if (process.env.NODE_ENV == 'test') - message = `[Test:Environment to user ${sender}] ` + message; + message = `[Test:Environment to user ${userId}] ` + message; + const chat = await models.Chat.create({ senderFk: sender.id, recipient: `@${recipient.name}`, From cf856a585bba1be47c63e66794df6ffef4f5467a Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 09:50:00 +0200 Subject: [PATCH 20/21] refs #6199 fix(sale_quantity): add isReduction --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 1c86ddc0cc..cce6343ecf 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -33,6 +33,7 @@ module.exports = Self => { const itemId = changes?.itemFk || instance?.itemFk; const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; + const isReduction = oldQuantity && newQuantity <= oldQuantity; const ticket = await models.Ticket.findById( ticketId, @@ -81,7 +82,7 @@ module.exports = Self => { const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); - if (!itemInfo?.available || itemInfo.available < quantityAdded) + if ((!isReduction && !itemInfo?.available) || itemInfo.available < quantityAdded) throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; @@ -89,7 +90,7 @@ module.exports = Self => { if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) throw new UserError('The amount cannot be less than the minimum'); - if (ctx.isNewInstance || newQuantity <= oldQuantity) return; + if (ctx.isNewInstance || isReduction) return; const [saleGrouping] = await models.Sale.rawSql(` SELECT t.price newPrice From 247aa5af2a9a1ffd4ba829d1ecfe776ceb8feb48 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 23 Oct 2023 09:52:06 +0200 Subject: [PATCH 21/21] refs #6199 fix(sale_quantity): add isReduction --- modules/ticket/back/models/sale.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index cce6343ecf..99cfeeeea8 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -81,13 +81,14 @@ module.exports = Self => { ctx.options); const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); + const available = itemInfo?.available; - if ((!isReduction && !itemInfo?.available) || itemInfo.available < quantityAdded) + if ((!isReduction && !available) || available < quantityAdded) throw new UserError(`This item is not available`); if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; - if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available) + if (newQuantity < item.minQuantity && newQuantity != available) throw new UserError('The amount cannot be less than the minimum'); if (ctx.isNewInstance || isReduction) return;