diff --git a/db/changes/10190-PostErte/00-route.sql b/db/changes/10190-PostErte/00-route.sql new file mode 100644 index 000000000..5ffab3a46 --- /dev/null +++ b/db/changes/10190-PostErte/00-route.sql @@ -0,0 +1,8 @@ +ALTER TABLE `vn`.`route` +DROP FOREIGN KEY `fk_route_1`; +ALTER TABLE `vn`.`route` +ADD CONSTRAINT `fk_route_1` + FOREIGN KEY (`zoneFk`) + REFERENCES `vn`.`zone` (`id`) + ON DELETE SET NULL + ON UPDATE CASCADE; diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index 113e6a75f..21c34232b 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -42,6 +42,9 @@ }, "priority": { "type": "Number" + }, + "zoneFk": { + "type": "Number" } }, "relations": { diff --git a/modules/travel/front/summary/index.html b/modules/travel/front/summary/index.html index d921bb83d..12dbded4e 100644 --- a/modules/travel/front/summary/index.html +++ b/modules/travel/front/summary/index.html @@ -76,7 +76,7 @@ {{entry.id}} - {{entry.supplierName}} + {{entry.supplierName}} {{entry.ref}} {{entry.hb}} {{entry.freightValue | currency: 'EUR': 2}} diff --git a/modules/zone/back/methods/zone/deleteZone.js b/modules/zone/back/methods/zone/deleteZone.js new file mode 100644 index 000000000..b371972bf --- /dev/null +++ b/modules/zone/back/methods/zone/deleteZone.js @@ -0,0 +1,44 @@ +module.exports = Self => { + Self.remoteMethod('deleteZone', { + description: 'Delete a zone', + accessType: 'WRITE', + accepts: { + arg: 'id', + type: 'Number', + description: 'The zone id', + http: {source: 'path'} + }, + returns: { + type: 'Object', + root: true + }, + http: { + path: `/:id/deleteZone`, + verb: 'POST' + } + }); + + Self.deleteZone = async id => { + const models = Self.app.models; + const tx = await Self.beginTransaction({}); + + try { + const options = {transaction: tx}; + const filter = {where: {zoneFk: id}}; + const promises = []; + + const ticketList = await models.Ticket.find(filter, options); + ticketList.forEach(ticket => { + promises.push(ticket.updateAttributes({zoneFk: null}, options)); + }); + await Promise.all(promises); + await models.Zone.destroyById(id, options); + await tx.commit(); + + return id; + } catch (err) { + await tx.rollback(); + throw err; + } + }; +}; diff --git a/modules/zone/back/methods/zone/specs/deleteZone.spec.js b/modules/zone/back/methods/zone/specs/deleteZone.spec.js new file mode 100644 index 000000000..74ae7751d --- /dev/null +++ b/modules/zone/back/methods/zone/specs/deleteZone.spec.js @@ -0,0 +1,33 @@ +const app = require('vn-loopback/server/server'); + +describe('zone deletezone()', () => { + let zoneId = 1; + let originalZoneTickets; + let originalZone; + + beforeAll(async done => { + originalZone = await app.models.Zone.findById(zoneId); + originalZoneTickets = await app.models.Ticket.find({where: {zoneFk: zoneId}}); + done(); + }); + + afterAll(async done => { + await originalZone.save(); + + originalZoneTickets.forEach(async ticket => { + await ticket.updateAttributes({zoneFk: zoneId}); + }); + done(); + }); + + it('should delete a zone and update their tickets', async() => { + await app.models.Zone.deleteZone(zoneId); + + let updatedZone = await app.models.Zone.findById(zoneId); + let zoneUpdatedTicket = await app.models.Ticket.findById(originalZoneTickets[0].id); + + expect(updatedZone).toBeNull(); + expect(zoneUpdatedTicket.zoneFk).not.toBe(zoneId); + }); +}); + diff --git a/modules/zone/back/models/zone.js b/modules/zone/back/models/zone.js index 07fec96ce..b0f21c998 100644 --- a/modules/zone/back/models/zone.js +++ b/modules/zone/back/models/zone.js @@ -4,6 +4,7 @@ module.exports = Self => { require('../methods/zone/getEvents')(Self); require('../methods/zone/toggleIsIncluded')(Self); require('../methods/zone/getUpcomingDeliveries')(Self); + require('../methods/zone/deleteZone')(Self); Self.validatesPresenceOf('agencyModeFk', { message: `Agency cannot be blank` diff --git a/modules/zone/front/descriptor/index.html b/modules/zone/front/descriptor/index.html index e1fa1c0ea..d4d3eca7b 100644 --- a/modules/zone/front/descriptor/index.html +++ b/modules/zone/front/descriptor/index.html @@ -3,10 +3,16 @@ description="$ctrl.zone.name"> Delete + + Clone +
@@ -39,7 +45,12 @@ + + \ No newline at end of file diff --git a/modules/zone/front/descriptor/index.js b/modules/zone/front/descriptor/index.js index a68a450ea..4b51c8011 100644 --- a/modules/zone/front/descriptor/index.js +++ b/modules/zone/front/descriptor/index.js @@ -10,9 +10,33 @@ class Controller extends Descriptor { this.entity = value; } - onDeleteAccept() { - return this.$http.delete(`Zones/${this.id}`) - .then(() => this.$state.go('zone.index')); + onDelete() { + const $t = this.$translate.instant; + const today = new Date(); + today.setHours(0, 0, 0, 0); + const filter = {where: {zoneFk: this.id, shipped: {gte: today}}}; + this.$http.get(`Tickets`, {filter}).then(res => { + const ticketsAmount = res.data.length; + if (ticketsAmount) { + const params = {ticketsAmount}; + console.log('ticketsAmount', res.data); + const question = $t('This zone contains tickets', params, null, null, 'sanitizeParameters'); + this.$.deleteZone.question = question; + this.$.deleteZone.show(); + } else + this.deleteZone(); + }); + } + + deleteZone() { + return this.$http.post(`Zones/${this.id}/deleteZone`).then(() => { + this.$state.go('zone.index'); + this.vnApp.showSuccess(this.$t('Zone deleted')); + }); + } + onCloneAccept() { + return this.$http.post(`Zones/${this.id}/clone`). + then(res => this.$state.go('zone.card.basicData', {id: res.data.id})); } } diff --git a/modules/zone/front/descriptor/locale/es.yml b/modules/zone/front/descriptor/locale/es.yml new file mode 100644 index 000000000..67bcbb5b7 --- /dev/null +++ b/modules/zone/front/descriptor/locale/es.yml @@ -0,0 +1,4 @@ +This zone contains tickets: Esta zona contiene {{ticketsAmount}} tickets. ¿Seguro que quieres eliminar esta zona? +Do you want to clone this zone?: ¿Quieres clonar esta zona? +All it's properties will be copied: Todas sus propiedades serán copiadas +Zone deleted: Zona eliminada \ No newline at end of file