This commit is contained in:
Bernat 2019-02-13 13:28:02 +01:00
commit df452ff345
46 changed files with 351 additions and 230 deletions

View File

@ -266,11 +266,11 @@ let actions = {
}); });
}, },
waitForTextInElement: function(selector, name, done) { waitForTextInElement: function(selector, text, done) {
this.wait(selector) this.wait(selector)
.wait((selector, name) => { .wait((selector, text) => {
return document.querySelector(selector).innerText.toLowerCase().includes(name.toLowerCase()); return document.querySelector(selector).innerText.toLowerCase().includes(text.toLowerCase());
}, selector, name) }, selector, text)
.then(done) .then(done)
.catch(done); .catch(done);
}, },

View File

@ -171,9 +171,9 @@ export default {
itemsIndex: { itemsIndex: {
goBackToModuleIndexButton: `vn-ticket-descriptor a[href="#!/ticket/index"]`, goBackToModuleIndexButton: `vn-ticket-descriptor a[href="#!/ticket/index"]`,
createItemButton: `${components.vnFloatButton}`, createItemButton: `${components.vnFloatButton}`,
searchResult: `vn-item-product a`, searchResult: `vn-item-index a.vn-tr`,
searchResultPreviewButton: `vn-item-product .buttons > [icon="desktop_windows"]`, searchResultPreviewButton: `vn-item-index .buttons > [icon="desktop_windows"]`,
searchResultCloneButton: `vn-item-product .buttons > [icon="icon-clone"]`, searchResultCloneButton: `vn-item-index .buttons > [icon="icon-clone"]`,
acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [response="ACCEPT"]`, acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [response="ACCEPT"]`,
searchItemInput: `vn-searchbar vn-textfield input`, searchItemInput: `vn-searchbar vn-textfield input`,
searchButton: `vn-searchbar vn-icon[icon="search"]`, searchButton: `vn-searchbar vn-icon[icon="search"]`,

View File

@ -19,7 +19,7 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
if (loaded[moduleName] instanceof Promise) if (loaded[moduleName] instanceof Promise)
return loaded[moduleName]; return loaded[moduleName];
if (loaded[moduleName] === false) if (loaded[moduleName] === false)
return $q.reject(new Error(`Module dependency loop detected: ${moduleName}`)); return Promise.resolve(true);
loaded[moduleName] = false; loaded[moduleName] = false;
@ -37,10 +37,7 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
$translatePartialLoader.addPart(moduleName); $translatePartialLoader.addPart(moduleName);
promises.push(new Promise(resolve => { promises.push(new Promise(resolve => {
$translate.refresh().then( $translate.refresh().then(resolve, resolve);
() => resolve(),
() => resolve()
);
})); }));
if (validations) { if (validations) {

View File

@ -28,19 +28,5 @@ describe('factory vnModuleLoader', () => {
expect(result).toEqual(jasmine.any(Promise)); expect(result).toEqual(jasmine.any(Promise));
}); });
it('should return an error if the module wasnt loaded', done => {
vnModuleLoader._loaded.myModule = false;
vnModuleLoader.load('myModule', {myValidations: () => {}})
.then(() => {
done.fail('this must fail');
})
.catch(error => {
expect(error.toString()).toEqual(`Error: Module dependency loop detected: myModule`);
done();
});
$scope.$apply();
});
}); });
}); });

View File

