diff --git a/back/methods/collection/getTickets.js b/back/methods/collection/getTickets.js new file mode 100644 index 000000000..445fc070d --- /dev/null +++ b/back/methods/collection/getTickets.js @@ -0,0 +1,146 @@ + +module.exports = Self => { + Self.remoteMethodCtx('getTickets', { + description: 'Make a new collection of tickets', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + description: 'The collection id', + required: true, + http: {source: 'path'} + }, { + arg: 'print', + type: 'boolean', + description: 'True if you want to print' + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:id/getTickets`, + verb: 'POST' + } + }); + + Self.getTickets = async(ctx, id, print, options) => { + const userId = ctx.req.accessToken.userId; + const origin = ctx.req.headers.origin; + const $t = ctx.req.__; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + myOptions.userId = userId; + + const promises = []; + + const [tickets] = await Self.rawSql(`CALL vn.collection_getTickets(?)`, [id], myOptions); + const sales = await Self.rawSql(` + SELECT s.ticketFk, + sgd.saleGroupFk, + s.id saleFk, + s.itemFk, + i.longName, + i.size, + ic.color, + o.code origin, + ish.packing, + ish.grouping, + s.isAdded, + s.originalQuantity, + s.quantity saleQuantity, + iss.quantity reservedQuantity, + SUM(iss.quantity) OVER (PARTITION BY s.id ORDER BY ish.id) accumulatedQuantity, + ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY pickingOrder) currentItemShelving, + COUNT(*) OVER (PARTITION BY s.id ORDER BY s.id) totalItemShelving, + sh.code, + IFNULL(p2.code, p.code) parkingCode, + IFNULL(p2.pickingOrder, p.pickingOrder) pickingOrder, + iss.id itemShelvingSaleFk, + iss.isPicked + FROM ticketCollection tc + LEFT JOIN collection c ON c.id = tc.collectionFk + JOIN ticket t ON t.id = tc.ticketFk + JOIN sale s ON s.ticketFk = t.id + LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id + LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk + LEFT JOIN parking p2 ON p2.id = sg.parkingFk + JOIN item i ON i.id = s.itemFk + LEFT JOIN itemShelvingSale iss ON iss.saleFk = s.id + LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk + LEFT JOIN shelving sh ON sh.code = ish.shelvingFk + LEFT JOIN parking p ON p.id = sh.parkingFk + LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk + LEFT JOIN origin o ON o.id = i.originFk + WHERE tc.collectionFk = ? + GROUP BY ish.id, p.code, p2.code + ORDER BY pickingOrder;`, [id], myOptions); + + if (print) + await Self.rawSql(`CALL vn.collection_printSticker(?, ?)`, [id, null], myOptions); + + const collection = {collectionFk: id, tickets: []}; + if (tickets && tickets.length) { + for (const ticket of tickets) { + const ticketId = ticket.ticketFk; + + // SEND ROCKET + if (ticket.observaciones != '') { + for (observation of ticket.observaciones.split(' ')) { + if (['#', '@'].includes(observation.charAt(0))) { + promises.push(Self.app.models.Chat.send(ctx, observation, + $t('The ticket is in preparation', { + ticketId: ticketId, + ticketUrl: `${origin}/#!/ticket/${ticketId}/summary`, + salesPersonId: ticket.salesPersonFk + }))); + } + } + } + + // SET COLLECTION + if (sales && sales.length) { + // GET BARCODES + const barcodes = await Self.rawSql(` + SELECT s.id saleFk, b.code, c.id + FROM vn.sale s + LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk + LEFT JOIN vn.buy c ON c.itemFk = s.itemFk + LEFT JOIN vn.entry e ON e.id = c.entryFk + LEFT JOIN vn.travel tr ON tr.id = e.travelFk + WHERE s.ticketFk = ? + AND tr.landed >= util.VN_CURDATE() - INTERVAL 1 YEAR`, + [ticketId], myOptions); + + // BINDINGS + ticket.sales = []; + for (const sale of sales) { + if (sale.ticketFk === ticketId) { + sale.Barcodes = []; + + if (barcodes && barcodes.length) { + for (const barcode of barcodes) { + if (barcode.saleFk === sale.saleFk) { + for (const prop in barcode) { + if (['id', 'code'].includes(prop) && barcode[prop]) + sale.Barcodes.push(barcode[prop].toString(), '0' + barcode[prop]); + } + } + } + } + + ticket.sales.push(sale); + } + } + } + collection.tickets.push(ticket); + } + } + await Promise.all(promises); + + return collection; + }; +}; diff --git a/back/methods/collection/spec/getTickets.spec.js b/back/methods/collection/spec/getTickets.spec.js new file mode 100644 index 000000000..e6b9e6a17 --- /dev/null +++ b/back/methods/collection/spec/getTickets.spec.js @@ -0,0 +1,39 @@ +const models = require('vn-loopback/server/server').models; + +describe('collection getTickets()', () => { + let ctx; + beforeAll(async() => { + ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'} + } + }; + }); + + it('should get tickets, sales and barcodes from collection', async() => { + const tx = await models.Collection.beginTransaction({}); + + try { + const options = {transaction: tx}; + const collectionId = 1; + + const collectionTickets = await models.Collection.getTickets(ctx, collectionId, null, options); + + expect(collectionTickets.collectionFk).toEqual(collectionId); + expect(collectionTickets.tickets.length).toEqual(3); + expect(collectionTickets.tickets[0].ticketFk).toEqual(1); + expect(collectionTickets.tickets[1].ticketFk).toEqual(2); + expect(collectionTickets.tickets[2].ticketFk).toEqual(23); + expect(collectionTickets.tickets[0].sales[0].ticketFk).toEqual(1); + expect(collectionTickets.tickets[0].sales[1].ticketFk).toEqual(1); + expect(collectionTickets.tickets[0].sales[2].ticketFk).toEqual(1); + expect(collectionTickets.tickets[0].sales[0].Barcodes.length).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/back/models/collection.js b/back/models/collection.js index a41742ee7..bfa906af6 100644 --- a/back/models/collection.js +++ b/back/models/collection.js @@ -4,4 +4,5 @@ module.exports = Self => { require('../methods/collection/getSectors')(Self); require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/previousLabel')(Self); + require('../methods/collection/getTickets')(Self); }; diff --git a/db/changes/233802/.gitkeep b/db/changes/233802/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/db/changes/233802/00-collectionGetTicketsACL.sql b/db/changes/233802/00-collectionGetTicketsACL.sql new file mode 100644 index 000000000..06b584386 --- /dev/null +++ b/db/changes/233802/00-collectionGetTicketsACL.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL`(model, property, accessType, permission, principalType, principalId) + VALUES + ('Collection', 'getTickets', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/234201/00-supplierAccountCheckLength.sql b/db/changes/234201/00-supplierAccountCheckLength.sql new file mode 100644 index 000000000..55a68e37b --- /dev/null +++ b/db/changes/234201/00-supplierAccountCheckLength.sql @@ -0,0 +1,6 @@ +UPDATE `vn`.`supplier` + SET account = LPAD(id,10,'0') + WHERE account IS NULL; + +ALTER TABLE `vn`.`supplier` ADD CONSTRAINT supplierAccountTooShort CHECK (LENGTH(account) = 10); +ALTER TABLE `vn`.`supplier` MODIFY COLUMN account varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT 4100000000 NOT NULL COMMENT 'Default accounting code for suppliers.'; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index eb28c4a01..b6c89bd40 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1409,10 +1409,8 @@ INSERT INTO `cache`.`cache_calc`(`id`, `cache_id`, `cacheName`, `params`, `last_ INSERT INTO `vn`.`ticketWeekly`(`ticketFk`, `weekDay`) VALUES - (1, 0), (2, 1), (3, 2), - (4, 4), (5, 6), (15, 6); @@ -2834,24 +2832,24 @@ UPDATE `account`.`user` INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`) VALUES - (7, 18, 'update', 'Sale', '{"quantity":1}', '{"quantity":10}', 1, NULL), - (7, 18, 'update', 'Ticket', '{"quantity":1,"concept":"Chest ammo box"}', '{"quantity":10,"concept":"Chest ammo box"}', 1, NULL), - (7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 1, NULL), + (7, 18, 'update', 'Sale', '{"quantity":1}', '{"quantity":10}', 22, NULL), + (7, 18, 'update', 'Ticket', '{"quantity":1,"concept":"Chest ammo box"}', '{"quantity":10,"concept":"Chest ammo box"}', 22, NULL), + (7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 22, NULL), (7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 100cm de '5' a '10'"), - (16, 9, 'update', 'Sale', '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', '{"quantity":8,"concept":"Shield", "price": 10.5, "itemFk": 1}' , 5689, 'Shield'); + (16, 9, 'update', 'Sale', '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', '{"quantity":8,"concept":"Shield", "price": 10.5, "itemFk": 1}' , 12, 'Shield'); INSERT INTO `vn`.`ticketLog` (originFk, userFk, `action`, creationDate, changedModel, changedModelId, changedModelValue, oldInstance, newInstance, description) VALUES (1, NULL, 'delete', '2001-06-09 11:00:04', 'Ticket', 45, 'Spider Man' , NULL, NULL, NULL), (1, 18, 'select', '2001-06-09 11:00:03', 'Ticket', 45, 'Spider Man' , NULL, NULL, NULL), - (1, NULL, 'update', '2001-05-09 10:00:02', 'Sale', 69854, 'Armor' , '{"isPicked": false}','{"isPicked": true}', NULL), - (1, 18, 'update', '2001-01-01 10:05:01', 'Sale', 69854, 'Armor' , NULL, NULL, 'Armor quantity changed from ''15'' to ''10'''), - (1, NULL, 'delete', '2001-01-01 10:00:10', 'Sale', 5689, 'Shield' , '{"quantity":10,"concept":"Shield"}', NULL, NULL), - (1, 18, 'insert', '2000-12-31 15:00:05', 'Sale', 69854, 'Armor' , NULL,'{"quantity":15,"concept":"Armor", "price": 345.99, "itemFk": 2}', NULL), + (1, NULL, 'update', '2001-05-09 10:00:02', 'Sale', 5, 'Armor' , '{"isPicked": false}','{"isPicked": true}', NULL), + (1, 18, 'update', '2001-01-01 10:05:01', 'Sale', 5, 'Armor' , NULL, NULL, 'Armor quantity changed from ''15'' to ''10'''), + (1, NULL, 'delete', '2001-01-01 10:00:10', 'Sale', 4, 'Shield' , '{"quantity":10,"concept":"Shield"}', NULL, NULL), + (1, 18, 'insert', '2000-12-31 15:00:05', 'Sale', 1, 'Armor' , NULL,'{"quantity":15,"concept":"Armor", "price": 345.99, "itemFk": 2}', NULL), (1, 18, 'update', '2000-12-28 08:40:45', 'Ticket', 45, 'Spider Man' , '{"warehouseFk":60,"shipped":"2023-05-16T22:00:00.000Z","nickname":"Super Man","isSigned":true,"isLabeled":true,"isPrinted":true,"packages":0,"hour":0,"isBlocked":false,"hasPriority":false,"companyFk":442,"landed":"2023-05-17T22:00:00.000Z","isBoxed":true,"isDeleted":true,"zoneFk":713,"zonePrice":13,"zoneBonus":0}','{"warehouseFk":61,"shipped":"2023-05-17T22:00:00.000Z","nickname":"Spider Man","isSigned":false,"isLabeled":false,"isPrinted":false,"packages":1,"hour":0,"isBlocked":true,"hasPriority":true,"companyFk":443,"landed":"2023-05-18T22:00:00.000Z","isBoxed":false,"isDeleted":false,"zoneFk":713,"zonePrice":13,"zoneBonus":1}', NULL), (1, 18, 'select', '2000-12-27 03:40:30', 'Ticket', 45, NULL , NULL, NULL, NULL), - (1, 18, 'insert', '2000-04-10 09:40:15', 'Sale', 5689, 'Shield' , NULL, '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', NULL), + (1, 18, 'insert', '2000-04-10 09:40:15', 'Sale', 4, 'Shield' , NULL, '{"quantity":10,"concept":"Shield", "price": 10.5, "itemFk": 1}', NULL), (1, 18, 'insert', '1999-05-09 10:00:00', 'Ticket', 45, 'Super Man' , NULL, '{"id":45,"clientFk":8608,"warehouseFk":60,"shipped":"2023-05-16T22:00:00.000Z","nickname":"Super Man","addressFk":48637,"isSigned":true,"isLabeled":true,"isPrinted":true,"packages":0,"hour":0,"created":"2023-05-16T11:42:56.000Z","isBlocked":false,"hasPriority":false,"companyFk":442,"agencyModeFk":639,"landed":"2023-05-17T22:00:00.000Z","isBoxed":true,"isDeleted":true,"zoneFk":713,"zonePrice":13,"zoneBonus":0}', NULL); INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 1b18eb866..6f78d7c4e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -520,8 +520,7 @@ export default { searchResultDate: 'vn-ticket-summary [label=Landed] span', topbarSearch: 'vn-searchbar', moreMenu: 'vn-ticket-index vn-icon-button[icon=more_vert]', - fourthWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(5)', - fiveWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(6)', + thirdWeeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(4)', weeklyTicket: 'vn-ticket-weekly-index vn-card smart-table slot-table table tbody tr', firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) vn-icon-button[icon="delete"]', firstWeeklyTicketAgency: 'vn-ticket-weekly-index vn-card smart-table slot-table tr:nth-child(2) [ng-model="weekly.agencyModeFk"]', diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js index a9cce2ead..74febfd01 100644 --- a/e2e/paths/05-ticket/09_weekly.spec.js +++ b/e2e/paths/05-ticket/09_weekly.spec.js @@ -19,7 +19,7 @@ describe('Ticket descriptor path', () => { it('should count the amount of tickets in the turns section', async() => { const result = await page.countElement(selectors.ticketsIndex.weeklyTicket); - expect(result).toEqual(7); + expect(result).toEqual(5); }); it('should go back to the ticket index then search and access a ticket summary', async() => { @@ -45,7 +45,7 @@ describe('Ticket descriptor path', () => { it('should confirm the ticket 11 was added to thursday', async() => { await page.accessToSection('ticket.weekly.index'); - const result = await page.waitToGetProperty(selectors.ticketsIndex.fourthWeeklyTicket, 'value'); + const result = await page.waitToGetProperty(selectors.ticketsIndex.thirdWeeklyTicket, 'value'); expect(result).toEqual('Thursday'); }); @@ -80,7 +80,9 @@ describe('Ticket descriptor path', () => { it('should confirm the ticket 11 was added on saturday', async() => { await page.accessToSection('ticket.weekly.index'); - const result = await page.waitToGetProperty(selectors.ticketsIndex.fiveWeeklyTicket, 'value'); + await page.waitForTimeout(5000); + + const result = await page.waitToGetProperty(selectors.ticketsIndex.thirdWeeklyTicket, 'value'); expect(result).toEqual('Saturday'); }); @@ -104,7 +106,7 @@ describe('Ticket descriptor path', () => { await page.doSearch(); const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(nResults).toEqual(7); + expect(nResults).toEqual(5); }); it('should update the agency then remove it afterwards', async() => { diff --git a/front/salix/components/index.js b/front/salix/components/index.js index f632904c4..38b0d0e1f 100644 --- a/front/salix/components/index.js +++ b/front/salix/components/index.js @@ -22,5 +22,4 @@ import './user-photo'; import './upload-photo'; import './bank-entity'; import './log'; -import './instance-log'; import './sendSms'; diff --git a/front/salix/components/instance-log/index.html b/front/salix/components/instance-log/index.html deleted file mode 100644 index 9794f75c2..000000000 --- a/front/salix/components/instance-log/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/front/salix/components/instance-log/index.js b/front/salix/components/instance-log/index.js deleted file mode 100644 index 6d8497c2d..000000000 --- a/front/salix/components/instance-log/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import ngModule from '../../module'; -import Section from '../section'; -import './style.scss'; - -export default class Controller extends Section { - open() { - this.$.instanceLog.show(); - } -} - -ngModule.vnComponent('vnInstanceLog', { - controller: Controller, - template: require('./index.html'), - bindings: { - model: '<', - originId: '<', - changedModelId: '<', - changedModel: '@', - url: '@' - } -}); diff --git a/front/salix/components/instance-log/style.scss b/front/salix/components/instance-log/style.scss deleted file mode 100644 index f355e0ac8..000000000 --- a/front/salix/components/instance-log/style.scss +++ /dev/null @@ -1,9 +0,0 @@ -vn-log.vn-instance-log { - vn-card { - width: 900px; - visibility: hidden; - & > * { - visibility: visible; - } - } -} diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index 1edaa72ae..854c57f00 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -72,6 +72,7 @@ export default class Controller extends Section { $postLink() { this.resetFilter(); + this.defaultFilter(); this.$.$watch( () => this.$.filter, () => this.applyFilter(), @@ -79,6 +80,14 @@ export default class Controller extends Section { ); } + defaultFilter() { + const defaultFilters = ['changedModel', 'changedModelId']; + for (const defaultFilter of defaultFilters) { + if (this[defaultFilter]) + this.$.filter[defaultFilter] = this[defaultFilter]; + } + } + get logs() { return this._logs; } diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 7e194451f..645a874e8 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -188,5 +188,6 @@ "The ticket doesn't exist.": "The ticket doesn't exist.", "The sales do not exists": "The sales do not exists", "Ticket without Route": "Ticket without route", - "Booking completed": "Booking completed" + "Booking completed": "Booking complete", + "The ticket is in preparation": "The ticket [{{ticketId}}]({{{ticketUrl}}}) of the sales person {{salesPersonId}} is in preparation" } diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 034f267d0..6e478c000 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -216,6 +216,7 @@ "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", + "The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", "You don't have privileges to create refund": "No tienes permisos para crear un abono", "The item is required": "El artículo es requerido", @@ -318,5 +319,6 @@ "Street should be uppercase": "La dirección fiscal debe ir en mayúscula", "The response is not a PDF": "La respuesta no es un PDF", "Ticket without Route": "Ticket sin ruta", - "Booking completed": "Reserva completada" -} \ No newline at end of file + "Booking completed": "Reserva completada", + "The ticket is in preparation": "El ticket [{{ticketId}}]({{{ticketUrl}}}) del comercial {{salesPersonId}} está en preparación" +} diff --git a/modules/client/back/methods/client/creditRequestEmail.js b/modules/client/back/methods/client/creditRequestEmail.js index 0255949e0..60047de77 100644 --- a/modules/client/back/methods/client/creditRequestEmail.js +++ b/modules/client/back/methods/client/creditRequestEmail.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethodCtx('clientCreditEmail', { + Self.remoteMethodCtx('creditRequestEmail', { description: 'Sends the credit request email with an attached PDF', accessType: 'WRITE', accepts: [ @@ -40,5 +40,5 @@ module.exports = Self => { }, }); - Self.clientCreditEmail = ctx => Self.sendTemplate(ctx, 'credit-request'); + Self.creditRequestEmail = ctx => Self.sendTemplate(ctx, 'credit-request'); }; diff --git a/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js index c368ec1b8..5fc2ea752 100644 --- a/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js +++ b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js @@ -32,6 +32,7 @@ describe('Supplier newSupplier()', () => { const result = await models.Supplier.newSupplier(ctx, options); expect(result.name).toEqual('newSupplier'); + await tx.rollback(); } catch (e) { await tx.rollback(); throw e; diff --git a/modules/supplier/back/models/specs/supplier.spec.js b/modules/supplier/back/models/specs/supplier.spec.js index f317f1fb9..fbd3a00db 100644 --- a/modules/supplier/back/models/specs/supplier.spec.js +++ b/modules/supplier/back/models/specs/supplier.spec.js @@ -123,5 +123,21 @@ describe('loopback model Supplier', () => { throw e; } }); + + it('should update the account attribute when a new supplier is created', async() => { + const tx = await models.Supplier.beginTransaction({}); + const options = {transaction: tx}; + + try { + const newSupplier = await models.Supplier.create({name: 'Alfred Pennyworth'}, options); + const fetchedSupplier = await models.Supplier.findById(newSupplier.id, null, options); + + expect(Number(fetchedSupplier.account)).toEqual(4100000000 + newSupplier.id); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); }); diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 96042c9a0..5cf357c13 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -117,6 +117,16 @@ module.exports = Self => { throw new UserError('You can not modify is pay method checked'); }); + Self.observe('after save', async function(ctx) { + if (ctx.instance && ctx.isNewInstance) { + const {id} = ctx.instance; + const {Supplier} = Self.app.models; + + const supplier = await Supplier.findById(id, null, ctx.options); + await supplier?.updateAttribute('account', Number(supplier.account) + id, ctx.options); + } + }); + Self.validateAsync('name', 'countryFk', hasSupplierSameName, { message: 'A supplier with the same name already exists. Change the country.' }); diff --git a/modules/supplier/front/create/index.html b/modules/supplier/front/create/index.html index c3efcf6ae..eb6e7261e 100644 --- a/modules/supplier/front/create/index.html +++ b/modules/supplier/front/create/index.html @@ -18,7 +18,6 @@ { const result = await models.TicketRequest.filter(ctx, options); - expect(result.length).toEqual(3); + expect(result.length).toEqual(5); await tx.rollback(); } catch (e) { @@ -93,7 +93,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, options); const requestId = result[0].id; - expect(requestId).toEqual(3); + expect(requestId).toEqual(1); await tx.rollback(); } catch (e) { @@ -113,7 +113,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, options); const requestId = result[0].id; - expect(requestId).toEqual(3); + expect(requestId).toEqual(1); await tx.rollback(); } catch (e) { @@ -153,7 +153,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, {order: 'id'}, options); const requestId = result[0].id; - expect(requestId).toEqual(3); + expect(requestId).toEqual(1); await tx.rollback(); } catch (e) { @@ -173,7 +173,7 @@ describe('ticket-request filter()', () => { const result = await models.TicketRequest.filter(ctx, options); const requestId = result[0].id; - expect(requestId).toEqual(3); + expect(requestId).toEqual(1); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js index 2587b6657..453b7924f 100644 --- a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js @@ -16,8 +16,8 @@ describe('ticket-weekly filter()', () => { const firstRow = result[0]; - expect(firstRow.ticketFk).toEqual(1); - expect(result.length).toEqual(6); + expect(firstRow.ticketFk).toEqual(2); + expect(result.length).toEqual(4); await tx.rollback(); } catch (e) { @@ -52,12 +52,12 @@ describe('ticket-weekly filter()', () => { try { const options = {transaction: tx}; - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'bruce'}}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'max'}}; const result = await models.TicketWeekly.filter(ctx, null, options); const firstRow = result[0]; - expect(firstRow.clientName).toEqual('Bruce Wayne'); + expect(firstRow.clientName).toEqual('Max Eisenhardt'); await tx.rollback(); } catch (e) { @@ -72,13 +72,13 @@ describe('ticket-weekly filter()', () => { try { const options = {transaction: tx}; - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 1101}}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 1105}}; const result = await models.TicketWeekly.filter(ctx, null, options); const firstRow = result[0]; - expect(firstRow.clientFk).toEqual(1101); - expect(firstRow.clientName).toEqual('Bruce Wayne'); + expect(firstRow.clientFk).toEqual(1105); + expect(firstRow.clientName).toEqual('Max Eisenhardt'); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/isEditableOrThrow.js b/modules/ticket/back/methods/ticket/isEditableOrThrow.js index 6a8bafa2c..f8285cecd 100644 --- a/modules/ticket/back/methods/ticket/isEditableOrThrow.js +++ b/modules/ticket/back/methods/ticket/isEditableOrThrow.js @@ -40,7 +40,7 @@ module.exports = Self => { if (!isEditable && !isRoleAdvanced) throw new ForbiddenError(`This ticket is not editable.`); - if (isLocked) + if (isLocked && !isWeekly) throw new ForbiddenError(`This ticket is locked.`); if (isWeekly && !canEditWeeklyTicket) diff --git a/modules/ticket/back/methods/ticket/specs/isEditable.spec.js b/modules/ticket/back/methods/ticket/specs/isEditable.spec.js index 301745ed3..9dd1f8544 100644 --- a/modules/ticket/back/methods/ticket/specs/isEditable.spec.js +++ b/modules/ticket/back/methods/ticket/specs/isEditable.spec.js @@ -8,7 +8,7 @@ describe('isEditable()', () => { try { const options = {transaction: tx}; const ctx = {req: {accessToken: {userId: 35}}}; - result = await models.Ticket.isEditable(ctx, 5, options); + result = await models.Ticket.isEditable(ctx, 19, options); await tx.rollback(); } catch (error) { await tx.rollback(); diff --git a/modules/ticket/front/log/index.html b/modules/ticket/front/log/index.html index 91109d3eb..c36b0aa52 100644 --- a/modules/ticket/front/log/index.html +++ b/modules/ticket/front/log/index.html @@ -1 +1,6 @@ - \ No newline at end of file + + diff --git a/modules/ticket/front/routes.json b/modules/ticket/front/routes.json index e403ab02d..da39fbbf7 100644 --- a/modules/ticket/front/routes.json +++ b/modules/ticket/front/routes.json @@ -187,7 +187,7 @@ } }, { - "url" : "/log", + "url" : "/log?changedModel&changedModelId", "state": "ticket.card.log", "component": "vn-ticket-log", "description": "Log" diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index be9e81964..b10df317b 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -212,16 +212,9 @@ vn-none vn-tooltip="History" icon="history" - ng-click="log.open()" + ng-click="$ctrl.goToLog(sale.id)" ng-show="sale.$hasLogs"> - - diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index b68db6dc0..f946d0a25 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -558,6 +558,14 @@ class Controller extends Section { cancel() { this.$.editDiscount.hide(); } + + goToLog(saleId) { + this.$state.go('ticket.card.log', { + originId: this.$params.id, + changedModel: 'Sale', + changedModelId: saleId + }); + } } ngModule.vnComponent('vnTicketSale', { diff --git a/print/templates/reports/invoice/assets/css/style.css b/print/templates/reports/invoice/assets/css/style.css index d4526ce56..f9f6f220f 100644 --- a/print/templates/reports/invoice/assets/css/style.css +++ b/print/templates/reports/invoice/assets/css/style.css @@ -44,3 +44,7 @@ h2 { .phytosanitary-info { margin-top: 10px } + +.panel { + margin-bottom: 0px; +}