From e01d676bb13b9d6ac178d75b6a53f21b8635ca1c Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 15 Dec 2021 14:45:45 +0100 Subject: [PATCH 01/16] feat(ticket_basic-data_step-two): show visible and option withoutNegatives --- .../back/methods/ticket/priceDifference.js | 15 ++++++++--- .../front/basic-data/step-two/index.html | 14 ++++++++++ .../ticket/front/basic-data/step-two/index.js | 27 +++++++++++++++++-- .../front/basic-data/step-two/locale/es.yml | 3 ++- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 2456d3de05..56f6ad7d22 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -100,19 +100,25 @@ module.exports = Self => { totalDifference: 0.00, }; - const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; + // Get items visible + let query = `CALL ticketGetVisibleAvailable(?)`; + const [salesVisible] = await Self.rawSql(query, [args.id], myOptions); + + const itemVisible = new Map(); + for (sale of salesVisible) + itemVisible.set(sale.id, sale.visible); + + // Sale price component, one per sale + query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; const params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId]; const [difComponents] = await Self.rawSql(query, params, myOptions); const map = new Map(); - - // Sale price component, one per sale for (difComponent of difComponents) map.set(difComponent.saleFk, difComponent); for (sale of salesObj.items) { const difComponent = map.get(sale.id); - if (difComponent) { sale.component = difComponent; @@ -125,6 +131,7 @@ module.exports = Self => { salesObj.totalUnitPrice += sale.price; salesObj.totalUnitPrice = round(salesObj.totalUnitPrice); + sale.visible = itemVisible.get(sale.id); } if (tx) await tx.commit(); diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 439f2b527f..3241335787 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,6 +9,7 @@ Item Description + Visible Quantity Price (PPU) New (PPU) @@ -31,6 +32,13 @@ tabindex="-1"> + + + {{::sale.visible}} + + {{::sale.quantity}} {{::sale.price | currency: 'EUR': 2}} {{::sale.component.newPrice | currency: 'EUR': 2}} @@ -66,6 +74,12 @@ +
+ + +
diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 7ffdb8315d..fbaa52a7ed 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -20,6 +20,7 @@ class Controller extends Component { this.getTotalNewPrice(); this.getTotalDifferenceOfPrice(); this.loadDefaultTicketAction(); + this.ticketHaveNegatives(); } loadDefaultTicketAction() { @@ -63,15 +64,37 @@ class Controller extends Component { this.totalPriceDifference = totalPriceDifference; } + ticketHaveNegatives() { + let haveNegatives = false; + this.ticket.sale.items.forEach(item => { + if (item.quantity > item.visible) + haveNegatives = true; + }); + this.haveNegatives = haveNegatives; + } + onSubmit() { if (!this.ticket.option) { return this.vnApp.showError( this.$t('Choose an option') ); } + if (this.ticket.withoutNegatives) { + let salesNewTicket = []; + this.ticket.sale.items.forEach(item => { + if (item.visible >= item.quantity) + salesNewTicket.push(item); + }); - let query = `tickets/${this.ticket.id}/componentUpdate`; - let params = { + const params = { + sales: salesNewTicket + }; + + const query = `tickets/${this.ticket.id}/transferSales`; + this.$http.post(query, params); + } + const query = `tickets/${this.ticket.id}/componentUpdate`; + const params = { clientFk: this.ticket.clientFk, nickname: this.ticket.nickname, agencyModeFk: this.ticket.agencyModeFk, diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index a2a07991bf..4f68d33e20 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -5,4 +5,5 @@ Charge difference to: Cargar diferencia a The ticket has been unrouted: El ticket ha sido desenrutado Price: Precio New price: Nuevo precio -Price difference: Diferencia de precio \ No newline at end of file +Price difference: Diferencia de precio +Without create negatives: Sin crear negativos \ No newline at end of file From 3e91929d0d8aa02e2ffc765cae725fc6ab98cdcc Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 15 Dec 2021 15:16:21 +0100 Subject: [PATCH 02/16] half test --- .../ticket/specs/priceDifference.spec.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index fed899d779..173bad2fdc 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -59,4 +59,36 @@ describe('sale priceDifference()', () => { expect(error).toEqual(new UserError(`The sales of this ticket can't be modified`)); }); + + it('should return ticket visible', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + + const ctx = {req: {accessToken: {userId: 1106}}}; + ctx.args = { + id: 11, + landed: tomorrow, + addressId: 122, + agencyModeId: 7, + zoneId: 3, + warehouseId: 1 + }; + + const result = await models.Ticket.priceDifference(ctx, options); + console.log(result.items[0]); + + expect(result.totalUnitPrice).toEqual(result.totalNewPrice); + expect(result.totalDifference).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); From 87f994aa7786065d40875961ea883bf53a8ea9b1 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 16 Dec 2021 08:14:27 +0100 Subject: [PATCH 03/16] test(ticket_basci-data_step-two): back and front --- .../ticket/specs/priceDifference.spec.js | 7 ++++--- .../front/basic-data/step-two/index.spec.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 173bad2fdc..e9648cebea 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -80,10 +80,11 @@ describe('sale priceDifference()', () => { }; const result = await models.Ticket.priceDifference(ctx, options); - console.log(result.items[0]); + const firstItem = result.items[0]; + const secondtItem = result.items[1]; - expect(result.totalUnitPrice).toEqual(result.totalNewPrice); - expect(result.totalDifference).toEqual(0); + expect(firstItem.visible).toEqual(445); + expect(secondtItem.visible).toEqual(1980); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index ea82687165..556176d051 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -64,5 +64,22 @@ describe('Ticket', () => { expect(controller.totalPriceDifference).toEqual(0.3); }); }); + + fdescribe('ticketHaveNegatives()', () => { + it('should show if ticket have any negative', () => { + controller.ticket = { + sale: { + items: [{ + quantity: 2, + visible: 1 + }] + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(true); + }); + }); }); }); From 850ea2ef39a701f31aac0ac01c73328d1a7f36fa Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 17 Dec 2021 12:38:56 +0100 Subject: [PATCH 04/16] getVisible sql --- .../00-ticket_getVisibleAvailable .sql | 50 +++++++++++++++++++ .../01-ticketGetVisibleAvailable .sql | 9 ++++ db/changes/10400-christmas/delete.keep | 1 - .../back/methods/ticket/priceDifference.js | 22 ++++++-- .../ticket/front/basic-data/step-one/index.js | 3 +- .../ticket/front/basic-data/step-two/index.js | 2 + 6 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql create mode 100644 db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql delete mode 100644 db/changes/10400-christmas/delete.keep diff --git a/db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql b/db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql new file mode 100644 index 0000000000..79a9b922a4 --- /dev/null +++ b/db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql @@ -0,0 +1,50 @@ +DROP PROCEDURE IF EXISTS `vn`.`ticket_getVisibleAvailable`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getVisibleAvailable`(vTicket INT, vDate DATE) +BEGIN + DECLARE vVisibleCalc INT; + DECLARE vAvailableCalc INT; + DECLARE vShipped DATE; + DECLARE vWarehouse TINYINT; + DECLARE vAlertLevel INT; + + SELECT t.warehouseFk, t.shipped, ts.alertLevel + INTO vWarehouse, vShipped, vAlertLevel + FROM ticket t + LEFT JOIN ticketState ts ON ts.ticketFk = vTicket + WHERE t.id = vTicket; + + IF vDate IS NULL THEN + SET vDate = vShipped; + END IF; + + IF vAlertLevel IS NULL OR vAlertLevel = 0 THEN + IF vDate >= CURDATE() THEN + CALL cache.available_refresh(vAvailableCalc, FALSE, vWarehouse, vDate); + END IF; + IF vDate = CURDATE() THEN + CALL cache.visible_refresh(vVisibleCalc, FALSE, vWarehouse); + END IF; + END IF; + + SELECT s.id, + s.itemFk, + s.quantity, + s.concept, + s.price, + s.reserved, + s.discount, + v.visible, + av.available, + it.image, + it.subName + FROM sale s + LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCalc + LEFT JOIN cache.available av ON av.item_id = s.itemFk AND av.calc_id = vAvailableCalc + LEFT JOIN item it ON it.id = s.itemFk + WHERE s.ticketFk = vTicket + ORDER BY s.concept; +END$$ +DELIMITER ; diff --git a/db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql b/db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql new file mode 100644 index 0000000000..84c4db8d56 --- /dev/null +++ b/db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql @@ -0,0 +1,9 @@ +DROP PROCEDURE IF EXISTS vn.ticketGetVisibleAvailable; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetVisibleAvailable`(vTicket INT) +BEGIN + CALL `ticket_getVisibleAvailable`(vTicket, null); +END$$ +DELIMITER ; diff --git a/db/changes/10400-christmas/delete.keep b/db/changes/10400-christmas/delete.keep deleted file mode 100644 index 603d82d74b..0000000000 --- a/db/changes/10400-christmas/delete.keep +++ /dev/null @@ -1 +0,0 @@ -Delete me! \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 56f6ad7d22..3448af17bf 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -40,6 +40,12 @@ module.exports = Self => { type: 'number', description: 'The warehouse id', required: true + }, + { + arg: 'shipped', + type: 'date', + description: 'shipped', + required: true }], returns: { type: ['object'], @@ -101,16 +107,22 @@ module.exports = Self => { }; // Get items visible - let query = `CALL ticketGetVisibleAvailable(?)`; - const [salesVisible] = await Self.rawSql(query, [args.id], myOptions); + let query = `CALL ticket_getVisibleAvailable(?,?)`; + let params = [args.id, args.shipped]; + const [salesVisible] = await Self.rawSql(query, params, myOptions); const itemVisible = new Map(); - for (sale of salesVisible) - itemVisible.set(sale.id, sale.visible); + for (sale of salesVisible) { + let visible = sale.available; + if (visible == null) + visible = 0; + + itemVisible.set(sale.id, visible); + } // Sale price component, one per sale query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; - const params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId]; + params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId]; const [difComponents] = await Self.rawSql(query, params, myOptions); const map = new Map(); diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js index 215f36a46e..f532265e22 100644 --- a/modules/ticket/front/basic-data/step-one/index.js +++ b/modules/ticket/front/basic-data/step-one/index.js @@ -201,7 +201,8 @@ class Controller extends Component { addressId: this.ticket.addressFk, agencyModeId: this.ticket.agencyModeFk, zoneId: this.ticket.zoneFk, - warehouseId: this.ticket.warehouseFk + warehouseId: this.ticket.warehouseFk, + shipped: this.ticket.shipped }; return this.$http.post(query, params).then(res => { diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index fbaa52a7ed..4a6a0302e7 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -79,6 +79,7 @@ class Controller extends Component { this.$t('Choose an option') ); } + if (this.ticket.withoutNegatives) { let salesNewTicket = []; this.ticket.sale.items.forEach(item => { @@ -93,6 +94,7 @@ class Controller extends Component { const query = `tickets/${this.ticket.id}/transferSales`; this.$http.post(query, params); } + const query = `tickets/${this.ticket.id}/componentUpdate`; const params = { clientFk: this.ticket.clientFk, From b0019d09ad4f8688bde8f79ccfae9063c1c99ad3 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 20 Dec 2021 13:50:31 +0100 Subject: [PATCH 05/16] feat(ticket_basic-data_step-two): adapted for available and transfer sales in back --- ....sql => 00-ticket_getVisibleAvailable.sql} | 4 +-- ... .sql => 01-ticketGetVisibleAvailable.sql} | 5 ++-- loopback/locale/es.json | 3 ++- .../back/methods/ticket/componentUpdate.js | 25 ++++++++++++++++- .../back/methods/ticket/priceDifference.js | 18 ++++++------- .../front/basic-data/step-two/index.html | 6 ++--- .../ticket/front/basic-data/step-two/index.js | 27 +++++++------------ 7 files changed, 52 insertions(+), 36 deletions(-) rename db/changes/10400-christmas/{00-ticket_getVisibleAvailable .sql => 00-ticket_getVisibleAvailable.sql} (95%) rename db/changes/10400-christmas/{01-ticketGetVisibleAvailable .sql => 01-ticketGetVisibleAvailable.sql} (66%) diff --git a/db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql b/db/changes/10400-christmas/00-ticket_getVisibleAvailable.sql similarity index 95% rename from db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql rename to db/changes/10400-christmas/00-ticket_getVisibleAvailable.sql index 79a9b922a4..6151b786da 100644 --- a/db/changes/10400-christmas/00-ticket_getVisibleAvailable .sql +++ b/db/changes/10400-christmas/00-ticket_getVisibleAvailable.sql @@ -2,13 +2,13 @@ DROP PROCEDURE IF EXISTS `vn`.`ticket_getVisibleAvailable`; DELIMITER $$ $$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getVisibleAvailable`(vTicket INT, vDate DATE) +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getVisibleAvailable`(`vTicket` INT, `vDate` DATE) BEGIN DECLARE vVisibleCalc INT; DECLARE vAvailableCalc INT; DECLARE vShipped DATE; DECLARE vWarehouse TINYINT; - DECLARE vAlertLevel INT; + DECLARE vAlertLevel INT; SELECT t.warehouseFk, t.shipped, ts.alertLevel INTO vWarehouse, vShipped, vAlertLevel diff --git a/db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql b/db/changes/10400-christmas/01-ticketGetVisibleAvailable.sql similarity index 66% rename from db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql rename to db/changes/10400-christmas/01-ticketGetVisibleAvailable.sql index 84c4db8d56..fc2429e72c 100644 --- a/db/changes/10400-christmas/01-ticketGetVisibleAvailable .sql +++ b/db/changes/10400-christmas/01-ticketGetVisibleAvailable.sql @@ -1,9 +1,10 @@ -DROP PROCEDURE IF EXISTS vn.ticketGetVisibleAvailable; +DROP PROCEDURE IF EXISTS `vn`.`ticketGetVisibleAvailable`; DELIMITER $$ $$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetVisibleAvailable`(vTicket INT) +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetVisibleAvailable`(`vTicket` INT) BEGIN CALL `ticket_getVisibleAvailable`(vTicket, null); END$$ DELIMITER ; + \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 2611ee0ddb..aa60f975e8 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -216,5 +216,6 @@ "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", - "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día" + "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", + "isWithoutNegatives": "Tiene Negativos" } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 5156896496..f620adb455 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -77,6 +77,12 @@ module.exports = Self => { type: 'number', description: 'Action id', required: true + }, + { + arg: 'isWithoutNegatives', + type: 'boolean', + description: 'Is whithout negatives', + required: true }], returns: { type: ['object'], @@ -112,11 +118,28 @@ module.exports = Self => { const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions); if (!isProductionBoss) { - const zoneShipped = await models.Agency.getShipped(args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk, myOptions); + const params = [args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk]; + const zoneShipped = await models.Agency.getShipped(params, myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) throw new UserError(`You don't have privileges to change the zone`); } + if (args.isWithoutNegatives) { + let query = `CALL ticket_getVisibleAvailable(?,?)`; + let params = [args.id, args.shipped]; + const [salesAvailable] = await Self.rawSql(query, params, myOptions); + + let salesNewTicket = []; + salesAvailable.forEach(sale => { + if (sale.available >= sale.quantity) + salesNewTicket.push(sale); + }); + + if (salesNewTicket.length) { + const newTicket = await models.Ticket.transferSales(ctx, args.id, null, salesNewTicket, myOptions); + args.id = newTicket.id; + } + } const originalTicket = await models.Ticket.findOne({ where: {id: args.id}, diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 3448af17bf..d933e9c22b 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -106,18 +106,18 @@ module.exports = Self => { totalDifference: 0.00, }; - // Get items visible + // Get items available let query = `CALL ticket_getVisibleAvailable(?,?)`; let params = [args.id, args.shipped]; - const [salesVisible] = await Self.rawSql(query, params, myOptions); + const [salesAvailable] = await Self.rawSql(query, params, myOptions); - const itemVisible = new Map(); - for (sale of salesVisible) { - let visible = sale.available; - if (visible == null) - visible = 0; + const itemAvailable = new Map(); + for (sale of salesAvailable) { + let available = sale.available; + if (available == null) + available = 0; - itemVisible.set(sale.id, visible); + itemAvailable.set(sale.id, available); } // Sale price component, one per sale @@ -143,7 +143,7 @@ module.exports = Self => { salesObj.totalUnitPrice += sale.price; salesObj.totalUnitPrice = round(salesObj.totalUnitPrice); - sale.visible = itemVisible.get(sale.id); + sale.available = itemAvailable.get(sale.id); } if (tx) await tx.commit(); diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 3241335787..27569b9098 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,7 +9,7 @@ Item Description - Visible + Available Quantity Price (PPU) New (PPU) @@ -35,8 +35,8 @@ - {{::sale.visible}} + ng-class="{'alert': sale.quantity>sale.available}"> + {{::sale.available}} {{::sale.quantity}} diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 4a6a0302e7..ec527abf03 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -66,11 +66,16 @@ class Controller extends Component { ticketHaveNegatives() { let haveNegatives = false; + let haveNotNegatives = false; + this.ticket.sale.items.forEach(item => { - if (item.quantity > item.visible) + if (item.quantity > item.available) haveNegatives = true; + else + haveNotNegatives = true; }); - this.haveNegatives = haveNegatives; + + this.haveNegatives = (haveNegatives && haveNotNegatives); } onSubmit() { @@ -80,21 +85,6 @@ class Controller extends Component { ); } - if (this.ticket.withoutNegatives) { - let salesNewTicket = []; - this.ticket.sale.items.forEach(item => { - if (item.visible >= item.quantity) - salesNewTicket.push(item); - }); - - const params = { - sales: salesNewTicket - }; - - const query = `tickets/${this.ticket.id}/transferSales`; - this.$http.post(query, params); - } - const query = `tickets/${this.ticket.id}/componentUpdate`; const params = { clientFk: this.ticket.clientFk, @@ -107,7 +97,8 @@ class Controller extends Component { shipped: this.ticket.shipped, landed: this.ticket.landed, isDeleted: this.ticket.isDeleted, - option: parseInt(this.ticket.option) + option: parseInt(this.ticket.option), + isWithoutNegatives: this.ticket.withoutNegatives }; this.$http.post(query, params).then(res => { From 18b6efe8f16886be023d476934e298c48269fb4a Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 21 Dec 2021 20:58:58 +0100 Subject: [PATCH 06/16] test(ticket_basic-data): test and fixtures --- db/dump/fixtures.sql | 9 ++- e2e/helpers/selectors.js | 4 ++ .../05-ticket/06_basic_data_steps.spec.js | 61 +++++++++++++++++++ loopback/locale/en.json | 3 +- .../back/methods/ticket/componentUpdate.js | 7 +-- .../ticket/specs/componentUpdate.spec.js | 6 +- .../ticket/specs/priceDifference.spec.js | 6 +- .../front/basic-data/step-two/index.html | 3 +- .../ticket/front/basic-data/step-two/index.js | 1 + .../front/basic-data/step-two/index.spec.js | 20 ++++-- .../front/basic-data/step-two/locale/es.yml | 3 +- 11 files changed, 103 insertions(+), 20 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 3e99bd39e3..ed50225b9d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -622,6 +622,7 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF (25 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 1, 5, 1, CURDATE()), (26 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'An incredibly long alias for testing purposes', 1, NULL, 0, 1, 5, 1, CURDATE()), (27 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Wolverine', 1, NULL, 0, 1, 5, 1, CURDATE()); + INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`) VALUES (1, 11, 1, 'ready'), @@ -665,7 +666,9 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`) (21, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)), (22, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)), (23, 16, 21, NOW()), - (24, 16, 21, NOW()); + (24, 16, 21, NOW()), + (27, 3, 21, NOW()); + INSERT INTO `vn`.`stowaway`(`id`, `shipFk`, `created`) VALUES @@ -896,7 +899,9 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (29, 4, 17, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, CURDATE()), (30, 4, 18, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, CURDATE()), (31, 2, 23, 'Melee weapon combat fist 15cm', -5, 7.08, 0, 0, 0, CURDATE()), - (32, 1, 24, 'Ranged weapon longbow 2m', -1, 8.07, 0, 0, 0, CURDATE()); + (32, 1, 24, 'Ranged weapon longbow 2m', -1, 8.07, 0, 0, 0, CURDATE()), + (33, 4, 27, 'Melee weapon combat fist 15cm', 1, 8.07, 0, 0, 0, CURDATE()), + (34, 5, 27, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, CURDATE()); INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 8675797e75..b4720f4c7b 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -525,6 +525,7 @@ export default { acceptDialog: '.vn-dialog.shown button[response="accept"]', acceptChangeHourButton: '.vn-dialog.shown button[response="accept"]', descriptorDeliveryDate: 'vn-ticket-descriptor slot-body > .attributes > vn-label-value:nth-child(4) > section > span', + descriptorDeliveryAgency: 'vn-ticket-descriptor slot-body > .attributes > vn-label-value:nth-child(5) > section > span', acceptInvoiceOutButton: '.vn-confirm.shown button[response="accept"]', acceptDeleteStowawayButton: '.vn-dialog.shown button[response="accept"]' }, @@ -562,6 +563,7 @@ export default { transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', firstSaleId: 'vn-ticket-sale vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(6) > span', + firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)', firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', @@ -601,10 +603,12 @@ export default { ticketBasicData: { agency: 'vn-autocomplete[ng-model="$ctrl.agencyModeId"]', zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]', + shipped: 'vn-date-picker[ng-model="$ctrl.shipped"]', nextStepButton: 'vn-step-control .buttons > section:last-child vn-button', finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]', stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > vn-side-menu div:nth-child(4)', chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio', + withoutNegatives: 'vn-check[ng-model="$ctrl.ticket.withoutNegatives"]', }, ticketComponents: { base: 'vn-ticket-components > vn-side-menu div:nth-child(1) > div:nth-child(2)' diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index a5f9a60cf5..cca63cd6f6 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -83,4 +83,65 @@ describe('Ticket Edit basic data path', () => { await page.waitToClick(selectors.ticketBasicData.finalizeButton); await page.waitForState('ticket.card.summary'); }); + + it(`should not find ticket`, async() => { + await page.doSearch('28'); + const count = await page.countElement(selectors.ticketsIndex.searchResult); + + expect(count).toEqual(0); + }); + + it(`should split ticket without negatives`, async() => { + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + + await page.accessToSearchResult('14'); + await page.accessToSection('ticket.card.basicData.stepOne'); + + const originalDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + const originalAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + + await page.autocompleteSearch(selectors.ticketBasicData.agency, 'Silla247'); + await page.pickDate(selectors.ticketBasicData.shipped, tomorrow); + await page.waitToClick(selectors.ticketBasicData.nextStepButton); + + await page.waitToClick(selectors.ticketBasicData.withoutNegatives); + await page.waitToClick(selectors.ticketBasicData.finalizeButton); + + const resultDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + const resultAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + + expect(resultDate).toEqual(originalDate); + expect(resultAgency).toEqual(originalAgency); + }); + + it(`should new ticket have one line from splited ticket`, async() => { + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + const expectedDay = tomorrow.getDate(); + const expectedMonth = tomorrow.getMonth() + 1; + const expectedYear = tomorrow.getFullYear(); + + await page.accessToSearchResult('28'); + await page.accessToSection('ticket.card.sale'); + + const item = await page.waitToGetProperty(selectors.ticketSales.firstSaleId, 'innerText'); + const agency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + let date = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + + date = date.split(' '); + date = date[0].split('/'); + + expect(item).toEqual('4'); + expect(agency).toEqual('Silla247'); + expect(date[0]).toContain(expectedDay); + expect(date[1]).toContain(expectedMonth); + expect(date[2]).toContain(expectedYear); + }); }); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 15c65fd89a..7f3e18d728 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -119,5 +119,6 @@ "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", "This item is not available": "This item is not available", "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}", - "The type of business must be filled in basic data": "The type of business must be filled in basic data" + "The type of business must be filled in basic data": "The type of business must be filled in basic data", + "isWithoutNegatives": "isWithoutNegatives" } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index f620adb455..3bccebdfef 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -118,15 +118,14 @@ module.exports = Self => { const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions); if (!isProductionBoss) { - const params = [args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk]; - const zoneShipped = await models.Agency.getShipped(params, myOptions); + const zoneShipped = await models.Agency.getShipped(args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk, myOptions); if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) throw new UserError(`You don't have privileges to change the zone`); } if (args.isWithoutNegatives) { - let query = `CALL ticket_getVisibleAvailable(?,?)`; - let params = [args.id, args.shipped]; + const query = `CALL ticket_getVisibleAvailable(?,?)`; + const params = [args.id, args.shipped]; const [salesAvailable] = await Self.rawSql(query, params, myOptions); let salesNewTicket = []; diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index 9fa69b595e..38e6ce6a7d 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -45,7 +45,8 @@ describe('ticket componentUpdate()', () => { shipped: today, landed: tomorrow, isDeleted: false, - option: 1 + option: 1, + isWithoutNegatives: false }; let ctx = { @@ -94,7 +95,8 @@ describe('ticket componentUpdate()', () => { shipped: today, landed: tomorrow, isDeleted: false, - option: 1 + option: 1, + isWithoutNegatives: false }; const ctx = { diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index e9648cebea..8fe906bcfa 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -60,7 +60,7 @@ describe('sale priceDifference()', () => { expect(error).toEqual(new UserError(`The sales of this ticket can't be modified`)); }); - it('should return ticket visible', async() => { + it('should return ticket available', async() => { const tx = await models.Ticket.beginTransaction({}); try { @@ -83,8 +83,8 @@ describe('sale priceDifference()', () => { const firstItem = result.items[0]; const secondtItem = result.items[1]; - expect(firstItem.visible).toEqual(445); - expect(secondtItem.visible).toEqual(1980); + expect(firstItem.available).toEqual(410); + expect(secondtItem.available).toEqual(1870); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 27569b9098..74b160fdad 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -77,7 +77,8 @@
+ label="Without create negatives" + info="Clone this ticket with the changes and only sales availables">
diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index ec527abf03..d770907818 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -75,6 +75,7 @@ class Controller extends Component { haveNotNegatives = true; }); + this.ticket.withoutNegatives = false; this.haveNegatives = (haveNegatives && haveNotNegatives); } diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index 556176d051..fcd1d7e49e 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -65,14 +65,22 @@ describe('Ticket', () => { }); }); - fdescribe('ticketHaveNegatives()', () => { - it('should show if ticket have any negative', () => { + describe('ticketHaveNegatives()', () => { + it('should show if ticket have any negative and any not negative', () => { controller.ticket = { sale: { - items: [{ - quantity: 2, - visible: 1 - }] + items: [ + { + item: 1, + quantity: 2, + available: 1 + }, + { + item: 2, + quantity: 1, + available: 5 + } + ] } }; diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index 4f68d33e20..08bef3b09a 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -6,4 +6,5 @@ The ticket has been unrouted: El ticket ha sido desenrutado Price: Precio New price: Nuevo precio Price difference: Diferencia de precio -Without create negatives: Sin crear negativos \ No newline at end of file +Without create negatives: Sin crear negativos +Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. \ No newline at end of file From 67dc5c2cbc885f3c2f5b3669b61c26cbe0459d9f Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 22 Dec 2021 08:11:33 +0100 Subject: [PATCH 07/16] refactor(ticket_basic-data): test e2e --- db/dump/fixtures.sql | 1 - e2e/helpers/selectors.js | 1 - e2e/paths/05-ticket/06_basic_data_steps.spec.js | 12 +++++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 8dfd6c8a89..d5bd7d8797 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -669,7 +669,6 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`) (24, 16, 21, NOW()), (27, 3, 21, NOW()); - INSERT INTO `vn`.`stowaway`(`id`, `shipFk`, `created`) VALUES (12, 13, CURDATE()); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b4720f4c7b..e088f56822 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -563,7 +563,6 @@ export default { transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', firstSaleId: 'vn-ticket-sale vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(6) > span', - firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)', firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index cca63cd6f6..af68eefcac 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -8,7 +8,7 @@ describe('Ticket Edit basic data path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('employee', 'ticket'); + await page.loginAndModule('employee', 'ticket'); await page.accessToSearchResult('11'); await page.accessToSection('ticket.card.basicData.stepOne'); }); @@ -95,7 +95,7 @@ describe('Ticket Edit basic data path', () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); - await page.accessToSearchResult('14'); + await page.accessToSearchResult('27'); await page.accessToSection('ticket.card.basicData.stepOne'); const originalDate = await page @@ -105,6 +105,7 @@ describe('Ticket Edit basic data path', () => { await page.autocompleteSearch(selectors.ticketBasicData.agency, 'Silla247'); await page.pickDate(selectors.ticketBasicData.shipped, tomorrow); + await page.waitToClick(selectors.ticketBasicData.nextStepButton); await page.waitToClick(selectors.ticketBasicData.withoutNegatives); @@ -122,6 +123,7 @@ describe('Ticket Edit basic data path', () => { it(`should new ticket have one line from splited ticket`, async() => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); + const expectedDay = tomorrow.getDate(); const expectedMonth = tomorrow.getMonth() + 1; const expectedYear = tomorrow.getFullYear(); @@ -140,8 +142,8 @@ describe('Ticket Edit basic data path', () => { expect(item).toEqual('4'); expect(agency).toEqual('Silla247'); - expect(date[0]).toContain(expectedDay); - expect(date[1]).toContain(expectedMonth); - expect(date[2]).toContain(expectedYear); + expect(parseInt(date[0])).toEqual(expectedDay); + expect(parseInt(date[1])).toEqual(expectedMonth); + expect(parseInt(date[2])).toEqual(expectedYear); }); }); From 1e6355cddef280e686ade6d6001b026e17c6705d Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 22 Dec 2021 08:37:50 +0100 Subject: [PATCH 08/16] fixtures --- db/dump/fixtures.sql | 6 ++---- e2e/paths/05-ticket/06_basic_data_steps.spec.js | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d5bd7d8797..bb18ec223c 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -666,8 +666,7 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`) (21, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)), (22, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)), (23, 16, 21, NOW()), - (24, 16, 21, NOW()), - (27, 3, 21, NOW()); + (24, 16, 21, NOW()); INSERT INTO `vn`.`stowaway`(`id`, `shipFk`, `created`) VALUES @@ -899,8 +898,7 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (30, 4, 18, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, CURDATE()), (31, 2, 23, 'Melee weapon combat fist 15cm', -5, 7.08, 0, 0, 0, CURDATE()), (32, 1, 24, 'Ranged weapon longbow 2m', -1, 8.07, 0, 0, 0, CURDATE()), - (33, 4, 27, 'Melee weapon combat fist 15cm', 1, 8.07, 0, 0, 0, CURDATE()), - (34, 5, 27, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, CURDATE()); + (33, 5, 14, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, CURDATE()); INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`) VALUES diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index af68eefcac..6ae7029797 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -95,7 +95,7 @@ describe('Ticket Edit basic data path', () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); - await page.accessToSearchResult('27'); + await page.accessToSearchResult('14'); await page.accessToSection('ticket.card.basicData.stepOne'); const originalDate = await page @@ -128,6 +128,7 @@ describe('Ticket Edit basic data path', () => { const expectedMonth = tomorrow.getMonth() + 1; const expectedYear = tomorrow.getFullYear(); + await page.loginAndModule('employee', 'ticket'); await page.accessToSearchResult('28'); await page.accessToSection('ticket.card.sale'); From c90a2b6e5cfb9dd54ad2672585ae03b8f40837d6 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 13 Jan 2022 07:24:46 +0100 Subject: [PATCH 09/16] update folder changes --- db/changes/{10410-noname => 10410-january}/00-smsConfig.sql | 0 .../00-ticket_getVisibleAvailable.sql | 0 .../{10410-noname => 10410-january}/01-smsConfig_update.sql | 0 .../01-ticketGetVisibleAvailable.sql | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename db/changes/{10410-noname => 10410-january}/00-smsConfig.sql (100%) rename db/changes/{10400-christmas => 10410-january}/00-ticket_getVisibleAvailable.sql (100%) rename db/changes/{10410-noname => 10410-january}/01-smsConfig_update.sql (100%) rename db/changes/{10400-christmas => 10410-january}/01-ticketGetVisibleAvailable.sql (100%) diff --git a/db/changes/10410-noname/00-smsConfig.sql b/db/changes/10410-january/00-smsConfig.sql similarity index 100% rename from db/changes/10410-noname/00-smsConfig.sql rename to db/changes/10410-january/00-smsConfig.sql diff --git a/db/changes/10400-christmas/00-ticket_getVisibleAvailable.sql b/db/changes/10410-january/00-ticket_getVisibleAvailable.sql similarity index 100% rename from db/changes/10400-christmas/00-ticket_getVisibleAvailable.sql rename to db/changes/10410-january/00-ticket_getVisibleAvailable.sql diff --git a/db/changes/10410-noname/01-smsConfig_update.sql b/db/changes/10410-january/01-smsConfig_update.sql similarity index 100% rename from db/changes/10410-noname/01-smsConfig_update.sql rename to db/changes/10410-january/01-smsConfig_update.sql diff --git a/db/changes/10400-christmas/01-ticketGetVisibleAvailable.sql b/db/changes/10410-january/01-ticketGetVisibleAvailable.sql similarity index 100% rename from db/changes/10400-christmas/01-ticketGetVisibleAvailable.sql rename to db/changes/10410-january/01-ticketGetVisibleAvailable.sql From 61859a23c9f6a044efcc5f63350ca3f9b475913b Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Jan 2022 07:14:29 +0100 Subject: [PATCH 10/16] feat(ticket): getAdvanceable --- .../10410-january/00-ticket_getAdvancable.sql | 44 ++++ .../00-ticket_getVisibleAvailable.sql | 50 ---- .../01-ticketGetVisibleAvailable.sql | 10 - loopback/locale/es.json | 239 ++---------------- .../back/methods/ticket/componentUpdate.js | 8 +- .../back/methods/ticket/priceDifference.js | 20 +- .../front/basic-data/step-two/index.html | 6 +- .../ticket/front/basic-data/step-two/index.js | 2 +- .../front/basic-data/step-two/locale/es.yml | 3 +- 9 files changed, 83 insertions(+), 299 deletions(-) create mode 100644 db/changes/10410-january/00-ticket_getAdvancable.sql delete mode 100644 db/changes/10410-january/00-ticket_getVisibleAvailable.sql delete mode 100644 db/changes/10410-january/01-ticketGetVisibleAvailable.sql diff --git a/db/changes/10410-january/00-ticket_getAdvancable.sql b/db/changes/10410-january/00-ticket_getAdvancable.sql new file mode 100644 index 0000000000..599e431b34 --- /dev/null +++ b/db/changes/10410-january/00-ticket_getAdvancable.sql @@ -0,0 +1,44 @@ +DROP PROCEDURE IF EXISTS `vn`.`ticket_getAdvanceable`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getAdvanceable`(vTicketFk INT, vDatedNew DATETIME) +BEGIN +/** + * Cálcula el stock avanzable para los artículos de un ticket + * + * @param vTicketFk -> Ticket + * @param vDatedNew -> Nueva fecha + * @return Sales con Avanzable +*/ + DECLARE vWarehouseFk INT; + DECLARE vDatedOld DATETIME; + + SELECT t.warehouseFk, t.shipped INTO vWarehouseFk, vDatedOld + FROM ticket t + WHERE t.id = vTicketFk; + + CALL itemStock(vWarehouseFk, DATE_SUB(vDatedNew, INTERVAL 1 DAY), NULL); + CALL item_getMinacum(vWarehouseFk, vDatedNew, DATEDIFF(vDatedOld, vDatedNew), NULL); + + SELECT s.id, + s.itemFk, + s.quantity, + s.concept, + s.price, + s.reserved, + s.discount, + i.image, + i.subName, + il.stock + IFNULL(im.amount, 0) AS advanceable + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + LEFT JOIN tmp.itemMinacum im ON im.itemFk = s.itemFk AND im.warehouseFk = vWarehouseFk + LEFT JOIN tmp.itemList il ON il.itemFk = s.itemFk + WHERE t.id = vTicketFk; + + DROP TEMPORARY TABLE IF EXISTS tmp.itemList; + DROP TEMPORARY TABLE IF EXISTS tmp.itemMinacum; +END$$ +DELIMITER ; diff --git a/db/changes/10410-january/00-ticket_getVisibleAvailable.sql b/db/changes/10410-january/00-ticket_getVisibleAvailable.sql deleted file mode 100644 index 6151b786da..0000000000 --- a/db/changes/10410-january/00-ticket_getVisibleAvailable.sql +++ /dev/null @@ -1,50 +0,0 @@ -DROP PROCEDURE IF EXISTS `vn`.`ticket_getVisibleAvailable`; - -DELIMITER $$ -$$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getVisibleAvailable`(`vTicket` INT, `vDate` DATE) -BEGIN - DECLARE vVisibleCalc INT; - DECLARE vAvailableCalc INT; - DECLARE vShipped DATE; - DECLARE vWarehouse TINYINT; - DECLARE vAlertLevel INT; - - SELECT t.warehouseFk, t.shipped, ts.alertLevel - INTO vWarehouse, vShipped, vAlertLevel - FROM ticket t - LEFT JOIN ticketState ts ON ts.ticketFk = vTicket - WHERE t.id = vTicket; - - IF vDate IS NULL THEN - SET vDate = vShipped; - END IF; - - IF vAlertLevel IS NULL OR vAlertLevel = 0 THEN - IF vDate >= CURDATE() THEN - CALL cache.available_refresh(vAvailableCalc, FALSE, vWarehouse, vDate); - END IF; - IF vDate = CURDATE() THEN - CALL cache.visible_refresh(vVisibleCalc, FALSE, vWarehouse); - END IF; - END IF; - - SELECT s.id, - s.itemFk, - s.quantity, - s.concept, - s.price, - s.reserved, - s.discount, - v.visible, - av.available, - it.image, - it.subName - FROM sale s - LEFT JOIN cache.visible v ON v.item_id = s.itemFk AND v.calc_id = vVisibleCalc - LEFT JOIN cache.available av ON av.item_id = s.itemFk AND av.calc_id = vAvailableCalc - LEFT JOIN item it ON it.id = s.itemFk - WHERE s.ticketFk = vTicket - ORDER BY s.concept; -END$$ -DELIMITER ; diff --git a/db/changes/10410-january/01-ticketGetVisibleAvailable.sql b/db/changes/10410-january/01-ticketGetVisibleAvailable.sql deleted file mode 100644 index fc2429e72c..0000000000 --- a/db/changes/10410-january/01-ticketGetVisibleAvailable.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP PROCEDURE IF EXISTS `vn`.`ticketGetVisibleAvailable`; - -DELIMITER $$ -$$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetVisibleAvailable`(`vTicket` INT) -BEGIN - CALL `ticket_getVisibleAvailable`(vTicket, null); -END$$ -DELIMITER ; - \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index a096a773d1..3d5c205bd6 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,220 +1,23 @@ { - "Phone format is invalid": "El formato del teléfono no es correcto", - "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", - "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", - "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", - "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", - "Can't be blank": "No puede estar en blanco", - "Invalid TIN": "NIF/CIF invalido", - "TIN must be unique": "El NIF/CIF debe ser único", - "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", - "Is invalid": "Is invalid", - "Quantity cannot be zero": "La cantidad no puede ser cero", - "Enter an integer different to zero": "Introduce un entero distinto de cero", - "Package cannot be blank": "El embalaje no puede estar en blanco", - "The company name must be unique": "La razón social debe ser única", - "Invalid email": "Correo electrónico inválido", - "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", - "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", - "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", - "State cannot be blank": "El estado no puede estar en blanco", - "Worker cannot be blank": "El trabajador no puede estar en blanco", - "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", - "can't be blank": "El campo no puede estar vacío", - "Observation type must be unique": "El tipo de observación no puede repetirse", + "Name cannot be blank": "Name cannot be blank", + "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", + "Street cannot be empty": "Street cannot be empty", + "City cannot be empty": "City cannot be empty", + "Invalid email": "Invalid email", + "Phone cannot be blank": "Phone cannot be blank", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", - "The grade must be similar to the last one": "El grade debe ser similar al último", - "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", - "Name cannot be blank": "El nombre no puede estar en blanco", - "Phone cannot be blank": "El teléfono no puede estar en blanco", - "Period cannot be blank": "El periodo no puede estar en blanco", - "Choose a company": "Selecciona una empresa", - "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", - "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", - "Cannot be blank": "El campo no puede estar en blanco", - "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 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", - "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", - "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", - "is not a valid date": "No es una fecha valida", - "Barcode must be unique": "El código de barras debe ser único", - "The warehouse can't be repeated": "El almacén no puede repetirse", - "The tag can't be repeated": "El tag no puede repetirse", - "The observation type can't be repeated": "El tipo de observación no puede repetirse", - "A claim with that sale already exists": "Ya existe una reclamación para esta línea", - "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", - "Warehouse cannot be blank": "El almacén no puede quedar en blanco", - "Agency cannot be blank": "La agencia no puede quedar en blanco", - "You can't make changes on a client with verified data": "No puedes hacer cambios en un cliente con datos comprobados", - "This address doesn't exist": "Este consignatario no existe", - "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", - "You don't have enough privileges": "No tienes suficientes permisos", - "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", - "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", - "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", - "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", - "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", - "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", - "ORDER_EMPTY": "Cesta vacía", - "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", - "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", - "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", - "Street cannot be empty": "Dirección no puede estar en blanco", - "City cannot be empty": "Cuidad no puede estar en blanco", - "Code cannot be blank": "Código no puede estar en blanco", - "You cannot remove this department": "No puedes eliminar este departamento", - "The extension must be unique": "La extensión debe ser unica", - "The secret can't be blank": "La contraseña no puede estar en blanco", - "We weren't able to send this SMS": "No hemos podido enviar el SMS", - "This client can't be invoiced": "Este cliente no puede ser facturado", - "This ticket can't be invoiced": "Este ticket no puede ser facturado", - "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", - "This ticket can not be modified": "Este ticket no puede ser modificado", - "The introduced hour already exists": "Esta hora ya ha sido introducida", - "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", - "The sales of the current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", - "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", - "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", - "The current ticket can't be modified": "El ticket actual no puede ser modificado", - "The current claim can't be modified": "La reclamación actual no puede ser modificada", - "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", - "Sale(s) blocked, contact production": "Linea(s) bloqueada(s), contacte con produccion", - "Please select at least one sale": "Por favor selecciona al menos una linea", - "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", - "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "This item doesn't exists": "El artículo no existe", - "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", - "Extension format is invalid": "El formato de la extensión es inválido", - "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", - "This item is not available": "Este artículo no está disponible", - "This postcode already exists": "Este código postal ya existe", - "Concept cannot be blank": "El concepto no puede quedar en blanco", - "File doesn't exists": "El archivo no existe", - "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", - "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", - "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", - "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", - "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", - "Can't create stowaway for this ticket": "No se puede crear un polizon para este ticket", - "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", - "Invalid quantity": "Cantidad invalida", - "This postal code is not valid": "This postal code is not valid", - "is invalid": "is invalid", - "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", - "The department name can't be repeated": "El nombre del departamento no puede repetirse", - "This phone already exists": "Este teléfono ya existe", - "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", - "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", - "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", - "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", - "You should specify a date": "Debes especificar una fecha", - "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", - "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", - "You should mark at least one week day": "Debes marcar al menos un día de la semana", - "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", - "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", - "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", - "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", - "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", - "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", - "State": "Estado", - "regular": "normal", - "reserved": "reservado", - "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", - "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", - "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", - "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", - "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", - "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", - "This ticket is not an stowaway anymore": "El ticket id [{{ticketId}}]({{{ticketUrl}}}) ha dejado de ser un polizón", - "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", - "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", - "This ticket is deleted": "Este ticket está eliminado", - "Unable to clone this travel": "No ha sido posible clonar este travel", - "This thermograph id already exists": "La id del termógrafo ya existe", - "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", - "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", - "Invalid password": "Invalid password", - "Password does not meet requirements": "Password does not meet requirements", - "Role already assigned": "Role already assigned", - "Invalid role name": "Invalid role name", - "Role name must be written in camelCase": "Role name must be written in camelCase", - "Email already exists": "Email already exists", - "User already exists": "User already exists", - "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", - "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", - "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", - "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", - "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", - "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", - "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", - "agencyModeFk": "Agencia", - "clientFk": "Cliente", - "zoneFk": "Zona", - "warehouseFk": "Almacén", - "shipped": "F. envío", - "landed": "F. entrega", - "addressFk": "Consignatario", - "companyFk": "Empresa", - "The social name cannot be empty": "La razón social no puede quedar en blanco", - "The nif cannot be empty": "El NIF no puede quedar en blanco", - "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", - "ASSIGN_ZONE_FIRST": "Asigna una zona primero", - "Amount cannot be zero": "El importe no puede ser cero", - "Company has to be official": "Empresa inválida", - "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", - "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", - "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", - "Sorts whole route": "Reordena ruta entera", - "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", - "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", - "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", - "This BIC already exist.": "Este BIC ya existe.", - "That item doesn't exists": "Ese artículo no existe", - "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", - "Invalid account": "Cuenta inválida", - "Compensation account is empty": "La cuenta para compensar está vacia", - "This genus already exist": "Este genus ya existe", - "This specie already exist": "Esta especie ya existe", - "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", - "None": "Ninguno", - "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", - "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", - "This document already exists on this ticket": "Este documento ya existe en el ticket", - "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", - "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "nickname": "nickname", - "INACTIVE_PROVIDER": "Proveedor inactivo", - "This client is not invoiceable": "Este cliente no es facturable", - "serial non editable": "Esta serie no permite asignar la referencia", - "Max shipped required": "La fecha límite es requerida", - "Can't invoice to future": "No se puede facturar a futuro", - "Can't invoice to past": "No se puede facturar a pasado", - "This ticket is already invoiced": "Este ticket ya está facturado", - "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", - "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", - "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", - "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes", - "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", - "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", - "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente", - "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", - "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", - "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días", - "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", - "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", - "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", - "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "isWithoutNegatives": "Tiene Negativos" + "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", + "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", + "Amount cannot be zero": "Amount cannot be zero", + "Period cannot be blank": "Period cannot be blank", + "Sample type cannot be blank": "Sample type cannot be blank", + "Cannot be blank": "Cannot be blank", + "The social name cannot be empty": "The social name cannot be empty", + "The nif cannot be empty": "The nif cannot be empty", + "Concept cannot be blank": "Concept cannot be blank", + "Enter an integer different to zero": "Enter an integer different to zero", + "Package cannot be blank": "Package cannot be blank", + "State cannot be blank": "State cannot be blank", + "Worker cannot be blank": "Worker cannot be blank", + "Agency cannot be blank": "Agency cannot be blank" +} \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 2575bfdbe0..59cf1a38a1 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -133,13 +133,13 @@ module.exports = Self => { } } if (args.isWithoutNegatives) { - const query = `CALL ticket_getVisibleAvailable(?,?)`; + const query = `CALL ticket_getAdvanceable(?,?)`; const params = [args.id, args.shipped]; - const [salesAvailable] = await Self.rawSql(query, params, myOptions); + const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); let salesNewTicket = []; - salesAvailable.forEach(sale => { - if (sale.available >= sale.quantity) + salesAdvanceable.forEach(sale => { + if (sale.advanceable >= sale.quantity) salesNewTicket.push(sale); }); diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 9bcea8e7ce..f0b112deea 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -110,19 +110,15 @@ module.exports = Self => { totalDifference: 0.00, }; - // Get items available - let query = `CALL ticket_getVisibleAvailable(?,?)`; + // Get items advanceable + let query = `CALL ticket_getAdvanceable(?,?)`; let params = [args.id, args.shipped]; - const [salesAvailable] = await Self.rawSql(query, params, myOptions); + const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); - const itemAvailable = new Map(); - for (sale of salesAvailable) { - let available = sale.available; - if (available == null) - available = 0; - - itemAvailable.set(sale.id, available); - } + const itemAdvanceable = new Map(); + console.log(salesAdvanceable); + for (sale of salesAdvanceable) + itemAdvanceable.set(sale.id, sale.advanceable); // Sale price component, one per sale query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; @@ -147,7 +143,7 @@ module.exports = Self => { salesObj.totalUnitPrice += sale.price; salesObj.totalUnitPrice = round(salesObj.totalUnitPrice); - sale.available = itemAvailable.get(sale.id); + sale.advanceable = itemAdvanceable.get(sale.id); } if (tx) await tx.commit(); diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 74b160fdad..2987251898 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,7 +9,7 @@ Item Description - Available + Advanceable Quantity Price (PPU) New (PPU) @@ -35,8 +35,8 @@ - {{::sale.available}} + ng-class="{'alert': sale.quantity>sale.advanceable}"> + {{::sale.advanceable}} {{::sale.quantity}} diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index d770907818..db0bb6d448 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -69,7 +69,7 @@ class Controller extends Component { let haveNotNegatives = false; this.ticket.sale.items.forEach(item => { - if (item.quantity > item.available) + if (item.quantity > item.advanceable) haveNegatives = true; else haveNotNegatives = true; diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index 08bef3b09a..ccf1f55721 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -7,4 +7,5 @@ Price: Precio New price: Nuevo precio Price difference: Diferencia de precio Without create negatives: Sin crear negativos -Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. \ No newline at end of file +Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. +Advanceable: Avanzable \ No newline at end of file From 5824acf3bca08bd586e7639511d57d281a758816 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Jan 2022 10:12:13 +0100 Subject: [PATCH 11/16] change tests to advanceable --- loopback/locale/en.json | 3 ++- loopback/locale/es.json | 7 ++++++- modules/ticket/back/methods/ticket/priceDifference.js | 1 - .../back/methods/ticket/specs/priceDifference.spec.js | 4 ++-- modules/ticket/front/basic-data/step-two/index.spec.js | 4 ++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 7f3e18d728..d0f818426c 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -120,5 +120,6 @@ "This item is not available": "This item is not available", "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}", "The type of business must be filled in basic data": "The type of business must be filled in basic data", - "isWithoutNegatives": "isWithoutNegatives" + "isWithoutNegatives": "isWithoutNegatives", + "The worker has hours recorded that day": "The worker has hours recorded that day" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 3d5c205bd6..18552a96c6 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -19,5 +19,10 @@ "Package cannot be blank": "Package cannot be blank", "State cannot be blank": "State cannot be blank", "Worker cannot be blank": "Worker cannot be blank", - "Agency cannot be blank": "Agency cannot be blank" + "Agency cannot be blank": "Agency cannot be blank", + "nickname": "nickname", + "shipped": "shipped", + "landed": "landed", + "isWithoutNegatives": "isWithoutNegatives", + "Changed this data from the ticket": "Changed this data from the ticket" } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index f0b112deea..807c17f00b 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -116,7 +116,6 @@ module.exports = Self => { const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); const itemAdvanceable = new Map(); - console.log(salesAdvanceable); for (sale of salesAdvanceable) itemAdvanceable.set(sale.id, sale.advanceable); diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 8fe906bcfa..bc37e33cbc 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -83,8 +83,8 @@ describe('sale priceDifference()', () => { const firstItem = result.items[0]; const secondtItem = result.items[1]; - expect(firstItem.available).toEqual(410); - expect(secondtItem.available).toEqual(1870); + expect(firstItem.advanceable).toEqual(440); + expect(secondtItem.advanceable).toEqual(1980); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index fcd1d7e49e..0567785e98 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -73,12 +73,12 @@ describe('Ticket', () => { { item: 1, quantity: 2, - available: 1 + advanceable: 1 }, { item: 2, quantity: 1, - available: 5 + advanceable: 5 } ] } From 8e1c3e107c229d26b53cfbcc1d175a55b568ac22 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 18 Jan 2022 12:48:39 +0100 Subject: [PATCH 12/16] refactor(ticket): advanceable code --- db/changes/10410-january/00-ticket_getAdvancable.sql | 5 ++--- .../ticket/back/methods/ticket/componentUpdate.js | 12 ++++-------- .../ticket/back/methods/ticket/priceDifference.js | 6 +++--- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/db/changes/10410-january/00-ticket_getAdvancable.sql b/db/changes/10410-january/00-ticket_getAdvancable.sql index 599e431b34..b8d9337e34 100644 --- a/db/changes/10410-january/00-ticket_getAdvancable.sql +++ b/db/changes/10410-january/00-ticket_getAdvancable.sql @@ -2,7 +2,7 @@ DROP PROCEDURE IF EXISTS `vn`.`ticket_getAdvanceable`; DELIMITER $$ $$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getAdvanceable`(vTicketFk INT, vDatedNew DATETIME) +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getAdvanceable`(vTicketFk INT, vDatedNew DATETIME, vWarehouseFk INT) BEGIN /** * Cálcula el stock avanzable para los artículos de un ticket @@ -11,10 +11,9 @@ BEGIN * @param vDatedNew -> Nueva fecha * @return Sales con Avanzable */ - DECLARE vWarehouseFk INT; DECLARE vDatedOld DATETIME; - SELECT t.warehouseFk, t.shipped INTO vWarehouseFk, vDatedOld + SELECT t.shipped INTO vDatedOld FROM ticket t WHERE t.id = vTicketFk; diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 59cf1a38a1..64b02e2f2c 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -132,17 +132,13 @@ module.exports = Self => { throw new UserError(error); } } + if (args.isWithoutNegatives) { - const query = `CALL ticket_getAdvanceable(?,?)`; - const params = [args.id, args.shipped]; + const query = `CALL ticket_getAdvanceable(?,?,?)`; + const params = [args.id, args.shipped, args.warehouseFk]; const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); - let salesNewTicket = []; - salesAdvanceable.forEach(sale => { - if (sale.advanceable >= sale.quantity) - salesNewTicket.push(sale); - }); - + const salesNewTicket = salesAdvanceable.filter(sale => (sale.advanceable ?? 0) >= sale.quantity); if (salesNewTicket.length) { const newTicket = await models.Ticket.transferSales(ctx, args.id, null, salesNewTicket, myOptions); args.id = newTicket.id; diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 807c17f00b..e6688da969 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -111,13 +111,13 @@ module.exports = Self => { }; // Get items advanceable - let query = `CALL ticket_getAdvanceable(?,?)`; - let params = [args.id, args.shipped]; + let query = `CALL ticket_getAdvanceable(?,?,?)`; + let params = [args.id, args.shipped, args.warehouseId]; const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); const itemAdvanceable = new Map(); for (sale of salesAdvanceable) - itemAdvanceable.set(sale.id, sale.advanceable); + itemAdvanceable.set(sale.id, sale.advanceable ?? 0); // Sale price component, one per sale query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; From 9ddf11c6bc1305ad3289431a56f9c9f66556d72a Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 18 Jan 2022 12:49:16 +0100 Subject: [PATCH 13/16] test(ticket): update to advanceable --- .../05-ticket/06_basic_data_steps.spec.js | 8 +-- .../ticket/specs/componentUpdate.spec.js | 56 +++++++++++++++++++ .../ticket/specs/priceDifference.spec.js | 2 +- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index 6ae7029797..93c6bba657 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -8,7 +8,7 @@ describe('Ticket Edit basic data path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('employee', 'ticket'); + await page.loginAndModule('employee', 'ticket'); await page.accessToSearchResult('11'); await page.accessToSection('ticket.card.basicData.stepOne'); }); @@ -85,7 +85,7 @@ describe('Ticket Edit basic data path', () => { }); it(`should not find ticket`, async() => { - await page.doSearch('28'); + await page.doSearch('29'); const count = await page.countElement(selectors.ticketsIndex.searchResult); expect(count).toEqual(0); @@ -128,8 +128,8 @@ describe('Ticket Edit basic data path', () => { const expectedMonth = tomorrow.getMonth() + 1; const expectedYear = tomorrow.getFullYear(); - await page.loginAndModule('employee', 'ticket'); - await page.accessToSearchResult('28'); + await page.loginAndModule('employee', 'ticket'); + await page.accessToSearchResult('29'); await page.accessToSection('ticket.card.sale'); const item = await page.waitToGetProperty(selectors.ticketSales.firstSaleId, 'innerText'); diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index 38e6ce6a7d..2aa2a07c4c 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -136,4 +136,60 @@ describe('ticket componentUpdate()', () => { throw e; } }); + + it('should change warehouse and without negatives', async() => { + const tx = await models.SaleComponent.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const saleToTransfer = 27; + const originDate = today; + const newDate = tomorrow; + const ticketID = 14; + newDate.setHours(0, 0, 0, 0, 0); + originDate.setHours(0, 0, 0, 0, 0); + + const args = { + id: ticketID, + clientFk: 1104, + agencyModeFk: 2, + addressFk: 4, + zoneFk: 9, + warehouseFk: 1, + companyFk: 442, + shipped: newDate, + landed: tomorrow, + isDeleted: false, + option: 1, + isWithoutNegatives: true + }; + + const ctx = { + args: args, + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } + } + }; + await models.Ticket.componentUpdate(ctx, options); + + const [newTicketID] = await models.Ticket.rawSql('SELECT MAX(id) as id FROM ticket', null, options); + const oldTicket = await models.Ticket.findById(ticketID, null, options); + const newTicket = await models.Ticket.findById(newTicketID.id, null, options); + const newTicketSale = await models.Sale.findOne({where: {ticketFk: args.id}}, options); + + expect(oldTicket.shipped).toEqual(originDate); + expect(newTicket.shipped).toEqual(newDate); + expect(newTicketSale.id).toEqual(saleToTransfer); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index bc37e33cbc..362c3e923e 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -60,7 +60,7 @@ describe('sale priceDifference()', () => { expect(error).toEqual(new UserError(`The sales of this ticket can't be modified`)); }); - it('should return ticket available', async() => { + it('should return ticket advanceable', async() => { const tx = await models.Ticket.beginTransaction({}); try { From f8a00943216a0b37f58829f95415a2fa4a3db396 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 26 Jan 2022 08:54:48 +0100 Subject: [PATCH 14/16] word movible --- .../10410-january/00-ticket_getAdvancable.sql | 10 +++++----- .../ticket/back/methods/ticket/componentUpdate.js | 6 +++--- .../ticket/back/methods/ticket/priceDifference.js | 14 +++++++------- .../methods/ticket/specs/priceDifference.spec.js | 6 +++--- .../ticket/front/basic-data/step-two/index.html | 6 +++--- modules/ticket/front/basic-data/step-two/index.js | 2 +- .../ticket/front/basic-data/step-two/index.spec.js | 4 ++-- .../ticket/front/basic-data/step-two/locale/es.yml | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/db/changes/10410-january/00-ticket_getAdvancable.sql b/db/changes/10410-january/00-ticket_getAdvancable.sql index b8d9337e34..5f5b0a93a3 100644 --- a/db/changes/10410-january/00-ticket_getAdvancable.sql +++ b/db/changes/10410-january/00-ticket_getAdvancable.sql @@ -1,15 +1,15 @@ -DROP PROCEDURE IF EXISTS `vn`.`ticket_getAdvanceable`; +DROP PROCEDURE IF EXISTS `vn`.`ticket_getMovable`; DELIMITER $$ $$ -CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getAdvanceable`(vTicketFk INT, vDatedNew DATETIME, vWarehouseFk INT) +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getMovable`(vTicketFk INT, vDatedNew DATETIME, vWarehouseFk INT) BEGIN /** - * Cálcula el stock avanzable para los artículos de un ticket + * Cálcula el stock movible para los artículos de un ticket * * @param vTicketFk -> Ticket * @param vDatedNew -> Nueva fecha - * @return Sales con Avanzable + * @return Sales con Movible */ DECLARE vDatedOld DATETIME; @@ -29,7 +29,7 @@ BEGIN s.discount, i.image, i.subName, - il.stock + IFNULL(im.amount, 0) AS advanceable + il.stock + IFNULL(im.amount, 0) AS movable FROM ticket t JOIN sale s ON s.ticketFk = t.id JOIN item i ON i.id = s.itemFk diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 64b02e2f2c..e01798887d 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -134,11 +134,11 @@ module.exports = Self => { } if (args.isWithoutNegatives) { - const query = `CALL ticket_getAdvanceable(?,?,?)`; + const query = `CALL ticket_getMovable(?,?,?)`; const params = [args.id, args.shipped, args.warehouseFk]; - const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); + const [salesMovable] = await Self.rawSql(query, params, myOptions); - const salesNewTicket = salesAdvanceable.filter(sale => (sale.advanceable ?? 0) >= sale.quantity); + const salesNewTicket = salesMovable.filter(sale => (sale.movable ?? 0) >= sale.quantity); if (salesNewTicket.length) { const newTicket = await models.Ticket.transferSales(ctx, args.id, null, salesNewTicket, myOptions); args.id = newTicket.id; diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index e6688da969..ffcdc19ef1 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -110,14 +110,14 @@ module.exports = Self => { totalDifference: 0.00, }; - // Get items advanceable - let query = `CALL ticket_getAdvanceable(?,?,?)`; + // Get items movable + let query = `CALL ticket_getMovable(?,?,?)`; let params = [args.id, args.shipped, args.warehouseId]; - const [salesAdvanceable] = await Self.rawSql(query, params, myOptions); + const [salesMovable] = await Self.rawSql(query, params, myOptions); - const itemAdvanceable = new Map(); - for (sale of salesAdvanceable) - itemAdvanceable.set(sale.id, sale.advanceable ?? 0); + const itemMovable = new Map(); + for (sale of salesMovable) + itemMovable.set(sale.id, sale.movable ?? 0); // Sale price component, one per sale query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; @@ -142,7 +142,7 @@ module.exports = Self => { salesObj.totalUnitPrice += sale.price; salesObj.totalUnitPrice = round(salesObj.totalUnitPrice); - sale.advanceable = itemAdvanceable.get(sale.id); + sale.movable = itemMovable.get(sale.id); } if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 362c3e923e..6659ed26e7 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -60,7 +60,7 @@ describe('sale priceDifference()', () => { expect(error).toEqual(new UserError(`The sales of this ticket can't be modified`)); }); - it('should return ticket advanceable', async() => { + it('should return ticket movable', async() => { const tx = await models.Ticket.beginTransaction({}); try { @@ -83,8 +83,8 @@ describe('sale priceDifference()', () => { const firstItem = result.items[0]; const secondtItem = result.items[1]; - expect(firstItem.advanceable).toEqual(440); - expect(secondtItem.advanceable).toEqual(1980); + expect(firstItem.movable).toEqual(440); + expect(secondtItem.movable).toEqual(1980); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 2987251898..88475daa24 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,7 +9,7 @@ Item Description - Advanceable + Movable Quantity Price (PPU) New (PPU) @@ -35,8 +35,8 @@ - {{::sale.advanceable}} + ng-class="{'alert': sale.quantity>sale.movable}"> + {{::sale.movable}} {{::sale.quantity}} diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index db0bb6d448..2daa98af98 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -69,7 +69,7 @@ class Controller extends Component { let haveNotNegatives = false; this.ticket.sale.items.forEach(item => { - if (item.quantity > item.advanceable) + if (item.quantity > item.movable) haveNegatives = true; else haveNotNegatives = true; diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index 0567785e98..0c299521bf 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -73,12 +73,12 @@ describe('Ticket', () => { { item: 1, quantity: 2, - advanceable: 1 + movable: 1 }, { item: 2, quantity: 1, - advanceable: 5 + movable: 5 } ] } diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index ccf1f55721..1a7427d2ec 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -8,4 +8,4 @@ New price: Nuevo precio Price difference: Diferencia de precio Without create negatives: Sin crear negativos Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. -Advanceable: Avanzable \ No newline at end of file +Movable: Movible \ No newline at end of file From b25ffa8feb80a1f3fd1d844356433fe7c746d3e6 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 28 Jan 2022 09:15:41 +0100 Subject: [PATCH 15/16] feat(ticket_step-two): redirect to new ticket --- ...dvancable.sql => 00-ticket_getMovable.sql} | 0 .../05-ticket/06_basic_data_steps.spec.js | 66 +++--- loopback/locale/es.json | 222 ++++++++++++++++-- .../back/methods/ticket/componentUpdate.js | 5 +- .../back/methods/ticket/priceDifference.js | 8 +- .../ticket/specs/priceDifference.spec.js | 3 + .../front/basic-data/step-two/index.html | 4 +- .../ticket/front/basic-data/step-two/index.js | 20 +- .../front/basic-data/step-two/index.spec.js | 77 +++++- 9 files changed, 329 insertions(+), 76 deletions(-) rename db/changes/10410-january/{00-ticket_getAdvancable.sql => 00-ticket_getMovable.sql} (100%) diff --git a/db/changes/10410-january/00-ticket_getAdvancable.sql b/db/changes/10410-january/00-ticket_getMovable.sql similarity index 100% rename from db/changes/10410-january/00-ticket_getAdvancable.sql rename to db/changes/10410-january/00-ticket_getMovable.sql diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index 93c6bba657..7a09edf06d 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -92,59 +92,53 @@ describe('Ticket Edit basic data path', () => { }); it(`should split ticket without negatives`, async() => { - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); + const newAgency = 'Silla247'; + const newDate = new Date(); + newDate.setDate(newDate.getDate() + 1); await page.accessToSearchResult('14'); await page.accessToSection('ticket.card.basicData.stepOne'); - const originalDate = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); - const originalAgency = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); - - await page.autocompleteSearch(selectors.ticketBasicData.agency, 'Silla247'); - await page.pickDate(selectors.ticketBasicData.shipped, tomorrow); + await page.autocompleteSearch(selectors.ticketBasicData.agency, newAgency); + await page.pickDate(selectors.ticketBasicData.shipped, newDate); await page.waitToClick(selectors.ticketBasicData.nextStepButton); await page.waitToClick(selectors.ticketBasicData.withoutNegatives); await page.waitToClick(selectors.ticketBasicData.finalizeButton); - const resultDate = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); - const resultAgency = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + await page.waitForState('ticket.card.summary'); - expect(resultDate).toEqual(originalDate); - expect(resultAgency).toEqual(originalAgency); + const newTicketAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + const newTicketDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + + expect(newAgency).toEqual(newTicketAgency); + expect(newTicketDate).toContain(newDate.getDate()); }); - it(`should new ticket have one line from splited ticket`, async() => { - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - - const expectedDay = tomorrow.getDate(); - const expectedMonth = tomorrow.getMonth() + 1; - const expectedYear = tomorrow.getFullYear(); - - await page.loginAndModule('employee', 'ticket'); - await page.accessToSearchResult('29'); + it(`should new ticket have sale of old ticket`, async() => { await page.accessToSection('ticket.card.sale'); + await page.waitForState('ticket.card.sale'); const item = await page.waitToGetProperty(selectors.ticketSales.firstSaleId, 'innerText'); - const agency = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); - let date = await page - .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); - - date = date.split(' '); - date = date[0].split('/'); expect(item).toEqual('4'); - expect(agency).toEqual('Silla247'); - expect(parseInt(date[0])).toEqual(expectedDay); - expect(parseInt(date[1])).toEqual(expectedMonth); - expect(parseInt(date[2])).toEqual(expectedYear); + }); + + it(`should old ticket have old date and agency`, async() => { + const oldDate = new Date(); + const oldAgency = 'Super-Man delivery'; + + await page.accessToSearchResult('14'); + + const oldTicketAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + const oldTicketDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + + expect(oldTicketAgency).toEqual(oldAgency); + expect(oldTicketDate).toContain(oldDate.getDate()); }); }); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index c8be37d638..493b45c321 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -1,30 +1,201 @@ { - "Name cannot be blank": "Name cannot be blank", - "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", - "Street cannot be empty": "Street cannot be empty", - "City cannot be empty": "City cannot be empty", - "Invalid email": "Invalid email", - "Phone cannot be blank": "Phone cannot be blank", + "Phone format is invalid": "El formato del teléfono no es correcto", + "You are not allowed to change the credit": "No tienes privilegios para modificar el crédito", + "Unable to mark the equivalence surcharge": "No se puede marcar el recargo de equivalencia", + "The default consignee can not be unchecked": "No se puede desmarcar el consignatario predeterminado", + "Unable to default a disabled consignee": "No se puede poner predeterminado un consignatario desactivado", + "Can't be blank": "No puede estar en blanco", + "Invalid TIN": "NIF/CIF invalido", + "TIN must be unique": "El NIF/CIF debe ser único", + "A client with that Web User name already exists": "Ya existe un cliente con ese Usuario Web", + "Is invalid": "Is invalid", + "Quantity cannot be zero": "La cantidad no puede ser cero", + "Enter an integer different to zero": "Introduce un entero distinto de cero", + "Package cannot be blank": "El embalaje no puede estar en blanco", + "The company name must be unique": "La razón social debe ser única", + "Invalid email": "Correo electrónico inválido", + "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", + "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", + "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", + "State cannot be blank": "El estado no puede estar en blanco", + "Worker cannot be blank": "El trabajador no puede estar en blanco", + "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", + "can't be blank": "El campo no puede estar vacío", + "Observation type must be unique": "El tipo de observación no puede repetirse", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", - "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", - "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", - "Amount cannot be zero": "Amount cannot be zero", - "Period cannot be blank": "Period cannot be blank", - "Sample type cannot be blank": "Sample type cannot be blank", - "Cannot be blank": "Cannot be blank", - "The social name cannot be empty": "The social name cannot be empty", - "The nif cannot be empty": "The nif cannot be empty", - "Concept cannot be blank": "Concept cannot be blank", - "Enter an integer different to zero": "Enter an integer different to zero", - "Package cannot be blank": "Package cannot be blank", - "State cannot be blank": "State cannot be blank", - "Worker cannot be blank": "Worker cannot be blank", - "Agency cannot be blank": "Agency cannot be blank", + "The grade must be similar to the last one": "El grade debe ser similar al último", + "Only manager can change the credit": "Solo el gerente puede cambiar el credito de este cliente", + "Name cannot be blank": "El nombre no puede estar en blanco", + "Phone cannot be blank": "El teléfono no puede estar en blanco", + "Period cannot be blank": "El periodo no puede estar en blanco", + "Choose a company": "Selecciona una empresa", + "Se debe rellenar el campo de texto": "Se debe rellenar el campo de texto", + "Description should have maximum of 45 characters": "La descripción debe tener maximo 45 caracteres", + "Cannot be blank": "El campo no puede estar en blanco", + "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 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", + "You can't create an order for a frozen client": "No puedes crear una orden para un cliente congelado", + "You can't create an order for a client that has a debt": "No puedes crear una orden para un cliente con deuda", + "is not a valid date": "No es una fecha valida", + "Barcode must be unique": "El código de barras debe ser único", + "The warehouse can't be repeated": "El almacén no puede repetirse", + "The tag can't be repeated": "El tag no puede repetirse", + "The observation type can't be repeated": "El tipo de observación no puede repetirse", + "A claim with that sale already exists": "Ya existe una reclamación para esta línea", + "You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo", + "Warehouse cannot be blank": "El almacén no puede quedar en blanco", + "Agency cannot be blank": "La agencia no puede quedar en blanco", + "You can't make changes on a client with verified data": "No puedes hacer cambios en un cliente con datos comprobados", + "This address doesn't exist": "Este consignatario no existe", + "You must delete the claim id %d first": "Antes debes borrar la reclamación %d", + "You don't have enough privileges": "No tienes suficientes permisos", + "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", + "You can't make changes on the basic data of an confirmed order or with rows": "No puedes cambiar los datos basicos de una orden con artículos", + "INVALID_USER_NAME": "El nombre de usuario solo debe contener letras minúsculas o, a partir del segundo carácter, números o subguiones, no esta permitido el uso de la letra ñ", + "You can't create a ticket for a frozen client": "No puedes crear un ticket para un cliente congelado", + "You can't create a ticket for a inactive client": "No puedes crear un ticket para un cliente inactivo", + "Tag value cannot be blank": "El valor del tag no puede quedar en blanco", + "ORDER_EMPTY": "Cesta vacía", + "You don't have enough privileges to do that": "No tienes permisos para cambiar esto", + "NO SE PUEDE DESACTIVAR EL CONSIGNAT": "NO SE PUEDE DESACTIVAR EL CONSIGNAT", + "Error. El NIF/CIF está repetido": "Error. El NIF/CIF está repetido", + "Street cannot be empty": "Dirección no puede estar en blanco", + "City cannot be empty": "Cuidad no puede estar en blanco", + "Code cannot be blank": "Código no puede estar en blanco", + "You cannot remove this department": "No puedes eliminar este departamento", + "The extension must be unique": "La extensión debe ser unica", + "The secret can't be blank": "La contraseña no puede estar en blanco", + "We weren't able to send this SMS": "No hemos podido enviar el SMS", + "This client can't be invoiced": "Este cliente no puede ser facturado", + "This ticket can't be invoiced": "Este ticket no puede ser facturado", + "You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado", + "This ticket can not be modified": "Este ticket no puede ser modificado", + "The introduced hour already exists": "Esta hora ya ha sido introducida", + "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", + "The sales of the current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", + "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", + "NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros", + "ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado", + "The current ticket can't be modified": "El ticket actual no puede ser modificado", + "The current claim can't be modified": "La reclamación actual no puede ser modificada", + "The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", + "Sale(s) blocked, contact production": "Linea(s) bloqueada(s), contacte con produccion", + "Please select at least one sale": "Por favor selecciona al menos una linea", + "All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket", + "NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "This item doesn't exists": "El artículo no existe", + "NOT_ZONE_WITH_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada", + "Extension format is invalid": "El formato de la extensión es inválido", + "Invalid parameters to create a new ticket": "Parámetros inválidos para crear un nuevo ticket", + "This item is not available": "Este artículo no está disponible", + "This postcode already exists": "Este código postal ya existe", + "Concept cannot be blank": "El concepto no puede quedar en blanco", + "File doesn't exists": "El archivo no existe", + "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias", + "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", + "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", + "Weekday cannot be blank": "El día de la semana no puede quedar en blanco", + "You can't delete a confirmed order": "No puedes borrar un pedido confirmado", + "Can't create stowaway for this ticket": "No se puede crear un polizon para este ticket", + "The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto", + "Invalid quantity": "Cantidad invalida", + "This postal code is not valid": "This postal code is not valid", + "is invalid": "is invalid", + "The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto", + "The department name can't be repeated": "El nombre del departamento no puede repetirse", + "This phone already exists": "Este teléfono ya existe", + "You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos", + "You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado", + "You cannot delete a ticket that part of it is being prepared": "No puedes eliminar un ticket en el que una parte que está siendo preparada", + "You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero", + "You should specify a date": "Debes especificar una fecha", + "You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín", + "Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín", + "You should mark at least one week day": "Debes marcar al menos un día de la semana", + "Swift / BIC can't be empty": "Swift / BIC no puede estar vacío", + "Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios", + "Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios", + "Deleted sales from ticket": "He eliminado las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{deletions}}}", + "Added sale to ticket": "He añadido la siguiente linea al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}", + "Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})", + "State": "Estado", + "regular": "normal", + "reserved": "reservado", + "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", + "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", + "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", + "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", + "Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", + "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", + "This ticket is not an stowaway anymore": "El ticket id [{{ticketId}}]({{{ticketUrl}}}) ha dejado de ser un polizón", + "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", + "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", + "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", + "This ticket is deleted": "Este ticket está eliminado", + "Unable to clone this travel": "No ha sido posible clonar este travel", + "This thermograph id already exists": "La id del termógrafo ya existe", + "Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante", + "ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED", + "Invalid password": "Invalid password", + "Password does not meet requirements": "Password does not meet requirements", + "Role already assigned": "Role already assigned", + "Invalid role name": "Invalid role name", + "Role name must be written in camelCase": "Role name must be written in camelCase", + "Email already exists": "Email already exists", + "User already exists": "User already exists", + "Absence change notification on the labour calendar": "Notificacion de cambio de ausencia en el calendario laboral", + "Created absence": "El empleado {{author}} ha añadido una ausencia de tipo '{{absenceType}}' a {{employee}} para el día {{dated}}.", + "Deleted absence": "El empleado {{author}} ha eliminado una ausencia de tipo '{{absenceType}}' a {{employee}} del día {{dated}}.", + "I have deleted the ticket id": "He eliminado el ticket id [{{id}}]({{{url}}})", + "I have restored the ticket id": "He restaurado el ticket id [{{id}}]({{{url}}})", + "You can only restore a ticket within the first hour after deletion": "Únicamente puedes restaurar el ticket dentro de la primera hora después de su eliminación", + "Changed this data from the ticket": "He cambiado estos datos del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", + "agencyModeFk": "Agencia", + "clientFk": "Cliente", + "zoneFk": "Zona", + "warehouseFk": "Almacén", + "shipped": "F. envío", + "landed": "F. entrega", + "addressFk": "Consignatario", + "companyFk": "Empresa", + "The social name cannot be empty": "La razón social no puede quedar en blanco", + "The nif cannot be empty": "El NIF no puede quedar en blanco", + "You need to fill sage information before you check verified data": "Debes rellenar la información de sage antes de marcar datos comprobados", + "ASSIGN_ZONE_FIRST": "Asigna una zona primero", + "Amount cannot be zero": "El importe no puede ser cero", + "Company has to be official": "Empresa inválida", + "You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria", + "Action not allowed on the test environment": "Esta acción no está permitida en el entorno de pruebas", + "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", + "Sorts whole route": "Reordena ruta entera", + "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", + "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", + "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", + "This BIC already exist.": "Este BIC ya existe.", + "That item doesn't exists": "Ese artículo no existe", + "There's a new urgent ticket:": "Hay un nuevo ticket urgente:", + "Invalid account": "Cuenta inválida", + "Compensation account is empty": "La cuenta para compensar está vacia", + "This genus already exist": "Este genus ya existe", + "This specie already exist": "Esta especie ya existe", + "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "None": "Ninguno", + "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", + "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", + "This document already exists on this ticket": "Este documento ya existe en el ticket", + "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", + "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", "nickname": "nickname", - "shipped": "shipped", - "landed": "landed", - "isWithoutNegatives": "isWithoutNegatives", - "Changed this data from the ticket": "Changed this data from the ticket", "INACTIVE_PROVIDER": "Proveedor inactivo", "This client is not invoiceable": "Este cliente no es facturable", "serial non editable": "Esta serie no permite asignar la referencia", @@ -47,5 +218,6 @@ "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create pay back": "No tienes permisos para crear un abono" + "You don't have privileges to create pay back": "No tienes permisos para crear un abono", + "isWithoutNegatives": "isWithoutNegatives" } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index e01798887d..083abc47d6 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -175,7 +175,7 @@ module.exports = Self => { // Force to unroute ticket const hasToBeUnrouted = true; const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - const res = await Self.rawSql(query, [ + let res = await Self.rawSql(query, [ args.id, args.clientFk, args.nickname, @@ -248,8 +248,9 @@ module.exports = Self => { await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); } + res.id = args.id; if (tx) await tx.commit(); - + return res; } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index ffcdc19ef1..c91956ece0 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -111,6 +111,12 @@ module.exports = Self => { }; // Get items movable + const ticketOrigin = await models.Ticket.findById(args.id, null, myOptions); + const differenceShipped = ticketOrigin.shipped.getTime() != args.shipped.getTime(); + const differenceWarehouse = ticketOrigin.warehouseFk != args.warehouseId; + + salesObj.haveDifferences = differenceShipped || differenceWarehouse; + let query = `CALL ticket_getMovable(?,?,?)`; let params = [args.id, args.shipped, args.warehouseId]; const [salesMovable] = await Self.rawSql(query, params, myOptions); @@ -146,7 +152,7 @@ module.exports = Self => { } if (tx) await tx.commit(); - + return salesObj; } catch (e) { if (tx) await tx.rollback(); diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 6659ed26e7..e9aa5030a1 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -15,6 +15,7 @@ describe('sale priceDifference()', () => { ctx.args = { id: 16, landed: tomorrow, + shipped: tomorrow, addressId: 126, agencyModeId: 7, zoneId: 3, @@ -45,6 +46,7 @@ describe('sale priceDifference()', () => { ctx.args = { id: 1, landed: new Date(), + shipped: new Date(), addressId: 121, zoneId: 3, warehouseId: 1 @@ -72,6 +74,7 @@ describe('sale priceDifference()', () => { const ctx = {req: {accessToken: {userId: 1106}}}; ctx.args = { id: 11, + shipped: tomorrow, landed: tomorrow, addressId: 122, agencyModeId: 7, diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 88475daa24..93012c7207 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,7 +9,7 @@ Item Description - Movable + Movable Quantity Price (PPU) New (PPU) @@ -32,7 +32,7 @@ tabindex="-1"> - + diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 2daa98af98..c12647aa5c 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -67,6 +67,7 @@ class Controller extends Component { ticketHaveNegatives() { let haveNegatives = false; let haveNotNegatives = false; + const haveDifferences = this.ticket.sale.haveDifferences; this.ticket.sale.items.forEach(item => { if (item.quantity > item.movable) @@ -76,7 +77,7 @@ class Controller extends Component { }); this.ticket.withoutNegatives = false; - this.haveNegatives = (haveNegatives && haveNotNegatives); + this.haveNegatives = (haveNegatives && haveNotNegatives && haveDifferences); } onSubmit() { @@ -102,13 +103,16 @@ class Controller extends Component { isWithoutNegatives: this.ticket.withoutNegatives }; - this.$http.post(query, params).then(res => { - this.vnApp.showMessage( - this.$t(`The ticket has been unrouted`) - ); - this.card.reload(); - this.$state.go('ticket.card.summary', {id: this.$params.id}); - }); + this.$http.post(query, params) + .then(res => { + this.ticketToMove = res.data.id; + this.vnApp.showMessage( + this.$t(`The ticket has been unrouted`) + ); + }) + .finally(() => { + this.$state.go('ticket.card.summary', {id: this.ticketToMove}); + }); } } diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index 0c299521bf..ac85a7818b 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -66,7 +66,7 @@ describe('Ticket', () => { }); describe('ticketHaveNegatives()', () => { - it('should show if ticket have any negative and any not negative', () => { + it('should show if ticket have any negative, have differences, but not all sale are negative', () => { controller.ticket = { sale: { items: [ @@ -80,7 +80,8 @@ describe('Ticket', () => { quantity: 1, movable: 5 } - ] + ], + haveDifferences: true } }; @@ -88,6 +89,78 @@ describe('Ticket', () => { expect(controller.haveNegatives).toEqual(true); }); + + it('should not show if ticket not have any negative', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 2, + movable: 1 + } + ], + haveDifferences: true + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); + + it('should not show if all sale are negative', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 2, + movable: 1 + } + ], + haveDifferences: true + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); + + it('should not show if ticket not have differences', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 1, + movable: 2 + } + ], + haveDifferences: false + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); }); }); }); From 60adb6f37c859b4c1d65d4f002b614c1ca5bd885 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 1 Feb 2022 07:21:34 +0100 Subject: [PATCH 16/16] translations --- loopback/locale/en.json | 1 - loopback/locale/es.json | 3 +-- modules/ticket/back/methods/ticket/componentUpdate.js | 2 +- modules/ticket/front/basic-data/step-two/index.html | 2 +- modules/ticket/front/basic-data/step-two/locale/es.yml | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index d0f818426c..7d675cb13d 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -120,6 +120,5 @@ "This item is not available": "This item is not available", "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}", "The type of business must be filled in basic data": "The type of business must be filled in basic data", - "isWithoutNegatives": "isWithoutNegatives", "The worker has hours recorded that day": "The worker has hours recorded that day" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 493b45c321..4c11611e3b 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -218,6 +218,5 @@ "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create pay back": "No tienes permisos para crear un abono", - "isWithoutNegatives": "isWithoutNegatives" + "You don't have privileges to create pay back": "No tienes permisos para crear un abono" } \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 083abc47d6..de06212c76 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -175,7 +175,7 @@ module.exports = Self => { // Force to unroute ticket const hasToBeUnrouted = true; const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - let res = await Self.rawSql(query, [ + const res = await Self.rawSql(query, [ args.id, args.clientFk, args.nickname, diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 93012c7207..092c9e7462 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -77,7 +77,7 @@
diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index 1a7427d2ec..e1f1e0bfc2 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -6,6 +6,6 @@ The ticket has been unrouted: El ticket ha sido desenrutado Price: Precio New price: Nuevo precio Price difference: Diferencia de precio -Without create negatives: Sin crear negativos +Create without negatives: Crear sin negativos Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. Movable: Movible \ No newline at end of file