@ -92,7 +92,7 @@ class Controller {
this.company = value; this.company = value;
if (value && if (value &&
(!window.localStorage.localCompanyFk || window.localStorage.localCompanyFk === 'null')) (!window.localStorage.localCompanyFk || window.localStorage.localCompanyFk === 'null'))
window.localStorage.defaultCompanyFk = value; window.localStorage.setItem('localCompanyFk', value);
this.setUserConfig('companyFk', value); this.setUserConfig('companyFk', value);
} }
@ -118,13 +118,13 @@ class Controller {
if (res.data && res.data.warehouseFk) { if (res.data && res.data.warehouseFk) {
this.warehouse = res.data.warehouseFk; this.warehouse = res.data.warehouseFk;
if (res.data.warehouseFk && !window.localStorage.localWarehouseFk) if (res.data.warehouseFk && !window.localStorage.localWarehouseFk)
window.localStorage.defaultWarehouseFk = res.data.warehouseFk; window.localStorage.setItem('localWarehouseFk', res.data.warehouseFk);
} }
if (res.data && res.data.companyFk) { if (res.data && res.data.companyFk) {
this.company = res.data.companyFk; this.company = res.data.companyFk;
if (res.data.companyFk && !window.localStorage.localCompanyFk) if (res.data.companyFk && !window.localStorage.localCompanyFk)
window.localStorage.defaultCompanyFk = res.data.companyFk; window.localStorage.setItem('defaultCompanyFk', res.data.companyFk);
} }
}); });
} }

View File

