Merge branch 'dev' into 2819-notify_assignment
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
c65fbef3df
|
@ -1 +0,0 @@
|
||||||
Delete me
|
|
|
@ -0,0 +1 @@
|
||||||
|
Delete this
|
|
@ -564,13 +564,13 @@ INSERT INTO `vn`.`zoneConfig` (`scope`) VALUES ('1');
|
||||||
|
|
||||||
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
|
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), CURDATE(), 1),
|
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1),
|
||||||
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 2, 'second route', 0.2, 20, CURDATE(), CURDATE(), 9),
|
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 2, 'second route', 0.2, 20, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 9),
|
||||||
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 3, 'third route', 0.5, 30, CURDATE(), CURDATE(), 10),
|
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 3, 'third route', 0.5, 30, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 10),
|
||||||
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 4, 'fourth route', 0, 40, CURDATE(), CURDATE(), 12),
|
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 4, 'fourth route', 0, 40, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 12),
|
||||||
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 5, 'fifth route', 0.1, 50, CURDATE(), CURDATE(), 13),
|
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 5, 'fifth route', 0.1, 50, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 13),
|
||||||
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
|
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 3),
|
||||||
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
|
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 5);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`)
|
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2257,3 +2257,10 @@ INSERT INTO `vn`.`ticketRecalc`(`ticketFk`)
|
||||||
SELECT `id` FROM `vn`.`ticket`;
|
SELECT `id` FROM `vn`.`ticket`;
|
||||||
|
|
||||||
CALL `vn`.`ticket_doRecalc`();
|
CALL `vn`.`ticket_doRecalc`();
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`zoneAgencyMode`(`id`, `agencyModeFk`, `zoneFk`)
|
||||||
|
VALUES
|
||||||
|
(1, 1, 1),
|
||||||
|
(2, 1, 2),
|
||||||
|
(3, 6, 5),
|
||||||
|
(4, 7, 1);
|
|
@ -790,10 +790,11 @@ export default {
|
||||||
saveButton: 'vn-route-basic-data button[type=submit]'
|
saveButton: 'vn-route-basic-data button[type=submit]'
|
||||||
},
|
},
|
||||||
routeTickets: {
|
routeTickets: {
|
||||||
firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-textfield[ng-model="ticket.priority"]',
|
firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-input-number[ng-model="ticket.priority"]',
|
||||||
firstTicketCheckbox: 'vn-route-tickets vn-tr:nth-child(1) vn-check',
|
firstTicketCheckbox: 'vn-route-tickets vn-tr:nth-child(1) vn-check',
|
||||||
buscamanButton: 'vn-route-tickets vn-button[icon="icon-buscaman"]',
|
buscamanButton: 'vn-route-tickets vn-button[icon="icon-buscaman"]',
|
||||||
firstTicketDeleteButton: 'vn-route-tickets vn-tr:nth-child(1) vn-icon[icon="delete"]',
|
firstTicketDeleteButton: 'vn-route-tickets vn-tr:nth-child(1) vn-icon[icon="delete"]',
|
||||||
|
anyTicket: 'vn-route-tickets vn-tbody > vn-tr',
|
||||||
confirmButton: '.vn-confirm.shown button[response="accept"]'
|
confirmButton: '.vn-confirm.shown button[response="accept"]'
|
||||||
},
|
},
|
||||||
workerSummary: {
|
workerSummary: {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
// #1528 e2e claim/detail
|
describe('Route tickets path', () => {
|
||||||
xdescribe('Route basic Data path', () => {
|
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
|
@ -10,7 +9,7 @@ xdescribe('Route basic Data path', () => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
await page.loginAndModule('delivery', 'route');
|
await page.loginAndModule('delivery', 'route');
|
||||||
await page.accessToSearchResult('3');
|
await page.accessToSearchResult('2');
|
||||||
await page.accessToSection('route.card.tickets');
|
await page.accessToSection('route.card.tickets');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,40 +18,32 @@ xdescribe('Route basic Data path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should modify the first ticket priority', async() => {
|
it('should modify the first ticket priority', async() => {
|
||||||
await page.write(selectors.routeTickets.firstTicketPriority, '2');
|
await page.clearInput(selectors.routeTickets.firstTicketPriority);
|
||||||
|
await page.type(selectors.routeTickets.firstTicketPriority, '9');
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the buscamanButton is disabled', async() => {
|
it('should confirm the buscaman button is disabled', async() => {
|
||||||
const result = await page.evaluate(selector => {
|
await page.waitForSelector(`${selectors.routeTickets.buscamanButton}.disabled`);
|
||||||
return document.querySelector(selector);
|
|
||||||
}, `${selectors.routeTickets.buscamanButton} :disabled`);
|
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check the first ticket checkbox and confirm the buscamanButton button is no longer disabled', async() => {
|
it('should check the first ticket checkbox and confirm the buscamanButton button is no longer disabled', async() => {
|
||||||
await page.waitToClick(selectors.routeTickets.firstTicketCheckbox);
|
await page.waitForSelector(`${selectors.routeTickets.buscamanButton}.disabled`, {visible: false});
|
||||||
const result = await page.evaluate(selector => {
|
|
||||||
return document.querySelector(selector);
|
|
||||||
}, `${selectors.routeTickets.buscamanButton} :disabled`);
|
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check the route volume on the descriptor', async() => {
|
it('should check the route volume on the descriptor', async() => {
|
||||||
const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText');
|
const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual('1.1 / 18 m³');
|
expect(result).toEqual('0.2 / 50 m³');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should count how many tickets are in route', async() => {
|
it('should count how many tickets are in route', async() => {
|
||||||
const result = await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]');
|
const result = await page.countElement(selectors.routeTickets.anyTicket);
|
||||||
|
|
||||||
expect(result).toEqual(11);
|
expect(result).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete the first ticket in route', async() => {
|
it('should delete the first ticket in route', async() => {
|
||||||
|
@ -63,23 +54,14 @@ xdescribe('Route basic Data path', () => {
|
||||||
expect(message.text).toContain('Ticket removed from route');
|
expect(message.text).toContain('Ticket removed from route');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should again delete the first ticket in route', async() => {
|
|
||||||
await page.waitToClick(selectors.routeTickets.firstTicketDeleteButton);
|
|
||||||
await page.waitToClick(selectors.routeTickets.confirmButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Ticket removed from route');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should now count how many tickets are in route to find one less', async() => {
|
it('should now count how many tickets are in route to find one less', async() => {
|
||||||
const result = await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]');
|
await page.waitForNumberOfElements(selectors.routeTickets.anyTicket, 0);
|
||||||
|
|
||||||
expect(result).toEqual(9);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the route volume on the descriptor has been updated by the changes made', async() => {
|
// #2862 updateVolume() route descriptor no actualiza volumen
|
||||||
|
xit('should confirm the route volume on the descriptor has been updated by the changes made', async() => {
|
||||||
const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText');
|
const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual('0.9 / 18 m³');
|
expect(result).toEqual('0 / 50 m³');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
// #2833 Refactor account.basicData
|
describe('Account create and basic data path', () => {
|
||||||
xdescribe('Account create and basic data path', () => {
|
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
|
@ -37,40 +36,23 @@ xdescribe('Account create and basic data path', () => {
|
||||||
await page.waitForState('account.card.basicData');
|
await page.waitForState('account.card.basicData');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should edit the basic data', async() => {
|
it('should reload the section and check the name is as expected', async() => {
|
||||||
await page.overwrite(selectors.accountBasicData.name, 'Anna');
|
|
||||||
await page.overwrite(selectors.accountBasicData.nickname, 'Rogue');
|
|
||||||
await page.overwrite(selectors.accountBasicData.email, 'AnnaMarieLeBeau@verdnatura.es');
|
|
||||||
await page.autocompleteSearch(selectors.accountBasicData.language, 'english');
|
|
||||||
await page.waitToClick(selectors.accountBasicData.save);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reload the section and check the name was edited successfully', async() => {
|
|
||||||
await page.reloadSection('account.card.basicData');
|
await page.reloadSection('account.card.basicData');
|
||||||
const result = await page.waitToGetProperty(selectors.accountBasicData.name, 'value');
|
const result = await page.waitToGetProperty(selectors.accountBasicData.name, 'value');
|
||||||
|
|
||||||
expect(result).toEqual('Anna');
|
expect(result).toEqual('Remy');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check the nickname was edited successfully', async() => {
|
it('should check the nickname is as expected', async() => {
|
||||||
const result = await page.waitToGetProperty(selectors.accountBasicData.nickname, 'value');
|
const result = await page.waitToGetProperty(selectors.accountBasicData.nickname, 'value');
|
||||||
|
|
||||||
expect(result).toEqual('Rogue');
|
expect(result).toEqual('Gambit');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check the email was edited successfully', async() => {
|
it('should check the email is as expected', async() => {
|
||||||
const result = await page.waitToGetProperty(selectors.accountBasicData.email, 'value');
|
const result = await page.waitToGetProperty(selectors.accountBasicData.email, 'value');
|
||||||
|
|
||||||
expect(result).toEqual('AnnaMarieLeBeau@verdnatura.es');
|
expect(result).toEqual('RemyEtienneLeBeau@verdnatura.es');
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the language was edited successfully', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.accountBasicData.language, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('English');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate to the roles section to check the roles are correct', async() => {
|
it('should navigate to the roles section to check the roles are correct', async() => {
|
||||||
|
|
|
@ -1,144 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"name": "salix-front",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"license": "GPL-3.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@uirouter/angularjs": "^1.0.20",
|
|
||||||
"angular": "^1.7.5",
|
|
||||||
"angular-animate": "^1.7.8",
|
|
||||||
"angular-translate": "^2.18.1",
|
|
||||||
"angular-translate-loader-partial": "^2.18.1",
|
|
||||||
"js-yaml": "^3.13.1",
|
|
||||||
"mg-crud": "^1.1.2",
|
|
||||||
"oclazyload": "^0.6.3",
|
|
||||||
"require-yaml": "0.0.1",
|
|
||||||
"validator": "^6.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@uirouter/angularjs": {
|
|
||||||
"version": "1.0.29",
|
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
|
|
||||||
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@uirouter/core": "6.0.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"angular": ">=1.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@uirouter/core": {
|
|
||||||
"version": "6.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
|
|
||||||
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/angular": {
|
|
||||||
"version": "1.8.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
|
|
||||||
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
|
|
||||||
},
|
|
||||||
"node_modules/angular-animate": {
|
|
||||||
"version": "1.8.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
|
|
||||||
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
|
|
||||||
},
|
|
||||||
"node_modules/angular-translate": {
|
|
||||||
"version": "2.18.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
|
|
||||||
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
|
|
||||||
"dependencies": {
|
|
||||||
"angular": "^1.8.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/angular-translate-loader-partial": {
|
|
||||||
"version": "2.18.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
|
|
||||||
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
|
|
||||||
"dependencies": {
|
|
||||||
"angular-translate": "~2.18.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/argparse": {
|
|
||||||
"version": "1.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
|
||||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
|
||||||
"dependencies": {
|
|
||||||
"sprintf-js": "~1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/esprima": {
|
|
||||||
"version": "4.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
|
||||||
"bin": {
|
|
||||||
"esparse": "bin/esparse.js",
|
|
||||||
"esvalidate": "bin/esvalidate.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-yaml": {
|
|
||||||
"version": "3.14.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
|
||||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
|
||||||
"dependencies": {
|
|
||||||
"argparse": "^1.0.7",
|
|
||||||
"esprima": "^4.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"js-yaml": "bin/js-yaml.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mg-crud": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
|
|
||||||
"integrity": "sha1-p6AWGzWSPK7/8ZpIBpS2V1vDggw=",
|
|
||||||
"dependencies": {
|
|
||||||
"angular": "^1.6.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/oclazyload": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
|
|
||||||
"integrity": "sha1-Kjirv/QJDAihEBZxkZRbWfLoJ5w="
|
|
||||||
},
|
|
||||||
"node_modules/require-yaml": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
|
||||||
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
|
||||||
"dependencies": {
|
|
||||||
"js-yaml": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/sprintf-js": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
|
||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
|
||||||
},
|
|
||||||
"node_modules/validator": {
|
|
||||||
"version": "6.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
|
||||||
"integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@uirouter/angularjs": {
|
"@uirouter/angularjs": {
|
||||||
"version": "1.0.29",
|
"version": "1.0.29",
|
||||||
|
@ -219,7 +83,22 @@
|
||||||
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
||||||
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"js-yaml": ""
|
"js-yaml": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<div ng-transclude="before"></div>
|
<div ng-transclude="before"></div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<h5>{{$ctrl.description}}</h5>
|
<h5 title="{{$ctrl.description}}">{{$ctrl.description}}</h5>
|
||||||
<div>
|
<div>
|
||||||
{{$ctrl.descriptor.id | id}}
|
{{$ctrl.descriptor.id | id}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,7 +42,7 @@ Travels: Envíos
|
||||||
Workers: Trabajadores
|
Workers: Trabajadores
|
||||||
Routes: Rutas
|
Routes: Rutas
|
||||||
Locator: Localizador
|
Locator: Localizador
|
||||||
Invoices out: Facturas emitidas
|
Invoices out: Fact. emitidas
|
||||||
Invoices in: Fact. recibidas
|
Invoices in: Fact. recibidas
|
||||||
Entries: Entradas
|
Entries: Entradas
|
||||||
Users: Usuarios
|
Users: Usuarios
|
||||||
|
|
|
@ -2,4 +2,5 @@ reference: Referencia
|
||||||
Observation: Observación
|
Observation: Observación
|
||||||
Box: Embalaje
|
Box: Embalaje
|
||||||
Import buys: Importar compras
|
Import buys: Importar compras
|
||||||
Some of the imported buys doesn't have an item: Algunas de las compras importadas no tienen un artículo
|
Some of the imported buys doesn't have an item: Algunas de las compras importadas no tienen un artículo
|
||||||
|
JSON files only: Solo ficheros JSON
|
|
@ -165,9 +165,13 @@
|
||||||
<vn-dialog class="edit"
|
<vn-dialog class="edit"
|
||||||
vn-id="edit"
|
vn-id="edit"
|
||||||
on-accept="$ctrl.onEditAccept()"
|
on-accept="$ctrl.onEditAccept()"
|
||||||
on-close="$ctrl.editedColumn = null"
|
on-close="$ctrl.editedColumn = null">
|
||||||
message="Edit buy(s)">
|
|
||||||
<tpl-body>
|
<tpl-body>
|
||||||
|
<span translate>Edit</span>
|
||||||
|
<span class="countLines">
|
||||||
|
{{::$ctrl.totalChecked}}
|
||||||
|
</span>
|
||||||
|
<span translate>buy(s)</span>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-two
|
vn-two
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
|
|
|
@ -12,3 +12,5 @@ Weight: Peso
|
||||||
Minimun amount: Cantidad mínima de compra
|
Minimun amount: Cantidad mínima de compra
|
||||||
Field to edit: Campo a editar
|
Field to edit: Campo a editar
|
||||||
PackageName: Cubo
|
PackageName: Cubo
|
||||||
|
Edit: Editar
|
||||||
|
buy(s): compra(s)
|
|
@ -0,0 +1,7 @@
|
||||||
|
.countLines {
|
||||||
|
flex: 0.15;
|
||||||
|
font-size: 24px;
|
||||||
|
color: orangered;
|
||||||
|
font-weight: bold;
|
||||||
|
max-width: 30px;
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getSuggestedTickets', {
|
||||||
|
description: 'Returns an array of suggested tickets for the given route',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The route id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/getSuggestedTickets`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getSuggestedTickets = async id => {
|
||||||
|
const ticketsInRoute = await Self.app.models.Ticket.find({
|
||||||
|
where: {routeFk: id},
|
||||||
|
fields: ['id']
|
||||||
|
});
|
||||||
|
const idsToExclude = ticketsInRoute.map(ticket => ticket.id);
|
||||||
|
|
||||||
|
const route = await Self.app.models.Route.findById(id);
|
||||||
|
|
||||||
|
const zoneAgencyModes = await Self.app.models.ZoneAgencyMode.find({
|
||||||
|
where: {
|
||||||
|
agencyModeFk: route.agencyModeFk
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const zoneIds = [];
|
||||||
|
for (let zoneAgencyMode of zoneAgencyModes)
|
||||||
|
zoneIds.push(zoneAgencyMode.zoneFk);
|
||||||
|
|
||||||
|
const minDate = new Date(route.finished);
|
||||||
|
minDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const maxDate = new Date(route.finished);
|
||||||
|
maxDate.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
|
let tickets = await Self.app.models.Ticket.find({
|
||||||
|
where: {
|
||||||
|
agencyModeFk: route.agencyModeFk,
|
||||||
|
zoneFk: {inq: zoneIds},
|
||||||
|
id: {nin: idsToExclude},
|
||||||
|
landed: {between: [minDate, maxDate]}
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'warehouse',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'address',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'street', 'postalCode', 'city'],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return tickets;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
|
describe('route getSuggestedTickets()', () => {
|
||||||
|
it('should return an array of suggested tickets', async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 19},
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
};
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
|
||||||
|
const routeID = 1;
|
||||||
|
const ticketInRoute = await app.models.Ticket.findById(12);
|
||||||
|
|
||||||
|
await ticketInRoute.updateAttribute('routeFk', null);
|
||||||
|
|
||||||
|
const result = await app.models.Route.getSuggestedTickets(routeID);
|
||||||
|
|
||||||
|
const length = result.length;
|
||||||
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(anyResult.zoneFk).toEqual(1);
|
||||||
|
expect(anyResult.agencyModeFk).toEqual(1);
|
||||||
|
|
||||||
|
await ticketInRoute.updateAttribute('routeFk', routeID);
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,7 +4,7 @@ const LoopBackContext = require('loopback-context');
|
||||||
describe('route insertTicket()', () => {
|
describe('route insertTicket()', () => {
|
||||||
const deliveryId = 56;
|
const deliveryId = 56;
|
||||||
let originalTicket;
|
let originalTicket;
|
||||||
const routeId = 2;
|
const routeId = 1;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: deliveryId},
|
accessToken: {userId: deliveryId},
|
||||||
};
|
};
|
||||||
|
@ -17,26 +17,18 @@ describe('route insertTicket()', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
try {
|
|
||||||
await originalTicket.updateAttribute('routeFk', null);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add the ticket to a route', async() => {
|
it('should add the ticket to a route', async() => {
|
||||||
originalTicket = await app.models.Ticket.findById(14);
|
const ticketId = 12;
|
||||||
|
originalTicket = await app.models.Ticket.findById(ticketId);
|
||||||
|
await originalTicket.updateAttribute('routeFk', null);
|
||||||
|
|
||||||
const ticketId = 14;
|
|
||||||
const result = await app.models.Route.insertTicket(routeId, ticketId);
|
const result = await app.models.Route.insertTicket(routeId, ticketId);
|
||||||
|
|
||||||
expect(result.routeFk).toEqual(2);
|
expect(result.routeFk).toEqual(routeId);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw and error if the ticket is not suitable for the route', async() => {
|
it('should throw and error if the ticket is not suitable for the route', async() => {
|
||||||
const ticketId = 23;
|
const ticketId = 2;
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -7,6 +7,7 @@ module.exports = Self => {
|
||||||
require('../methods/route/getDeliveryPoint')(Self);
|
require('../methods/route/getDeliveryPoint')(Self);
|
||||||
require('../methods/route/insertTicket')(Self);
|
require('../methods/route/insertTicket')(Self);
|
||||||
require('../methods/route/clone')(Self);
|
require('../methods/route/clone')(Self);
|
||||||
|
require('../methods/route/getSuggestedTickets')(Self);
|
||||||
|
|
||||||
Self.validate('kmStart', validateDistance, {
|
Self.validate('kmStart', validateDistance, {
|
||||||
message: 'Distance must be lesser than 1000'
|
message: 'Distance must be lesser than 1000'
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-if="ticket.notes.length"
|
ng-if="ticket.notes.length"
|
||||||
title="::{{ticket.notes[0].description}}"
|
title="{{ticket.notes[0].description}}"
|
||||||
icon="insert_drive_file"
|
icon="insert_drive_file"
|
||||||
class="bright">
|
class="bright">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
@ -110,10 +110,9 @@
|
||||||
question="Delete ticket from route?"
|
question="Delete ticket from route?"
|
||||||
on-accept="$ctrl.removeTicketFromRoute()">
|
on-accept="$ctrl.removeTicketFromRoute()">
|
||||||
</vn-confirm>
|
</vn-confirm>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="possibleTicketsModel"
|
vn-id="possibleTicketsModel"
|
||||||
url="Tickets"
|
url="Routes/{{$ctrl.$params.id}}/getSuggestedTickets"
|
||||||
filter="$ctrl.possibleTicketsFilter"
|
|
||||||
data="$ctrl.possibleTickets">
|
data="$ctrl.possibleTickets">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-dialog
|
<vn-dialog
|
||||||
|
|
|
@ -9,8 +9,6 @@ class Controller extends Section {
|
||||||
|
|
||||||
set route(value) {
|
set route(value) {
|
||||||
this._route = value;
|
this._route = value;
|
||||||
if (value)
|
|
||||||
this.buildPossibleTicketsFilter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get isChecked() {
|
get isChecked() {
|
||||||
|
@ -22,32 +20,6 @@ class Controller extends Section {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildPossibleTicketsFilter() {
|
|
||||||
let minDate = new Date(this.route.finished);
|
|
||||||
minDate.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
let maxDate = new Date(this.route.finished);
|
|
||||||
maxDate.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
this.possibleTicketsFilter = {
|
|
||||||
where: {
|
|
||||||
zoneFk: this.route.zoneFk,
|
|
||||||
routeFk: null,
|
|
||||||
landed: {between: [minDate, maxDate]},
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'warehouse',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
relation: 'address'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getHighestPriority() {
|
getHighestPriority() {
|
||||||
let highestPriority = Math.max(...this.$.model.data.map(tag => {
|
let highestPriority = Math.max(...this.$.model.data.map(tag => {
|
||||||
return tag.priority;
|
return tag.priority;
|
||||||
|
@ -134,14 +106,26 @@ class Controller extends Section {
|
||||||
setTicketsRoute() {
|
setTicketsRoute() {
|
||||||
let tickets = this.getSelectedItems(this.possibleTickets);
|
let tickets = this.getSelectedItems(this.possibleTickets);
|
||||||
if (tickets.length === 0) return;
|
if (tickets.length === 0) return;
|
||||||
for (let i = 0; i < tickets.length; i++) {
|
|
||||||
delete tickets[i].checked;
|
const updates = [];
|
||||||
tickets[i].routeFk = this.route.id;
|
|
||||||
|
for (let ticket of tickets) {
|
||||||
|
delete ticket.checked;
|
||||||
|
const update = {
|
||||||
|
where: {id: ticket.id},
|
||||||
|
data: {routeFk: this.route.id}
|
||||||
|
};
|
||||||
|
|
||||||
|
updates.push(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.$.possibleTicketsModel.save().then(() => {
|
const data = {creates: [], updates: updates, deletes: []};
|
||||||
this.$.model.data = this.$.model.data.concat(tickets);
|
|
||||||
});
|
return this.$http.post(`Tickets/crud`, data)
|
||||||
|
.then(() => {
|
||||||
|
this.$.model.data = this.$.model.data.concat(tickets);
|
||||||
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop($event) {
|
onDrop($event) {
|
||||||
|
|
|
@ -37,42 +37,6 @@ describe('Route', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('buildPossibleTicketsFilter()', () => {
|
|
||||||
it('should build the possible tickets filter', () => {
|
|
||||||
let expectedFilter = {
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'warehouse',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'address'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
where: {
|
|
||||||
landed: {
|
|
||||||
between: [
|
|
||||||
jasmine.any(Date),
|
|
||||||
jasmine.any(Date)
|
|
||||||
]
|
|
||||||
},
|
|
||||||
routeFk: null,
|
|
||||||
zoneFk: 67
|
|
||||||
}
|
|
||||||
};
|
|
||||||
controller.route = {
|
|
||||||
finished: new Date(),
|
|
||||||
routeFk: null,
|
|
||||||
zoneFk: 67
|
|
||||||
};
|
|
||||||
|
|
||||||
controller.buildPossibleTicketsFilter();
|
|
||||||
|
|
||||||
expect(controller.possibleTicketsFilter).toEqual(expectedFilter);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getHighestPriority()', () => {
|
describe('getHighestPriority()', () => {
|
||||||
it('should return the highest value found in priorities plus 1', () => {
|
it('should return the highest value found in priorities plus 1', () => {
|
||||||
controller.$.model = {data: [
|
controller.$.model = {data: [
|
||||||
|
@ -228,13 +192,13 @@ describe('Route', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setTicketsRoute()', () => {
|
describe('setTicketsRoute()', () => {
|
||||||
it('should perform a POST query to add tickets to the route', done => {
|
it('should perform a POST query to add tickets to the route', () => {
|
||||||
controller.$.possibleTicketsModel = {save: () => {}};
|
|
||||||
jest.spyOn(controller.$.possibleTicketsModel, 'save').mockReturnValue(Promise.resolve());
|
|
||||||
controller.$.model = {data: [
|
controller.$.model = {data: [
|
||||||
{id: 1, checked: false}
|
{id: 1, checked: false}
|
||||||
]};
|
]};
|
||||||
|
|
||||||
|
const existingTicket = controller.$.model.data[0];
|
||||||
|
|
||||||
controller.route = {id: 111};
|
controller.route = {id: 111};
|
||||||
|
|
||||||
controller.possibleTickets = [
|
controller.possibleTickets = [
|
||||||
|
@ -245,15 +209,16 @@ describe('Route', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
let expectedResult = [
|
let expectedResult = [
|
||||||
{checked: false, id: 1},
|
existingTicket,
|
||||||
{id: 3, routeFk: 111},
|
{id: 3},
|
||||||
{id: 5, routeFk: 111}
|
{id: 5}
|
||||||
];
|
];
|
||||||
|
|
||||||
controller.setTicketsRoute().then(() => {
|
$httpBackend.expectPOST(`Tickets/crud`).respond();
|
||||||
expect(controller.$.model.data).toEqual(expectedResult);
|
controller.setTicketsRoute();
|
||||||
done();
|
$httpBackend.flush();
|
||||||
}).catch(done.fail);
|
|
||||||
|
expect(controller.$.model.data).toEqual(expectedResult);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
"Zone": {
|
"Zone": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"ZoneAgencyMode": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ZoneClosure": {
|
"ZoneClosure": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "ZoneAgencyMode",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "zoneAgencyMode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"agencyModeFk": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"zoneFk": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue