Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
fba637f3b3
|
@ -1,49 +1,55 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.item"
|
||||
form = "form">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.submit()">
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-one margin-medium-top>
|
||||
<vn-title>Item Niches</vn-title>
|
||||
<vn-horizontal ng-repeat="itemNiche in $ctrl.niches track by $index">
|
||||
<vn-autocomplete
|
||||
vn-three
|
||||
initial-data = "itemNiche.warehouse"
|
||||
field = "itemNiche.warehouseFk"
|
||||
data = "$ctrl.warehouses"
|
||||
show-field = "name"
|
||||
value-field = "id"
|
||||
label = "Warehouse"
|
||||
order = "name ASC"
|
||||
vn-acl="buyer,replenisher">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
vn-three label="code"
|
||||
model="itemNiche.code"
|
||||
rule="itemNiche.code"
|
||||
vn-acl="buyer,replenisher">
|
||||
</vn-textfield>
|
||||
<vn-one pad-medium-top>
|
||||
<vn-icon
|
||||
vn-acl="buyer,replenisher"
|
||||
pointer
|
||||
medium-grey
|
||||
icon="remove_circle_outline"
|
||||
ng-click="$ctrl.removeNiche($index)">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-acl="buyer, replenisher"
|
||||
pointer
|
||||
margin-medium-left
|
||||
orange
|
||||
icon="add_circle"
|
||||
ng-if = "itemNiche.showAddIcon"
|
||||
ng-click="$ctrl.addNiche()">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-title>Item Niches</vn-title>
|
||||
<vn-horizontal ng-repeat="itemNiche in $ctrl.niches track by $index">
|
||||
<vn-autocomplete
|
||||
vn-three
|
||||
initial-data = "itemNiche.warehouse"
|
||||
field = "itemNiche.warehouseFk"
|
||||
data = "$ctrl.warehouses"
|
||||
show-field = "name"
|
||||
value-field = "id"
|
||||
label = "Warehouse"
|
||||
order = "name ASC"
|
||||
vn-acl="buyer,replenisher">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
vn-three
|
||||
label="code"
|
||||
model="itemNiche.code"
|
||||
rule="itemNiche.code"
|
||||
vn-acl="buyer,replenisher">
|
||||
</vn-textfield>
|
||||
<vn-one pad-medium-top>
|
||||
<vn-icon
|
||||
vn-acl="buyer,replenisher"
|
||||
pointer
|
||||
medium-grey
|
||||
icon="remove_circle_outline"
|
||||
ng-click="$ctrl.removeNiche($index)">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-acl="buyer, replenisher"
|
||||
pointer
|
||||
margin-medium-left
|
||||
orange
|
||||
icon="add_circle"
|
||||
ng-if = "itemNiche.showAddIcon"
|
||||
ng-click="$ctrl.addNiche()">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
</form>
|
|
@ -1,8 +1,8 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
export default class Controller {
|
||||
constructor($state, $scope, $http, $translate, vnApp) {
|
||||
this.$state = $state;
|
||||
constructor($stateParams, $scope, $http, $translate, vnApp) {
|
||||
this.params = $stateParams;
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.$translate = $translate;
|
||||
|
@ -38,7 +38,7 @@ export default class Controller {
|
|||
}
|
||||
|
||||
addNiche() {
|
||||
this.niches.push({code: null, itemFk: this.$state.params.id, showAddIcon: true});
|
||||
this.niches.push({code: null, itemFk: this.params.id, showAddIcon: true});
|
||||
this._setIconAdd();
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,34 @@ export default class Controller {
|
|||
return oldNiche.id === newNiche.id && oldNiche.code === newNiche.code && oldNiche.warehouseFk === newNiche.warehouseFk;
|
||||
}
|
||||
|
||||
setOldNiches(response) {
|
||||
this._setIconAdd();
|
||||
response.data.forEach(niche => {
|
||||
this.oldNiches[niche.id] = Object.assign({}, niche);
|
||||
});
|
||||
}
|
||||
|
||||
getNiches() {
|
||||
let filter = {
|
||||
where: {itemFk: this.params.id},
|
||||
include: {relation: 'warehouse'}
|
||||
};
|
||||
this.$http.get(`/item/api/ItemNiches?filter=${JSON.stringify(filter)}`).then(response => {
|
||||
this.niches = response.data;
|
||||
this.setOldNiches(response);
|
||||
});
|
||||
}
|
||||
|
||||
getWarehouse(id, warehouses) {
|
||||
return warehouses.find(warehouse => warehouse.id === id);
|
||||
}
|
||||
|
||||
getWarehouses() {
|
||||
this.$http.get(`/item/api/Warehouses`).then(response => {
|
||||
this.warehouses = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
submit() {
|
||||
let warehousesDefined = [];
|
||||
let repeatedWarehouse = false;
|
||||
|
@ -92,6 +120,7 @@ export default class Controller {
|
|||
if (repeatedWarehouse) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('The niche must be unique'));
|
||||
}
|
||||
|
||||
canSubmit = nichesObj.update.length > 0 || nichesObj.create.length > 0 || nichesObj.delete.length > 0;
|
||||
|
||||
if (canSubmit) {
|
||||
|
@ -103,41 +132,13 @@ export default class Controller {
|
|||
this.vnApp.showMessage(this.$translate.instant('No changes to save'));
|
||||
}
|
||||
|
||||
setOldNiches(response) {
|
||||
this._setIconAdd();
|
||||
response.data.forEach(niche => {
|
||||
this.oldNiches[niche.id] = Object.assign({}, niche);
|
||||
});
|
||||
}
|
||||
|
||||
getWarehouse(id, warehouses) {
|
||||
return warehouses.find(warehouse => warehouse.id === id);
|
||||
}
|
||||
|
||||
getNiches() {
|
||||
let filter = {
|
||||
where: {itemFk: this.$state.params.id},
|
||||
include: {relation: 'warehouse'}
|
||||
};
|
||||
this.$http.get(`/item/api/ItemNiches?filter=${JSON.stringify(filter)}`).then(response => {
|
||||
this.niches = response.data;
|
||||
this.setOldNiches(response);
|
||||
});
|
||||
}
|
||||
|
||||
getWarehouses() {
|
||||
this.$http.get(`/item/api/Warehouses`).then(response => {
|
||||
this.warehouses = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.getNiches();
|
||||
this.getWarehouses();
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$state', '$scope', '$http', '$translate', 'vnApp'];
|
||||
Controller.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnApp'];
|
||||
|
||||
ngModule.component('vnItemNiche', {
|
||||
template: require('./item-niche.html'),
|
||||
|
|
|
@ -18,7 +18,7 @@ describe('Item', () => {
|
|||
controller = $componentController('vnItemNiche', {$state: $state});
|
||||
}));
|
||||
|
||||
describe('add / remove niche()', () => {
|
||||
describe('add / remove niche', () => {
|
||||
it('should add one empty niche into controller niches collection and call _setIconAdd()', () => {
|
||||
controller.niches = [];
|
||||
spyOn(controller, '_setIconAdd').and.callThrough();
|
||||
|
@ -72,7 +72,7 @@ describe('Item', () => {
|
|||
it('should perform a GET query to receive the item niches', () => {
|
||||
let res = [{id: 1, warehouseFk: 1, code: '1111'}];
|
||||
|
||||
$httpBackend.when('GET', `/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`).respond(res);
|
||||
$httpBackend.whenGET(`/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`).respond(res);
|
||||
$httpBackend.expectGET(`/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`);
|
||||
controller.getNiches();
|
||||
$httpBackend.flush();
|
||||
|
@ -84,7 +84,7 @@ describe('Item', () => {
|
|||
{id: 2, warehouseFk: 2, name: 'warehouse two'}
|
||||
];
|
||||
|
||||
$httpBackend.when('GET', `/item/api/Warehouses`).respond(res);
|
||||
$httpBackend.whenGET(`/item/api/Warehouses`).respond(res);
|
||||
$httpBackend.expectGET(`/item/api/Warehouses`);
|
||||
controller.getWarehouses();
|
||||
$httpBackend.flush();
|
||||
|
@ -93,6 +93,7 @@ describe('Item', () => {
|
|||
|
||||
describe('submit()', () => {
|
||||
it("should return an error message 'The niche must be unique' when the niche code isnt unique", () => {
|
||||
controller.$scope.form = {};
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
controller.niches = [
|
||||
{warehouseFk: 1, code: 123454, itemFk: 1, id: 1},
|
||||
|
@ -105,17 +106,19 @@ describe('Item', () => {
|
|||
});
|
||||
|
||||
it("should perfom a query to delete niches", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.oldNiches = {1: {id: 1, warehouseFk: 1, code: '1111'}};
|
||||
controller.niches = [];
|
||||
controller.removedNiches = [1];
|
||||
|
||||
$httpBackend.when('GET', `/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`).respond([]);
|
||||
$httpBackend.whenGET(`/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`).respond([]);
|
||||
$httpBackend.expectPOST(`/item/api/ItemNiches/crudItemNiches`).respond('ok!');
|
||||
controller.submit();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it("should perfom a query to update niches", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.niches = [{id: 1, warehouseFk: 1, code: '2222'}];
|
||||
controller.oldNiches = {1: {id: 1, warehouseFk: 1, code: '1111'}};
|
||||
|
||||
|
@ -126,6 +129,7 @@ describe('Item', () => {
|
|||
});
|
||||
|
||||
it("should perfom a query to create new niche", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.niches = [{warehouseFk: 1, code: 1111, itemFk: 1}];
|
||||
|
||||
$httpBackend.whenGET(`/item/api/ItemNiches?filter={"where":{},"include":{"relation":"warehouse"}}`).respond([]);
|
||||
|
@ -135,6 +139,7 @@ describe('Item', () => {
|
|||
});
|
||||
|
||||
it("should return a message 'No changes to save' when there are no changes to apply", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
controller.oldNiches = [
|
||||
{warehouseFk: 1, code: 1, itemFk: 1, id: 1},
|
||||
|
|
|
@ -5,36 +5,46 @@
|
|||
<form name="form" ng-submit="$ctrl.submit()">
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Item tags</vn-title>
|
||||
<mg-ajax path="/item/api/Tags" options="mgIndex as tags"></mg-ajax>
|
||||
<vn-horizontal ng-repeat="itemTag in $ctrl.itemTags track by $index">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
initial-data = "itemTag.tag"
|
||||
field = "itemTag.tagFk"
|
||||
data = "tags.model"
|
||||
show-field = "name"
|
||||
label = "Tag">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield vn-three label="Value" model="itemTag.value"></vn-textfield>
|
||||
<vn-textfield vn-one type="number" label="Priority" model="itemTag.priority"></vn-textfield>
|
||||
<vn-one pad-medium-top>
|
||||
<vn-icon
|
||||
pointer
|
||||
medium-grey
|
||||
icon="remove_circle_outline"
|
||||
ng-click="$ctrl.removeItemTag($index)">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
pointer
|
||||
margin-medium-left
|
||||
orange
|
||||
icon="add_circle"
|
||||
ng-if = "itemTag.showAddIcon && tags.model.length > $ctrl.itemTags.length"
|
||||
ng-click="$ctrl.addItemTag()">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-one margin-medium-top>
|
||||
<vn-title>Item tags</vn-title>
|
||||
<mg-ajax path="/item/api/Tags" options="mgIndex as tags"></mg-ajax>
|
||||
<vn-horizontal ng-repeat="itemTag in $ctrl.itemTags track by $index">
|
||||
<vn-autocomplete
|
||||
vn-three
|
||||
initial-data = "itemTag.tag"
|
||||
field = "itemTag.tagFk"
|
||||
data = "tags.model"
|
||||
show-field = "name"
|
||||
label = "Tag"
|
||||
order = "name ASC"
|
||||
vn-acl="buyer">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
vn-three
|
||||
label="Value"
|
||||
model="itemTag.value"
|
||||
rule="itemTag.value"
|
||||
vn-acl="buyer">
|
||||
</vn-textfield>
|
||||
<vn-one pad-medium-top>
|
||||
<vn-icon
|
||||
pointer
|
||||
medium-grey
|
||||
icon="remove_circle_outline"
|
||||
ng-click="$ctrl.removeItemTag($index)"
|
||||
vn-acl="buyer">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
pointer
|
||||
margin-medium-left
|
||||
orange
|
||||
icon="add_circle"
|
||||
ng-if = "itemTag.showAddIcon && tags.model.length > $ctrl.itemTags.length"
|
||||
ng-click="$ctrl.addItemTag()"
|
||||
vn-acl="buyer">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class ItemTags {
|
||||
constructor($http, $scope, $translate, vnApp, params) {
|
||||
this.$http = $http;
|
||||
constructor($stateParams, $scope, $http, $translate, vnApp) {
|
||||
this.params = $stateParams;
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.$translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.itemId = params.id;
|
||||
|
||||
this.itemTagTypes = [];
|
||||
this.itemTags = [];
|
||||
this.itemTagsRemoved = [];
|
||||
this.removedItemTags = [];
|
||||
this.oldItemTags = {};
|
||||
}
|
||||
|
||||
|
@ -34,82 +36,89 @@ class ItemTags {
|
|||
}
|
||||
}
|
||||
|
||||
addItemTag() {
|
||||
this.itemTags.push({value: null, itemFk: this.params.id, showAddIcon: true});
|
||||
this._setIconAdd();
|
||||
}
|
||||
|
||||
removeItemTag(index) {
|
||||
let item = this.itemTags[index];
|
||||
if (item) {
|
||||
this.itemTags.splice(index, 1);
|
||||
this._setIconAdd();
|
||||
if (item.id) {
|
||||
this.itemTagsRemoved.push(item.id);
|
||||
this.removedItemTags.push(item.id);
|
||||
this._setDirtyForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addItemTag() {
|
||||
this.itemTags.push({value: null, itemFk: this.itemId, tagFk: null, priority: null, showAddIcon: true});
|
||||
this._setIconAdd();
|
||||
_equalItemTags(oldTag, newTag) {
|
||||
return oldTag.id === newTag.id && oldTag.value === newTag.value && oldTag.tagFk === newTag.tagFk;
|
||||
}
|
||||
|
||||
_setOlTags(itemTags) {
|
||||
itemTags.map(tag => {
|
||||
_setOlTags(response) {
|
||||
this._setIconAdd();
|
||||
response.data.forEach(tag => {
|
||||
this.oldItemTags[tag.id] = Object.assign({}, tag);
|
||||
return tag;
|
||||
});
|
||||
this._setIconAdd();
|
||||
}
|
||||
|
||||
_getItemtags() {
|
||||
_getItemTags() {
|
||||
let filter = {
|
||||
where: {itemFk: this.itemId},
|
||||
where: {itemFk: this.params.id},
|
||||
order: "priority ASC",
|
||||
include: {relation: "tag"}
|
||||
};
|
||||
this.$http.get(`/item/api/ItemTags?filter=${JSON.stringify(filter)}`).then(response => {
|
||||
this.itemTags = response.data;
|
||||
this._setOlTags(response.data);
|
||||
this._setOlTags(response);
|
||||
});
|
||||
}
|
||||
|
||||
_equalItemTags(tagOld, tagNew) {
|
||||
return tagOld.tagFk === tagNew.tagFk && tagOld.value === tagNew.value && tagOld.priority === tagNew.priority;
|
||||
}
|
||||
|
||||
submit() {
|
||||
let codes = [];
|
||||
let itemTagsDefined = [];
|
||||
let repeatedItemTags = false;
|
||||
let canSubmit;
|
||||
let submitObj = {
|
||||
delete: this.itemTagsRemoved,
|
||||
let tagsObj = {
|
||||
delete: this.removedItemTags,
|
||||
create: [],
|
||||
update: []
|
||||
};
|
||||
for (let i = 0; i < this.itemTags.length; i++) {
|
||||
let itemTag = this.itemTags[i];
|
||||
let isNewItemTag = itemTag.id === undefined;
|
||||
this.itemTags.forEach(tag => {
|
||||
let isNewTag = !tag.id;
|
||||
|
||||
if (itemTag.tagFk && codes.indexOf(itemTag.tagFk) !== -1) {
|
||||
if (itemTagsDefined.indexOf(tag.tagFk) !== -1) {
|
||||
repeatedItemTags = true;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
if (itemTag.tagFk) codes.push(itemTag.tagFk);
|
||||
itemTagsDefined.push(tag.tagFk);
|
||||
|
||||
if (isNewItemTag && itemTag.tagFk) {
|
||||
submitObj.create.push(itemTag);
|
||||
} else if (!isNewItemTag && !this._equalItemTags(this.oldItemTags[itemTag.id], itemTag)) {
|
||||
submitObj.update.push(itemTag);
|
||||
if (isNewTag) {
|
||||
tagsObj.create.push(tag);
|
||||
}
|
||||
|
||||
if (!isNewTag && !this._equalItemTags(this.oldItemTags[tag.id], tag)) {
|
||||
let tagToUpdate = Object.assign({}, tag);
|
||||
delete tagToUpdate.tag;
|
||||
delete tagToUpdate.showAddIcon;
|
||||
tagsObj.update.push(tagToUpdate);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.$scope.form.$invalid) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('Some fields are invalid'));
|
||||
}
|
||||
|
||||
if (repeatedItemTags) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('The tag must be unique'));
|
||||
}
|
||||
|
||||
canSubmit = submitObj.update.length > 0 || submitObj.create.length > 0 || submitObj.delete.length > 0;
|
||||
canSubmit = tagsObj.update.length > 0 || tagsObj.create.length > 0 || tagsObj.delete.length > 0;
|
||||
|
||||
if (canSubmit) {
|
||||
return this.$http.post(`/item/api/ItemTags/crudItemTags`, submitObj).then(() => {
|
||||
this._getItemtags();
|
||||
return this.$http.post(`/item/api/ItemTags/crudItemTags`, tagsObj).then(() => {
|
||||
this._getItemTags();
|
||||
this._unsetDirtyForm();
|
||||
});
|
||||
}
|
||||
|
@ -117,10 +126,10 @@ class ItemTags {
|
|||
}
|
||||
|
||||
$onInit() {
|
||||
this._getItemtags();
|
||||
this._getItemTags();
|
||||
}
|
||||
}
|
||||
ItemTags.$inject = ['$http', '$scope', '$translate', 'vnApp', '$stateParams'];
|
||||
ItemTags.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnApp'];
|
||||
|
||||
ngModule.component('vnItemTags', {
|
||||
template: require('./item-tags.html'),
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
import './item-tags.js';
|
||||
|
||||
describe('Item', () => {
|
||||
describe('Component vnItemTags', () => {
|
||||
let $componentController;
|
||||
let $state;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('item');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$state = _$state_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnItemTags', {$state: $state});
|
||||
}));
|
||||
|
||||
describe('add / remove tags', () => {
|
||||
it('should add one empty tag into controller tags collection and call _setIconAdd()', () => {
|
||||
controller.itemTags = [];
|
||||
spyOn(controller, '_setIconAdd').and.callThrough();
|
||||
controller.addItemTag();
|
||||
|
||||
expect(controller._setIconAdd).toHaveBeenCalledWith();
|
||||
expect(controller.itemTags.length).toEqual(1);
|
||||
expect(controller.itemTags[0].id).toBe(undefined);
|
||||
expect(controller.itemTags[0].showAddIcon).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should remove a tag that occupies the position in the index given and call _setIconAdd()', () => {
|
||||
let index = 2;
|
||||
controller.itemTags = [
|
||||
{id: 1, typeFk: 1, value: '1111', showAddIcon: false},
|
||||
{id: 2, typeFk: 2, value: '2222', showAddIcon: false},
|
||||
{id: 3, typeFk: 3, value: '3333', showAddIcon: true}
|
||||
];
|
||||
|
||||
spyOn(controller, '_setIconAdd').and.callThrough();
|
||||
|
||||
controller.removeItemTag(index);
|
||||
|
||||
expect(controller._setIconAdd).toHaveBeenCalledWith();
|
||||
expect(controller.itemTags.length).toEqual(2);
|
||||
expect(controller.itemTags[0].showAddIcon).toBeFalsy();
|
||||
expect(controller.itemTags[1].showAddIcon).toBeTruthy();
|
||||
expect(controller.itemTags[index]).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_equalItemTags()', () => {
|
||||
it('should return true if two tags are equals independent of control attributes', () => {
|
||||
let tag1 = {id: 1, typeFk: 1, value: '1111', showAddIcon: true};
|
||||
let tag2 = {id: 1, typeFk: 1, value: '1111', showAddIcon: false};
|
||||
let equals = controller._equalItemTags(tag2, tag1);
|
||||
|
||||
expect(equals).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if two tags aint equal independent of control attributes', () => {
|
||||
let tag1 = {id: 1, typeFk: 1, value: '1111', showAddIcon: true};
|
||||
let tag2 = {id: 1, typeFk: 1, value: '2222', showAddIcon: true};
|
||||
let equals = controller._equalItemTags(tag2, tag1);
|
||||
|
||||
expect(equals).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('get itemTags', () => {
|
||||
it('should perform a GET query to receive the item tags', () => {
|
||||
let res = [{id: 1, typeFk: 1, value: '1111'}];
|
||||
|
||||
$httpBackend.whenGET(`/item/api/ItemTags?filter={"where":{},"order":"priority ASC","include":{"relation":"tag"}}`).respond(res);
|
||||
$httpBackend.expectGET(`/item/api/ItemTags?filter={"where":{},"order":"priority ASC","include":{"relation":"tag"}}`);
|
||||
controller._getItemTags();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('submit()', () => {
|
||||
it("should return an error message 'The tag must be unique' when the tag value isnt unique", () => {
|
||||
controller.$scope.form = [];
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
controller.itemTags = [
|
||||
{typeFk: 1, value: 123454, itemFk: 1, id: 1},
|
||||
{typeFk: 1, value: 123454, itemFk: 1}
|
||||
];
|
||||
controller.oldItemTags = {1: {typeFk: 1, id: 1, value: 123454, itemFk: 1}};
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The tag must be unique');
|
||||
});
|
||||
|
||||
it("should perfom a query to delete tags", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.oldItemTags = {1: {id: 1, typeFk: 1, value: '1111'}};
|
||||
controller.itemTags = [];
|
||||
controller.removedItemTags = [1];
|
||||
|
||||
$httpBackend.whenGET(`/item/api/ItemTags?filter={"where":{},"order":"priority ASC","include":{"relation":"tag"}}`).respond([]);
|
||||
$httpBackend.expectPOST(`/item/api/ItemTags/crudItemTags`).respond('ok!');
|
||||
controller.submit();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it("should perfom a query to update tags", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.itemTags = [{id: 1, typeFk: 1, value: '2222'}];
|
||||
controller.oldItemTags = {1: {id: 1, typeFk: 1, value: '1111'}};
|
||||
|
||||
$httpBackend.whenGET(`/item/api/ItemTags?filter={"where":{},"order":"priority ASC","include":{"relation":"tag"}}`).respond([]);
|
||||
$httpBackend.expectPOST(`/item/api/ItemTags/crudItemTags`).respond('ok!');
|
||||
controller.submit();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it("should perfom a query to create new tag", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
controller.itemTags = [{typeFk: 1, value: 1111, itemFk: 1}];
|
||||
|
||||
$httpBackend.whenGET(`/item/api/ItemTags?filter={"where":{},"order":"priority ASC","include":{"relation":"tag"}}`).respond([]);
|
||||
$httpBackend.expectPOST(`/item/api/ItemTags/crudItemTags`).respond('ok!');
|
||||
controller.submit();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it("should return a message 'No changes to save' when there are no changes to apply", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
controller.oldItemTags = [
|
||||
{typeFk: 1, value: 1, itemFk: 1, id: 1},
|
||||
{typeFk: 2, value: 2, itemFk: 1, id: 2}
|
||||
];
|
||||
controller.itemTags = [];
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No changes to save');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -181,6 +181,27 @@ export default {
|
|||
expenceSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
|
||||
submitBasicDataButton: `${components.vnSubmit}`
|
||||
},
|
||||
itemTags: {
|
||||
tagsButton: `${components.vnMenuItem}[ui-sref="item.card.tags"]`,
|
||||
firstTagSelect: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
firstTagSelectOptionOne: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
|
||||
firstValueInput: `vn-horizontal:nth-child(3) > ${components.vnTextfield}`,
|
||||
secondTagSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
secondTagSelectOptionOne: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
|
||||
secondValueInput: `vn-horizontal:nth-child(4) > ${components.vnTextfield}`,
|
||||
thirdTagSelect: `vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
thirdTagSelectOptionOne: `vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
|
||||
thirdValueInput: `vn-horizontal:nth-child(5) > ${components.vnTextfield}`,
|
||||
fourthTagSelect: `vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
fourthTagSelectOptionOne: `vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
|
||||
fourthValueInput: `vn-horizontal:nth-child(6) > ${components.vnTextfield}`,
|
||||
fifthRemoveTagButton: `vn-horizontal:nth-child(7) > vn-one > ${components.vnIcon}[icon="remove_circle_outline"]`,
|
||||
addItemTagButton: `${components.vnIcon}[icon="add_circle"]`,
|
||||
fifthTagSelect: `vn-horizontal:nth-child(7) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
fifthTagSelectOptionFive: `vn-horizontal:nth-child(7) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(5)`,
|
||||
fifthValueInput: `vn-horizontal:nth-child(7) > ${components.vnTextfield}`,
|
||||
submitItemTagsButton: `${components.vnSubmit}`
|
||||
},
|
||||
itemTax: {
|
||||
taxButton: `${components.vnMenuItem}[ui-sref="item.card.tax"]`,
|
||||
firstClassSelect: `vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="tax.taxClassFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
|
@ -221,9 +242,6 @@ export default {
|
|||
speciesSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
|
||||
submitBotanicalButton: `${components.vnSubmit}`
|
||||
},
|
||||
itemTags: {
|
||||
tagsButton: `${components.vnMenuItem}[ui-sref="item.card.tags"]`
|
||||
},
|
||||
itemSummary: {
|
||||
basicData: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(2) > vn-vertical > p:nth-child(2)`,
|
||||
tags: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(3) > vn-vertical > p`,
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/helpers';
|
||||
|
||||
describe('create item tags path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
it('should access to the items index by clicking the items button', () => {
|
||||
return nightmare
|
||||
.click(selectors.moduleAccessView.itemsSectionButton)
|
||||
.wait(selectors.itemsIndex.createItemButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/item/list');
|
||||
});
|
||||
});
|
||||
|
||||
it('should search for the item Gem of Time', () => {
|
||||
return nightmare
|
||||
.wait(selectors.itemsIndex.searchResult)
|
||||
.type(selectors.itemsIndex.searchItemInput, 'Gem of Time')
|
||||
.click(selectors.itemsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.itemsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the item tags`, () => {
|
||||
return nightmare
|
||||
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Gem of Time')
|
||||
.waitToClick(selectors.itemsIndex.searchResult)
|
||||
.waitToClick(selectors.itemTags.tagsButton)
|
||||
.waitForURL('tags')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('tags');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should create a new tag, edit another and delete a former one`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.itemTags.firstTagSelect)
|
||||
.waitToClick(selectors.itemTags.firstTagSelectOptionOne)
|
||||
.clearInput(selectors.itemTags.firstValueInput)
|
||||
.type(selectors.itemTags.firstValueInput, 'Dark Blue')
|
||||
.waitToClick(selectors.itemTags.fifthRemoveTagButton)
|
||||
.waitToClick(selectors.itemTags.addItemTagButton)
|
||||
.waitToClick(selectors.itemTags.fifthTagSelect)
|
||||
.waitToClick(selectors.itemTags.fifthTagSelectOptionFive)
|
||||
.type(selectors.itemTags.fifthValueInput, 'Thanos')
|
||||
.click(selectors.itemTags.submitItemTagsButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should confirm the remaining tags are the expected ones`, () => {
|
||||
return nightmare
|
||||
.click(selectors.itemBasicData.basicDataButton)
|
||||
.wait(selectors.itemBasicData.nameInput)
|
||||
.click(selectors.itemTags.tagsButton)
|
||||
.wait(200)
|
||||
.getInputValue(selectors.itemTags.firstTagSelect)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Owner');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.firstValueInput);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Thanos');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.secondTagSelect);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Color');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.secondValueInput);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Dark Blue');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.thirdTagSelect);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Location');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.thirdValueInput);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Gamoras hideout');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.fourthTagSelect);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Shape');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.fourthValueInput);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('round');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.fifthTagSelect);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Power');
|
||||
return nightmare
|
||||
.getInputValue(selectors.itemTags.fifthValueInput);
|
||||
})
|
||||
.then(result => {
|
||||
expect(result).toEqual('Manipulates time');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,37 +1,3 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('crudAddressObservations', {
|
||||
description: 'create, delete or update address observations',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'observations',
|
||||
type: 'Object',
|
||||
require: true,
|
||||
description: 'object with observations to create, delete or update, Example: {delete: [], create: [], update: []}',
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/crudAddressObservations`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.crudAddressObservations = observations => {
|
||||
let promises = [];
|
||||
|
||||
if (observations.delete.length) {
|
||||
promises.push(Self.destroyAll({id: {inq: observations.delete}}));
|
||||
}
|
||||
if (observations.create.length) {
|
||||
promises.push(Self.create(observations.create));
|
||||
}
|
||||
if (observations.update.length) {
|
||||
observations.update.forEach(observation => {
|
||||
promises.push(Self.upsert(observation));
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
Self.installCrudModel('crudAddressObservations');
|
||||
};
|
||||
|
|
|
@ -1,36 +1,3 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('crudItemBarcodes', {
|
||||
description: 'create, update or delete barcodes',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'barcodes',
|
||||
type: 'Object',
|
||||
require: true,
|
||||
description: 'object with barcodes to create, update or delete, Example: {create: [], update: [], delete: []}',
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/crudItemBarcodes`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.crudItemBarcodes = barcodes => {
|
||||
let promises = [];
|
||||
|
||||
if (barcodes.delete && barcodes.delete.length) {
|
||||
promises.push(Self.destroyAll({id: {inq: barcodes.delete}}));
|
||||
}
|
||||
if (barcodes.create.length) {
|
||||
promises.push(Self.create(barcodes.create));
|
||||
}
|
||||
if (barcodes.update.length) {
|
||||
barcodes.update.forEach(barcode => {
|
||||
promises.push(Self.upsert(barcode));
|
||||
});
|
||||
}
|
||||
return Promise.all(promises);
|
||||
};
|
||||
Self.installCrudModel('crudItemBarcodes');
|
||||
};
|
||||
|
|
|
@ -1,36 +1,3 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('crudItemNiches', {
|
||||
description: 'create, update or delete niches',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'niches',
|
||||
type: 'Object',
|
||||
require: true,
|
||||
description: 'object with niches to create, update or delete, Example: {create: [], update: [], delete: []}',
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/crudItemNiches`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.crudItemNiches = niches => {
|
||||
let promises = [];
|
||||
|
||||
if (niches.delete && niches.delete.length) {
|
||||
promises.push(Self.destroyAll({id: {inq: niches.delete}}));
|
||||
}
|
||||
if (niches.create.length) {
|
||||
promises.push(Self.create(niches.create));
|
||||
}
|
||||
if (niches.update.length) {
|
||||
niches.update.forEach(niche => {
|
||||
promises.push(Self.upsert(niche));
|
||||
});
|
||||
}
|
||||
return Promise.all(promises);
|
||||
};
|
||||
Self.installCrudModel('crudItemNiches');
|
||||
};
|
||||
|
|
|
@ -1,36 +1,3 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('crudItemTags', {
|
||||
description: 'create, update or delete itemTags',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'itemtags',
|
||||
type: 'Object',
|
||||
require: true,
|
||||
description: 'object with itemTags to create, update or delete, Example: {create: [], update: [], delete: []}',
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/crudItemTags`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.crudItemTags = itemtags => {
|
||||
let promises = [];
|
||||
|
||||
if (itemtags.delete && itemtags.delete.length) {
|
||||
promises.push(Self.destroyAll({id: {inq: itemtags.delete}}));
|
||||
}
|
||||
if (itemtags.create.length) {
|
||||
promises.push(Self.create(itemtags.create));
|
||||
}
|
||||
if (itemtags.update.length) {
|
||||
itemtags.update.forEach(itemtag => {
|
||||
promises.push(Self.upsert(itemtag));
|
||||
});
|
||||
}
|
||||
return Promise.all(promises);
|
||||
};
|
||||
Self.installCrudModel('crudItemTags');
|
||||
};
|
||||
|
|
|
@ -1,72 +1,72 @@
|
|||
const crudItemBarcodes = require('../crudItemBarcodes');
|
||||
const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
let mysql = require('mysql2');
|
||||
// const crudItemBarcodes = require('../crudItemBarcodes');
|
||||
// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
// let mysql = require('mysql2');
|
||||
|
||||
describe('Item crudItemBarcodes()', () => {
|
||||
let connection;
|
||||
beforeAll(() => {
|
||||
connection = mysql.createConnection({
|
||||
multipleStatements: true,
|
||||
host: 'localhost',
|
||||
user: 'root',
|
||||
password: '',
|
||||
database: 'salix'
|
||||
});
|
||||
});
|
||||
// describe('Item crudItemBarcodes()', () => {
|
||||
// let connection;
|
||||
// beforeAll(() => {
|
||||
// connection = mysql.createConnection({
|
||||
// multipleStatements: true,
|
||||
// host: 'localhost',
|
||||
// user: 'root',
|
||||
// password: '',
|
||||
// database: 'salix'
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should call the destroyAll methodif there are ids in delete Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
// it('should call the destroyAll methodif there are ids in delete Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemBarcodes(self);
|
||||
self.crudItemBarcodes({
|
||||
delete: [1],
|
||||
create: [],
|
||||
update: []
|
||||
}).then(result => {
|
||||
expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}});
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
// crudItemBarcodes(self);
|
||||
// self.crudItemBarcodes({
|
||||
// delete: [1],
|
||||
// create: [],
|
||||
// update: []
|
||||
// }).then(result => {
|
||||
// expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}});
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
it('should call the create method if there are ids in create Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
// it('should call the create method if there are ids in create Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemBarcodes(self);
|
||||
self.crudItemBarcodes({
|
||||
delete: [],
|
||||
create: [1],
|
||||
update: []
|
||||
}).then(result => {
|
||||
expect(self.create).toHaveBeenCalledWith([1]);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
// crudItemBarcodes(self);
|
||||
// self.crudItemBarcodes({
|
||||
// delete: [],
|
||||
// create: [1],
|
||||
// update: []
|
||||
// }).then(result => {
|
||||
// expect(self.create).toHaveBeenCalledWith([1]);
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
it('should call the upsert method as many times as ids in update Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
// it('should call the upsert method as many times as ids in update Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemBarcodes(self);
|
||||
self.crudItemBarcodes({
|
||||
delete: [],
|
||||
create: [],
|
||||
update: [1, 2]
|
||||
}).then(result => {
|
||||
expect(self.upsert).toHaveBeenCalledWith(1);
|
||||
expect(self.upsert).toHaveBeenCalledWith(2);
|
||||
expect(self.upsert.calls.count()).toEqual(2);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
// crudItemBarcodes(self);
|
||||
// self.crudItemBarcodes({
|
||||
// delete: [],
|
||||
// create: [],
|
||||
// update: [1, 2]
|
||||
// }).then(result => {
|
||||
// expect(self.upsert).toHaveBeenCalledWith(1);
|
||||
// expect(self.upsert).toHaveBeenCalledWith(2);
|
||||
// expect(self.upsert.calls.count()).toEqual(2);
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
it('should return an error when attempting to save a duplicated barcode', done => {
|
||||
let callback = (err, res) => {
|
||||
expect(err.toString()).toBe("Error: Duplicate entry '4' for key 'PRIMARY'");
|
||||
done();
|
||||
};
|
||||
// it('should return an error when attempting to save a duplicated barcode', done => {
|
||||
// let callback = (err, res) => {
|
||||
// expect(err.toString()).toBe("Error: Duplicate entry '4' for key 'PRIMARY'");
|
||||
// done();
|
||||
// };
|
||||
|
||||
connection.query('INSERT INTO `vn`.`itemBarcode` VALUES (4, 2 ,4 );', callback);
|
||||
});
|
||||
});
|
||||
// connection.query('INSERT INTO `vn`.`itemBarcode` VALUES (4, 2 ,4 );', callback);
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
const crudItemNiches = require('../crudItemNiches');
|
||||
const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
// const crudItemNiches = require('../crudItemNiches');
|
||||
// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
|
||||
describe('Item crudItemNiches()', () => {
|
||||
it('should call the destroyAll method if there are ids in delete Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
// describe('Item crudItemNiches()', () => {
|
||||
// it('should call the destroyAll method if there are ids in delete Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemNiches(self);
|
||||
self.crudItemNiches({
|
||||
delete: [1],
|
||||
create: [],
|
||||
update: []
|
||||
}).then(result => {
|
||||
expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}});
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
// crudItemNiches(self);
|
||||
// self.crudItemNiches({
|
||||
// delete: [1],
|
||||
// create: [],
|
||||
// update: []
|
||||
// }).then(result => {
|
||||
// expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}});
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
it('should call the create method if there are ids in create Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
// it('should call the create method if there are ids in create Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemNiches(self);
|
||||
self.crudItemNiches({
|
||||
delete: [],
|
||||
create: [1],
|
||||
update: []
|
||||
}).then(result => {
|
||||
expect(self.create).toHaveBeenCalledWith([1]);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
// crudItemNiches(self);
|
||||
// self.crudItemNiches({
|
||||
// delete: [],
|
||||
// create: [1],
|
||||
// update: []
|
||||
// }).then(result => {
|
||||
// expect(self.create).toHaveBeenCalledWith([1]);
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
it('should call the upsert method as many times as ids in update Array', done => {
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
// it('should call the upsert method as many times as ids in update Array', done => {
|
||||
// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']);
|
||||
|
||||
crudItemNiches(self);
|
||||
self.crudItemNiches({
|
||||
delete: [],
|
||||
create: [],
|
||||
update: [1, 2]
|
||||
}).then(result => {
|
||||
expect(self.upsert).toHaveBeenCalledWith(1);
|
||||
expect(self.upsert).toHaveBeenCalledWith(2);
|
||||
expect(self.upsert.calls.count()).toEqual(2);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
||||
// crudItemNiches(self);
|
||||
// self.crudItemNiches({
|
||||
// delete: [],
|
||||
// create: [],
|
||||
// update: [1, 2]
|
||||
// }).then(result => {
|
||||
// expect(self.upsert).toHaveBeenCalledWith(1);
|
||||
// expect(self.upsert).toHaveBeenCalledWith(2);
|
||||
// expect(self.upsert.calls.count()).toEqual(2);
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -17,14 +17,14 @@ describe('Client activeSalesPerson', () => {
|
|||
app.models.Client.activeSalesPerson(filter, callback);
|
||||
});
|
||||
|
||||
it('should call the activeSalesPerson() method with no limit and receive all 6 salesPersons', done => {
|
||||
it('should call the activeSalesPerson() method with no limit and receive all 10 salesPersons', done => {
|
||||
let filter = {
|
||||
};
|
||||
|
||||
let callback = (error, result) => {
|
||||
if (error) return catchErrors(done)(error);
|
||||
|
||||
expect(result.length).toEqual(6);
|
||||
expect(result.length).toEqual(10);
|
||||
done();
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
module.exports = function(Self) {
|
||||
Self.installCrudModel = function(methodName) {
|
||||
let Model = this;
|
||||
Model.remoteMethod(methodName, {
|
||||
description: 'create, update or delete model',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'crudStruct',
|
||||
type: 'Object',
|
||||
require: true,
|
||||
description: 'object with instances of model to create, update or delete, Example: {create: [], update: [], delete: []}',
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/${methodName}`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
Model[methodName] = async crudStruct => {
|
||||
let promises = [];
|
||||
let tx = await Model.beginTransaction({});
|
||||
let options = {transaction: tx};
|
||||
|
||||
try {
|
||||
if (crudStruct.delete && crudStruct.delete.length) {
|
||||
promises.push(Model.destroyAll({id: {inq: crudStruct.delete}}, options));
|
||||
}
|
||||
if (crudStruct.create.length) {
|
||||
promises.push(Model.create(crudStruct.create, options));
|
||||
}
|
||||
if (crudStruct.update.length) {
|
||||
crudStruct.update.forEach(toUpdate => {
|
||||
promises.push(Model.upsert(toUpdate, options));
|
||||
});
|
||||
}
|
||||
await Promise.all(promises);
|
||||
await tx.commit();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
module.exports = function(Self) {
|
||||
Self.installMethod = function(methodName, filterCb, filterResult) {
|
||||
this.remoteMethod(methodName, {
|
||||
description: 'List items using a filter',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
required: true,
|
||||
description: 'Filter defining where',
|
||||
http: function(ctx) {
|
||||
return ctx.req.query;
|
||||
}
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
arg: 'data',
|
||||
type: [this.modelName],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
verb: 'get',
|
||||
path: `/${methodName}`
|
||||
}
|
||||
});
|
||||
|
||||
this[methodName] = (params, cb) => {
|
||||
let filter = removeEmpty(filterCb(params));
|
||||
|
||||
var response = {};
|
||||
|
||||
function returnValues() {
|
||||
if (response.instances !== undefined && response.count !== undefined) {
|
||||
if (filterResult)
|
||||
cb(null, filterResult(response));
|
||||
else
|
||||
cb(null, response);
|
||||
}
|
||||
}
|
||||
|
||||
function error() {
|
||||
cb(null, response);
|
||||
}
|
||||
|
||||
this.find(filter, function(err, instances) {
|
||||
if (err) {
|
||||
error();
|
||||
} else {
|
||||
response.instances = instances;
|
||||
returnValues();
|
||||
}
|
||||
});
|
||||
|
||||
this.count(filter.where, function(err, totalCount) {
|
||||
if (err) {
|
||||
error();
|
||||
} else {
|
||||
response.count = totalCount;
|
||||
returnValues();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
function removeEmpty(o) {
|
||||
if (Array.isArray(o)) {
|
||||
let array = [];
|
||||
for (let item of o) {
|
||||
let i = removeEmpty(item);
|
||||
if (!isEmpty(i))
|
||||
array.push(i);
|
||||
}
|
||||
if (array.length > 0)
|
||||
return array;
|
||||
} else if (typeof o === 'object') {
|
||||
let object = {};
|
||||
for (let key in o) {
|
||||
let i = removeEmpty(o[key]);
|
||||
if (!isEmpty(i))
|
||||
object[key] = i;
|
||||
}
|
||||
if (Object.keys(object).length > 0)
|
||||
return object;
|
||||
} else if (!isEmpty(o))
|
||||
return o;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEmpty(value) {
|
||||
return value === undefined || value === '';
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = function(Self) {
|
||||
Self.rawSql = function(query, params, cb) {
|
||||
var connector = this.dataSource.connector;
|
||||
return new Promise(function(resolve, reject) {
|
||||
connector.execute(query, params, function(error, response) {
|
||||
if (cb)
|
||||
cb(error, response);
|
||||
if (error)
|
||||
reject(error);
|
||||
else
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
const app = require('../../../../../item/server/server');
|
||||
|
||||
describe('Model installCrudModel()', () => {
|
||||
it('all models extends installCrudModel propertie', () => {
|
||||
let someModel = app.models.Item;
|
||||
|
||||
expect(someModel.installCrudModel).toBeDefined();
|
||||
});
|
||||
|
||||
it('installCrudModel() create a new remothed method', () => {
|
||||
let someModel = app.models.Item;
|
||||
someModel.installCrudModel('someCrudMethod');
|
||||
|
||||
expect(someModel.someCrudMethod).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
module.exports = function(Self) {
|
||||
Self.validateBinded = function(propertyName, validatorFn, options) {
|
||||
var customValidator = function(err) {
|
||||
if (!validatorFn(this[propertyName])) err();
|
||||
};
|
||||
options.isExportable = true;
|
||||
options.bindedFunction = validatorFn;
|
||||
this.validate(propertyName, customValidator, options);
|
||||
};
|
||||
};
|
|
@ -82,20 +82,6 @@ module.exports = function(Self) {
|
|||
};
|
||||
};
|
||||
|
||||
Self.rawSql = function(query, params, cb) {
|
||||
var connector = this.dataSource.connector;
|
||||
return new Promise(function(resolve, reject) {
|
||||
connector.execute(query, params, function(error, response) {
|
||||
if (cb)
|
||||
cb(error, response);
|
||||
if (error)
|
||||
reject(error);
|
||||
else
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Self.remoteMethodCtx = function(methodName, args) {
|
||||
var ctx = {
|
||||
arg: 'context',
|
||||
|
@ -130,104 +116,8 @@ module.exports = function(Self) {
|
|||
};
|
||||
};
|
||||
|
||||
Self.installMethod = function(methodName, filterCb, filterResult) {
|
||||
this.remoteMethod(methodName, {
|
||||
description: 'List items using a filter',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
required: true,
|
||||
description: 'Filter defining where',
|
||||
http: function(ctx) {
|
||||
return ctx.req.query;
|
||||
}
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
arg: 'data',
|
||||
type: [this.modelName],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
verb: 'get',
|
||||
path: `/${methodName}`
|
||||
}
|
||||
});
|
||||
|
||||
this[methodName] = (params, cb) => {
|
||||
let filter = removeEmpty(filterCb(params));
|
||||
|
||||
var response = {};
|
||||
|
||||
function returnValues() {
|
||||
if (response.instances !== undefined && response.count !== undefined) {
|
||||
if (filterResult)
|
||||
cb(null, filterResult(response));
|
||||
else
|
||||
cb(null, response);
|
||||
}
|
||||
}
|
||||
|
||||
function error() {
|
||||
cb(null, response);
|
||||
}
|
||||
|
||||
this.find(filter, function(err, instances) {
|
||||
if (err) {
|
||||
error();
|
||||
} else {
|
||||
response.instances = instances;
|
||||
returnValues();
|
||||
}
|
||||
});
|
||||
|
||||
this.count(filter.where, function(err, totalCount) {
|
||||
if (err) {
|
||||
error();
|
||||
} else {
|
||||
response.count = totalCount;
|
||||
returnValues();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Self.validateBinded = function(propertyName, validatorFn, options) {
|
||||
var customValidator = function(err) {
|
||||
if (!validatorFn(this[propertyName])) err();
|
||||
};
|
||||
options.isExportable = true;
|
||||
options.bindedFunction = validatorFn;
|
||||
this.validate(propertyName, customValidator, options);
|
||||
};
|
||||
require('../methods/vnModel/rawSql')(Self);
|
||||
require('../methods/vnModel/installMethod')(Self);
|
||||
require('../methods/vnModel/validateBinded')(Self);
|
||||
require('../methods/vnModel/installCrudModel')(Self);
|
||||
};
|
||||
function removeEmpty(o) {
|
||||
if (Array.isArray(o)) {
|
||||
let array = [];
|
||||
for (let item of o) {
|
||||
let i = removeEmpty(item);
|
||||
if (!isEmpty(i))
|
||||
array.push(i);
|
||||
}
|
||||
if (array.length > 0)
|
||||
return array;
|
||||
} else if (typeof o === 'object') {
|
||||
let object = {};
|
||||
for (let key in o) {
|
||||
let i = removeEmpty(o[key]);
|
||||
if (!isEmpty(i))
|
||||
object[key] = i;
|
||||
}
|
||||
if (Object.keys(object).length > 0)
|
||||
return object;
|
||||
} else if (!isEmpty(o))
|
||||
return o;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEmpty(value) {
|
||||
return value === undefined || value === '';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue