Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2105-export_structure_db

This commit is contained in:
Bernat Exposito Domenech 2020-02-13 08:44:25 +01:00
commit 1887cc8c60
20 changed files with 196 additions and 62 deletions

View File

@ -0,0 +1,3 @@
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId)
VALUES ('TicketWeekly', '*', 'WRITE', 'ALLOW', 'ROLE', 'buyer');
UPDATE salix.ACL SET accessType = 'READ' WHERE (id = '91');

View File

@ -35,7 +35,7 @@ INSERT INTO `vn`.`packagingConfig`(`upperGap`)
UPDATE `account`.`role` SET id = 100 WHERE id = 0;
INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active`,`email`, `lang`)
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@mydomain.com'), 'es'
SELECT id, name, CONCAT(name, 'Nick'),MD5('nightmare'), id, 1, CONCAT(name, '@mydomain.com'), 'EN'
FROM `account`.`role` WHERE id <> 20
ORDER BY id;
@ -55,18 +55,18 @@ INSERT INTO `hedera`.`tpvConfig`(`id`, `currency`, `terminal`, `transactionType`
INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`)
VALUES
(101, 'BruceWayne', 'Bruce Wayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'es'),
(102, 'PetterParker', 'Petter Parker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'en'),
(103, 'ClarkKent', 'Clark Kent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'fr'),
(104, 'TonyStark', 'Tony Stark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'es'),
(105, 'MaxEisenhardt', 'Max Eisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt'),
(106, 'DavidCharlesHaller', 'David Charles Haller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'es'),
(107, 'HankPym', 'Hank Pym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'es'),
(108, 'CharlesXavier', 'Charles Xavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'es'),
(109, 'BruceBanner', 'Bruce Banner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'es'),
(110, 'JessicaJones', 'Jessica Jones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'es'),
(111, 'Missing', 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es'),
(112, 'Trash', 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es');
(101, 'BruceWayne', 'Bruce Wayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'ES'),
(102, 'PetterParker', 'Petter Parker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'EN'),
(103, 'ClarkKent', 'Clark Kent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'FR'),
(104, 'TonyStark', 'Tony Stark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'ES'),
(105, 'MaxEisenhardt', 'Max Eisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'PT'),
(106, 'DavidCharlesHaller', 'David Charles Haller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'EN'),
(107, 'HankPym', 'Hank Pym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'EN'),
(108, 'CharlesXavier', 'Charles Xavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'EN'),
(109, 'BruceBanner', 'Bruce Banner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'EN'),
(110, 'JessicaJones', 'Jessica Jones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'EN'),
(111, 'Missing', 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'EN'),
(112, 'Trash', 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'EN');
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`)
VALUES
@ -753,7 +753,7 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric
(7, 2, 11, 'Melee weapon combat fist 15cm', 15, 7.44, 0, 0, 0, CURDATE()),
(8, 4, 11, 'Melee weapon heavy shield 1x0.5m', 10, 1.79, 0, 0, 0, CURDATE()),
(9, 1, 16, 'Ranged weapon longbow 2m', 1, 103.49, 0, 0, 0, CURDATE()),
(10, 2, 16, 'Melee weapon combat fist 15cm', 10, 7.08, 0, 0, 0, CURDATE()),
(10, 2, 16, 'Melee weapon combat fist 15cm', 10, 7.09, 0, 0, 0, CURDATE()),
(11, 1, 16, 'Ranged weapon longbow 2m', 1, 103.49, 0, 0, 0, CURDATE()),
(12, 4, 16, 'Melee weapon heavy shield 1x0.5m', 20, 1.71, 0, 0, 0, CURDATE()),
(13, 2, 8, 'Melee weapon combat fist 15cm', 10, 7.08, 0, 0, 0, CURDATE()),
@ -814,25 +814,25 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(8, 28, 1.25),
(8, 29, 0.42),
(8, 39, 0.017),
(9, 15, 3.0949),
(9, 21, 0.001),
(9, 28, 50),
(9, 29, 49.4),
(9, 28, 53),
(9, 29, 46.4),
(9, 39, 0.994),
(10, 15, 0.0111),
(10, 21, -0.001),
(10, 28, 5),
(10, 29, 2),
(10, 15, 0.0199),
(10, 28, 7),
(10, 29, 0),
(10, 39, 0.07),
(11, 15, 3.0949),
(11, 21, 0.001),
(11, 28, 50),
(11, 29, 49.4),
(11, 28, 53),
(11, 29, 46.4),
(11, 39, 0.994),
(12, 15, 0.0199),
(12, 21, 0.003),
(12, 28, 1.25),
(12, 29, 0.42),
(12, 28, 2.25),
(12, 29, -0.58),
(12, 39, 0.017),
(13, 15, 0.114),
(13, 28, 5),

View File

@ -0,0 +1,62 @@
const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticket_recalcComponents()', () => {
it('should recalculate the components in a ticket and check it', async() => {
let stmts = [];
let stmt;
const ticketId = 11;
stmts.push('START TRANSACTION');
let sales = await app.models.Sale.find({where: {ticketFk: ticketId}});
stmt = new ParameterizedSQL('UPDATE vn.sale SET price=100 WHERE id IN(?,?)', [
sales[0].id,
sales[1].id
]);
stmts.push(stmt);
stmt = new ParameterizedSQL('SELECT * FROM vn.sale WHERE ticketFk = ?', [
ticketId
]);
stmts.push(stmt);
let modifiedSales = stmts.push(stmt) - 1;
stmt = new ParameterizedSQL('CALL vn.ticket_recalcComponents(?)', [
ticketId,
]);
stmts.push(stmt);
stmt = new ParameterizedSQL('SELECT * FROM vn.sale WHERE ticketFk = ?', [
ticketId
]);
stmts.push(stmt);
let expectedSales = stmts.push(stmt) - 1;
stmts.push('ROLLBACK');
let sql = ParameterizedSQL.join(stmts, ';');
let result = await app.models.Ticket.rawStmt(sql);
// original data
const firstPrice = sales[0].price;
const secondPrice = sales[1].price;
// alteratons for test purposes
const modifiedFirstPrice = result[modifiedSales][0].price;
const modifiedSecondPrice = result[modifiedSales][1].price;
// expected data after recalc
const expectedSalesFirstPrice = result[expectedSales][0].price;
const expectedSalesSecondPrice = result[expectedSales][1].price;
expect(firstPrice).not.toEqual(modifiedFirstPrice);
expect(secondPrice).not.toEqual(modifiedSecondPrice);
expect(firstPrice).toEqual(expectedSalesFirstPrice);
expect(secondPrice).toEqual(expectedSalesSecondPrice);
});
});

View File

@ -1,4 +1,3 @@
/* eslint no-invalid-this: "off" */
import {url as defaultURL} from './config';
let actions = {
@ -31,20 +30,6 @@ let actions = {
}, selector);
},
changeLanguageToEnglish: async function() {
let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]';
await this.waitToClick('#user');
await this.waitForSelector(`${langSelector} input`, {});
let lang = await this.waitToGetProperty(langSelector, 'value');
if (lang !== 'English')
await this.autocompleteSearch(langSelector, 'English');
await this.keyboard.press('Escape');
await this.waitForSelector(langSelector, {hidden: true});
},
doLogin: async function(userName, password = 'nightmare') {
await this.waitForSelector(`vn-login vn-textfield[ng-model="$ctrl.user"]`, {visible: true});
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`);
@ -70,7 +55,6 @@ let actions = {
await this.waitForFunction(() => {
return document.location.hash === '#!/';
}, {});
await this.changeLanguageToEnglish();
},
selectModule: async function(moduleName) {
@ -534,6 +518,13 @@ let actions = {
}, selector);
},
closePopup: async function(selector) {
await Promise.all([
this.keyboard.press('Escape'),
this.waitForSelector('.vn-popup', {hidden: true}),
]);
},
waitForContentLoaded: async function() {
await this.waitFor(1000);
// to be implemented in base of a directive loaded once al modules are done loading, further investigation required.

View File

@ -15,6 +15,18 @@ export async function getBrowser() {
slowMo: 0, // slow down by ms
});
let page = (await browser.pages())[0];
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'language', {
get: function() {
return 'en';
}
});
Object.defineProperty(navigator, 'languages', {
get: function() {
return ['en'];
}
});
});
page = extendPage(page);
page.setDefaultTimeout(5000);
await page.goto(defaultURL, {waitUntil: 'networkidle0'});

View File

@ -643,7 +643,13 @@ export default {
volume: 'vn-route-descriptor vn-label-value[label="Volume"] > section > span'
},
routeSummary: {
routeId: 'vn-route-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(1) > section > span'
header: 'vn-route-summary > vn-card > h5',
routeId: 'vn-route-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(1) > section > span',
cost: 'vn-route-summary vn-label-value[label="Cost"]',
firstTicketID: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(2) > span',
firstTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor',
firstAlias: 'vn-route-summary vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(3) > span',
firstClientDescriptor: '.vn-popover.shown vn-client-descriptor',
},
routeBasicData: {
worker: 'vn-route-basic-data vn-autocomplete[ng-model="$ctrl.route.workerFk"]',

View File

@ -39,7 +39,7 @@ describe('Client balance path', () => {
});
it('should click the new payment button', async() => {
await page.keyboard.press('Escape');
await page.closePopup();
await page.reloadSection('client.card.balance.index');
let url = await page.expectURL('/balance');

View File

@ -27,7 +27,7 @@ describe('Client DMS', () => {
it(`should click on the first document line worker name making the descriptor visible`, async() => {
await page.waitToClick(selectors.dms.firstDocWorker);
await page.wait(selectors.dms.firstDocWorkerDescriptor);
await page.waitForSelector(selectors.dms.firstDocWorkerDescriptor);
const visible = await page.isVisible(selectors.dms.firstDocWorkerDescriptor);
expect(visible).toBeTruthy();

View File

@ -68,9 +68,8 @@ describe('Item summary path', () => {
});
it(`should close the summary popup`, async() => {
await page.keyboard.press('Escape');
await page.waitUntilNotPresent(selectors.itemSummary.basicData);
await page.waitFor(selectors.itemSummary.basicData, {hidden: true});
await page.closePopup();
await page.waitForSelector(selectors.itemSummary.basicData, {hidden: true});
});
it('should search for other item', async() => {
@ -125,7 +124,7 @@ describe('Item summary path', () => {
});
it(`should now close the summary popup`, async() => {
await page.keyboard.press('Escape');
await page.closePopup();
await page.waitForSelector(selectors.itemSummary.basicData, {hidden: true});
});

View File

@ -27,8 +27,7 @@ describe('Item regularize path', () => {
const userLocalWarehouse = await page
.waitToGetProperty(selectors.globalItems.userLocalWarehouse, 'value');
await page.keyboard.press('Escape');
await page.waitForSelector('.user-popover.vn-popover', {hidden: true});
await page.closePopup();
expect(userLocalWarehouse).toContain('Warehouse Four');
});

View File

@ -8,7 +8,7 @@ describe('Ticket descriptor path', () => {
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.loginAndModule('buyer', 'ticket');
await page.accessToSection('ticket.weekly.index');
});

View File

@ -60,8 +60,7 @@ describe('claim Summary path', () => {
it(`should check the url for the item diary link of the descriptor is for the right item id`, async() => {
await page.waitForSelector(selectors.claimSummary.itemDescriptorPopoverItemDiaryButton, {visible: true});
await page.keyboard.press('Escape');
await page.waitFor(1000);
await page.closePopup();
});
it('should display the claim development details', async() => {
@ -81,8 +80,7 @@ describe('claim Summary path', () => {
it(`should check the url for the go to clientlink of the descriptor is for the right client id`, async() => {
await page.waitForSelector(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton, {visible: true});
await page.keyboard.press('Escape');
await page.waitFor(1000);
await page.closePopup();
});
it(`should click on the first action ticket ID making the ticket descriptor visible`, async() => {

View File

@ -0,0 +1,61 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Route summary path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'route');
await page.waitToClick('vn-route-index vn-tbody > a:nth-child(1)');
});
afterAll(async() => {
await browser.close();
});
it('should reach the first route summary section', async() => {
let url = await page.expectURL('#!/route/1/summary');
expect(url).toBe(true);
});
it(`should display details from the route on the header`, async() => {
await page.waitForTextInElement(selectors.routeSummary.header, 'first route');
const result = await page.waitToGetProperty(selectors.routeSummary.header, 'innerText');
expect(result).toContain('first route');
});
it('should display some route details like the cost', async() => {
const result = await page.waitToGetProperty(selectors.routeSummary.cost, 'innerText');
expect(result).toContain('€10.00');
});
it('should click on the first ticket ID making the descriptor popover visible', async() => {
await page.waitToClick(selectors.routeSummary.firstTicketID);
await page.waitForSelector(selectors.routeSummary.firstTicketDescriptor);
const visible = await page.isVisible(selectors.routeSummary.firstTicketDescriptor);
expect(visible).toBe(true);
});
it('should close the ticket descriptor', async() => {
await page.closePopup();
});
it('should click on the first alias making the client descriptor popover visible', async() => {
await page.waitToClick(selectors.routeSummary.firstAlias);
await page.waitForSelector(selectors.routeSummary.firstClientDescriptor);
const visible = await page.isVisible(selectors.routeSummary.firstClientDescriptor);
expect(visible).toBe(true);
});
it('should close the client descriptor', async() => {
await page.closePopup();
});
});

View File

@ -37,7 +37,6 @@ describe('Route create path', () => {
beforeAll(async() => {
await page.login('delivery');
await page.selectModule('route');
await page.changeLanguageToEnglish();
});
it('should again click on the add new route button and open the creation form', async() => {

View File

@ -80,7 +80,7 @@ export function config($translateProvider, $translatePartialLoaderProvider, $ani
let langs = ['en', 'es'];
let langAliases = {
en_US: 'en',
en_UK: 'en',
en_GB: 'en',
es_ES: 'es',
es_AR: 'es'
};

View File

@ -84,8 +84,8 @@
<vn-td number shrink>{{ticket.packages}}</vn-td>
<vn-td shrink>{{ticket.volume}}</vn-td>
<vn-td shrink>{{ticket.warehouse.name}}</vn-td>
<vn-td shrink>{{ticket.client.postcode}}</vn-td>
<vn-td expand title="{{ticket.client.street}}">{{ticket.client.street}}</vn-td>
<vn-td shrink>{{ticket.address.postalCode}}</vn-td>
<vn-td expand title="{{ticket.address.street}}">{{ticket.address.street}}</vn-td>
<vn-td shrink>
<vn-icon
ng-if="ticket.notes.length"

View File

@ -17,8 +17,8 @@ describe('sale priceDifference()', () => {
let result = await app.models.Ticket.priceDifference(httpCtx, ticketId, landed,
addressId, agencyModeId, zoneId, warehouseId);
expect(result.totalUnitPrice).toEqual(215.77);
expect(result.totalNewPrice).toEqual(215.77);
expect(result.totalUnitPrice).toEqual(215.78);
expect(result.totalNewPrice).toEqual(215.78);
expect(result.totalDifference).toEqual(0);
});

View File

@ -7,7 +7,11 @@ class Controller extends Component {
this.aclService = aclService;
this.$httpParamSerializer = $httpParamSerializer;
this.moreOptions = [
{name: 'Add turn', callback: this.showAddTurnDialog},
{
name: 'Add turn',
acl: 'buyer',
callback: this.showAddTurnDialog
},
{name: 'Show Delivery Note', callback: this.showDeliveryNote},
{name: 'Send Delivery Note', callback: this.confirmDeliveryNote},
{name: 'Delete ticket', callback: this.showDeleteTicketDialog},

View File

@ -14,7 +14,7 @@
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<h1 class="title uppercase">{{$t('title')}}</h1>
<h1 class="title uppercase">{{route.id}}</h1>
<div class="panel">
<div class="header">{{$t('information')}}</div>
<div class="body">