@ -74,7 +74,7 @@ defaultTask.description = `Starts all application services`;
// Backend tests // Backend tests
async function backTestOnly() { async function backTestOnce() {
let bootOptions; let bootOptions;
if (argv['random']) if (argv['random'])
@ -107,11 +107,19 @@ async function backTestOnly() {
await app.disconnect(); await app.disconnect();
} }
backTestOnly.description = `Runs the backend tests only, can receive --junit arg to save reports on a xml file`; backTestOnce.description = `Runs the backend tests once, can receive --junit arg to save reports on a xml file`;
async function backTestDockerOnce() {
let containerId = await docker();
await backTestOnce();
if (argv['random'])
await execP(`docker rm -fv ${containerId}`);
}
backTestDockerOnce.description = `Runs backend tests using in site container once`;
async function backTestDocker() { async function backTestDocker() {
let containerId = await docker(); let containerId = await docker();
await backTestOnly(); await backTest();
if (argv['random']) if (argv['random'])
await execP(`docker rm -fv ${containerId}`); await execP(`docker rm -fv ${containerId}`);
} }
@ -122,7 +130,7 @@ function backTest(done) {
nodemon({ nodemon({
exec: ['node ./node_modules/gulp/bin/gulp.js'], exec: ['node ./node_modules/gulp/bin/gulp.js'],
args: ['backTestOnly'], args: ['backTestOnce'],
watch: backSources, watch: backSources,
done: done done: done
}); });
@ -484,8 +492,9 @@ module.exports = {
back, back,
backOnly, backOnly,
backWatch, backWatch,
backTestOnce,
backTestDockerOnce,
backTest, backTest,
backTestOnly,
backTestDocker, backTestDocker,
e2e, e2e,
e2eOnly, e2eOnly,

View File

@ -10,7 +10,7 @@ class Controller {
} }
onSearch() { onSearch() {
this.$scope.$$postDigest(() => { this.$scope.$applyAsync(() => {
this.$scope.treeview.refresh(); this.$scope.treeview.refresh();
}); });
} }

View File

@ -32,12 +32,19 @@ module.exports = Self => {
let stmt = new ParameterizedSQL( let stmt = new ParameterizedSQL(
`SELECT i.id, i.image, i.name, i.description, `SELECT i.id, i.image, i.name, i.description,
i.size, i.tag5, i.value5, i.tag6, i.value6, i.size, i.tag5, i.value5, i.tag6, i.value6,
i.tag7, i.value7, i.tag8, i.value8, i.tag7, i.value7, i.tag8, i.value8, i.isActive,
t.name type, u.nickname userNickname t.name type, u.nickname userNickname,
intr.description AS intrastat, i.stems,
ori.code AS origin, t.name AS type,
ic.name AS category
FROM item i FROM item i
JOIN itemType t ON t.id = i.typeFk JOIN itemType t ON t.id = i.typeFk
LEFT JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN worker w ON w.id = t.workerFk JOIN worker w ON w.id = t.workerFk
JOIN account.user u ON u.id = w.userFk` JOIN account.user u ON u.id = w.userFk
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
LEFT JOIN producer pr ON pr.id = i.producerFk
LEFT JOIN origin ori ON ori.id = i.originFk`
); );
if (tags) { if (tags) {

View File

@ -92,7 +92,7 @@
<tpl-body> <tpl-body>
<div> <div>
<h5 style="text-align: center"> <h5 style="text-align: center">
<span translate>Regularize</span> <span translate>Regularize stock</span>
</h5> </h5>
<vn-textfield <vn-textfield
label="Quantity" label="Quantity"

View File

@ -9,7 +9,7 @@ class Controller {
this.vnApp = vnApp; this.vnApp = vnApp;
this.$translate = $translate; this.$translate = $translate;
this.moreOptions = [ this.moreOptions = [
{callback: this.showRegularizeDialog, name: 'Regularize'} {callback: this.showRegularizeDialog, name: 'Regularize stock'}
]; ];
} }
@ -22,7 +22,8 @@ class Controller {
} }
set warehouseFk(value) { set warehouseFk(value) {
this._warehouseFk = value; if (value)
this._warehouseFk = value;
} }
get warehouseFk() { get warehouseFk() {

View File

@ -1 +1 @@
Regularize: Regularizar Regularize stock: Regularizar stock

View File

@ -22,7 +22,7 @@ class Controller {
where: {itemFk: this.$stateParams.id} where: {itemFk: this.$stateParams.id}
}; };
this.$scope.$$postDigest(() => { this.$scope.$applyAsync(() => {
if (this.$stateParams.warehouseFk) if (this.$stateParams.warehouseFk)
this.warehouseFk = this.$stateParams.warehouseFk; this.warehouseFk = this.$stateParams.warehouseFk;
else if (value) else if (value)

View File

@ -69,23 +69,23 @@ describe('Item', () => {
describe('set item()', () => { describe('set item()', () => {
it(`should set warehouseFk property based on itemType warehouseFk`, () => { it(`should set warehouseFk property based on itemType warehouseFk`, () => {
spyOn(controller.$scope, '$$postDigest').and.callThrough(); spyOn(controller.$scope, '$applyAsync').and.callThrough();
controller.item = {id: 1, itemType: {warehouseFk: 1}}; controller.item = {id: 1, itemType: {warehouseFk: 1}};
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function)); expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$digest(); $scope.$apply();
expect(controller.warehouseFk).toEqual(1); expect(controller.warehouseFk).toEqual(1);
expect(controller.item.id).toEqual(1); expect(controller.item.id).toEqual(1);
}); });
it(`should set warehouseFk property based on url query warehouseFk`, () => { it(`should set warehouseFk property based on url query warehouseFk`, () => {
spyOn(controller.$scope, '$$postDigest').and.callThrough(); spyOn(controller.$scope, '$applyAsync').and.callThrough();
controller.$stateParams.warehouseFk = 4; controller.$stateParams.warehouseFk = 4;
controller.item = {id: 1, itemType: {warehouseFk: 1}}; controller.item = {id: 1, itemType: {warehouseFk: 1}};
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function)); expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$digest(); $scope.$apply();
expect(controller.warehouseFk).toEqual(4); expect(controller.warehouseFk).toEqual(4);
expect(controller.item.id).toEqual(1); expect(controller.item.id).toEqual(1);

View File

@ -7,10 +7,6 @@ import './create';
import './card'; import './card';
import './descriptor'; import './descriptor';
import './descriptor-popover'; import './descriptor-popover';
import './ticket-descriptor';
import './ticket-descriptor/addStowaway';
import './ticket-descriptor/removeStowaway';
import './ticket-descriptor-popover';
import './data'; import './data';
import './tags'; import './tags';
import './tax'; import './tax';

View File

@ -1,10 +1,10 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="/item/api/Items/filter" url="/item/api/Items/filter"
limit="8" limit="12"
order="isActive DESC, name, id" order="isActive DESC, name, id"
data="items" data="items"
auto-load="false"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<div class="content-block"> <div class="content-block">
<div class="vn-list"> <div class="vn-list">
@ -17,23 +17,76 @@
vn-focus> vn-focus>
</vn-searchbar> </vn-searchbar>
</vn-card> </vn-card>
<vn-card margin-medium-v> </div>
<vn-item-product <vn-card margin-medium-v>
class="searchResult" <vn-table model="model" show-fields="$ctrl.showFields" vn-uvc="itemIndex">
ng-repeat="item in items track by item.id" <vn-thead>
item="::item"> <vn-tr>
</vn-item-product> <vn-th th-id="picture"></vn-th>
<vn-empty-rows class="vn-list-item" style="text-align: center" <vn-th field="id" number>Id</vn-th>
ng-if="model.data.length === 0" translate> <vn-th th-id="description" style="text-align: center">Description</vn-th>
<vn-th th-id="stems">Stems</vn-th>
<vn-th th-id="type">Type</vn-th>
<vn-th th-id="category">Category</vn-th>
<vn-th th-id="intrastat">Intrastat</vn-th>
<vn-th th-id="origin">Origin</vn-th>
<vn-th th-id="salesperson">Sales person</vn-th>
<vn-th th-id="active">Active</vn-th>
<vn-th></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<a ng-repeat="item in items"
class="clickable vn-tr searchResult"
ui-sref="item.card.summary({id: item.id})">
<vn-td shrink>
<img
ng-src="{{::$ctrl.imagesPath}}/50x50/{{::item.image}}"
zoom-image="{{::$ctrl.imagesPath}}/1600x900/{{::item.image}}"
on-error-src/>
</vn-td>
<vn-td number>{{::item.id | zeroFill:6}}</vn-td>
<vn-td expand>
<vn-fetched-tags
max-length="6"
item="item"
title="item.name">
</vn-fetched-tags>
</vn-td>
<vn-td number>{{::item.stems}}</vn-td>
<vn-td>{{::item.type}}</vn-td>
<vn-td>{{::item.category}}</vn-td>
<vn-td>{{::item.intrastat}}</vn-td>
<vn-td>{{::item.origin}}</vn-td>
<vn-td>{{::item.userNickname}}</vn-td>
<vn-td>
<vn-check
disabled="true"
field="item.isActive">
</vn-check>
</vn-td>
<vn-td shrink>
<vn-horizontal class="buttons">
<vn-icon-button
ng-click="$ctrl.cloneItem($event, item)"
vn-tooltip="Clone"
icon="icon-clone">
</vn-icon-button>
<vn-icon-button
ng-click="$ctrl.preview($event, item)"
vn-tooltip="Preview"
icon="desktop_windows">
</vn-icon-button>
</vn-horizontal>
</vn-td>
</a>
</vn-tbody>
<vn-empty-rows ng-if="items.length === 0" translate>
No results No results
</vn-empty-rows> </vn-empty-rows>
<vn-empty-rows class="vn-list-item" style="text-align: center" </vn-table>
ng-if="model.data === null" translate> <vn-card margin-medium-v>
Enter a new search <vn-pagination model="model"></vn-pagination>
</vn-empty-rows>
</vn-card>
<vn-pagination model="model"></vn-pagination>
</div>
</div> </div>
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right> <a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button> <vn-float-button icon="add"></vn-float-button>

View File

@ -8,6 +8,12 @@ class Controller {
this.$state = $state; this.$state = $state;
this.$ = $scope; this.$ = $scope;
this.itemSelected = null; this.itemSelected = null;
this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
this.showFields = {
id: false,
actions: false
};
} }
exprBuilder(param, value) { exprBuilder(param, value) {
@ -25,6 +31,23 @@ class Controller {
} }
} }
showDescriptor(event, itemFk) {
this.quicklinks = {
btnThree: {
icon: 'icon-transaction',
state: `item.card.diary({
id: ${itemFk},
warehouseFk: ${this.ticket.warehouseFk},
ticketFk: ${this.ticket.id}
})`,
tooltip: 'Item diary'
}
};
this.$scope.descriptor.itemFk = itemFk;
this.$scope.descriptor.parent = event.target;
this.$scope.descriptor.show();
}
paramBuilder(param, value) { paramBuilder(param, value) {
switch (param) { switch (param) {
case 'tags': case 'tags':
@ -32,7 +55,9 @@ class Controller {
} }
} }
cloneItem(item) { cloneItem(event, item) {
event.preventDefault();
event.stopImmediatePropagation();
this.itemSelected = item; this.itemSelected = item;
this.$.clone.show(); this.$.clone.show();
} }
@ -49,7 +74,9 @@ class Controller {
this.itemSelected = null; this.itemSelected = null;
} }
showItemPreview(item) { preview(event, item) {
event.preventDefault();
event.stopImmediatePropagation();
this.itemSelected = item; this.itemSelected = item;
this.$.preview.show(); this.$.preview.show();
} }

View File

@ -25,3 +25,10 @@ vn-item-product {
margin-top: 0.9em; margin-top: 0.9em;
} }
} }
vn-table {
img {
border-radius: 50%;
max-width: 50px;
}
}

View File

@ -3,7 +3,7 @@
"name": "Items", "name": "Items",
"icon": "inbox", "icon": "inbox",
"validations" : true, "validations" : true,
"dependencies": ["client"], "dependencies": ["client", "ticket"],
"menu": [ "menu": [
{"state": "item.card.data", "icon": "settings"}, {"state": "item.card.data", "icon": "settings"},
{"state": "item.card.tags", "icon": "icon-tags"}, {"state": "item.card.tags", "icon": "icon-tags"},

View File

@ -1,126 +0,0 @@
import './index.js';
describe('Item', () => {
describe('Component vnTicketDescriptorPopover', () => {
let $httpBackend;
let $scope;
let controller;
let $element;
let $timeout;
beforeEach(ngModule('item'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$timeout_) => {
$httpBackend = _$httpBackend_;
$timeout = _$timeout_;
$element = angular.element(`<div></div>`);
$scope = $rootScope.$new();
$scope.popover = {relocate: () => {}, show: () => {}};
controller = $componentController('vnTicketDescriptorPopover', {$scope, $element});
}));
describe('ticketFk()', () => {
it(`should not apply any changes if the received id is the same stored in _ticketFk`, () => {
controller.ticket = 'I exist!';
controller._ticketFk = 1;
spyOn(controller, 'getCard');
controller.ticketFk = 1;
expect(controller.ticket).toEqual('I exist!');
expect(controller._ticketFk).toEqual(1);
expect(controller.getCard).not.toHaveBeenCalled();
});
it(`should set the received id into _ticketFk, set the ticket to null and then call getCard()`, () => {
controller.ticket = `Please don't`;
controller._ticketFk = 1;
spyOn(controller, 'getCard');
controller.ticketFk = 999;
expect(controller.ticket).toBeNull();
expect(controller._ticketFk).toEqual(999);
expect(controller.getCard).toHaveBeenCalledWith();
});
});
describe('ticket()', () => {
it(`should save the ticket into _ticket and then call relocate()`, () => {
spyOn(controller.$.popover, 'relocate');
controller.ticket = `i'm the ticket!`;
$timeout.flush();
expect(controller._ticket).toEqual(`i'm the ticket!`);
expect(controller.$.popover.relocate).toHaveBeenCalledWith();
});
});
describe('show()', () => {
it(`should call the show()`, () => {
spyOn(controller.$.popover, 'show');
controller.show();
expect(controller.$.popover.show).toHaveBeenCalledWith();
});
});
describe('getCard()', () => {
it(`should perform a get query to store the ticket data into the controller`, () => {
controller.ticketFk = 1;
controller.canceler = null;
let response = {};
let filter = {
include: [
{
relation: 'warehouse',
scope: {
fields: ['name']
}
},
{
relation: 'agencyMode',
scope: {
fields: ['name']
}
},
{
relation: 'client',
scope: {
fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
include: {
relation: 'salesPerson',
scope: {
fields: ['userFk'],
include: {
relation: 'user',
scope: {
fields: ['nickname']
}
}
}
}
}
},
{
relation: 'state',
scope: {
fields: ['stateFk'],
include: {
relation: 'state',
fields: ['id', 'name'],
}
}
}
]
};
let json = encodeURIComponent(JSON.stringify(filter));
$httpBackend.when('GET', `/ticket/api/Tickets/${controller._ticketFk}?filter=${json}`).respond(response);
$httpBackend.expect('GET', `/ticket/api/Tickets/${controller._ticketFk}?filter=${json}`);
controller.getCard();
$httpBackend.flush();
expect(controller.ticket).toEqual(response);
});
});
});
});

View File

@ -28,7 +28,7 @@ class Controller {
this._order = value; this._order = value;
this.$scope.$$postDigest(() => { this.$scope.$applyAsync(() => {
let category; let category;
let type; let type;

View File

@ -6,10 +6,12 @@ describe('Order', () => {
let $scope; let $scope;
let $state; let $state;
let controller; let controller;
let $httpBackend;
beforeEach(ngModule('order')); beforeEach(ngModule('order'));
beforeEach(angular.mock.inject(($componentController, _$state_, $rootScope) => { beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_, $rootScope) => {
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.model = crudModel; $scope.model = crudModel;
$scope.search = {}; $scope.search = {};
@ -27,12 +29,14 @@ describe('Order', () => {
})); }));
describe('order() setter', () => { describe('order() setter', () => {
it(`should call scope $$postDigest() method and apply filters from state params`, () => { it(`should call scope $applyAsync() method and apply filters from state params`, () => {
spyOn(controller.$scope, '$$postDigest').and.callThrough(); $httpBackend.expect('GET', `/item/api/ItemCategories/1/itemTypes`).respond();
spyOn(controller.$scope, '$applyAsync').and.callThrough();
controller.order = {id: 4}; controller.order = {id: 4};
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function)); expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$digest(); $scope.$apply();
expect(controller.category).toEqual({id: 1, value: 'My Category'}); expect(controller.category).toEqual({id: 1, value: 'My Category'});
expect(controller.type).toEqual({id: 1, value: 'My type'}); expect(controller.type).toEqual({id: 1, value: 'My type'});
@ -96,28 +100,38 @@ describe('Order', () => {
}); });
describe('applyFilters()', () => { describe('applyFilters()', () => {
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => { it(`should call model applyFilter() method with a new filter`, () => {
spyOn(controller.catalog.$scope.model, 'applyFilter'); let model = controller.catalog.$scope.model;
controller.order = {id: 4}; spyOn(model, 'applyFilter');
$scope.$digest(); controller._category = {id: 1, value: 'My Category'};
controller._type = {id: 1, value: 'My type'};
controller._order = {id: 4};
controller.applyFilters(); controller.applyFilters();
expect(controller.catalog.$scope.model.applyFilter).toHaveBeenCalledWith( expect(model.applyFilter).toHaveBeenCalledWith(
{where: {categoryFk: 1, typeFk: 1}}, {where: {categoryFk: 1, typeFk: 1}},
{orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []}); {orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []});
}); });
}); });
describe('remove()', () => { describe('remove()', () => {
it(`should remove a filter from tags property and then call applyFilters()`, () => { it(`should remove a tag from tags property`, () => {
spyOn(controller, 'applyFilters');
controller.order = {id: 4};
controller.tags = [{tagFk: 1, value: 'Blue'}, {tagFk: 2, value: '70'}]; controller.tags = [{tagFk: 1, value: 'Blue'}, {tagFk: 2, value: '70'}];
$scope.$digest();
controller.remove(0); controller.remove(0);
expect(controller.tags.length).toEqual(1); expect(controller.tags.length).toEqual(1);
expect(controller.tags[0].tagFk).toEqual(2); expect(controller.tags[0].tagFk).toEqual(2);
});
it(`should remove a tag from tags property and call applyFilters() if there's no more tags`, () => {
spyOn(controller, 'applyFilters');
controller._category = {id: 1, value: 'My Category'};
controller._type = {id: 1, value: 'My type'};
controller.tags = [{tagFk: 1, value: 'Blue'}];
controller.remove(0);
expect(controller.tags.length).toEqual(0);
expect(controller.applyFilters).toHaveBeenCalledWith(); expect(controller.applyFilters).toHaveBeenCalledWith();
}); });
}); });
@ -125,10 +139,10 @@ describe('Order', () => {
describe('updateStateParams()', () => { describe('updateStateParams()', () => {
it(`should call state go() method passing category and type state params`, () => { it(`should call state go() method passing category and type state params`, () => {
spyOn(controller.$state, 'go'); spyOn(controller.$state, 'go');
controller.order = {id: 4}; controller._category = {id: 1, value: 'My Category'};
$scope.$digest(); controller._type = {id: 1, value: 'My type'};
let result = {category: '{"id":1,"value":"My Category"}', type: '{"id":1,"value":"My type"}'}; let result = {category: '{"id":1,"value":"My Category"}', type: '{"id":1,"value":"My type"}'};
controller.updateStateParams();
expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', result); expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', result);
}); });

View File

@ -35,6 +35,9 @@ class Controller {
}; };
this.$http.get(`/item/api/ItemTags?filter=${JSON.stringify(filter)}`).then(response => { this.$http.get(`/item/api/ItemTags?filter=${JSON.stringify(filter)}`).then(response => {
this.tags = response.data; this.tags = response.data;
this.$.$applyAsync(() => {
this.$.popover.relocate();
});
}); });
} }
show(event, item) { show(event, item) {
@ -42,8 +45,8 @@ class Controller {
this.prices = this.item.prices; this.prices = this.item.prices;
this.getTags(); this.getTags();
this.$.popover.parent = event.target; this.$.popover.parent = event.target;
this.$.popover.relocate();
this.$.popover.show(); this.$.popover.show();
this.$.popover.relocate();
} }
clear() { clear() {
this.item = {}; this.item = {};

View File

@ -0,0 +1,125 @@
import './index.js';
describe('ticket Component vnTicketDescriptorPopover', () => {
let $httpBackend;
let $scope;
let controller;
let $element;
let $timeout;
beforeEach(ngModule('ticket'));
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$timeout_) => {
$httpBackend = _$httpBackend_;
$timeout = _$timeout_;
$element = angular.element(`<div></div>`);
$scope = $rootScope.$new();
$scope.popover = {relocate: () => {}, show: () => {}};
controller = $componentController('vnTicketDescriptorPopover', {$scope, $element});
}));
describe('ticketFk()', () => {
it(`should not apply any changes if the received id is the same stored in _ticketFk`, () => {
controller.ticket = 'I exist!';
controller._ticketFk = 1;
spyOn(controller, 'getCard');
controller.ticketFk = 1;
expect(controller.ticket).toEqual('I exist!');
expect(controller._ticketFk).toEqual(1);
expect(controller.getCard).not.toHaveBeenCalled();
});
it(`should set the received id into _ticketFk, set the ticket to null and then call getCard()`, () => {
controller.ticket = `Please don't`;
controller._ticketFk = 1;
spyOn(controller, 'getCard');
controller.ticketFk = 999;
expect(controller.ticket).toBeNull();
expect(controller._ticketFk).toEqual(999);
expect(controller.getCard).toHaveBeenCalledWith();
});
});
describe('ticket()', () => {
it(`should save the ticket into _ticket and then call relocate()`, () => {
spyOn(controller.$.popover, 'relocate');
controller.ticket = `i'm the ticket!`;
$timeout.flush();
expect(controller._ticket).toEqual(`i'm the ticket!`);
expect(controller.$.popover.relocate).toHaveBeenCalledWith();
});
});
describe('show()', () => {
it(`should call the show()`, () => {
spyOn(controller.$.popover, 'show');
controller.show();
expect(controller.$.popover.show).toHaveBeenCalledWith();
});
});
describe('getCard()', () => {
it(`should perform a get query to store the ticket data into the controller`, () => {
controller.ticketFk = 1;
controller.canceler = null;
let response = {};
let filter = {
include: [
{
relation: 'warehouse',
scope: {
fields: ['name']
}
},
{
relation: 'agencyMode',
scope: {
fields: ['name']
}
},
{
relation: 'client',
scope: {
fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
include: {
relation: 'salesPerson',
scope: {
fields: ['userFk'],
include: {
relation: 'user',
scope: {
fields: ['nickname']
}
}
}
}
}
},
{
relation: 'state',
scope: {
fields: ['stateFk'],
include: {
relation: 'state',
fields: ['id', 'name'],
}
}
}
]
};
let json = encodeURIComponent(JSON.stringify(filter));
$httpBackend.when('GET', `/ticket/api/Tickets/${controller._ticketFk}?filter=${json}`).respond(response);
$httpBackend.expect('GET', `/ticket/api/Tickets/${controller._ticketFk}?filter=${json}`);
controller.getCard();
$httpBackend.flush();
expect(controller.ticket).toEqual(response);
});
});
});

View File

@ -1,12 +1,10 @@
import './index.js'; import './index.js';
describe('Item Component vnTicketDescriptor', () => { describe('Ticket Component vnTicketDescriptor', () => {
let $httpBackend; let $httpBackend;
let controller; let controller;
beforeEach(() => { beforeEach(ngModule('ticket'));
ngModule('item');
});
beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => { beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;

View File

@ -3,6 +3,10 @@ export * from './module';
import './index/'; import './index/';
import './search-panel'; import './search-panel';
import './card'; import './card';
import './descriptor';
import './descriptor/addStowaway';
import './descriptor/removeStowaway';
import './descriptor-popover';
import './create/card'; import './create/card';
import './create/index'; import './create/index';
import './summary'; import './summary';

View File

@ -83,7 +83,6 @@
"yaml-loader": "^0.5.0" "yaml-loader": "^0.5.0"
}, },
"scripts": { "scripts": {
"test": "nodemon -q back/tests.js -w modules",
"dbtest": "nodemon -q services/db/tests.js -w services/db/tests", "dbtest": "nodemon -q services/db/tests.js -w services/db/tests",
"back": "nodemon --inspect -w modules ./node_modules/gulp/bin/gulp.js back", "back": "nodemon --inspect -w modules ./node_modules/gulp/bin/gulp.js back",
"lint": "eslint ./ --cache --ignore-pattern .gitignore", "lint": "eslint ./ --cache --ignore-pattern .gitignore",

View File

@ -0,0 +1,18 @@
USE `vn`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`workerDepartment` AS
SELECT
`p`.`id_trabajador` AS `workerFk`,
`d`.`id` AS `departmentFk`
FROM
(((`postgresql`.`person` `p`
JOIN `postgresql`.`profile` `pr` ON ((`pr`.`person_id` = `p`.`person_id`)))
LEFT JOIN (`postgresql`.`business` `b`
LEFT JOIN `postgresql`.`business_labour` `bl` ON ((`b`.`business_id` = `bl`.`business_id`))) ON ((`pr`.`profile_id` = `b`.`client_id`)))
JOIN `vn`.`department` `d` ON ((`d`.`id` = `bl`.`department_id`)))
WHERE
(ISNULL(`b`.`date_end`)
OR (`b`.`date_end` > CURDATE()));

View File

@ -0,0 +1 @@
INSERT INTO salix.ACL(id,model, property, accessType, permission, principalType, principalId)VALUES(147,'UserConfigView', '*', '*', 'ALLOW', 'ROLE', 'employee');

View File

@ -9,7 +9,9 @@ let verbose = false;
if (process.argv[2] === '--v') if (process.argv[2] === '--v')
verbose = true; verbose = true;
loopbackApp = `vn-loopback/server/server`; let app = require(`vn-loopback/server/server`);
app.boot();
loopbackApp = 'vn-loopback/server/server';
let Jasmine = require('jasmine'); let Jasmine = require('jasmine');
let jasmine = new Jasmine(); let jasmine = new Jasmine();

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('buyUltimate()', () => { describe('buyUltimate()', () => {

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('buyUltimateFromInterval()', () => { describe('buyUltimateFromInterval()', () => {

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('logAddWithUser()', () => { describe('logAddWithUser()', () => {

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticket ticketCalculateClon()', () => { describe('ticket ticketCalculateClon()', () => {

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticketComponentUpdateSale()', () => { describe('ticketComponentUpdateSale()', () => {

View File

@ -1,4 +1,4 @@
const app = require(`${loopbackApp}`); const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticket ticketCreateWithUser()', () => { describe('ticket ticketCreateWithUser()', () => {