diff --git a/front/core/components/watcher/watcher.js b/front/core/components/watcher/watcher.js
index ddef745fd..04ccba45e 100644
--- a/front/core/components/watcher/watcher.js
+++ b/front/core/components/watcher/watcher.js
@@ -100,7 +100,9 @@ export default class Watcher extends Component {
*/
submit() {
try {
- this.check();
+ if (this.requestMethod() !== 'post')
+ this.check();
+ else this.isInvalid();
} catch (err) {
return this.$q.reject(err);
}
@@ -120,12 +122,12 @@ export default class Watcher extends Component {
if (this.form)
this.form.$setSubmitted();
- if (!this.dataChanged()) {
+ const isPost = (this.requestMethod() === 'post');
+ if (!this.dataChanged() && !isPost) {
this.updateOriginalData();
return this.$q.resolve();
}
- let isPost = (this.$attrs.save && this.$attrs.save.toLowerCase() === 'post');
let changedData = isPost
? this.data
: getModifiedData(this.data, this.orgData);
@@ -158,7 +160,6 @@ export default class Watcher extends Component {
});
}
-
return this.$q((resolve, reject) => {
this.$http.post(this.url, changedData).then(
json => this.writeData(json, resolve),
@@ -167,6 +168,10 @@ export default class Watcher extends Component {
});
}
+ requestMethod() {
+ return this.$attrs.save && this.$attrs.save.toLowerCase();
+ }
+
/**
* Checks if data is ready to send.
*/
@@ -177,6 +182,15 @@ export default class Watcher extends Component {
throw new UserError('No changes to save');
}
+ /**
+ * Checks if data is ready to send.
+ */
+ isInvalid() {
+ console.log(this.form.$invalid);
+ if (this.form && this.form.$invalid)
+ throw new UserError('Some fields are invalid');
+ }
+
/**
* Notifies the user that the data has been saved.
*/
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index fe95bc065..e97518504 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -128,5 +128,6 @@
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
"Distance must be lesser than 1000": "La distancia debe ser inferior a 1000",
- "This ticket is deleted": "Este ticket está eliminado"
+ "This ticket is deleted": "Este ticket está eliminado",
+ "The introduced data already exists": "La información introducida ya existe"
}
\ No newline at end of file
diff --git a/modules/travel/back/models/travel.js b/modules/travel/back/models/travel.js
index 4643f79fd..a7c045b31 100644
--- a/modules/travel/back/models/travel.js
+++ b/modules/travel/back/models/travel.js
@@ -1,3 +1,5 @@
+const UserError = require('vn-loopback/util/user-error');
+
module.exports = Self => {
require('../methods/travel/getTravel')(Self);
require('../methods/travel/getEntries')(Self);
@@ -5,4 +7,10 @@ module.exports = Self => {
require('../methods/travel/createThermograph')(Self);
require('../methods/travel/deleteThermograph')(Self);
require('../methods/travel/updateThermograph')(Self);
+
+ Self.rewriteDbError(function(err) {
+ if (err.code === 'ER_DUP_ENTRY')
+ return new UserError('The introduced data already exists');
+ return err;
+ });
};
diff --git a/modules/travel/front/create/index.js b/modules/travel/front/create/index.js
index 02be34ca7..513e1e0b1 100644
--- a/modules/travel/front/create/index.js
+++ b/modules/travel/front/create/index.js
@@ -2,6 +2,26 @@ import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
+ constructor($element, $, $stateParams) {
+ super($element, $);
+ this.$stateParams = $stateParams;
+ this.travel = {};
+ }
+
+ $onChanges() {
+ if (this.$stateParams && this.$stateParams.q)
+ this._travel = JSON.parse(this.$stateParams.q);
+ }
+
+ get travel() {
+ return this._travel;
+ }
+
+ set travel(value) {
+ this._travel = value;
+ if (!value) return;
+ }
+
onSubmit() {
return this.$.watcher.submit().then(
res => this.$state.go('travel.card.summary', {id: res.data.id})
@@ -9,6 +29,8 @@ class Controller extends Section {
}
}
+Controller.$inject = ['$element', '$scope', '$stateParams'];
+
ngModule.component('vnTravelCreate', {
template: require('./index.html'),
controller: Controller
diff --git a/modules/travel/front/create/index.spec.js b/modules/travel/front/create/index.spec.js
index 63f0eda42..ef83d98ff 100644
--- a/modules/travel/front/create/index.spec.js
+++ b/modules/travel/front/create/index.spec.js
@@ -26,5 +26,22 @@ describe('Travel Component vnTravelCreate', () => {
expect(controller.$state.go).toHaveBeenCalledWith('travel.card.summary', {id: 1234});
});
});
+
+ describe('$onChanges()', () => {
+ it('should update the travel data when stateParams.q is defined', () => {
+ controller.$stateParams = {q: {
+ ref: 1,
+ agencyModeFk: 1
+ }};
+
+ const result = {q: {
+ ref: 1,
+ agencyModeFk: 1
+ }};
+ controller.$onChanges();
+
+ expect(controller._travel).toBe(result);
+ });
+ });
});
diff --git a/modules/travel/front/index/index.html b/modules/travel/front/index/index.html
index 3af99eb6b..ee7f88507 100644
--- a/modules/travel/front/index/index.html
+++ b/modules/travel/front/index/index.html
@@ -41,12 +41,19 @@
{{::travel.warehouseInName}}
{{::travel.landed | date:'dd/MM/yyyy'}}
-
-
-
+
+
+
+
+
+
+
@@ -65,4 +72,10 @@
fixed-bottom-right>
+
+
\ No newline at end of file
diff --git a/modules/travel/front/index/index.js b/modules/travel/front/index/index.js
index a1e22d2e7..8402d00a2 100644
--- a/modules/travel/front/index/index.js
+++ b/modules/travel/front/index/index.js
@@ -1,16 +1,10 @@
import ngModule from '../module';
export default class Controller {
- constructor($scope) {
+ constructor($scope, $state) {
this.$ = $scope;
this.ticketSelected = null;
- }
-
- preview(event, travel) {
- this.travelSelected = travel;
- this.$.summary.show();
- event.preventDefault();
- event.stopImmediatePropagation();
+ this.$state = $state;
}
getScopeDates(days) {
@@ -35,9 +29,45 @@ export default class Controller {
} else
this.$.model.clear();
}
+
+ stopEvent(event) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+
+ cloneTravel(event, travel) {
+ this.stopEvent(event);
+ this.travelSelected = travel;
+ this.$.clone.show();
+ }
+
+ onCloneAccept(response) {
+ if (!(response == 'accept' && this.travelSelected))
+ return;
+ if (this.travelSelected) {
+ console.log('this.travelSelected', this.travelSelected);
+ const travel = {
+ ref: this.travelSelected.ref,
+ agencyModeFk: this.travelSelected.agencyFk,
+ shipped: this.travelSelected.shipped,
+ landed: this.travelSelected.landed,
+ warehouseInFk: this.travelSelected.warehouseInFk,
+ warehouseOutFk: this.travelSelected.warehouseOutFk
+ };
+ const queryParams = JSON.stringify(travel);
+ this.$state.go('travel.create', {q: queryParams});
+ }
+
+ this.travelSelected = null;
+ }
+ preview(event, travel) {
+ this.stopEvent(event);
+ this.travelSelected = travel;
+ this.$.summary.show();
+ }
}
-Controller.$inject = ['$scope'];
+Controller.$inject = ['$scope', '$state'];
ngModule.component('vnTravelIndex', {
template: require('./index.html'),
diff --git a/modules/travel/front/index/index.spec.js b/modules/travel/front/index/index.spec.js
index 5affc7c1a..8e180e168 100644
--- a/modules/travel/front/index/index.spec.js
+++ b/modules/travel/front/index/index.spec.js
@@ -61,4 +61,48 @@ describe('Travel Component vnTravelIndex', () => {
expect(range - dayInMilliseconds).toEqual(dayInMilliseconds + millisecondsPerAddedDay);
});
});
+
+ describe('onCloneAccept()', () => {
+ it('should do nothing if response is not accept', () => {
+ jest.spyOn(controller.$state, 'go');
+
+ let response = 'ERROR!';
+ controller.travelSelected = 'check me';
+
+ controller.onCloneAccept(response);
+
+ expect(controller.$state.go).not.toHaveBeenCalledWith();
+ expect(controller.travelSelected).toEqual('check me');
+ });
+
+ it('should do nothing if response is accept but travelSelected is not defined in the controller', () => {
+ jest.spyOn(controller.$state, 'go');
+
+ let response = 'accept';
+ controller.travelSelected = undefined;
+
+ controller.onCloneAccept(response);
+
+ expect(controller.$state.go).not.toHaveBeenCalledWith();
+ expect(controller.travelSelected).toBeUndefined();
+ });
+
+ it('should call go() then update travelSelected in the controller', () => {
+ jest.spyOn(controller.$state, 'go');
+
+ let response = 'accept';
+ controller.travelSelected = {
+ ref: 1,
+ agencyFk: 1};
+ const travel = {
+ ref: controller.travelSelected.ref,
+ agencyModeFk: controller.travelSelected.agencyFk
+ };
+ const queryParams = JSON.stringify(travel);
+ controller.onCloneAccept(response);
+
+ expect(controller.$state.go).toHaveBeenCalledWith('travel.create', {q: queryParams});
+ expect(controller.travelSelected).toBeNull();
+ });
+ });
});
diff --git a/modules/travel/front/index/locale/es.yml b/modules/travel/front/index/locale/es.yml
new file mode 100644
index 000000000..63d23affd
--- /dev/null
+++ b/modules/travel/front/index/locale/es.yml
@@ -0,0 +1,2 @@
+Do you want to clone this travel?: ¿Desea clonar este envio?
+All it's properties will be copied: Todas sus propiedades serán copiadas
\ No newline at end of file
diff --git a/modules/travel/front/routes.json b/modules/travel/front/routes.json
index 50e236889..b802aaa4a 100644
--- a/modules/travel/front/routes.json
+++ b/modules/travel/front/routes.json
@@ -54,7 +54,7 @@
"component": "vn-travel-log",
"description": "Log"
}, {
- "url": "/create",
+ "url": "/create?q",
"state": "travel.create",
"component": "vn-travel-create",
"description": "New travel"