diff --git a/db/routines/vn/procedures/sale_getBoxPickingList.sql b/db/routines/vn/procedures/sale_getBoxPickingList.sql index 0f2b2bc71..84ae45614 100644 --- a/db/routines/vn/procedures/sale_getBoxPickingList.sql +++ b/db/routines/vn/procedures/sale_getBoxPickingList.sql @@ -17,7 +17,6 @@ BEGIN CALL productionControl(vWarehouseFk, 0); - -- Products with vn.item.isBoxPickingMode = TRUE, pay atention to vn.itemShelving.packing CREATE OR REPLACE TEMPORARY TABLE tmp.sale (saleFk INT PRIMARY KEY) SELECT @@ -52,8 +51,8 @@ BEGIN LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk LEFT JOIN buy b ON b.id = lb.buy_id - WHERE s.quantity BETWEEN ish.packing AND (ish.visible - IFNULL(tISS.reserve,0)) - AND i.isBoxPickingMode + WHERE IF(i.isBoxPickingMode, ish.packing, i.packingOut) + <= LEAST(s.quantity, ish.visible - IFNULL(tISS.reserve,0)) AND NOT pb.problem AND sgd.saleFk IS NULL AND p.sectorFk = vSectorFk @@ -64,47 +63,13 @@ BEGIN GROUP BY s.id ORDER BY etd; - -- Remaining products, vn.item.packingOut - INSERT IGNORE INTO tmp.sale - SELECT - s.ticketFk, - s.id saleFk, - s.itemFk, - s.concept, - s.quantity, - MAKETIME(pb.HH,pb.mm,0) etd, - pb.routeFk, - s.quantity / i.packingOut stickers, - i.packingOut, - pc.defaultBigPackageFk - FROM sale s - JOIN item i ON i.id = s.itemFk - JOIN itemShelving ish ON ish.itemFk = s.itemFk - JOIN shelving sh ON sh.code = ish.shelvingFk - JOIN parking p ON p.id = sh.parkingFk - JOIN tmp.productionBuffer pb ON pb.ticketFk = s.ticketFk - JOIN agencyMode am ON am.id = pb.agencyModeFk - JOIN packagingConfig pc - LEFT JOIN routesMonitor rm ON rm.routeFk = pb.routeFk - LEFT JOIN itemShelvingStock iss ON iss.itemFk = s.itemFk AND iss.sectorFk = p.sectorFk - LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id - LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk - WHERE s.quantity >= i.packingOut - AND NOT pb.problem - AND s.quantity > 0 - AND sgd.saleFk IS NULL - AND p.sectorFk = vSectorFk - AND ts.isPreviousPreparable - AND iss.visible >= s.quantity - AND ((rm.bufferFk AND rm.isPickingAllowed) - OR am.code = 'REC_ALG') - AND pb.shipped = vDated - GROUP BY s.id - ORDER BY etd; - - SELECT * FROM tmp.sale; + SELECT * + FROM tmp.sale + WHERE stickers; DROP TEMPORARY TABLE tmp.productionBuffer; DROP TEMPORARY TABLE tmp.sale; END$$ DELIMITER ; + +CALL `vn`.`sale_getBoxPickingList`(1, curdate()); \ No newline at end of file diff --git a/db/routines/vn/triggers/ticket_beforeUpdate.sql b/db/routines/vn/triggers/ticket_beforeUpdate.sql index 0836b2486..72831bc3d 100644 --- a/db/routines/vn/triggers/ticket_beforeUpdate.sql +++ b/db/routines/vn/triggers/ticket_beforeUpdate.sql @@ -4,7 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`ticket_beforeUpdate` FOR EACH ROW BEGIN DECLARE vNewTime TIME; - DECLARE vHasTicketRefund BOOL; SET NEW.editorFk = account.myUser_getId(); @@ -64,14 +63,5 @@ BEGIN CALL vn.routeUpdateM3(NEW.routeFk); END IF; - - SELECT COUNT(*) INTO vHasTicketRefund - FROM ticketRefund - WHERE originalTicketFk = NEW.id - OR refundTicketFk = NEW.id; - - IF vHasTicketRefund AND NEW.clientFk <> OLD.clientFk THEN - CALL util.throw('The ticket has a refund associated'); - END IF; END$$ DELIMITER ; diff --git a/db/versions/10885-wheatHydrangea/00-revokeUpdateClient.sql b/db/versions/10885-wheatHydrangea/00-revokeUpdateClient.sql new file mode 100644 index 000000000..b22e09615 --- /dev/null +++ b/db/versions/10885-wheatHydrangea/00-revokeUpdateClient.sql @@ -0,0 +1,37 @@ +REVOKE UPDATE ON vn.ticket FROM employee; + +GRANT UPDATE (id, + warehouseFk, + shipped, + nickname, + refFk, + addressFk, + workerFk, + observations, + isSigned, + isLabeled, + isPrinted, + packages, + location, + hour, + created, + isBlocked, + solution, + routeFk, + priority, + hasPriority, + companyFk, + agencyModeFk, + landed, + isBoxed, + isDeleted, + zoneFk, + zonePrice, + zoneBonus, + totalWithVat, + totalWithoutVat, + weight, + clonedFrom, + cmrFk, + editorFk) + ON vn.ticket TO employee; diff --git a/modules/ticket/back/methods/ticket/specs/transferClient.spec.js b/modules/ticket/back/methods/ticket/specs/transferClient.spec.js index 5a9edd17e..5f1c09776 100644 --- a/modules/ticket/back/methods/ticket/specs/transferClient.spec.js +++ b/modules/ticket/back/methods/ticket/specs/transferClient.spec.js @@ -1,49 +1,60 @@ const models = require('vn-loopback/server/server').models; describe('Ticket transferClient()', () => { - const userId = 9; - const activeCtx = { - accessToken: {userId: userId}, - }; - const ctx = {req: activeCtx}; + const originalTicketId = 8; + const refundTicketId = 24; + const clientId = 1; + let ctx; + let options; + let tx; + beforeEach(async() => { + ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'} + }, + args: {} + }; + + options = {transaction: tx}; + tx = await models.Ticket.beginTransaction({}); + options.transaction = tx; + }); + + afterEach(async() => { + await tx.rollback(); + }); it('should throw an error as the ticket is not editable', async() => { - const tx = await models.Ticket.beginTransaction({}); - let error; - try { - const options = {transaction: tx}; const ticketId = 4; const clientId = 1; await models.Ticket.transferClient(ctx, ticketId, clientId, options); - - await tx.rollback(); } catch (e) { - await tx.rollback(); - error = e; + expect(e.message).toEqual(`This ticket is locked`); } - - expect(error.message).toEqual(`This ticket is locked`); }); - it('should be assigned a different clientFk', async() => { - const tx = await models.Ticket.beginTransaction({}); - let updatedTicket; - const ticketId = 10; - const clientId = 1; + it('should be assigned a different clientFk in the original ticket', async() => { + await models.Ticket.transferClient(ctx, 2, clientId, options); + const afterTransfer = await models.Ticket.findById(2, null, options); - try { - const options = {transaction: tx}; + expect(afterTransfer.clientFk).toEqual(clientId); + }); - await models.Ticket.transferClient(ctx, ticketId, clientId, options); - updatedTicket = await models.Ticket.findById(ticketId, {fields: ['clientFk']}, options); + it('should be assigned a different clientFk in the original and refund ticket and claim', async() => { + await models.Ticket.transferClient(ctx, originalTicketId, clientId, options); - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } + const [originalTicket, refundTicket] = await models.Ticket.find({ + where: {id: {inq: [originalTicketId, refundTicketId]}} + }, options); - expect(updatedTicket.clientFk).toEqual(clientId); + const claim = await models.Claim.findOne({ + where: {ticketFk: originalTicketId} + }, options); + + expect(originalTicket.clientFk).toEqual(clientId); + expect(refundTicket.clientFk).toEqual(clientId); + expect(claim.clientFk).toEqual(clientId); }); }); diff --git a/modules/ticket/back/methods/ticket/transferClient.js b/modules/ticket/back/methods/ticket/transferClient.js index 60e70d710..d38c0e8a7 100644 --- a/modules/ticket/back/methods/ticket/transferClient.js +++ b/modules/ticket/back/methods/ticket/transferClient.js @@ -2,20 +2,17 @@ module.exports = Self => { Self.remoteMethodCtx('transferClient', { description: 'Transfering ticket to another client', accessType: 'WRITE', - accepts: [ - { - arg: 'id', - type: 'number', - required: true, - description: 'the ticket id', - http: {source: 'path'} - }, - { - arg: 'clientFk', - type: 'number', - required: true, - }, - ], + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'the ticket id', + http: {source: 'path'} + }, { + arg: 'clientFk', + type: 'number', + required: true, + }], http: { path: `/:id/transferClient`, verb: 'PATCH' @@ -25,21 +22,51 @@ module.exports = Self => { Self.transferClient = async(ctx, id, clientFk, options) => { const models = Self.app.models; const myOptions = {}; + let tx; + if (typeof options == 'object') Object.assign(myOptions, options); - await Self.isEditableOrThrow(ctx, id, myOptions); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - const ticket = await models.Ticket.findById( - id, - {fields: ['id', 'shipped', 'clientFk', 'addressFk']}, - myOptions - ); - const client = await models.Client.findById(clientFk, {fields: ['id', 'defaultAddressFk']}, myOptions); + try { + await Self.isEditableOrThrow(ctx, id, myOptions); - await ticket.updateAttributes({ - clientFk, - addressFk: client.defaultAddressFk, - }); + const ticketRefund = await models.TicketRefund.findOne({ + where: {or: [{originalTicketFk: id}, {refundTicketFk: id}]}, + include: [{relation: 'refundTicket'}, {relation: 'originalTicket'}] + }, myOptions); + + const {defaultAddressFk: addressFk} = await models.Client.findById(clientFk, + {fields: ['id', 'defaultAddressFk']}, myOptions); + + const attributes = {clientFk, addressFk}; + + const tickets = []; + const ticketIds = []; + + if (ticketRefund) { + const {refundTicket, originalTicket} = ticketRefund; + tickets.push(refundTicket(), originalTicket()); + + for (const ticket of tickets) { + await ticket.updateAttributes(attributes, myOptions); + ticketIds.push(ticket.id); + } + } else { + await Self.updateAll({id}, attributes, myOptions); + ticketIds.push(id); + } + + await models.Claim.updateAll({ticketFk: {inq: ticketIds}}, {clientFk}, myOptions); + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; };