diff --git a/modules/route/back/methods/route/sendSms.js b/modules/route/back/methods/route/sendSms.js
new file mode 100644
index 000000000..9a93b040e
--- /dev/null
+++ b/modules/route/back/methods/route/sendSms.js
@@ -0,0 +1,46 @@
+/* eslint-disable no-console */
+
+module.exports = Self => {
+ Self.remoteMethodCtx('sendSms', {
+ description: 'Sends a SMS to each client of the routes, each client only recieves the SMS once',
+ accessType: 'WRITE',
+ accepts: [{
+ arg: 'id',
+ type: 'string',
+ required: true,
+ description: 'The routes Ids, is separated by commas',
+ http: {source: 'path'}
+ },
+ {
+ arg: 'destination',
+ type: 'string',
+ description: 'A comma separated string of destinations',
+ required: true,
+ },
+ {
+ arg: 'message',
+ type: 'string',
+ required: true,
+ }],
+ returns: {
+ type: 'object',
+ root: true
+ },
+ http: {
+ path: `/:id/sendSms`,
+ verb: 'POST'
+ }
+ });
+
+ Self.sendSms = async(ctx, id, destination, message) => {
+ const targetClients = destination.split(',');
+
+ const allSms = [];
+ for (let client of targetClients) {
+ let sms = await Self.app.models.Sms.send(ctx, client, message);
+ allSms.push(sms);
+ }
+
+ return allSms;
+ };
+};
diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js
index f5406728a..08cabd30e 100644
--- a/modules/route/back/models/route.js
+++ b/modules/route/back/models/route.js
@@ -12,6 +12,7 @@ module.exports = Self => {
require('../methods/route/updateWorkCenter')(Self);
require('../methods/route/driverRoutePdf')(Self);
require('../methods/route/driverRouteEmail')(Self);
+ require('../methods/route/sendSms')(Self);
Self.validate('kmStart', validateDistance, {
message: 'Distance must be lesser than 1000'
diff --git a/modules/route/front/index.js b/modules/route/front/index.js
index 55cb745e1..c43048df5 100644
--- a/modules/route/front/index.js
+++ b/modules/route/front/index.js
@@ -15,3 +15,4 @@ import './agency-term/index';
import './agency-term/createInvoiceIn';
import './agency-term-search-panel';
import './ticket-popup';
+import './sms';
diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html
index cc76d22f2..e9785d958 100644
--- a/modules/route/front/index/index.html
+++ b/modules/route/front/index/index.html
@@ -160,13 +160,6 @@
+
+
+
+
+
e === ticket.clientFk).length > 0)
+ clientsFk.push(ticket.clientFk);
+ }
+
+ for (let client of clientsFk) {
+ let currentClient = await this.$http.get(`Clients/${client}`);
+ clients.push(currentClient.data);
+ }
+
+ let destination = '';
+ let destinationFk = '';
+ let routesId = '';
+
+ for (let client of clients) {
+ if (destination !== '')
+ destination = destination + ',';
+ if (destinationFk !== '')
+ destinationFk = destinationFk + ',';
+ destination = destination + client.phone;
+ destinationFk = destinationFk + client.id;
+ }
+
+ for (let route of routes) {
+ if (routesId !== '')
+ routesId = routesId + ',';
+ routesId = routesId + route;
+ }
+ this.newSMS = Object.assign({
+ routesId: routesId,
+ destinationFk: destinationFk,
+ destination: destination
+ });
+
+ this.$.sms.open();
+ return true;
+ } catch (e) {
+ this.vnApp.showError(this.$t(e.message));
+ return false;
+ }
+ }
}
Controller.$inject = ['$element', '$scope', 'vnReport'];
diff --git a/modules/route/front/index/locale/es.yml b/modules/route/front/index/locale/es.yml
index e4c5c8c55..3db84d81e 100644
--- a/modules/route/front/index/locale/es.yml
+++ b/modules/route/front/index/locale/es.yml
@@ -8,4 +8,6 @@ Hour finished: Hora fin
Go to route: Ir a la ruta
You must select a valid time: Debe seleccionar una hora válida
You must select a valid date: Debe seleccionar una fecha válida
-Mark as served: Marcar como servidas
\ No newline at end of file
+Mark as served: Marcar como servidas
+Retrieving data from the routes: Recuperando datos de las rutas
+Send SMS to all clients: Mandar sms a todos los clientes de las rutas
\ No newline at end of file
diff --git a/modules/route/front/sms/index.html b/modules/route/front/sms/index.html
new file mode 100644
index 000000000..4f86b346f
--- /dev/null
+++ b/modules/route/front/sms/index.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+ {{'Characters remaining' | translate}}:
+
+ {{$ctrl.charactersRemaining()}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/route/front/sms/index.js b/modules/route/front/sms/index.js
new file mode 100644
index 000000000..701306071
--- /dev/null
+++ b/modules/route/front/sms/index.js
@@ -0,0 +1,47 @@
+import ngModule from '../module';
+import Component from 'core/lib/component';
+import './style.scss';
+
+class Controller extends Component {
+ open() {
+ this.$.SMSDialog.show();
+ }
+
+ charactersRemaining() {
+ const element = this.$.message;
+ const value = element.input.value;
+
+ const maxLength = 160;
+ const textAreaLength = new Blob([value]).size;
+ return maxLength - textAreaLength;
+ }
+
+ onResponse() {
+ try {
+ if (!this.sms.destination)
+ throw new Error(`The destination can't be empty`);
+ if (!this.sms.message)
+ throw new Error(`The message can't be empty`);
+ if (this.charactersRemaining() < 0)
+ throw new Error(`The message it's too long`);
+
+ this.$http.post(`Routes/${this.sms.routesId}/sendSms`, this.sms).then(res => {
+ this.vnApp.showMessage(this.$t('SMS sent!'));
+
+ if (res.data) this.emit('send', {response: res.data});
+ });
+ } catch (e) {
+ this.vnApp.showError(this.$t(e.message));
+ return false;
+ }
+ return true;
+ }
+}
+
+ngModule.vnComponent('vnRouteSms', {
+ template: require('./index.html'),
+ controller: Controller,
+ bindings: {
+ sms: '<',
+ }
+});
diff --git a/modules/route/front/sms/index.spec.js b/modules/route/front/sms/index.spec.js
new file mode 100644
index 000000000..b133db04d
--- /dev/null
+++ b/modules/route/front/sms/index.spec.js
@@ -0,0 +1,71 @@
+import './index';
+
+describe('Ticket', () => {
+ describe('Component vnTicketSms', () => {
+ let controller;
+ let $httpBackend;
+
+ beforeEach(ngModule('ticket'));
+
+ beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
+ $httpBackend = _$httpBackend_;
+ let $scope = $rootScope.$new();
+ const $element = angular.element('');
+ controller = $componentController('vnTicketSms', {$element, $scope});
+ controller.$.message = {
+ input: {
+ value: 'My SMS'
+ }
+ };
+ }));
+
+ describe('onResponse()', () => {
+ it('should perform a POST query and show a success snackbar', () => {
+ let params = {ticketId: 11, destinationFk: 1101, destination: 111111111, message: 'My SMS'};
+ controller.sms = {ticketId: 11, destinationFk: 1101, destination: 111111111, message: 'My SMS'};
+
+ jest.spyOn(controller.vnApp, 'showMessage');
+ $httpBackend.expect('POST', `Tickets/11/sendSms`, params).respond(200, params);
+
+ controller.onResponse();
+ $httpBackend.flush();
+
+ expect(controller.vnApp.showMessage).toHaveBeenCalledWith('SMS sent!');
+ });
+
+ it('should call onResponse without the destination and show an error snackbar', () => {
+ controller.sms = {destinationFk: 1101, message: 'My SMS'};
+
+ jest.spyOn(controller.vnApp, 'showError');
+
+ controller.onResponse();
+
+ expect(controller.vnApp.showError).toHaveBeenCalledWith(`The destination can't be empty`);
+ });
+
+ it('should call onResponse without the message and show an error snackbar', () => {
+ controller.sms = {destinationFk: 1101, destination: 222222222};
+
+ jest.spyOn(controller.vnApp, 'showError');
+
+ controller.onResponse();
+
+ expect(controller.vnApp.showError).toHaveBeenCalledWith(`The message can't be empty`);
+ });
+ });
+
+ describe('charactersRemaining()', () => {
+ it('should return the characters remaining in a element', () => {
+ controller.$.message = {
+ input: {
+ value: 'My message 0€'
+ }
+ };
+
+ let result = controller.charactersRemaining();
+
+ expect(result).toEqual(145);
+ });
+ });
+ });
+});
diff --git a/modules/route/front/sms/locale/es.yml b/modules/route/front/sms/locale/es.yml
new file mode 100644
index 000000000..4d6022921
--- /dev/null
+++ b/modules/route/front/sms/locale/es.yml
@@ -0,0 +1,9 @@
+Send SMS: Enviar SMS
+Routes to notify: Rutas a notificar
+Message: Mensaje
+SMS sent!: ¡SMS enviado!
+Characters remaining: Carácteres restantes
+The destination can't be empty: El destinatario no puede estar vacio
+The message can't be empty: El mensaje no puede estar vacio
+The message it's too long: El mensaje es demasiado largo
+Special characters like accents counts as a multiple: Carácteres especiales como los acentos cuentan como varios
\ No newline at end of file
diff --git a/modules/route/front/sms/style.scss b/modules/route/front/sms/style.scss
new file mode 100644
index 000000000..84571a5f4
--- /dev/null
+++ b/modules/route/front/sms/style.scss
@@ -0,0 +1,5 @@
+@import "variables";
+
+.SMSDialog {
+ min-width: 400px
+}
\ No newline at end of file