diff --git a/db/changes/10070-coffee/00-ticket_componentMakeUpdate.sql b/db/changes/10070-coffee/00-ticket_componentMakeUpdate.sql new file mode 100644 index 000000000..0c9602b35 --- /dev/null +++ b/db/changes/10070-coffee/00-ticket_componentMakeUpdate.sql @@ -0,0 +1,38 @@ +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_componentMakeUpdate`( + vTicketFk INT, + vClientFk INT, + vAgencyModeFk INT, + vAddressFk INT, + vZoneFk INT, + vWarehouseFk TINYINT, + vCompanyFk SMALLINT, + vShipped DATETIME, + vLanded DATE, + vIsDeleted BOOLEAN, + vHasToBeUnrouted BOOLEAN, + vOption INT) +BEGIN + + CALL vn.ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk); + CALL vn.ticket_componentUpdate ( + vTicketFk, + vClientFk, + vAgencyModeFk, + vAddressFk, + vZoneFk, + vWarehouseFk, + vCompanyFk, + vShipped, + vLanded, + vIsDeleted, + vHasToBeUnrouted, + vOption + ); + + DROP TEMPORARY TABLE + tmp.ticketComponent, + tmp.ticketComponentPrice; +END$$ + +DELIMITER ; diff --git a/db/changes/10070-coffee/00-ticket_componentPreview.sql b/db/changes/10070-coffee/00-ticket_componentPreview.sql new file mode 100644 index 000000000..82403c829 --- /dev/null +++ b/db/changes/10070-coffee/00-ticket_componentPreview.sql @@ -0,0 +1,111 @@ +USE `vn`; +DROP procedure IF EXISTS `ticket_componentPreview`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `ticket_componentPreview`( + vTicketFk INT, + vLanded DATE, + vAddressFk INT, + vZoneFk INT, + vWarehouseFk SMALLINT) +BEGIN +/** + * Calcula los componentes de los articulos de un ticket + * + * @param vTicketFk id del ticket + * @param vLanded nueva fecha de entrega + * @param vAddressFk nuevo consignatario + * @param vZoneFk nueva zona + * @param vWarehouseFk nuevo warehouse + * + * @return tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost) + */ + DECLARE vShipped DATE; + DECLARE vBuyOrderItem INT DEFAULT 100; + + DECLARE vHasDataChanged BOOL DEFAULT FALSE; + DECLARE vHasAddressChanged BOOL; + DECLARE vHasZoneChanged BOOL DEFAULT FALSE; + DECLARE vHasWarehouseChanged BOOL DEFAULT FALSE; + + DECLARE vAddressTypeRateFk INT DEFAULT NULL; + DECLARE vAgencyModeTypeRateFk INT DEFAULT NULL; + + DECLARE vHasChangeAll BOOL DEFAULT FALSE; + + SELECT DATE(landed) <> vLanded, + addressFk <> vAddressFk, + zoneFk <> vZoneFk, + warehouseFk <> vWarehouseFk + INTO + vHasDataChanged, + vHasAddressChanged, + vHasZoneChanged, + vHasWarehouseChanged + FROM vn.ticket t + WHERE t.id = vTicketFk; + + IF vHasDataChanged OR vHasWarehouseChanged THEN + SET vHasChangeAll = TRUE; + END IF; + + IF vHasAddressChanged THEN + SET vAddressTypeRateFk = 5; + END IF; + + IF vHasZoneChanged THEN + SET vAgencyModeTypeRateFk = 6; + END IF; + + SELECT TIMESTAMPADD(DAY, -travelingDays, vLanded) INTO vShipped + FROM zone + WHERE id = vZoneFk; + + CALL buyUltimate(vWarehouseFk, vShipped); + + DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot; + CREATE TEMPORARY TABLE tmp.ticketLot ENGINE = MEMORY ( + SELECT + vWarehouseFk AS warehouseFk, + NULL AS available, + s.itemFk, + bu.buyFk + FROM sale s + LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk + WHERE s.ticketFk = vTicketFk + AND s.itemFk != vBuyOrderItem + GROUP BY bu.warehouseFk, bu.itemFk); + + CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped); + + REPLACE INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost) + SELECT t.warehouseFk, s.itemFk, sc.componentFk, sc.value + FROM saleComponent sc + JOIN sale s ON s.id = sc.saleFk + JOIN ticket t ON t.id = s.ticketFk + JOIN componentRate cr ON cr.id = sc.componentFk + WHERE s.ticketFk = vTicketFk + AND (cr.isRenewable = FALSE + OR + (NOT vHasChangeAll + AND (NOT (cr.componentTypeRate <=> vAddressTypeRateFk + OR cr.componentTypeRate <=> vAgencyModeTypeRateFk)))); + + SET @shipped = vShipped; + + DROP TEMPORARY TABLE + tmp.buyUltimate, + tmp.ticketLot; + + IF vShipped IS NULL THEN + CALL util.throw('NO_ZONE_AVAILABLE'); + END IF; + + IF vShipped < CURDATE() THEN + CALL util.throw('ERROR_PAST_SHIPMENT'); + END IF; +END$$ + +DELIMITER ; + diff --git a/db/changes/10070-coffee/00-ticket_priceDifference.sql b/db/changes/10070-coffee/00-ticket_priceDifference.sql new file mode 100644 index 000000000..33146b124 --- /dev/null +++ b/db/changes/10070-coffee/00-ticket_priceDifference.sql @@ -0,0 +1,52 @@ +DROP procedure IF EXISTS `vn`.`ticket_priceDifference`; + +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_priceDifference`( + vTicketFk INT, + vLanded DATE, + vAddressFk INT, + vZoneFk INT, + vWarehouseFk INT) +BEGIN +/** + * Devuelve las diferencias de precio + * de los movimientos de un ticket. + * + * @param vTicketFk Id del ticket + * @param vLanded Fecha de recepcion + * @param vAddressFk Id del consignatario + * @param vZoneFk Id de la zona + * @param vWarehouseFk Id del almacén + */ + CALL vn.ticket_componentPreview(vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk); + + SELECT s.itemFk, + i.name, + i.size, + i.category, + IFNULL(s.quantity, 0) AS quantity, + IFNULL(s.price, 0) AS price, + ROUND(SUM(tc.cost), 2) AS newPrice, + s.quantity * (s.price - ROUND(SUM(tc.cost), 2)) difference, + s.id AS saleFk + FROM sale s + JOIN item i ON i.id = s.itemFk + JOIN ticket t ON t.id = s.ticketFk + LEFT JOIN tmp.ticketComponent tc ON tc.itemFk = s.itemFk + AND tc.warehouseFk = t.warehouseFk + LEFT JOIN saleComponent sc ON sc.saleFk = s.id + AND sc.componentFk = tc.componentFk + LEFT JOIN componentRate cr ON cr.id = tc.componentFk + WHERE + t.id = vTicketFk + AND IF(sc.componentFk IS NULL + AND cr.classRate IS NOT NULL, FALSE, TRUE) + GROUP BY s.id ORDER BY s.id; + + DROP TEMPORARY TABLE + tmp.ticketComponent, + tmp.ticketComponentPrice; +END$$ + +DELIMITER ; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 023f18dd4..90834cf97 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1448,6 +1448,14 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `atenderFk` (3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, 4, 3.06, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)), (4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, CURDATE()); +INSERT INTO `vn`.`ticketServiceType`(`id`, `name`) + VALUES + (1, 'Porte Agencia'), + (2, 'Portes Retorno'), + (3, 'Porte Carry'), + (4, 'Cargo FITOSANITARIO'), + (5, 'Documentos'); + INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`) VALUES (1, 'Documentos', 1, 2.00, 1, 1), diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 7586b1846..e2c75597a 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -441,7 +441,8 @@ export default { basicDataButton: 'vn-left-menu a[ui-sref="ticket.card.basicData.stepOne"]', clientAutocomplete: 'vn-autocomplete[field="$ctrl.clientFk"]', addressAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.addressFk"]', - agencyAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.agencyModeFk"]', + agencyAutocomplete: 'vn-autocomplete[field="$ctrl.agencyModeId"]', + zoneAutocomplete: 'vn-autocomplete[field="$ctrl.zoneId"]', nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button', finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit', stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)', diff --git a/e2e/paths/05-ticket-module/06_basic_data_steps.spec.js b/e2e/paths/05-ticket-module/06_basic_data_steps.spec.js index 4e0fe9945..72e194600 100644 --- a/e2e/paths/05-ticket-module/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket-module/06_basic_data_steps.spec.js @@ -14,6 +14,7 @@ describe('Ticket Edit basic data path', () => { it(`should edit the ticket agency then click next`, async() => { let url = await nightmare .autocompleteSearch(selectors.ticketBasicData.agencyAutocomplete, 'Silla247Expensive') + .waitToGetProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value') .waitToClick(selectors.ticketBasicData.nextStepButton) .waitForURL('data/step-two') .parsedUrl(); diff --git a/front/core/components/autocomplete/autocomplete.js b/front/core/components/autocomplete/autocomplete.js index b2ac40c45..45e28350b 100755 --- a/front/core/components/autocomplete/autocomplete.js +++ b/front/core/components/autocomplete/autocomplete.js @@ -92,8 +92,6 @@ export default class Autocomplete extends Input { set field(value) { this._field = value; - if (!value) return; - this.refreshSelection(); this.emit('change', {value}); } diff --git a/gulpfile.js b/gulpfile.js index b696431c0..2ac31a86e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -198,7 +198,9 @@ async function backendStatus() { timer = setInterval(() => { const url = `${e2eConfig.url}/api/Applications/status`; request.get(url, (err, res) => { - if (res.body == 'true') { + if (err || attempts > 100) // 250ms * 100 => 25s timeout + throw new Error('Could not connect to backend'); + else if (res && res.body == 'true') { clearInterval(timer); resolve(attempts); } else diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 4a86734fd..111349c17 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -21,7 +21,6 @@ "Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF", "You can't create an order for a frozen client": "You can't create an order for a frozen client", "This address doesn't exist": "This address doesn't exist", - "NO_AGENCY_AVAILABLE": "NO_AGENCY_AVAILABLE", "Warehouse cannot be blank": "Warehouse cannot be blank", "Agency cannot be blank": "Agency cannot be blank", "The IBAN does not have the correct format": "The IBAN does not have the correct format", diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 94c425279..76b1017b3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -82,7 +82,8 @@ "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 agencias disponibles", + "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 sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", "Please select at least one sale": "Por favor selecciona al menos una linea", @@ -95,5 +96,6 @@ "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" + "File doesn't exists": "El archivo no existe", + "You don't have privileges to change the zone": "No tienes permisos para cambiar la zona" } \ No newline at end of file diff --git a/modules/agency/back/methods/agency/getLanded.js b/modules/agency/back/methods/agency/getLanded.js index 8d21320e3..f2571afcf 100644 --- a/modules/agency/back/methods/agency/getLanded.js +++ b/modules/agency/back/methods/agency/getLanded.js @@ -1,14 +1,10 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { - Self.remoteMethodCtx('getLanded', { + Self.remoteMethod('getLanded', { description: 'Returns the first shipped and landed possible for params', accessType: 'READ', accepts: [{ - arg: 'params', - type: 'Object', - description: `shipped, addressFk, agencyModeFk, warehouseFk` - }, { arg: 'shipped', type: 'date', required: true @@ -38,15 +34,14 @@ module.exports = Self => { } }); - Self.getLanded = async(ctx, params) => { + Self.getLanded = async(shipped, addressFk, agencyModeFk, warehouseFk) => { let stmts = []; - params = params || ctx.args; stmts.push(new ParameterizedSQL( `CALL vn.zoneGetLanded(?, ?, ?, ?)`, [ - params.shipped, - params.addressFk, - params.agencyModeFk, - params.warehouseFk + shipped, + addressFk, + agencyModeFk, + warehouseFk ] )); diff --git a/modules/agency/back/methods/agency/getShipped.js b/modules/agency/back/methods/agency/getShipped.js index a88d78713..eecc98ddf 100644 --- a/modules/agency/back/methods/agency/getShipped.js +++ b/modules/agency/back/methods/agency/getShipped.js @@ -1,12 +1,8 @@ module.exports = Self => { - Self.remoteMethodCtx('getShipped', { + Self.remoteMethod('getShipped', { description: 'Returns the first shipped possible for params', accessType: 'READ', accepts: [{ - arg: 'params', - type: 'Object', - description: `landed, addressFk, agencyModeFk, warehouseFk` - }, { arg: 'landed', type: 'date', required: true @@ -36,15 +32,14 @@ module.exports = Self => { } }); - Self.getShipped = async(ctx, params)=> { - params = params || ctx.args; + Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk)=> { let query = `CALL vn.zoneGetShipped(?, ?, ?, ?)`; - let [response] = await Self.rawSql(query, [ - params.landed, - params.addressFk, - params.agencyModeFk, - params.warehouseFk + let [[response]] = await Self.rawSql(query, [ + landed, + addressFk, + agencyModeFk, + warehouseFk ]); - return (response[0] && response[0].shipped && response[0].shipped.toJSON()) || null; + return response; }; }; diff --git a/modules/agency/back/methods/agency/specs/getLanded.spec.js b/modules/agency/back/methods/agency/specs/getLanded.spec.js index aa50529e3..9724f7841 100644 --- a/modules/agency/back/methods/agency/specs/getLanded.spec.js +++ b/modules/agency/back/methods/agency/specs/getLanded.spec.js @@ -2,13 +2,11 @@ const app = require('vn-loopback/server/server'); describe('agency getLanded()', () => { it('should return a landing date', async() => { - let data = { - shipped: new Date(), - addressFk: 121, - agencyModeFk: 7, - warehouseFk: 1 - }; - let result = await app.models.Agency.getLanded({}, data); + const shipped = new Date(); + const addressFk = 121; + const agencyModeFk = 7; + const warehouseFk = 1; + let result = await app.models.Agency.getLanded(shipped, addressFk, agencyModeFk, warehouseFk); expect(result.landed).toBeDefined(); }); diff --git a/modules/agency/back/methods/agency/specs/getShipped.spec.js b/modules/agency/back/methods/agency/specs/getShipped.spec.js index 90a55e5db..5c2e18369 100644 --- a/modules/agency/back/methods/agency/specs/getShipped.spec.js +++ b/modules/agency/back/methods/agency/specs/getShipped.spec.js @@ -2,13 +2,12 @@ const app = require('vn-loopback/server/server'); describe('agency getShipped()', () => { it('should return a shipment date', async() => { - let data = { - landed: new Date(), - addressFk: 121, - agencyModeFk: 7, - warehouseFk: 1 - }; - let result = await app.models.Agency.getShipped({}, data); + const landed = new Date(); + const addressFk = 121; + const agencyModeFk = 7; + const warehouseFk = 1; + + let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk); expect(result).toBeDefined(); }); @@ -17,14 +16,13 @@ describe('agency getShipped()', () => { let newDate = new Date(); newDate.setMonth(newDate.getMonth() - 1); - let data = { - landed: newDate, - addressFk: 121, - agencyModeFk: 7, - warehouseFk: 1 - }; - let result = await app.models.Agency.getShipped({}, data); + const landed = newDate; + const addressFk = 121; + const agencyModeFk = 7; + const warehouseFk = 1; - expect(result).toBeNull(); + let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk); + + expect(result).toBeUndefined(); }); }); diff --git a/modules/client/back/methods/receipt/filter.js b/modules/client/back/methods/receipt/filter.js index 768661114..5c0d6c1dd 100644 --- a/modules/client/back/methods/receipt/filter.js +++ b/modules/client/back/methods/receipt/filter.js @@ -43,7 +43,7 @@ module.exports = Self => { r.bankFk, u.nickname userNickname, r.clientFk, - FALSE pdf, + FALSE hasPdf, FALSE isInvoice FROM vn.receipt r LEFT JOIN vn.worker w ON w.id = r.workerFk @@ -64,7 +64,7 @@ module.exports = Self => { NULL, NULL, i.clientFk, - i.pdf, + i.hasPdf, TRUE isInvoice FROM vn.invoiceOut i JOIN vn.company c ON c.id = i.companyFk diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html index 708dd920d..045eb1f80 100644 --- a/modules/client/front/balance/index/index.html +++ b/modules/client/front/balance/index/index.html @@ -83,7 +83,7 @@ - { case 'max': return {amount: {lte: value}}; case 'hasPdf': - return {'i.pdf': value}; + return {'i.hasPdf': value}; case 'created': return {'i.created': value}; case 'amount': @@ -109,7 +109,7 @@ module.exports = Self => { i.created, i.dued, i.clientFk, - i.pdf AS hasPdf, + i.hasPdf, c.socialName AS clientSocialName, co.code AS companyCode FROM invoiceOut i diff --git a/modules/ticket/back/methods/sale/priceDifference.js b/modules/ticket/back/methods/sale/priceDifference.js deleted file mode 100644 index dd19b5810..000000000 --- a/modules/ticket/back/methods/sale/priceDifference.js +++ /dev/null @@ -1,75 +0,0 @@ -const UserError = require('vn-loopback/util/user-error'); - -module.exports = Self => { - Self.remoteMethodCtx('priceDifference', { - description: 'Returns sales with price difference if the ticket is editable', - accessType: 'READ', - accepts: [{ - arg: 'ticketFk', - type: 'number', - required: true, - description: 'ticket id', - http: {source: 'path'} - }, { - arg: 'data', - type: 'Object', - required: true, - description: 'landed, addressFk, agencyModeFk', - http: {source: 'body'} - }], - returns: { - type: ['Object'], - root: true - }, - http: { - path: `/:ticketFk/priceDifference`, - verb: 'post' - } - }); - - Self.priceDifference = async(ctx, ticketFk, data) => { - let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, ticketFk); - if (!thisTicketIsEditable) - throw new UserError(`The sales of this ticket can't be modified`); - - let filter = { - where: { - ticketFk: ticketFk - }, - order: 'concept ASC', - include: [{ - relation: 'item' - }] - }; - let salesObj = {}; - salesObj.items = await Self.find(filter); - salesObj.totalUnitPrice = 0.00; - salesObj.totalNewPrice = 0.00; - salesObj.totalDifference = 0.00; - - let query = `CALL vn.ticketComponentPriceDifference(?, ?, ?, ?, ?)`; - let [differences] = await Self.rawSql(query, [ - ticketFk, - data.landed, - data.addressFk, - data.agencyModeFk, - data.warehouseFk - ]); - - salesObj.items.forEach(sale => { - differences.forEach(difference => { - if (sale.id == difference.saleFk) - sale.component = difference; - }); - - salesObj.totalUnitPrice += sale.price; - salesObj.totalNewPrice += sale.component.newPrice; - salesObj.totalDifference += sale.component.difference; - salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100; - salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100; - salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100; - }); - - return salesObj; - }; -}; diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 728b80523..e20727d72 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -1,56 +1,116 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { - Self.remoteMethod('componentUpdate', { + Self.remoteMethodCtx('componentUpdate', { description: 'Save ticket sale components', accessType: 'WRITE', accepts: [{ - arg: 'ticketFk', - type: 'number', + arg: 'id', + type: 'Number', required: true, - description: 'ticket id', + description: 'The ticket id', http: {source: 'path'} }, { - arg: 'data', - type: 'Object', - required: true, - description: 'landed, addressFk, agencyModeFk, warehouseFk', - http: {source: 'body'} + arg: 'clientId', + type: 'Number', + description: 'The client id', + required: true }, { - arg: 'context', - type: 'object', - http: function(ctx) { - return ctx; - } + arg: 'agencyModeId', + type: 'Number', + description: 'The agencyMode id', + required: true + }, { + arg: 'addressId', + type: 'Number', + description: 'The address id', + required: true + }, { + arg: 'zoneId', + type: 'Number', + description: 'The zone id', + required: true + }, { + arg: 'warehouseId', + type: 'Number', + description: 'The warehouse id', + required: true + }, { + arg: 'companyId', + type: 'Number', + description: 'The company id', + required: true + }, { + arg: 'shipped', + type: 'Date', + description: 'The shipped date', + required: true + }, { + arg: 'landed', + type: 'Date', + description: 'The landing date', + required: true + }, { + arg: 'isDeleted', + type: 'Boolean', + description: 'Ticket is deleted', + required: true + }, { + arg: 'hasToBeUnrouted', + type: 'Boolean', + description: 'Ticket should be removed from ticket', + required: true + }, { + arg: 'option', + type: 'Number', + description: 'Action id', + required: true }], returns: { type: ['Object'], root: true }, http: { - path: `/:ticketFk/componentUpdate`, + path: `/:id/componentUpdate`, verb: 'post' } }); - Self.componentUpdate = async(ticketFk, data, ctx) => { - let userId = ctx.req.accessToken.userId; - let hasDeliveryRole = await Self.app.models.Account.hasRole(userId, 'delivery'); + Self.componentUpdate = async(ctx, id, clientId, agencyModeId, addressId, zoneId, warehouseId, + companyId, shipped, landed, isDeleted, hasToBeUnrouted, option) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const isEditable = await models.Ticket.isEditable(ctx, id); + if (!isEditable) + throw new UserError(`The sales of this ticket can't be modified`); + + const hasDeliveryRole = await models.Account.hasRole(userId, 'delivery'); if (!hasDeliveryRole) - data.hasToBeUnrouted = true; + hasToBeUnrouted = true; - let query = 'CALL vn.ticketComponentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss'); + if (!isProductionBoss) { + const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId); + + if (zone.id != zoneId) + throw new UserError(`You don't have privileges to change the zone`); + } + + let query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; let res = await Self.rawSql(query, [ - ticketFk, - data.clientFk, - data.agencyModeFk, - data.addressFk, - data.warehouseFk, - data.companyFk, - data.shipped, - data.landed, - data.isDeleted, - data.hasToBeUnrouted, - data.option + id, + clientId, + agencyModeId, + addressId, + zoneId, + warehouseId, + companyId, + shipped, + landed, + isDeleted, + hasToBeUnrouted, + option ]); return res; }; diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index 6c47ca63b..b3d9bb17c 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -20,7 +20,7 @@ module.exports = Self => { }); Self.isEditable = async(ctx, ticketFk) => { - const accessToken = ctx.active && ctx.active.accessToken || ctx.req && ctx.req.accessToken; + const accessToken = ctx.req.accessToken; const userId = accessToken.userId; let state = await Self.app.models.TicketState.findOne({ where: {ticketFk: ticketFk} diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js index defa25963..5bfb1996e 100644 --- a/modules/ticket/back/methods/ticket/new.js +++ b/modules/ticket/back/methods/ticket/new.js @@ -61,21 +61,14 @@ module.exports = Self => { try { if (!params.shipped && params.landed) { - params.shipped = await models.Agency.getShipped(ctx, { - landed: params.landed, - addressFk: address.id, - agencyModeFk: params.agencyModeFk, - warehouseFk: params.warehouseFk - }); + const shippedResult = await models.Agency.getShipped(params.landed, + address.id, params.agencyModeFk, params.warehouseFk); + params.shipped = shippedResult.shipped; } if (params.shipped && !params.landed) { - const landedResult = await models.Agency.getLanded(ctx, { - shipped: params.shipped, - addressFk: address.id, - agencyModeFk: params.agencyModeFk, - warehouseFk: params.warehouseFk - }); + const landedResult = await models.Agency.getLanded(params.shipped, + address.id, params.agencyModeFk, params.warehouseFk); params.landed = landedResult.landed; } diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js new file mode 100644 index 000000000..96c34d252 --- /dev/null +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -0,0 +1,110 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('priceDifference', { + description: 'Returns sales with price difference if the ticket is editable', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'Number', + required: true, + description: 'The ticket id', + http: {source: 'path'} + }, + { + arg: 'landed', + type: 'Date', + description: 'The landing date', + required: true + }, + { + arg: 'addressId', + type: 'Number', + description: 'The address id', + required: true + }, + { + arg: 'agencyModeId', + type: 'Number', + description: 'The agencyMode id', + required: true + }, + { + arg: 'zoneId', + type: 'Number', + description: 'The zone id', + required: true + }, + { + arg: 'warehouseId', + type: 'Number', + description: 'The warehouse id', + required: true + }], + returns: { + type: ['Object'], + root: true + }, + http: { + path: `/:id/priceDifference`, + verb: 'POST' + } + }); + + Self.priceDifference = async(ctx, id, landed, addressId, agencyModeId, zoneId, warehouseId) => { + const models = Self.app.models; + const isEditable = await models.Ticket.isEditable(ctx, id); + const userId = ctx.req.accessToken.userId; + + if (!isEditable) + throw new UserError(`The sales of this ticket can't be modified`); + + const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss'); + if (!isProductionBoss) { + const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId); + + if (zone.id != zoneId) + throw new UserError(`You don't have privileges to change the zone`); + } + + let salesObj = {}; + salesObj.items = await models.Sale.find({ + where: { + ticketFk: id + }, + order: 'concept ASC', + include: [{ + relation: 'item' + }] + }); + salesObj.totalUnitPrice = 0.00; + salesObj.totalNewPrice = 0.00; + salesObj.totalDifference = 0.00; + + const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; + const args = [id, landed, addressId, zoneId, warehouseId]; + const [difComponents] = await Self.rawSql(query, args); + + const map = new Map(); + + difComponents.forEach(difComponent => { + map.set(difComponent.saleFk, difComponent); + }); + + salesObj.items.forEach(sale => { + const difComponent = map.get(sale.id); + + if (difComponent) + sale.component = difComponent; + + salesObj.totalUnitPrice += sale.price; + salesObj.totalNewPrice += sale.component.newPrice; + salesObj.totalDifference += sale.component.difference; + salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100; + salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100; + salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100; + }); + + return salesObj; + }; +}; diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index 347ee9e7e..f3864b6dc 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -28,22 +28,22 @@ describe('ticket componentUpdate()', () => { }); it('should change the agencyMode to modify the sale components value', async() => { - let data = { - clientFk: 102, - agencyModeFk: 8, - addressFk: 122, - warehouseFk: 1, - companyFk: 442, - shipped: today, - landed: tomorrow, - isDeleted: false, - hasToBeUnrouted: false, - option: 1 - }; + const clientId = 102; + const addressId = 122; + const agencyModeId = 8; + const warehouseId = 1; + const zoneId = 5; + const shipped = today; + const companyId = 442; + const isDeleted = false; + const landed = tomorrow; + const hasToBeUnrouted = false; + const option = 1; let ctx = {req: {accessToken: {userId: 101}}}; - await app.models.Ticket.componentUpdate(ticketId, data, ctx); + await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId, + zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option); [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); let firstvalueAfterChange = componentValue.value; @@ -56,21 +56,21 @@ describe('ticket componentUpdate()', () => { }); it('should change the agencyMode to go back to the originals sale components value', async() => { - let data = { - clientFk: 102, - agencyModeFk: 7, - addressFk: 122, - warehouseFk: 1, - companyFk: 442, - shipped: today, - landed: tomorrow, - isDeleted: false, - hasToBeUnrouted: false, - option: 1 - }; + const clientId = 102; + const addressId = 122; + const agencyModeId = 7; + const warehouseId = 1; + const zoneId = 3; + const shipped = today; + const companyId = 442; + const isDeleted = false; + const landed = tomorrow; + const hasToBeUnrouted = false; + const option = 1; let ctx = {req: {accessToken: {userId: 101}}}; - await app.models.Ticket.componentUpdate(ticketId, data, ctx); + await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId, + zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option); [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); let firstvalueAfterChange = componentValue.value; diff --git a/modules/ticket/back/methods/sale/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js similarity index 50% rename from modules/ticket/back/methods/sale/specs/priceDifference.spec.js rename to modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index 4ec7651bd..61060c9a2 100644 --- a/modules/ticket/back/methods/sale/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -3,16 +3,19 @@ let UserError = require('vn-loopback/util/user-error'); describe('sale priceDifference()', () => { it('should return ticket price differences', async() => { - let ctx = {req: {accessToken: {userId: 9}}}; let tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); - let data = { - landed: tomorrow, - addressFk: 126, - agencyModeFk: 7, - warehouseFk: 1 - }; - let result = await app.models.Sale.priceDifference(ctx, 16, data); + + const ticketId = 16; + const landed = tomorrow; + const addressId = 126; + const agencyModeId = 7; + const zoneId = 3; + const warehouseId = 1; + + const httpCtx = {req: {accessToken: {userId: 106}}}; + let result = await app.models.Ticket.priceDifference(httpCtx, ticketId, landed, + addressId, agencyModeId, zoneId, warehouseId); expect(result.totalUnitPrice).toEqual(215.77); expect(result.totalNewPrice).toEqual(215.77); @@ -20,15 +23,14 @@ describe('sale priceDifference()', () => { }); it('should return an error if the ticket is not editable', async() => { - let ctx = {req: {accessToken: {userId: 9}}}; + const ticketId = 1; + const landed = new Date(); + const addressId = 121; + const zoneId = 3; + const warehouseId = 1; let error; - let data = { - landed: new Date(), - addressFk: 121, - agencyModeFk: 1, - warehouseFk: 1 - }; - await app.models.Sale.priceDifference(ctx, 1, data) + const httpCtx = {req: {accessToken: {userId: 106}}}; + await app.models.Ticket.priceDifference(httpCtx, ticketId, landed, addressId, zoneId, warehouseId) .catch(e => { error = e; }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index df5b95839..fc1281911 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -1,6 +1,5 @@ module.exports = Self => { require('../methods/sale/getClaimableFromTicket')(Self); - require('../methods/sale/priceDifference')(Self); require('../methods/sale/moveToTicket')(Self); require('../methods/sale/reserve')(Self); require('../methods/sale/removes')(Self); diff --git a/modules/ticket/back/models/ticket-service.js b/modules/ticket/back/models/ticket-service.js index 1758de476..ce675f360 100644 --- a/modules/ticket/back/models/ticket-service.js +++ b/modules/ticket/back/models/ticket-service.js @@ -4,10 +4,12 @@ const LoopBackContext = require('loopback-context'); module.exports = Self => { Self.observe('before save', async ctx => { const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; + const models = Self.app.models; let changes = ctx.currentInstance || ctx.instance; if (changes) { let ticketId = changes.ticketFk; - let isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, ticketId); + let isEditable = await models.Ticket.isEditable(httpCtx, ticketId); if (!isEditable) throw new UserError(`The current ticket can't be modified`); } @@ -15,9 +17,10 @@ module.exports = Self => { Self.observe('before delete', async ctx => { const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; const models = Self.app.models; const service = await models.TicketService.findById(ctx.where.id); - const isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, service.ticketFk); + const isEditable = await models.Ticket.isEditable(httpCtx, service.ticketFk); if (!isEditable) throw new UserError(`The current ticket can't be modified`); diff --git a/modules/ticket/back/models/ticket.js b/modules/ticket/back/models/ticket.js index a058bbd89..91abb58cb 100644 --- a/modules/ticket/back/models/ticket.js +++ b/modules/ticket/back/models/ticket.js @@ -7,6 +7,7 @@ module.exports = Self => { require('../methods/ticket/getTotal')(Self); require('../methods/ticket/getTaxes')(Self); require('../methods/ticket/subtotal')(Self); + require('../methods/ticket/priceDifference')(Self); require('../methods/ticket/componentUpdate')(Self); require('../methods/ticket/new')(Self); require('../methods/ticket/isEditable')(Self); diff --git a/modules/ticket/front/basic-data/step-one/index.html b/modules/ticket/front/basic-data/step-one/index.html index 20ddc1a69..d3f2807b9 100644 --- a/modules/ticket/front/basic-data/step-one/index.html +++ b/modules/ticket/front/basic-data/step-one/index.html @@ -1,3 +1,11 @@ + + +
@@ -7,8 +15,8 @@ label="Client" show-field="name" value-field="id" - field="$ctrl.clientFk" - initial-data="$ctrl.clientFk" + field="$ctrl.clientId" + initial-data="$ctrl.clientId" order="id"> + field="$ctrl.ticket.warehouseFk" + initial-data="$ctrl.ticket.warehouseFk"> @@ -53,16 +61,29 @@ + field="$ctrl.agencyModeId"> - - - + + + {{::name}} - {{::warehouse.name}} - Max. {{::hour | dateTime: 'HH:mm'}} h. + + + + + +
diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js index d913d7339..636f6a32f 100644 --- a/modules/ticket/front/basic-data/step-one/index.js +++ b/modules/ticket/front/basic-data/step-one/index.js @@ -10,7 +10,11 @@ class Controller { } $onInit() { - this.data.registerChild(this); + this.basicData.registerChild(this); + } + + get ticket() { + return this._ticket; } set ticket(value) { @@ -18,27 +22,23 @@ class Controller { if (!value || !value.id) return; - this.onChangeAddress(value.clientFk); + this.onChangeClient(value.clientFk); } - get ticket() { - return this._ticket; - } - - set clientFk(value) { - this.ticket.clientFk = value; - this.ticket.addressFk = null; - - this.onChangeAddress(value); - } - - get clientFk() { + get clientId() { if (this.ticket) return this.ticket.clientFk; return null; } + set clientId(value) { + this.ticket.clientFk = value; + this.ticket.addressFk = null; + + this.onChangeClient(value); + } + set shipped(value) { this.ticket.shipped = value; this.onChangeShipped(value); @@ -51,11 +51,6 @@ class Controller { return null; } - set landed(value) { - this.ticket.landed = value; - this.onChangeLanded(value); - } - get landed() { if (this.ticket) return this.ticket.landed; @@ -63,47 +58,43 @@ class Controller { return null; } - onChangeShipped(value) { - let params = { - shipped: value, - addressFk: this.ticket.addressFk, - agencyModeFk: this.ticket.agencyModeFk, - warehouseFk: this.ticket.warehouseFk - }; - - let query = `/api/Agencies/getLanded`; - this.$http.get(query, {params}).then(res => { - if (res.data && res.data.landed) - this.ticket.landed = res.data.landed; - else { - return this.vnApp.showError( - this.$translate.instant(`There's no available agency for this shipping date`) - ); - } - }); + set landed(value) { + this.ticket.landed = value; + this.onChangeLanded(value); } - onChangeLanded(value) { - let params = { - landed: value, - addressFk: this.ticket.addressFk, - agencyModeFk: this.ticket.agencyModeFk, - warehouseFk: this.ticket.warehouseFk - }; + get agencyModeId() { + if (this.ticket) + return this.ticket.agencyModeFk; - let query = `/api/Agencies/getShipped`; - this.$http.get(query, {params}).then(res => { - if (res.data) - this.ticket.shipped = res.data; - else { - return this.vnApp.showError( - this.$translate.instant(`There's no available agency for this landing date`) - ); - } - }); + return null; } - onChangeAddress(value) { + set agencyModeId(value) { + this.ticket.agencyModeFk = value; + + if (value) + this.onChangeAgencyMode(value); + } + + get zoneId() { + if (this.ticket) + return this.ticket.zoneFk; + + return null; + } + + set zoneId(value) { + this.ticket.zoneFk = value; + + if (value) + this.onChangeZone(value); + } + + /* + * Autocompletes address on client change + */ + onChangeClient(value) { let filter = { include: [ { @@ -129,6 +120,96 @@ class Controller { }); } + /* + * Returns a landing date + */ + getLanded(params) { + let query = `/api/Agencies/getLanded`; + return this.$http.get(query, {params}); + } + + /* + * Returns a shipment date + */ + getShipped(params) { + let query = `/api/Agencies/getShipped`; + return this.$http.get(query, {params}); + } + + + onChangeShipped(shipped) { + let params = { + shipped: shipped, + addressFk: this.ticket.addressFk, + agencyModeFk: this.ticket.agencyModeFk, + warehouseFk: this.ticket.warehouseFk + }; + let query = `/api/Agencies/getLanded`; + this.$http.get(query, {params}).then(res => { + if (res.data && res.data.landed) + this.ticket.landed = res.data.landed; + else { + return this.vnApp.showError( + this.$translate.instant(`No delivery zone available for this shipping date`) + ); + } + }); + } + + onChangeLanded(landed) { + let params = { + landed: landed, + addressFk: this.ticket.addressFk, + agencyModeFk: this.ticket.agencyModeFk, + warehouseFk: this.ticket.warehouseFk + }; + let query = `/api/Agencies/getShipped`; + this.$http.get(query, {params}).then(res => { + if (res.data) + this.ticket.shipped = res.data.shipped; + else { + return this.vnApp.showError( + this.$translate.instant(`No delivery zone available for this landing date`) + ); + } + }); + } + + /* + * Gets an agency from an specified zone + */ + onChangeZone(zoneId) { + const query = `/api/Zones/${zoneId}`; + this.$http.get(query).then(res => { + if (res.data) + this.ticket.agencyModeFk = res.data.agencyModeFk; + }); + } + + /* + * Gets a zone from an agency + */ + onChangeAgencyMode(agencyModeId) { + let params = { + landed: this.ticket.landed, + addressFk: this.ticket.addressFk, + agencyModeFk: agencyModeId, + warehouseFk: this.ticket.warehouseFk + }; + + this.ticket.zoneFk = null; + let query = `/api/Agencies/getShipped`; + this.$http.get(query, {params}).then(res => { + if (res.data) + this.ticket.zoneFk = res.data.id; + else { + return this.vnApp.showMessage( + this.$translate.instant('No delivery zone available for this parameters') + ); + } + }); + } + async onStepChange() { if (this.isFormInvalid()) { return this.vnApp.showError( @@ -136,35 +217,31 @@ class Controller { ); } - let query = `/ticket/api/sales/${this.ticket.id}/priceDifference`; - let data = { + let query = `/api/tickets/${this.ticket.id}/priceDifference`; + let params = { landed: this.ticket.landed, - addressFk: this.ticket.addressFk, - agencyModeFk: this.ticket.agencyModeFk, - warehouseFk: this.ticket.warehouseFk + addressId: this.ticket.addressFk, + agencyModeId: this.ticket.agencyModeFk, + zoneId: this.ticket.zoneFk, + warehouseId: this.ticket.warehouseFk }; - return this.$http.post(query, data).then(res => { + return this.$http.post(query, params).then(res => { if (res.data) this.ticket.sale = res.data; return true; }, err => { - if (err.data.error.message === 'NO_AGENCY_AVAILABLE') { - this.vnApp.showMessage( - this.$translate.instant(`There's no available agency for this landing date`) - ); - } else { - this.vnApp.showMessage( - this.$translate.instant(err.data.error.message) - ); - } + this.vnApp.showError( + this.$translate.instant(err.data.error.message) + ); }); } isFormInvalid() { return !this.ticket.clientFk || !this.ticket.addressFk || !this.ticket.agencyModeFk - || !this.ticket.companyFk || !this.ticket.shipped || !this.ticket.landed; + || !this.ticket.companyFk || !this.ticket.shipped || !this.ticket.landed + || !this.ticket.zoneFk; } } @@ -177,6 +254,6 @@ ngModule.component('vnTicketBasicDataStepOne', { ticket: '<' }, require: { - data: '^vnTicketBasicData' + basicData: '^vnTicketBasicData' } }); diff --git a/modules/ticket/front/basic-data/step-one/index.spec.js b/modules/ticket/front/basic-data/step-one/index.spec.js index dc3a92f33..646a3a723 100644 --- a/modules/ticket/front/basic-data/step-one/index.spec.js +++ b/modules/ticket/front/basic-data/step-one/index.spec.js @@ -18,21 +18,21 @@ describe('Ticket', () => { })); describe('ticket() setter', () => { - it('should set ticket property and call onChangeAddress() method', () => { - spyOn(controller, 'onChangeAddress'); + it('should set ticket property and call onChangeClient() method', () => { + spyOn(controller, 'onChangeClient'); controller.ticket = {id: 1, clientFk: 101}; - expect(controller.onChangeAddress).toHaveBeenCalledWith(101); + expect(controller.onChangeClient).toHaveBeenCalledWith(101); }); }); - describe('clientFk() setter', () => { - it('should set clientFk property and call onChangeAddress() method ', () => { - spyOn(controller, 'onChangeAddress'); - controller.ticket = {id: 1, clientFk: 101}; - controller.clientFk = 102; + describe('clientId() setter', () => { + it('should set clientId property and call onChangeClient() method ', () => { + spyOn(controller, 'onChangeClient'); + controller.ticket = {id: 1, clientId: 101}; + controller.clientId = 102; - expect(controller.onChangeAddress).toHaveBeenCalledWith(102); + expect(controller.onChangeClient).toHaveBeenCalledWith(102); }); }); @@ -58,6 +58,57 @@ describe('Ticket', () => { }); }); + describe('agencyModeId() setter', () => { + it('should set agencyModeId property and call onChangeAgencyMode() method ', () => { + const agencyModeId = 8; + spyOn(controller, 'onChangeAgencyMode'); + controller.ticket = {id: 1}; + controller.agencyModeId = 8; + + expect(controller.onChangeAgencyMode).toHaveBeenCalledWith(agencyModeId); + }); + }); + + describe('zoneId() setter', () => { + it('should set zoneId property and call onChangeZone() method ', () => { + const zoneId = 5; + spyOn(controller, 'onChangeZone'); + controller.ticket = {id: 1}; + controller.zoneId = 5; + + expect(controller.onChangeZone).toHaveBeenCalledWith(zoneId); + }); + }); + + describe('onChangeClient()', () => { + it('should return a list of addresses from choosed client', async() => { + const clientId = 102; + let filter = { + include: [ + { + relation: 'province', + scope: { + fields: ['name'] + } + }, + { + relation: 'agencyMode', + scope: { + fields: ['name'] + } + } + ] + }; + filter = encodeURIComponent(JSON.stringify(filter)); + + $httpBackend.when('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`).respond(200); + $httpBackend.expect('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`); + + controller.onChangeClient(clientId); + $httpBackend.flush(); + }); + }); + describe('onChangeShipped()', () => { it('should return an available landing date', async() => { let shipped = new Date(); @@ -111,11 +162,51 @@ describe('Ticket', () => { }); }); + describe('onChangeZone()', () => { + it('should return an available zone', async() => { + const zoneId = 5; + + $httpBackend.when('GET', `/api/Zones/${zoneId}`).respond(200); + $httpBackend.expect('GET', `/api/Zones/${zoneId}`); + + controller.onChangeZone(zoneId); + $httpBackend.flush(); + }); + }); + + describe('onChangeAgencyMode()', () => { + it('should return an available agency', async() => { + const landed = new Date(); + const agencyModeId = 7; + controller._ticket = { + id: 1, + landed: landed, + addressFk: 121, + agencyModeFk: agencyModeId, + warehouseFk: 1 + }; + let params = { + landed: landed, + addressFk: 121, + agencyModeFk: agencyModeId, + warehouseFk: 1 + }; + + let serializedParams = $httpParamSerializer(params); + $httpBackend.when('GET', `/api/Agencies/getShipped?${serializedParams}`).respond(200); + $httpBackend.expect('GET', `/api/Agencies/getShipped?${serializedParams}`); + + controller.onChangeAgencyMode(agencyModeId); + $httpBackend.flush(); + }); + }); + describe('isFormInvalid()', () => { it('should check if all form fields are valid', () => { controller.ticket = { clientFk: 1, addressFk: 121, + zoneFk: 3, agencyModeFk: 1, companyFk: 442, warehouseFk: 1, @@ -136,6 +227,7 @@ describe('Ticket', () => { id: 1, clientFk: 1, addressFk: 121, + zoneFk: 3, agencyModeFk: 1, companyFk: 442, warehouseFk: 1, @@ -145,8 +237,8 @@ describe('Ticket', () => { let response = {error: new Error('NO_AGENCY_AVAILABLE')}; - $httpBackend.whenPOST(`/ticket/api/sales/1/priceDifference`).respond(400, response); - $httpBackend.expectPOST(`/ticket/api/sales/1/priceDifference`); + $httpBackend.whenPOST(`/api/tickets/1/priceDifference`).respond(400, response); + $httpBackend.expectPOST(`/api/tickets/1/priceDifference`); controller.onStepChange(); $httpBackend.flush(); }); diff --git a/modules/ticket/front/basic-data/step-one/locale/es.yml b/modules/ticket/front/basic-data/step-one/locale/es.yml index bc86a397b..ab804aea5 100644 --- a/modules/ticket/front/basic-data/step-one/locale/es.yml +++ b/modules/ticket/front/basic-data/step-one/locale/es.yml @@ -1,3 +1,5 @@ -There's no available agency for this landing date: No hay ninguna agencia disponible para la fecha de envío seleccionada +No delivery zone available for this landing date: No hay una zona de reparto disponible para la fecha de envío seleccionada +No delivery zone available for this shipping date: No hay una zona de reparto disponible para la fecha de preparación seleccionada +No delivery zone available for this parameters: No hay una zona de reparto disponible con estos parámetros Deleted: Eliminado -There's no available agency for this shipping date: No hay ninguna agencia disponible para la fecha de preparación seleccionada +Zone: Zona \ No newline at end of file diff --git a/modules/ticket/front/basic-data/step-three/index.js b/modules/ticket/front/basic-data/step-three/index.js index f6ab66a37..04fcbc36e 100644 --- a/modules/ticket/front/basic-data/step-three/index.js +++ b/modules/ticket/front/basic-data/step-three/index.js @@ -29,13 +29,14 @@ class Controller { ); } - let query = `/ticket/api/tickets/${this.ticket.id}/componentUpdate`; - let data = { - clientFk: this.ticket.clientFk, - agencyModeFk: this.ticket.agencyModeFk, - addressFk: this.ticket.addressFk, - warehouseFk: this.ticket.warehouseFk, - companyFk: this.ticket.companyFk, + let query = `/api/tickets/${this.ticket.id}/componentUpdate`; + let params = { + clientId: this.ticket.clientFk, + agencyModeId: this.ticket.agencyModeFk, + addressId: this.ticket.addressFk, + zoneId: this.ticket.zoneFk, + warehouseId: this.ticket.warehouseFk, + companyId: this.ticket.companyFk, shipped: this.ticket.shipped, landed: this.ticket.landed, isDeleted: this.ticket.isDeleted, @@ -43,7 +44,7 @@ class Controller { option: this.ticket.option }; - this.$http.post(query, data).then(res => { + this.$http.post(query, params).then(res => { if (res.data) { this.$state.go('ticket.card.summary', {id: this.$state.params.id}); this.card.reload(); diff --git a/modules/ticket/front/basic-data/step-three/index.spec.js b/modules/ticket/front/basic-data/step-three/index.spec.js index 190a51f75..21301ad88 100644 --- a/modules/ticket/front/basic-data/step-three/index.spec.js +++ b/modules/ticket/front/basic-data/step-three/index.spec.js @@ -36,6 +36,7 @@ describe('ticket', () => { id: 1, agencyModeFk: 1, addressFk: 121, + zoneFk: 3, warehouseFk: 1, shipped: now, landed: now, @@ -43,16 +44,17 @@ describe('ticket', () => { }; let data = { - agencyModeFk: 1, - addressFk: 121, - warehouseFk: 1, + agencyModeId: 1, + addressId: 121, + zoneId: 3, + warehouseId: 1, shipped: now, landed: now, option: 1 }; - $httpBackend.whenPOST(`/ticket/api/tickets/1/componentUpdate`, data).respond('ok'); - $httpBackend.expectPOST(`/ticket/api/tickets/1/componentUpdate`, data); + $httpBackend.whenPOST(`/api/tickets/1/componentUpdate`, data).respond('ok'); + $httpBackend.expectPOST(`/api/tickets/1/componentUpdate`, data); controller.onSubmit(); $httpBackend.flush();