refs #5517 Fix e2e #1502

Merged
juan merged 11 commits from 5517-e2eFix into dev 2023-05-05 13:33:46 +00:00
36 changed files with 662 additions and 788 deletions
Showing only changes of commit a48e197e46 - Show all commits

View File

@ -218,23 +218,6 @@ let actions = {
return handle.jsonValue(); return handle.jsonValue();
}, },
getValue: async function(selector) {
return await this.waitToGetProperty(selector, 'value');
},
getValues: async function(selectorMap) {
const values = {};
for (const key in selectorMap)
values[key] = await this.waitToGetProperty(selectorMap[key], 'value');
return values;
},
innerText: async function(selector) {
const element = await this.$(selector);
const handle = await element.getProperty('innerText');
return handle.jsonValue();
},
waitPropertyLength: async function(selector, property, minLength) { waitPropertyLength: async function(selector, property, minLength) {
await this.waitForFunction((selector, property, minLength) => { await this.waitForFunction((selector, property, minLength) => {
const element = document.querySelector(selector); const element = document.querySelector(selector);
@ -431,7 +414,7 @@ let actions = {
const selector = 'vn-snackbar .shape.shown'; const selector = 'vn-snackbar .shape.shown';
await this.waitForSelector(selector); await this.waitForSelector(selector);
let message = await this.evaluate(selector => { const message = await this.evaluate(selector => {
const shape = document.querySelector(selector); const shape = document.querySelector(selector);
const message = { const message = {
text: shape.querySelector('.text').innerText text: shape.querySelector('.text').innerText
@ -448,6 +431,8 @@ let actions = {
return message; return message;
}, selector); }, selector);
message.isSuccess = message.type == 'success';
await this.hideSnackbar(); await this.hideSnackbar();
return message; return message;
}, },
@ -483,28 +468,6 @@ let actions = {
}, selector); }, selector);
}, },
clearInput: async function(selector) {
await this.waitForSelector(selector);
let field = await this.evaluate(selector => {
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field;
}, selector);
if ((field != null && field != '') || field == '0') {
let coords = await this.evaluate(selector => {
let rect = document.querySelector(selector).getBoundingClientRect();
return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width};
}, selector);
await this.mouse.move(coords.x, coords.y);
await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true});
await this.waitToClick(`${selector} [icon="clear"]`);
}
await this.evaluate(selector => {
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == '';
}, selector);
},
autocompleteSearch: async function(selector, searchValue) { autocompleteSearch: async function(selector, searchValue) {
let builtSelector = await this.selectorFormater(selector); let builtSelector = await this.selectorFormater(selector);
@ -536,17 +499,15 @@ let actions = {
checkboxState: async function(selector) { checkboxState: async function(selector) {
await this.waitForSelector(selector); await this.waitForSelector(selector);
return this.evaluate(selector => { const value = await this.getInputValue(selector);
let checkbox = document.querySelector(selector); switch (value) {
switch (checkbox.$ctrl.field) { case null:
case null: return 'intermediate';
return 'intermediate'; case true:
case true: return 'checked';
return 'checked'; default:
default: return 'unchecked';
return 'unchecked'; }
}
}, selector);
}, },
isDisabled: async function(selector) { isDisabled: async function(selector) {
@ -639,6 +600,138 @@ let actions = {
waitForContentLoaded: async function() { waitForContentLoaded: async function() {
await this.waitForSpinnerLoad(); await this.waitForSpinnerLoad();
},
async getInputValue(selector) {
return this.evaluate(selector => {
const input = document.querySelector(selector);
return input.$ctrl.field;
}, selector);
},
async getValue(selector) {
return await this.waitToGetProperty(selector, 'value');
},
async innerText(selector) {
const element = await this.$(selector);
const handle = await element.getProperty('innerText');
return handle.jsonValue();
},
async setInput(selector, value) {
const input = await this.$(selector);
const tagName = (await input.evaluate(e => e.tagName)).toLowerCase();
switch (tagName) {
case 'vn-textfield':
case 'vn-datalist':
case 'vn-input-number':
await this.clearInput(selector);
if (value)
await this.write(selector, value.toString());
break;
case 'vn-autocomplete':
if (value)
await this.autocompleteSearch(selector, value.toString());
else
await this.clearInput(selector);
break;
case 'vn-date-picker':
if (value)
await this.pickDate(selector, value);
else
await this.clearInput(selector);
break;
case 'vn-input-time':
if (value)
await this.pickTime(selector, value);
else
await this.clearInput(selector);
break;
case 'vn-check':
for (let i = 0; i < 3; i++) {
if (await this.getInput(selector) == value) break;
await this.click(selector);
}
break;
}
},
async getInput(selector) {
const input = await this.$(selector);
const tagName = (await input.evaluate(e => e.tagName)).toLowerCase();
let el;
let value;
switch (tagName) {
case 'vn-textfield':
case 'vn-autocomplete':
case 'vn-input-time':
case 'vn-datalist':
el = await input.$('input');
value = await el.getProperty('value');
return value.jsonValue();
case 'vn-check':
case 'vn-input-number':
return await this.getInputValue(selector);
case 'vn-textarea':
el = await input.$('textarea');
value = await el.getProperty('value');
return value.jsonValue();
case 'vn-date-picker':
el = await input.$('input');
value = await el.getProperty('value');
if (value) {
const date = new Date(await value.jsonValue());
date.setUTCHours(0, 0, 0, 0);
return date;
} else
return null;
default:
value = await this.innerText(selector);
return value.jsonValue();
}
},
async clearInput(selector) {
await this.waitForSelector(selector);
let field = await this.evaluate(selector => {
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field;
}, selector);
if ((field != null && field != '') || field == '0') {
let coords = await this.evaluate(selector => {
let rect = document.querySelector(selector).getBoundingClientRect();
return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width};
}, selector);
await this.mouse.move(coords.x, coords.y);
await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true});
await this.waitToClick(`${selector} [icon="clear"]`);
}
await this.evaluate(selector => {
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == '';
}, selector);
},
async fetchForm(selector, inputNames) {
const values = {};
for (const inputName of inputNames)
values[inputName] = await this.getInput(`${selector} [vn-name="${inputName}"]`);
return values;
},
async fillForm(selector, values) {
for (const inputName in values)
await this.setInput(`${selector} [vn-name="${inputName}"]`, values[inputName]);
},
async sendForm(selector, values) {
if (values) await this.fillForm(selector, values);
await this.click(`${selector} button[type=submit]`);
return await this.waitForSnackbar();
} }
}; };
@ -646,12 +739,14 @@ export function extendPage(page) {
for (let name in actions) { for (let name in actions) {
page[name] = async(...args) => { page[name] = async(...args) => {
try { try {
return actions[name].apply(page, args); return await actions[name].apply(page, args);
} catch (err) { } catch (err) {
let stringArgs = args let stringArgs = args
.map(i => typeof i == 'function' ? 'Function' : i) .map(i => typeof i == 'function' ? 'Function' : `'${i}'`)
.join(', '); .join(', ');
throw new Error(`.${name}(${stringArgs}): ${err.message}`); const myErr = new Error(`${err.message}\n at Page.${name}(${stringArgs})`);
myErr.stack = err.stack;
throw myErr;
} }
}; };
} }

View File

@ -193,10 +193,6 @@ export default {
saveNewPoscode: '#savePostcode', saveNewPoscode: '#savePostcode',
createButton: 'vn-client-create button[type=submit]' createButton: 'vn-client-create button[type=submit]'
}, },
clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-button[icon=more_vert]',
simpleTicketButton: '.vn-menu [name="simpleTicket"]'
},
clientBasicData: { clientBasicData: {
name: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.name"]', name: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.name"]',
contact: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.contact"]', contact: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.contact"]',
@ -449,10 +445,6 @@ export default {
packingOut: 'vn-input-number[ng-model="$ctrl.item.packingOut"]', packingOut: 'vn-input-number[ng-model="$ctrl.item.packingOut"]',
isActiveCheckbox: 'vn-check[label="Active"]', isActiveCheckbox: 'vn-check[label="Active"]',
priceInKgCheckbox: 'vn-check[label="Price in kg"]', priceInKgCheckbox: 'vn-check[label="Price in kg"]',
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button',
newIntrastatId: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.newIntrastat.intrastatId"]',
newIntrastatDescription: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newIntrastat.description"]',
acceptIntrastatButton: '.vn-dialog.shown button[response="accept"]',
submitBasicDataButton: `button[type=submit]` submitBasicDataButton: `button[type=submit]`
}, },
itemTags: { itemTags: {
@ -605,13 +597,6 @@ export default {
saveButton: '.vn-dialog.shown [response="accept"]', saveButton: '.vn-dialog.shown [response="accept"]',
expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr' expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr'
}, },
ticketPackages: {
firstPackage: 'vn-autocomplete[label="Package"]',
firstQuantity: 'vn-ticket-package vn-horizontal:nth-child(1) vn-input-number[ng-model="package.quantity"]',
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
savePackagesButton: `button[type=submit]`
},
ticketSales: { ticketSales: {
setOk: 'vn-ticket-sale vn-tool-bar > vn-button[label="Ok"] > button', setOk: 'vn-ticket-sale vn-tool-bar > vn-button[label="Ok"] > button',
saleLine: 'vn-table div > vn-tbody > vn-tr vn-check', saleLine: 'vn-table div > vn-tbody > vn-tr vn-check',
@ -882,14 +867,6 @@ export default {
fifthFilterRemoveButton: 'vn-order-catalog > vn-side-menu .chips > vn-chip:nth-child(5) vn-icon[icon=cancel]', fifthFilterRemoveButton: 'vn-order-catalog > vn-side-menu .chips > vn-chip:nth-child(5) vn-icon[icon=cancel]',
sixthFilterRemoveButton: 'vn-order-catalog > vn-side-menu .chips > vn-chip:nth-child(6) vn-icon[icon=cancel]', sixthFilterRemoveButton: 'vn-order-catalog > vn-side-menu .chips > vn-chip:nth-child(6) vn-icon[icon=cancel]',
}, },
orderBasicData: {
client: 'vn-autocomplete[label="Client"]',
address: 'vn-autocomplete[label="Address"]',
agency: 'vn-autocomplete[label="Agency"]',
observation: 'vn-textarea[label="Notes"]',
saveButton: `button[type=submit]`,
acceptButton: '.vn-confirm.shown button[response="accept"]'
},
orderLine: { orderLine: {
orderSubtotal: 'vn-order-line .header :first-child', orderSubtotal: 'vn-order-line .header :first-child',
firstLineDeleteButton: 'vn-order-line vn-tbody > vn-tr:nth-child(1) vn-icon[icon="delete"]', firstLineDeleteButton: 'vn-order-line vn-tbody > vn-tr:nth-child(1) vn-icon[icon="delete"]',
@ -929,16 +906,6 @@ export default {
goToRouteSummaryButton: 'vn-route-summary > vn-card > h5 > a', goToRouteSummaryButton: 'vn-route-summary > vn-card > h5 > a',
}, },
routeBasicData: {
worker: 'vn-route-basic-data vn-autocomplete[ng-model="$ctrl.route.workerFk"]',
vehicle: 'vn-route-basic-data vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]',
kmStart: 'vn-route-basic-data vn-input-number[ng-model="$ctrl.route.kmStart"]',
kmEnd: 'vn-route-basic-data vn-input-number[ng-model="$ctrl.route.kmEnd"]',
createdDate: 'vn-route-basic-data vn-date-picker[ng-model="$ctrl.route.created"]',
startedHour: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.started"]',
finishedHour: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.finished"]',
saveButton: 'vn-route-basic-data button[type=submit]'
},
routeTickets: { routeTickets: {
firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-input-number[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',
@ -1223,22 +1190,6 @@ export default {
confirmed: 'vn-entry-summary vn-check[label="Confirmed"]', confirmed: 'vn-entry-summary vn-check[label="Confirmed"]',
anyBuyLine: 'vn-entry-summary tr.dark-row' anyBuyLine: 'vn-entry-summary tr.dark-row'
}, },
entryBasicData: {
reference: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.reference"]',
invoiceNumber: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.invoiceNumber"]',
notes: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.notes"]',
observations: 'vn-entry-basic-data vn-textarea[ng-model="$ctrl.entry.observation"]',
supplier: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.supplierFk"]',
currency: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.currencyFk"]',
commission: 'vn-entry-basic-data vn-input-number[ng-model="$ctrl.entry.commission"]',
company: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.companyFk"]',
ordered: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isOrdered"]',
confirmed: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isConfirmed"]',
inventory: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isExcludedFromAvailable"]',
raid: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isRaid"]',
booked: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isBooked"]',
save: 'vn-entry-basic-data button[type=submit]',
},
entryDescriptor: { entryDescriptor: {
agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span', agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span',
travelsQuicklink: 'vn-entry-descriptor vn-quick-link[icon="local_airport"] > a', travelsQuicklink: 'vn-entry-descriptor vn-quick-link[icon="local_airport"] > a',

View File

@ -1,14 +1,23 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-item-basic-data form',
intrastatForm: '.vn-dialog.shown form',
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button'
};
describe('Item Edit basic data path', () => { describe('Item Edit basic data path', () => {
let browser; let browser;
let page; let page;
beforeAll(async() => { beforeAll(async() => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('buyer', 'item'); await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Melee weapon combat fist 15cm'); await page.accessToSearchResult('Melee weapon combat fist 15cm');
});
beforeEach(async() => {
await page.accessToSection('item.card.basicData'); await page.accessToSection('item.card.basicData');
}); });
@ -16,124 +25,42 @@ describe('Item Edit basic data path', () => {
await browser.close(); await browser.close();
}); });
it(`should check the descritor edit button is visible for buyer`, async() => { it(`should edit the item basic data and confirm the item data was edited`, async() => {
await page.waitForSelector(selectors.itemDescriptor.editButton, {visible: true}); const values = {
}); name: 'Rose of Purity',
longName: 'RS Rose of Purity',
type: 'Anthurium',
intrastat: 'Coral y materiales similares',
origin: 'Spain',
relevancy: 1,
generic: 'Pallet',
isActive: false,
priceInKg: true,
isFragile: true,
packingOut: 5
};
it(`should edit the item basic data`, async() => { const message = await page.sendForm($.form, values);
await page.clearInput(selectors.itemBasicData.name);
await page.write(selectors.itemBasicData.name, 'Rose of Purity');
await page.clearInput(selectors.itemBasicData.longName);
await page.write(selectors.itemBasicData.longName, 'RS Rose of Purity');
await page.autocompleteSearch(selectors.itemBasicData.type, 'Anthurium');
await page.autocompleteSearch(selectors.itemBasicData.intrastat, 'Coral y materiales similares');
await page.autocompleteSearch(selectors.itemBasicData.origin, 'Spain');
await page.clearInput(selectors.itemBasicData.relevancy);
await page.write(selectors.itemBasicData.relevancy, '1');
await page.clearInput(selectors.itemBasicData.generic);
await page.autocompleteSearch(selectors.itemBasicData.generic, '16');
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox);
await page.waitToClick(selectors.itemBasicData.isFragile);
await page.write(selectors.itemBasicData.packingOut, '5');
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should create a new intrastat`, async() => {
await page.waitToClick(selectors.itemBasicData.newIntrastatButton);
await page.write(selectors.itemBasicData.newIntrastatId, '588420239');
await page.write(selectors.itemBasicData.newIntrastatDescription, 'Tropical Flowers');
await page.waitToClick(selectors.itemBasicData.acceptIntrastatButton);
await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers');
let newcode = await page.waitToGetProperty(selectors.itemBasicData.intrastat, 'value');
expect(newcode).toEqual('588420239 Tropical Flowers');
});
it('should save with the new intrastat', async() => {
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the item name was edited`, async() => {
await page.reloadSection('item.card.basicData'); await page.reloadSection('item.card.basicData');
const result = await page.waitToGetProperty(selectors.itemBasicData.name, 'value'); const formValues = await page.fetchForm($.form, Object.keys(values));
expect(result).toEqual('Rose of Purity'); expect(message.isSuccess).toBeTrue();
expect(formValues).toEqual(values);
}); });
it(`should confirm the item type was edited`, async() => { it(`should create a new intrastat and save it`, async() => {
const result = await page await page.click($.newIntrastatButton);
.waitToGetProperty(selectors.itemBasicData.type, 'value'); await page.fillForm($.intrastatForm, {
id: '588420239',
description: 'Tropical Flowers'
});
await page.respondToDialog('accept');
expect(result).toEqual('Anthurium'); const message = await page.sendForm($.form);
}); await page.reloadSection('item.card.basicData');
const formValues = await page.fetchForm($.form, ['intrastat']);
it(`should confirm the item intrastat was edited`, async() => { expect(message.isSuccess).toBeTrue();
const result = await page expect(formValues).toEqual({intrastat: 'Tropical Flowers'});
.waitToGetProperty(selectors.itemBasicData.intrastat, 'value');
expect(result).toEqual('588420239 Tropical Flowers');
});
it(`should confirm the item relevancy was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.relevancy, 'value');
expect(result).toEqual('1');
});
it(`should confirm the item origin was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.origin, 'value');
expect(result).toEqual('Spain');
});
it(`should confirm the item generic was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.generic, 'value');
expect(result).toEqual('16 - Pallet');
});
it(`should confirm the item long name was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.longName, 'value');
expect(result).toEqual('RS Rose of Purity');
});
it('should confirm isFragile checkbox is unchecked', async() => {
const result = await page
.checkboxState(selectors.itemBasicData.isFragile);
expect(result).toBe('checked');
});
it('should confirm isActive checkbox is unchecked', async() => {
const result = await page
.checkboxState(selectors.itemBasicData.isActiveCheckbox);
expect(result).toBe('unchecked');
});
it('should confirm the priceInKg checkbox is checked', async() => {
const result = await page
.checkboxState(selectors.itemBasicData.priceInKgCheckbox);
expect(result).toBe('checked');
});
it(`should confirm the item packingOut was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.packingOut, 'value');
expect(result).toEqual('5');
}); });
}); });

View File

@ -1,6 +1,10 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-item-create form'
};
describe('Item Create', () => { describe('Item Create', () => {
let browser; let browser;
let page; let page;
@ -14,13 +18,6 @@ describe('Item Create', () => {
await browser.close(); await browser.close();
}); });
it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => {
await page.doSearch('Infinity Gauntlet');
const resultsCount = await page.countElement(selectors.itemsIndex.searchResult);
expect(resultsCount).toEqual(0);
});
it('should access to the create item view by clicking the create floating button', async() => { it('should access to the create item view by clicking the create floating button', async() => {
await page.waitToClick(selectors.itemsIndex.createItemButton); await page.waitToClick(selectors.itemsIndex.createItemButton);
await page.waitForState('item.create'); await page.waitForState('item.create');
@ -37,44 +34,32 @@ describe('Item Create', () => {
}); });
it('should throw an error when insert an invalid priority', async() => { it('should throw an error when insert an invalid priority', async() => {
await page.write(selectors.itemCreateView.temporalName, 'Infinity Gauntlet'); const values = {
await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo'); name: 'Infinity Gauntlet',
await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); type: 'Crisantemo',
await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); intrastat: 'Coral y materiales similares',
await page.clearInput(selectors.itemCreateView.priority); origin: 'Holand',
await page.waitToClick(selectors.itemCreateView.createButton); priority: null
const message = await page.waitForSnackbar(); };
const message = await page.sendForm($.form, values);
expect(message.text).toContain('Valid priorities'); expect(message.text).toContain('Valid priorities');
}); });
it('should create the Infinity Gauntlet item', async() => { it('should create the Infinity Gauntlet item', async() => {
await page.autocompleteSearch(selectors.itemCreateView.priority, '2'); const values = {
await page.waitToClick(selectors.itemCreateView.createButton); name: 'Infinity Gauntlet',
const message = await page.waitForSnackbar(); type: 'Crisantemo',
intrastat: 'Coral y materiales similares',
origin: 'Holand',
priority: '2'
};
expect(message.text).toContain('Data saved!'); await page.fillForm($.form, values);
}); const formValues = await page.fetchForm($.form, Object.keys(values));
const message = await page.sendForm($.form);
it('should confirm Infinity Gauntlet item was created', async() => { expect(message.isSuccess).toBeTrue();
let result = await page expect(formValues).toEqual(values);
.waitToGetProperty(selectors.itemBasicData.name, 'value');
expect(result).toEqual('Infinity Gauntlet');
result = await page
.waitToGetProperty(selectors.itemBasicData.type, 'value');
expect(result).toEqual('Crisantemo');
result = await page
.waitToGetProperty(selectors.itemBasicData.intrastat, 'value');
expect(result).toEqual('5080000 Coral y materiales similares');
result = await page
.waitToGetProperty(selectors.itemBasicData.origin, 'value');
expect(result).toEqual('Holand');
}); });
}); });

View File

@ -1,6 +1,8 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = selectors.itemFixedPrice;
describe('Item fixed prices path', () => { describe('Item fixed prices path', () => {
let browser; let browser;
let page; let page;
@ -22,63 +24,63 @@ describe('Item fixed prices path', () => {
}); });
it('should filter using all the fields', async() => { it('should filter using all the fields', async() => {
await page.write(selectors.itemFixedPrice.generalSearchFilter, 'item'); await page.write($.generalSearchFilter, 'item');
await page.keyboard.press('Enter'); await page.keyboard.press('Enter');
expect(httpRequest).toContain('search=item'); expect(httpRequest).toContain('search=item');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.click(selectors.itemFixedPrice.reignFilter); await page.click($.reignFilter);
expect(httpRequest).toContain('categoryFk'); expect(httpRequest).toContain('categoryFk');
await page.autocompleteSearch(selectors.itemFixedPrice.typeFilter, 'Alstroemeria'); await page.autocompleteSearch($.typeFilter, 'Alstroemeria');
expect(httpRequest).toContain('typeFk'); expect(httpRequest).toContain('typeFk');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.autocompleteSearch(selectors.itemFixedPrice.buyerFilter, 'buyerNick'); await page.autocompleteSearch($.buyerFilter, 'buyerNick');
expect(httpRequest).toContain('buyerFk'); expect(httpRequest).toContain('buyerFk');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.autocompleteSearch(selectors.itemFixedPrice.warehouseFilter, 'Algemesi'); await page.autocompleteSearch($.warehouseFilter, 'Algemesi');
expect(httpRequest).toContain('warehouseFk'); expect(httpRequest).toContain('warehouseFk');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.click(selectors.itemFixedPrice.mineFilter); await page.click($.mineFilter);
expect(httpRequest).toContain('mine=true'); expect(httpRequest).toContain('mine=true');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.click(selectors.itemFixedPrice.hasMinPriceFilter); await page.click($.hasMinPriceFilter);
expect(httpRequest).toContain('hasMinPrice=true'); expect(httpRequest).toContain('hasMinPrice=true');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
await page.click(selectors.itemFixedPrice.addTag); await page.click($.addTag);
await page.autocompleteSearch(selectors.itemFixedPrice.tagFilter, 'Color'); await page.autocompleteSearch($.tagFilter, 'Color');
await page.autocompleteSearch(selectors.itemFixedPrice.tagValueFilter, 'Brown'); await page.autocompleteSearch($.tagValueFilter, 'Brown');
expect(httpRequest).toContain('tags'); expect(httpRequest).toContain('tags');
await page.click(selectors.itemFixedPrice.chip); await page.click($.chip);
}); });
it('should click on the add new fixed price button', async() => { it('should click on the add new fixed price button', async() => {
await page.waitToClick(selectors.itemFixedPrice.add); await page.waitToClick($.add);
await page.waitForSelector(selectors.itemFixedPrice.fourthFixedPrice); await page.waitForSelector($.fourthFixedPrice);
}); });
it('should fill the fixed price data', async() => { it('should fill the fixed price data', async() => {
const now = Date.vnNew(); const now = Date.vnNew();
await page.autocompleteSearch(selectors.itemFixedPrice.fourthWarehouse, 'Warehouse one'); await page.autocompleteSearch($.fourthWarehouse, 'Warehouse one');
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthGroupingPrice, '1'); await page.writeOnEditableTD($.fourthGroupingPrice, '1');
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthPackingPrice, '1'); await page.writeOnEditableTD($.fourthPackingPrice, '1');
await page.write(selectors.itemFixedPrice.fourthMinPrice, '1'); await page.write($.fourthMinPrice, '1');
await page.pickDate(selectors.itemFixedPrice.fourthStarted, now); await page.pickDate($.fourthStarted, now);
await page.pickDate(selectors.itemFixedPrice.fourthEnded, now); await page.pickDate($.fourthEnded, now);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
@ -87,7 +89,7 @@ describe('Item fixed prices path', () => {
it('should reload the section and check the created price has the expected ID', async() => { it('should reload the section and check the created price has the expected ID', async() => {
await page.goto(`http://localhost:5000/#!/item/fixed-price`); await page.goto(`http://localhost:5000/#!/item/fixed-price`);
const result = await page.waitToGetProperty(selectors.itemFixedPrice.fourthItemID, 'value'); const result = await page.waitToGetProperty($.fourthItemID, 'value');
expect(result).toContain('13'); expect(result).toContain('13');
}); });

View File

@ -1,6 +1,13 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
firstPackage: 'vn-autocomplete[label="Package"]',
firstQuantity: 'vn-ticket-package vn-horizontal:nth-child(1) vn-input-number[ng-model="package.quantity"]',
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
savePackagesButton: `button[type=submit]`
};
describe('Ticket Create packages path', () => { describe('Ticket Create packages path', () => {
let browser; let browser;
let page; let page;
@ -18,19 +25,19 @@ describe('Ticket Create packages path', () => {
}); });
it(`should attempt create a new package but receive an error if package is blank`, async() => { it(`should attempt create a new package but receive an error if package is blank`, async() => {
await page.waitToClick(selectors.ticketPackages.firstRemovePackageButton); await page.waitToClick($.firstRemovePackageButton);
await page.waitToClick(selectors.ticketPackages.addPackageButton); await page.waitToClick($.addPackageButton);
await page.write(selectors.ticketPackages.firstQuantity, '99'); await page.write($.firstQuantity, '99');
await page.waitToClick(selectors.ticketPackages.savePackagesButton); await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Package cannot be blank'); expect(message.text).toContain('Package cannot be blank');
}); });
it(`should delete the first package and receive and error to save a new one with blank quantity`, async() => { it(`should delete the first package and receive and error to save a new one with blank quantity`, async() => {
await page.clearInput(selectors.ticketPackages.firstQuantity); await page.clearInput($.firstQuantity);
await page.autocompleteSearch(selectors.ticketPackages.firstPackage, 'Container medical box 1m'); await page.autocompleteSearch($.firstPackage, 'Container medical box 1m');
await page.waitToClick(selectors.ticketPackages.savePackagesButton); await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Some fields are invalid'); expect(message.text).toContain('Some fields are invalid');
@ -40,15 +47,15 @@ describe('Ticket Create packages path', () => {
const result = await page const result = await page
.evaluate(selector => { .evaluate(selector => {
return document.querySelector(`${selector} input`).checkValidity(); return document.querySelector(`${selector} input`).checkValidity();
}, selectors.ticketPackages.firstQuantity); }, $.firstQuantity);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
it(`should create a new package with correct data`, async() => { it(`should create a new package with correct data`, async() => {
await page.clearInput(selectors.ticketPackages.firstQuantity); await page.clearInput($.firstQuantity);
await page.write(selectors.ticketPackages.firstQuantity, '-99'); await page.write($.firstQuantity, '-99');
await page.waitToClick(selectors.ticketPackages.savePackagesButton); await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
@ -56,15 +63,15 @@ describe('Ticket Create packages path', () => {
it(`should confirm the first select is the expected one`, async() => { it(`should confirm the first select is the expected one`, async() => {
await page.reloadSection('ticket.card.package'); await page.reloadSection('ticket.card.package');
await page.waitForTextInField(selectors.ticketPackages.firstPackage, 'Container medical box 1m'); await page.waitForTextInField($.firstPackage, 'Container medical box 1m');
const result = await page.waitToGetProperty(selectors.ticketPackages.firstPackage, 'value'); const result = await page.waitToGetProperty($.firstPackage, 'value');
expect(result).toEqual('7 : Container medical box 1m'); expect(result).toEqual('Container medical box 1m');
}); });
it(`should confirm quantity is just a number and the string part was ignored by the imput number`, async() => { it(`should confirm quantity is just a number and the string part was ignored by the imput number`, async() => {
await page.waitForTextInField(selectors.ticketPackages.firstQuantity, '-99'); await page.waitForTextInField($.firstQuantity, '-99');
const result = await page.waitToGetProperty(selectors.ticketPackages.firstQuantity, 'value'); const result = await page.waitToGetProperty($.firstQuantity, 'value');
expect(result).toEqual('-99'); expect(result).toEqual('-99');
}); });

View File

@ -1,6 +1,11 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-ticket-create-card',
moreMenu: 'vn-client-descriptor vn-icon-button[icon=more_vert]',
simpleTicketButton: '.vn-menu [name="simpleTicket"]'
};
describe('Ticket create from client path', () => { describe('Ticket create from client path', () => {
let browser; let browser;
let page; let page;
@ -16,20 +21,17 @@ describe('Ticket create from client path', () => {
await browser.close(); await browser.close();
}); });
it('should click the create simple ticket on the descriptor menu', async() => { it('should create simple ticket and check if the client details are the expected ones', async() => {
await page.waitToClick(selectors.clientDescriptor.moreMenu); await page.waitToClick($.moreMenu);
await page.waitToClick(selectors.clientDescriptor.simpleTicketButton); await page.waitToClick($.simpleTicketButton);
await page.waitForState('ticket.create'); await page.waitForState('ticket.create');
});
it('should check if the client details are the expected ones', async() => { const values = {
const client = await page client: 'Petter Parker',
.waitToGetProperty(selectors.createTicketView.client, 'value'); address: 'Petter Parker'
};
const formValues = await page.fetchForm($.form, Object.keys(values));
const address = await page expect(formValues).toEqual(values);
.waitToGetProperty(selectors.createTicketView.address, 'value');
expect(client).toContain('Petter Parker');
expect(address).toContain('20 Ingram Street');
}); });
}); });

View File

@ -1,6 +1,13 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-order-basic-data form',
observation: 'vn-order-basic-data form [vn-name="note"]',
saveButton: `vn-order-basic-data form button[type=submit]`,
acceptButton: '.vn-confirm.shown button[response="accept"]'
};
describe('Order edit basic data path', () => { describe('Order edit basic data path', () => {
let browser; let browser;
let page; let page;
@ -20,90 +27,43 @@ describe('Order edit basic data path', () => {
describe('when confirmed order', () => { describe('when confirmed order', () => {
it('should not be able to change the client', async() => { it('should not be able to change the client', async() => {
await page.autocompleteSearch(selectors.orderBasicData.client, 'Tony Stark'); const message = await page.sendForm($.form, {
await page.autocompleteSearch(selectors.orderBasicData.address, 'Tony Stark'); client: 'Tony Stark',
await page.waitToClick(selectors.orderBasicData.saveButton); address: 'Tony Stark',
const message = await page.waitForSnackbar(); });
expect(message.text).toContain(`You can't make changes on the basic data of an confirmed order or with rows`); expect(message.text).toContain(`You can't make changes on the basic data`);
});
});
describe('when order with rows', () => {
it('should now navigate to order index', async() => {
const orderId = '16';
await page.waitToClick(selectors.orderDescriptor.returnToModuleIndexButton);
await page.waitToClick(selectors.globalItems.acceptButton);
await page.waitForContentLoaded();
await page.accessToSearchResult(orderId);
await page.accessToSection('order.card.basicData');
await page.waitForSelector(selectors.orderBasicData.observation, {visible: true});
await page.waitForState('order.card.basicData');
});
it('should not be able to change anything', async() => {
await page.write(selectors.orderBasicData.observation, 'observation');
await page.waitToClick(selectors.orderBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`You can't make changes on the basic data of an confirmed order or with rows`);
}); });
}); });
describe('when new order', () => { describe('when new order', () => {
it('should navigate to the order index and click the new order button', async() => { it('should create an order and edit its basic data', async() => {
await page.waitToClick(selectors.globalItems.returnToModuleIndexButton); await page.waitToClick(selectors.globalItems.returnToModuleIndexButton);
await page.waitToClick(selectors.orderBasicData.acceptButton); await page.waitToClick($.acceptButton);
await page.waitForContentLoaded(); await page.waitForContentLoaded();
await page.waitToClick(selectors.ordersIndex.createOrderButton); await page.waitToClick(selectors.ordersIndex.createOrderButton);
await page.waitForState('order.create'); await page.waitForState('order.create');
});
it('should now create a new one', async() => {
await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones'); await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones');
await page.pickDate(selectors.createOrderView.landedDatePicker); await page.pickDate(selectors.createOrderView.landedDatePicker);
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency'); await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
await page.waitToClick(selectors.createOrderView.createButton); await page.waitToClick(selectors.createOrderView.createButton);
await page.waitForState('order.card.catalog'); await page.waitForState('order.card.catalog');
});
it('should navigate to the basic data section of the new order', async() => {
await page.accessToSection('order.card.basicData'); await page.accessToSection('order.card.basicData');
await page.waitForState('order.card.basicData');
});
it('should be able to modify all the properties', async() => { const values = {
await page.autocompleteSearch(selectors.orderBasicData.client, 'Tony Stark'); client: 'Tony Stark',
await page.autocompleteSearch(selectors.orderBasicData.address, 'Tony Stark'); address: 'Tony Stark',
await page.autocompleteSearch(selectors.orderBasicData.agency, 'Other agency'); agencyMode: 'Other agency'
await page.write(selectors.orderBasicData.observation, 'my observation'); };
await page.waitToClick(selectors.orderBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!'); const message = await page.sendForm($.form, values);
});
it('should now confirm the client have been edited', async() => {
await page.reloadSection('order.card.basicData'); await page.reloadSection('order.card.basicData');
const result = await page const formValues = await page.fetchForm($.form, Object.keys(values));
.waitToGetProperty(selectors.orderBasicData.client, 'value');
expect(result).toEqual('1104: Tony Stark'); expect(message.isSuccess).toBeTrue();
}); expect(formValues).toEqual(values);
it('should now confirm the agency have been edited', async() => {
const result = await page
.waitToGetProperty(selectors.orderBasicData.agency, 'value');
expect(result).toEqual('Other agency');
});
it('should now confirm the observations have been edited', async() => {
const result = await page
.waitToGetProperty(selectors.orderBasicData.observation, 'value');
expect(result).toEqual('my observation');
}); });
}); });
}); });

View File

@ -1,4 +1,3 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Route basic Data path', () => { describe('Route basic Data path', () => {
@ -17,47 +16,27 @@ describe('Route basic Data path', () => {
await browser.close(); await browser.close();
}); });
it('should edit the route basic data', async() => { it('should edit the route basic data and confirm the route was edited', async() => {
const nextMonth = Date.vnNew(); const nextMonth = Date.vnNew();
nextMonth.setMonth(nextMonth.getMonth() + 1); nextMonth.setMonth(nextMonth.getMonth() + 1);
nextMonth.setUTCHours(0, 0, 0, 0);
await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick'); const form = 'vn-route-basic-data form';
await page.autocompleteSearch(selectors.routeBasicData.vehicle, '1111-IMK'); const values = {
await page.pickDate(selectors.routeBasicData.createdDate, nextMonth); worker: 'adminBossNick',
await page.clearInput(selectors.routeBasicData.kmStart); vehicle: '1111-IMK',
await page.write(selectors.routeBasicData.kmStart, '1'); created: nextMonth,
await page.clearInput(selectors.routeBasicData.kmEnd); kmStart: 1,
await page.write(selectors.routeBasicData.kmEnd, '2'); kmEnd: 2,
await page.type(`${selectors.routeBasicData.startedHour} input`, '0800'); started: '08:00',
await page.type(`${selectors.routeBasicData.finishedHour} input`, '1230'); finished: '12:30',
await page.waitToClick(selectors.routeBasicData.saveButton); };
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!'); const message = await page.sendForm(form, values);
});
it('should confirm the worker was edited', async() => {
await page.reloadSection('route.card.basicData'); await page.reloadSection('route.card.basicData');
const worker = await page.waitToGetProperty(selectors.routeBasicData.worker, 'value'); const formValues = await page.fetchForm(form, Object.keys(values));
expect(worker).toEqual('adminBoss - adminBossNick'); expect(message.isSuccess).toBeTrue();
}); expect(formValues).toEqual(values);
it('should confirm the vehicle was edited', async() => {
const vehicle = await page.waitToGetProperty(selectors.routeBasicData.vehicle, 'value');
expect(vehicle).toEqual('1111-IMK');
});
it('should confirm the km start was edited', async() => {
const kmStart = await page.waitToGetProperty(selectors.routeBasicData.kmStart, 'value');
expect(kmStart).toEqual('1');
});
it('should confirm the km end was edited', async() => {
const kmEnd = await page.waitToGetProperty(selectors.routeBasicData.kmEnd, 'value');
expect(kmEnd).toEqual('2');
}); });
}); });

View File

@ -17,55 +17,36 @@ describe('InvoiceIn tax path', () => {
await browser.close(); await browser.close();
}); });
it('should add a new tax', async() => { it('should add a new tax and check it', async() => {
await page.waitToClick(selectors.invoiceInTax.addTaxButton); await page.waitToClick(selectors.invoiceInTax.addTaxButton);
await page.autocompleteSearch(selectors.invoiceInTax.thirdExpense, '6210000567'); await page.autocompleteSearch(selectors.invoiceInTax.thirdExpense, '6210000567');
await page.write(selectors.invoiceInTax.thirdTaxableBase, '100'); await page.write(selectors.invoiceInTax.thirdTaxableBase, '100');
await page.autocompleteSearch(selectors.invoiceInTax.thirdTaxType, '6'); await page.autocompleteSearch(selectors.invoiceInTax.thirdTaxType, 'H.P. IVA');
await page.autocompleteSearch(selectors.invoiceInTax.thirdTransactionType, 'Operaciones exentas'); await page.autocompleteSearch(selectors.invoiceInTax.thirdTransactionType, 'Operaciones exentas');
await page.waitToClick(selectors.invoiceInTax.saveButton); await page.waitToClick(selectors.invoiceInTax.saveButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should navigate to the summary and check the taxable base sum is correct', async() => {
await page.waitToClick(selectors.invoiceInDescriptor.summaryIcon); await page.waitToClick(selectors.invoiceInDescriptor.summaryIcon);
await page.waitForState('invoiceIn.card.summary'); await page.waitForState('invoiceIn.card.summary');
const result = await page.waitToGetProperty(selectors.invoiceInSummary.totalTaxableBase, 'innerText'); const total = await page.waitToGetProperty(selectors.invoiceInSummary.totalTaxableBase, 'innerText');
expect(result).toEqual('Taxable base €1,323.16');
});
it('should navigate back to tax section, check the reciently added line contains the expected expense', async() => {
await page.accessToSection('invoiceIn.card.tax'); await page.accessToSection('invoiceIn.card.tax');
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdExpense, 'value');
expect(result).toEqual('6210000567: Alquiler VNH'); const thirdExpense = await page.waitToGetProperty(selectors.invoiceInTax.thirdExpense, 'value');
}); const thirdTaxableBase = await page.waitToGetProperty(selectors.invoiceInTax.thirdTaxableBase, 'value');
const thirdTaxType = await page.waitToGetProperty(selectors.invoiceInTax.thirdTaxType, 'value');
const thirdTransactionType = await page.waitToGetProperty(selectors.invoiceInTax.thirdTransactionType, 'value');
const thirdRate = await page.waitToGetProperty(selectors.invoiceInTax.thirdRate, 'value');
it('should check the reciently added line contains the expected taxable base', async() => { expect(message.text).toContain('Data saved!');
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdTaxableBase, 'value');
expect(result).toEqual('100'); expect(total).toEqual('Taxable base €1,323.16');
});
it('should check the reciently added line contains the expected tax type', async() => { expect(thirdExpense).toEqual('6210000567');
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdTaxType, 'value'); expect(thirdTaxableBase).toEqual('100');
expect(thirdTaxType).toEqual('H.P. IVA 4% CEE');
expect(result).toEqual('6: H.P. IVA 4% CEE'); expect(thirdTransactionType).toEqual('Operaciones exentas');
}); expect(thirdRate).toEqual('€4.00');
it('should check the reciently added line contains the expected transaction type', async() => {
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdTransactionType, 'value');
expect(result).toEqual('37: Operaciones exentas');
});
it('should check the reciently added line contains the expected rate', async() => {
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdRate, 'value');
expect(result).toEqual('€4.00');
}); });
it('should delete the added line', async() => { it('should delete the added line', async() => {

View File

@ -15,49 +15,39 @@ describe('InvoiceOut manual invoice path', () => {
await browser.close(); await browser.close();
}); });
it('should open the manual invoice form', async() => { it('should create an invoice from a ticket', async() => {
await page.waitToClick(selectors.invoiceOutIndex.createInvoice); await page.waitToClick(selectors.invoiceOutIndex.createInvoice);
await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm); await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm);
});
it('should create an invoice from a ticket', async() => {
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTicket, '15'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTicket, '15');
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional');
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national');
await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); await page.waitToClick(selectors.invoiceOutIndex.saveInvoice);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
await page.waitForState('invoiceOut.card.summary');
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
}); });
it(`should have been redirected to the created invoice summary`, async() => { it(`should create another invoice from a client`, async() => {
await page.waitForState('invoiceOut.card.summary');
});
it(`should navigate back to the invoiceOut index`, async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.invoiceOutButton); await page.waitToClick(selectors.globalItems.invoiceOutButton);
await page.waitForSelector(selectors.invoiceOutIndex.topbarSearch); await page.waitForSelector(selectors.invoiceOutIndex.topbarSearch);
await page.waitForState('invoiceOut.index'); await page.waitForState('invoiceOut.index');
});
it('should now open the manual invoice form', async() => {
await page.waitToClick(selectors.invoiceOutIndex.createInvoice); await page.waitToClick(selectors.invoiceOutIndex.createInvoice);
await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm); await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm);
});
it('should create an invoice from a client', async() => {
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Max Eisenhardt'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Max Eisenhardt');
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional');
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national'); await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national');
await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); await page.waitToClick(selectors.invoiceOutIndex.saveInvoice);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
await page.waitForState('invoiceOut.card.summary');
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
}); });
it(`should have been redirected to the created invoice summary`, async() => {
await page.waitForState('invoiceOut.card.summary');
});
}); });

View File

@ -18,7 +18,6 @@ describe('InvoiceOut global invoice path', () => {
}); });
let invoicesBeforeOneClient; let invoicesBeforeOneClient;
let invoicesBeforeAllClients;
let now = Date.vnNew(); let now = Date.vnNew();
it('should count the amount of invoices listed before globla invoces are made', async() => { it('should count the amount of invoices listed before globla invoces are made', async() => {
@ -27,13 +26,10 @@ describe('InvoiceOut global invoice path', () => {
expect(invoicesBeforeOneClient).toBeGreaterThanOrEqual(4); expect(invoicesBeforeOneClient).toBeGreaterThanOrEqual(4);
}); });
it('should open the global invoice form', async() => {
await page.accessToSection('invoiceOut.global-invoicing');
});
it('should create a global invoice for charles xavier today', async() => { it('should create a global invoice for charles xavier today', async() => {
await page.accessToSection('invoiceOut.global-invoicing');
await page.waitToClick(selectors.invoiceOutGlobalInvoicing.oneClient); await page.waitToClick(selectors.invoiceOutGlobalInvoicing.oneClient);
await page.autocompleteSearch(selectors.invoiceOutGlobalInvoicing.clientId, '1108'); await page.autocompleteSearch(selectors.invoiceOutGlobalInvoicing.clientId, 'Charles Xavier');
await page.pickDate(selectors.invoiceOutGlobalInvoicing.invoiceDate, now); await page.pickDate(selectors.invoiceOutGlobalInvoicing.invoiceDate, now);
await page.pickDate(selectors.invoiceOutGlobalInvoicing.maxShipped, now); await page.pickDate(selectors.invoiceOutGlobalInvoicing.maxShipped, now);
await page.autocompleteSearch(selectors.invoiceOutGlobalInvoicing.printer, '1'); await page.autocompleteSearch(selectors.invoiceOutGlobalInvoicing.printer, '1');

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Entry lastest buys path', () => { fdescribe('Entry lastest buys path', () => {
let browser; let browser;
let page; let page;
const httpRequests = []; const httpRequests = [];

View File

@ -21,8 +21,8 @@ describe('Entry create path', () => {
}); });
it('should fill the form to create a valid entry then redirect to basic Data', async() => { it('should fill the form to create a valid entry then redirect to basic Data', async() => {
await page.autocompleteSearch(selectors.entryIndex.newEntrySupplier, '2'); await page.autocompleteSearch(selectors.entryIndex.newEntrySupplier, 'The farmer');
await page.autocompleteSearch(selectors.entryIndex.newEntryTravel, 'Warehouse Three'); await page.autocompleteSearch(selectors.entryIndex.newEntryTravel, 'Warehouse');
await page.autocompleteSearch(selectors.entryIndex.newEntryCompany, 'ORN'); await page.autocompleteSearch(selectors.entryIndex.newEntryCompany, 'ORN');
await page.waitToClick(selectors.entryIndex.saveNewEntry); await page.waitToClick(selectors.entryIndex.saveNewEntry);

View File

@ -1,6 +1,22 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
reference: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.reference"]',
invoiceNumber: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.invoiceNumber"]',
notes: 'vn-entry-basic-data vn-textfield[ng-model="$ctrl.entry.notes"]',
observations: 'vn-entry-basic-data vn-textarea[ng-model="$ctrl.entry.observation"]',
supplier: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.supplierFk"]',
currency: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.currencyFk"]',
commission: 'vn-entry-basic-data vn-input-number[ng-model="$ctrl.entry.commission"]',
company: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.companyFk"]',
ordered: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isOrdered"]',
confirmed: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isConfirmed"]',
inventory: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isExcludedFromAvailable"]',
raid: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isRaid"]',
booked: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isBooked"]',
save: 'vn-entry-basic-data button[type=submit]',
};
describe('Entry basic data path', () => { describe('Entry basic data path', () => {
let browser; let browser;
let page; let page;
@ -17,98 +33,49 @@ describe('Entry basic data path', () => {
await browser.close(); await browser.close();
}); });
it('should edit the basic data', async() => { it('should edit the basic data and confirm the reference was edited', async() => {
await page.write(selectors.entryBasicData.reference, 'new movement 8'); await page.write($.reference, 'new movement 8');
await page.write(selectors.entryBasicData.invoiceNumber, 'new movement 8'); await page.write($.invoiceNumber, 'new movement 8');
await page.write(selectors.entryBasicData.observations, ' edited'); await page.write($.observations, ' edited');
await page.autocompleteSearch(selectors.entryBasicData.supplier, 'Plants nick'); await page.autocompleteSearch($.supplier, 'Plants nick');
await page.autocompleteSearch(selectors.entryBasicData.currency, 'eur'); await page.autocompleteSearch($.currency, 'eur');
await page.clearInput(selectors.entryBasicData.commission); await page.clearInput($.commission);
await page.write(selectors.entryBasicData.commission, '100'); await page.write($.commission, '100');
await page.autocompleteSearch(selectors.entryBasicData.company, 'CCs'); await page.autocompleteSearch($.company, 'CCs');
await page.waitToClick(selectors.entryBasicData.ordered); await page.waitToClick($.ordered);
await page.waitToClick(selectors.entryBasicData.confirmed); await page.waitToClick($.confirmed);
await page.waitToClick(selectors.entryBasicData.inventory); await page.waitToClick($.inventory);
await page.waitToClick(selectors.entryBasicData.raid); await page.waitToClick($.raid);
await page.waitToClick(selectors.entryBasicData.booked); await page.waitToClick($.booked);
await page.waitToClick(selectors.entryBasicData.save); await page.waitToClick($.save);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
await page.reloadSection('entry.card.basicData');
const reference = await page.waitToGetProperty($.reference, 'value');
const supplier = await page.waitToGetProperty($.supplier, 'value');
const invoiceNumber = await page.waitToGetProperty($.invoiceNumber, 'value');
const observations = await page.waitToGetProperty($.observations, 'value');
const currency = await page.waitToGetProperty($.currency, 'value');
const commission = await page.waitToGetProperty($.commission, 'value');
const company = await page.waitToGetProperty($.company, 'value');
const ordered = await page.checkboxState($.ordered);
const confirmed = await page.checkboxState($.confirmed);
const inventory = await page.checkboxState($.inventory);
const raid = await page.checkboxState($.raid);
const booked = await page.checkboxState($.booked);
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
}); expect(reference).toEqual('new movement 8');
expect(supplier).toEqual('Plants nick');
it('should confirm the reference was edited', async() => { expect(invoiceNumber).toEqual('new movement 8');
await page.reloadSection('entry.card.basicData'); expect(observations).toEqual('observation two edited');
const result = await page.waitToGetProperty(selectors.entryBasicData.reference, 'value'); expect(currency).toEqual('EUR');
expect(commission).toEqual('100');
expect(result).toEqual('new movement 8'); expect(company).toEqual('CCs');
}); expect(ordered).toBe('checked');
expect(confirmed).toBe('checked');
it('should confirm the invoiceNumber was edited', async() => { expect(inventory).toBe('checked');
await page.reloadSection('entry.card.basicData'); expect(raid).toBe('checked');
const result = await page.waitToGetProperty(selectors.entryBasicData.invoiceNumber, 'value'); expect(booked).toBe('checked');
expect(result).toEqual('new movement 8');
});
it('should confirm the observation was edited', async() => {
const result = await page.waitToGetProperty(selectors.entryBasicData.observations, 'value');
expect(result).toEqual('observation two edited');
});
it('should confirm the supplier was edited', async() => {
const result = await page.waitToGetProperty(selectors.entryBasicData.supplier, 'value');
expect(result).toEqual('1 - Plants nick');
});
it('should confirm the currency was edited', async() => {
const result = await page.waitToGetProperty(selectors.entryBasicData.currency, 'value');
expect(result).toEqual('EUR');
});
it('should confirm the commission was edited', async() => {
const result = await page.waitToGetProperty(selectors.entryBasicData.commission, 'value');
expect(result).toEqual('100');
});
it('should confirm the company was edited', async() => {
const result = await page.waitToGetProperty(selectors.entryBasicData.company, 'value');
expect(result).toEqual('CCs');
});
it('should confirm ordered was edited', async() => {
const result = await page.checkboxState(selectors.entryBasicData.ordered);
expect(result).toBe('checked');
});
it('should confirm confirmed was edited', async() => {
const result = await page.checkboxState(selectors.entryBasicData.confirmed);
expect(result).toBe('checked');
});
it('should confirm inventory was edited', async() => {
const result = await page.checkboxState(selectors.entryBasicData.inventory);
expect(result).toBe('checked');
});
it('should confirm raid was edited', async() => {
const result = await page.checkboxState(selectors.entryBasicData.raid);
expect(result).toBe('checked');
});
it('should confirm booked was edited', async() => {
const result = await page.checkboxState(selectors.entryBasicData.booked);
expect(result).toBe('checked');
}); });
}); });

View File

@ -86,40 +86,47 @@ describe('Entry import, create and edit buys path', () => {
await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 2); await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 2);
}); });
it('should edit the newest buy', async() => { it('should edit the newest buy and check data', async() => {
await page.clearInput(selectors.entryBuys.secondBuyPackingPrice); await page.clearInput(selectors.entryBuys.secondBuyPackingPrice);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyPackingPrice, '100'); await page.write(selectors.entryBuys.secondBuyPackingPrice, '100');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyGroupingPrice); await page.clearInput(selectors.entryBuys.secondBuyGroupingPrice);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyGroupingPrice, '200'); await page.write(selectors.entryBuys.secondBuyGroupingPrice, '200');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyPrice); await page.clearInput(selectors.entryBuys.secondBuyPrice);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyPrice, '300'); await page.write(selectors.entryBuys.secondBuyPrice, '300');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyGrouping); await page.clearInput(selectors.entryBuys.secondBuyGrouping);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyGrouping, '400'); await page.write(selectors.entryBuys.secondBuyGrouping, '400');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyPacking); await page.clearInput(selectors.entryBuys.secondBuyPacking);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyPacking, '500'); await page.write(selectors.entryBuys.secondBuyPacking, '500');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyWeight); await page.clearInput(selectors.entryBuys.secondBuyWeight);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyWeight, '600'); await page.write(selectors.entryBuys.secondBuyWeight, '600');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.clearInput(selectors.entryBuys.secondBuyStickers); await page.clearInput(selectors.entryBuys.secondBuyStickers);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyStickers, '700'); await page.write(selectors.entryBuys.secondBuyStickers, '700');
await page.keyboard.press('Enter');
await page.waitForSnackbar(); await page.waitForSnackbar();
await page.autocompleteSearch(selectors.entryBuys.secondBuyPackage, '94'); await page.autocompleteSearch(selectors.entryBuys.secondBuyPackage, '94');
@ -128,60 +135,28 @@ describe('Entry import, create and edit buys path', () => {
await page.clearInput(selectors.entryBuys.secondBuyQuantity); await page.clearInput(selectors.entryBuys.secondBuyQuantity);
await page.waitForTimeout(250); await page.waitForTimeout(250);
await page.write(selectors.entryBuys.secondBuyQuantity, '800'); await page.write(selectors.entryBuys.secondBuyQuantity, '800');
}); await page.keyboard.press('Enter');
it('should reload the section and check the packing price is as expected', async() => {
await page.reloadSection('entry.card.buy.index'); await page.reloadSection('entry.card.buy.index');
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyPackingPrice, 'value');
expect(result).toEqual('100'); const secondBuyPackingPrice = await page.getValue(selectors.entryBuys.secondBuyPackingPrice);
}); const secondBuyGroupingPrice = await page.getValue(selectors.entryBuys.secondBuyGroupingPrice);
const secondBuyPrice = await page.getValue(selectors.entryBuys.secondBuyPrice);
const secondBuyGrouping = await page.getValue(selectors.entryBuys.secondBuyGrouping);
const secondBuyPacking = await page.getValue(selectors.entryBuys.secondBuyPacking);
const secondBuyWeight = await page.getValue(selectors.entryBuys.secondBuyWeight);
const secondBuyStickers = await page.getValue(selectors.entryBuys.secondBuyStickers);
const secondBuyPackage = await page.getValue(selectors.entryBuys.secondBuyPackage);
const secondBuyQuantity = await page.getValue(selectors.entryBuys.secondBuyQuantity);
it('should reload the section and check the grouping price is as expected', async() => { expect(secondBuyPackingPrice).toEqual('100');
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyGroupingPrice, 'value'); expect(secondBuyGroupingPrice).toEqual('200');
expect(secondBuyPrice).toEqual('300');
expect(result).toEqual('200'); expect(secondBuyGrouping).toEqual('400');
}); expect(secondBuyPacking).toEqual('500');
expect(secondBuyWeight).toEqual('600');
it('should reload the section and check the price is as expected', async() => { expect(secondBuyStickers).toEqual('700');
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyPrice, 'value'); expect(secondBuyPackage).toEqual('94');
expect(secondBuyQuantity).toEqual('800');
expect(result).toEqual('300');
});
it('should reload the section and check the grouping is as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyGrouping, 'value');
expect(result).toEqual('400');
});
it('should reload the section and check the packing is as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyPacking, 'value');
expect(result).toEqual('500');
});
it('should reload the section and check the weight is as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyWeight, 'value');
expect(result).toEqual('600');
});
it('should reload the section and check the stickers are as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyStickers, 'value');
expect(result).toEqual('700');
});
it('should reload the section and check the package is as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyPackage, 'value');
expect(result).toEqual('94');
});
it('should reload the section and check the quantity is as expected', async() => {
const result = await page.waitToGetProperty(selectors.entryBuys.secondBuyQuantity, 'value');
expect(result).toEqual('800');
}); });
}); });

View File

@ -1,20 +1,5 @@
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
const $ = {
saveButton: 'vn-supplier-fiscal-data button[type="submit"]',
};
const $inputs = {
province: 'vn-supplier-fiscal-data [name="province"]',
country: 'vn-supplier-fiscal-data [name="country"]',
postcode: 'vn-supplier-fiscal-data [name="postcode"]',
city: 'vn-supplier-fiscal-data [name="city"]',
socialName: 'vn-supplier-fiscal-data [name="socialName"]',
taxNumber: 'vn-supplier-fiscal-data [name="taxNumber"]',
account: 'vn-supplier-fiscal-data [name="account"]',
sageWithholding: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageWithholdingFk"]',
sageTaxType: 'vn-supplier-fiscal-data [ng-model="$ctrl.supplier.sageTaxTypeFk"]'
};
describe('Supplier fiscal data path', () => { describe('Supplier fiscal data path', () => {
let browser; let browser;
let page; let page;
@ -32,28 +17,32 @@ describe('Supplier fiscal data path', () => {
it('should attempt to edit the fiscal data and check data is saved', async() => { it('should attempt to edit the fiscal data and check data is saved', async() => {
await page.accessToSection('supplier.card.fiscalData'); await page.accessToSection('supplier.card.fiscalData');
await page.clearInput($inputs.province);
await page.clearInput($inputs.country); const form = 'vn-supplier-fiscal-data form';
await page.clearInput($inputs.postcode); const values = {
await page.overwrite($inputs.city, 'Valencia'); province: null,
await page.overwrite($inputs.socialName, 'Farmer King SL'); country: null,
await page.overwrite($inputs.taxNumber, 'Wrong tax number'); postcode: null,
await page.overwrite($inputs.account, '0123456789'); city: 'Valencia',
await page.autocompleteSearch($inputs.sageWithholding, 'retencion estimacion objetiva'); socialName: 'Farmer King SL',
await page.autocompleteSearch($inputs.sageTaxType, 'operaciones no sujetas'); taxNumber: 'Wrong tax number',
await page.click($.saveButton); account: '0123456789',
const errorMessage = await page.waitForSnackbar(); sageWithholding: 'retencion estimacion objetiva',
await page.overwrite($inputs.taxNumber, '12345678Z'); sageTaxType: 'operaciones no sujetas'
await page.click($.saveButton); };
const successMessage = await page.waitForSnackbar();
const errorMessage = await page.sendForm(form, values);
const message = await page.sendForm(form, {
taxNumber: '12345678Z'
});
await page.reloadSection('supplier.card.fiscalData'); await page.reloadSection('supplier.card.fiscalData');
const values = await page.getValues($inputs); const formValues = await page.fetchForm(form, Object.keys(values));
expect(errorMessage.text).toContain('Invalid Tax number'); expect(errorMessage.text).toContain('Invalid Tax number');
expect(successMessage.type).toBe('success'); expect(message.isSuccess).toBeTrue();
expect(values).toEqual({ expect(formValues).toEqual({
province: 'Province one (España)', province: 'Province one',
country: 'España', country: 'España',
postcode: '46000', postcode: '46000',
city: 'Valencia', city: 'Valencia',

View File

@ -20,7 +20,7 @@ export default class Field extends FormInput {
super.$onInit(); super.$onInit();
if (this.info) this.classList.add('has-icons'); if (this.info) this.classList.add('has-icons');
this.input.addEventListener('change', event => this.element.addEventListener('change', event =>
this.onChange(event)); this.onChange(event));
} }

View File

@ -160,6 +160,9 @@ export default class Controller extends Section {
const to = new Date(value); const to = new Date(value);
to.setHours(23, 59, 59, 999); to.setHours(23, 59, 59, 999);
return {creationDate: {lte: to}}; return {creationDate: {lte: to}};
case 'userFk':
return filter.who != 'system'
? {[prop]: value} : null;
default: default:
return {[prop]: value}; return {[prop]: value};
} }

View File

@ -14,7 +14,6 @@
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal> <vn-horizontal>
<vn-autocomplete <vn-autocomplete
vn-one
label="Billing data" label="Billing data"
vn-acl="salesAssistant, hr" vn-acl="salesAssistant, hr"
ng-model="$ctrl.client.payMethodFk" ng-model="$ctrl.client.payMethodFk"
@ -23,7 +22,6 @@
initial-data="$ctrl.client.payMethod"> initial-data="$ctrl.client.payMethod">
</vn-autocomplete> </vn-autocomplete>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
step="1" step="1"
label="Due day" label="Due day"
@ -34,7 +32,6 @@
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textfield <vn-textfield
vn-one
label="IBAN" label="IBAN"
ng-model="$ctrl.client.iban" ng-model="$ctrl.client.iban"
rule rule
@ -42,7 +39,6 @@
vn-acl="salesAssistant, hr"> vn-acl="salesAssistant, hr">
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete
vn-one
label="Swift / BIC" label="Swift / BIC"
url="BankEntities" url="BankEntities"
ng-model="$ctrl.client.bankEntityFk" ng-model="$ctrl.client.bankEntityFk"
@ -71,19 +67,16 @@
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-check <vn-check
vn-one
label="Received LCR" label="Received LCR"
ng-model="$ctrl.client.hasLcr" ng-model="$ctrl.client.hasLcr"
vn-acl="salesAssistant, hr"> vn-acl="salesAssistant, hr">
</vn-check> </vn-check>
<vn-check <vn-check
vn-one
label="Received core VNL" label="Received core VNL"
ng-model="$ctrl.client.hasCoreVnl" ng-model="$ctrl.client.hasCoreVnl"
vn-acl="salesAssistant, hr"> vn-acl="salesAssistant, hr">
</vn-check> </vn-check>
<vn-check <vn-check
vn-one
label="Received B2B VNL" label="Received B2B VNL"
ng-model="$ctrl.client.hasSepaVnl" ng-model="$ctrl.client.hasSepaVnl"
vn-acl="salesAssistant, hr"> vn-acl="salesAssistant, hr">
@ -103,8 +96,6 @@
</vn-button> </vn-button>
</vn-button-bar> </vn-button-bar>
</form> </form>
<!-- New bankentity dialog -->
<vn-new-bank-entity <vn-new-bank-entity
vn-id="bankEntity" vn-id="bankEntity"
on-accept="$ctrl.onAccept($data)"> on-accept="$ctrl.onAccept($data)">

View File

@ -19,7 +19,8 @@
label="Supplier" label="Supplier"
required="true"> required="true">
<tpl-item> <tpl-item>
{{::id}} - {{::nickname}} <div>#{{::nickname}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
@ -28,12 +29,16 @@
url="Travels/filter" url="Travels/filter"
search-function="$ctrl.searchFunction($search)" search-function="$ctrl.searchFunction($search)"
value-field="id" value-field="id"
show-field="warehouseInName"
order="id" order="id"
label="Travel" label="Travel"
required="true"> required="true">
<tpl-item> <tpl-item>
{{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192; <div>
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}}) {{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192;
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item> </tpl-item>
<append> <append>
<vn-icon-button <vn-icon-button

View File

@ -66,14 +66,15 @@
vn-focus vn-focus
url="Items/withName" url="Items/withName"
ng-model="buy.itemFk" ng-model="buy.itemFk"
show-field="name" show-field="id"
value-field="id" value-field="id"
search-function="$ctrl.itemSearchFunc($search)" search-function="$ctrl.itemSearchFunc($search)"
on-change="$ctrl.saveBuy(buy)" on-change="$ctrl.saveBuy(buy)"
order="id DESC" order="id DESC"
tabindex="1"> tabindex="1">
<tpl-item> <tpl-item>
{{::id}} - {{::name}} <div>{{::name}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</td> </td>

View File

@ -21,7 +21,8 @@
order="nickname" order="nickname"
required="true"> required="true">
<tpl-item> <tpl-item>
{{::id}} - {{::nickname}} <div>{{::nickname}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
@ -31,11 +32,16 @@
ng-model="$ctrl.entry.travelFk" ng-model="$ctrl.entry.travelFk"
url="Travels/filter" url="Travels/filter"
search-function="$ctrl.searchFunction($search)" search-function="$ctrl.searchFunction($search)"
show-field="warehouseInName"
order="id" order="id"
required="true"> required="true">
<tpl-item> <tpl-item>
{{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192; <div>
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}}) {{::agencyModeName}}
- {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}})
&#x2192; {{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>

View File

@ -57,7 +57,10 @@
search-function="{or: [{id: $search}, {vat: {like: '%'+ $search +'%'}}]}" search-function="{or: [{id: $search}, {vat: {like: '%'+ $search +'%'}}]}"
selection="taxRateSelection" selection="taxRateSelection"
rule> rule>
<tpl-item>{{id}}: {{vat}}</tpl-item> <tpl-item>
<div>{{::vat}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-three <vn-autocomplete vn-three
label="Sage transaction" label="Sage transaction"
@ -66,7 +69,10 @@
show-field="transaction" show-field="transaction"
search-function="{or: [{id: $search}, {transaction: {like: '%'+ $search +'%'}}]}" search-function="{or: [{id: $search}, {transaction: {like: '%'+ $search +'%'}}]}"
rule> rule>
<tpl-item>{{id}}: {{transaction}}</tpl-item> <tpl-item>
<div>{{::transaction}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
disabled="true" disabled="true"

View File

@ -98,7 +98,10 @@
ng-model="$ctrl.clientId" ng-model="$ctrl.clientId"
required="true" required="true"
ng-if="$ctrl.clientsToInvoice == 'one'"> ng-if="$ctrl.clientsToInvoice == 'one'">
<tpl-item>{{::id}} - {{::name}}</tpl-item> <tpl-item>
<div>{{::name}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-date-picker <vn-date-picker
vn-one vn-one

View File

@ -27,13 +27,15 @@
url="Tickets" url="Tickets"
label="Ticket" label="Ticket"
search-function="{or: [{id: $search}, {nickname: {like: '%'+$search+'%'}}]}" search-function="{or: [{id: $search}, {nickname: {like: '%'+$search+'%'}}]}"
show-field="nickname" show-field="id"
value-field="id" value-field="id"
fields="['nickname']"
ng-model="$ctrl.invoice.ticketFk" ng-model="$ctrl.invoice.ticketFk"
order="shipped DESC" order="shipped DESC"
on-change="$ctrl.invoice.clientFk = null"> on-change="$ctrl.invoice.clientFk = null">
<tpl-item> <tpl-item>
{{::id}} - {{::nickname}} <div>#{{::id}}</div>
<div class="text-secondary text-caption">{{::nickname}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-none class="or vn-px-md" translate>Or</vn-none> <vn-none class="or vn-px-md" translate>Or</vn-none>

View File

@ -20,47 +20,52 @@
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal> <vn-horizontal>
<vn-textfield <vn-textfield
vn-one
label="Name" label="Name"
ng-model="$ctrl.item.name" ng-model="$ctrl.item.name"
vn-name="name"
rule rule
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<vn-textfield <vn-textfield
vn-one label="Full name" label="Full name"
ng-model="$ctrl.item.longName" ng-model="$ctrl.item.longName"
vn-name="longName"
rule rule
info="Full name calculates based on tags 1-3. Is not recommended to change it manually"> info="Full name calculates based on tags 1-3. Is not recommended to change it manually">
</vn-textfield> </vn-textfield>
<vn-autocomplete vn-one <vn-autocomplete
url="ItemTypes" url="ItemTypes"
label="Type" label="Type"
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="$ctrl.item.typeFk" ng-model="$ctrl.item.typeFk"
vn-name="type"
initial-data="$ctrl.item.itemType" initial-data="$ctrl.item.itemType"
fields="['categoryFk']" fields="['categoryFk']"
include="'category'"> include="'category'">
<tpl-item> <tpl-item>
<div>{{name}}</div> <div>{{::name}}</div>
<div class="text-caption text-secondary"> <div class="text-caption text-secondary">
{{category.name}} {{::category.name}}
</div> </div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-autocomplete vn-one <vn-autocomplete
url="Intrastats" url="Intrastats"
label="Intrastat" label="Intrastat"
show-field="description" show-field="description"
value-field="id" value-field="id"
ng-model="$ctrl.item.intrastatFk" ng-model="$ctrl.item.intrastatFk"
vn-name="intrastat"
search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}" search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}"
initial-data="$ctrl.item.intrastat"> initial-data="$ctrl.item.intrastat">
<tpl-item style="display: flex;"> <tpl-item>
<div style="width: 6em; text-align: right; padding-right: 1em;">{{::id}}</div>
<div>{{::description}}</div> <div>{{::description}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item> </tpl-item>
<append> <append>
<vn-icon-button <vn-icon-button
@ -70,83 +75,88 @@
</vn-icon-button> </vn-icon-button>
</append> </append>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete
url="Expenses" url="Expenses"
label="Expense" label="Expense"
ng-model="$ctrl.item.expenseFk" ng-model="$ctrl.item.expenseFk"
vn-name="expence"
initial-data="$ctrl.item.expense"> initial-data="$ctrl.item.expense">
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete
data="originsData" data="originsData"
label="Origin" label="Origin"
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="$ctrl.item.originFk" ng-model="$ctrl.item.originFk"
vn-name="origin"
initial-data="$ctrl.item.origin"> initial-data="$ctrl.item.origin">
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
vn-one
label="Reference" label="Reference"
ng-model="$ctrl.item.comment" ng-model="$ctrl.item.comment"
vn-name="comment"
rule> rule>
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="Relevancy" label="Relevancy"
ng-model="$ctrl.item.relevancy" ng-model="$ctrl.item.relevancy"
vn-name="relevancy"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="Size" label="Size"
ng-model="$ctrl.item.size" ng-model="$ctrl.item.size"
vn-name="size"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="stems" label="stems"
ng-model="$ctrl.item.stems" ng-model="$ctrl.item.stems"
vn-name="stems"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="Multiplier" label="Multiplier"
ng-model="$ctrl.item.stemMultiplier"> ng-model="$ctrl.item.stemMultiplier"
vn-name="stemMultiplier">
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="Weight/Piece" label="Weight/Piece"
ng-model="$ctrl.item.weightByPiece" ng-model="$ctrl.item.weightByPiece"
vn-name="weightByPiece"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one
min="0" min="0"
label="Units/Box" label="Units/Box"
ng-model="$ctrl.item.packingOut" ng-model="$ctrl.item.packingOut"
vn-name="packingOut"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-autocomplete <vn-autocomplete
vn-one
label="Generic" label="Generic"
url="Items/withName" url="Items/withName"
ng-model="$ctrl.item.genericFk" ng-model="$ctrl.item.genericFk"
vn-name="generic"
show-field="name" show-field="name"
value-field="id" value-field="id"
search-function="$ctrl.itemSearchFunc($search)" search-function="$ctrl.itemSearchFunc($search)"
order="id DESC" order="id DESC"
tabindex="1"> tabindex="1">
<tpl-item> <tpl-item>
{{::id}} - {{::name}} <div>{{::name}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item> </tpl-item>
<append> <append>
<vn-icon-button <vn-icon-button
@ -159,33 +169,33 @@
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textarea <vn-textarea
vn-one
label="Description" label="Description"
ng-model="$ctrl.item.description" ng-model="$ctrl.item.description"
vn-name="description"
rule> rule>
</vn-textarea> </vn-textarea>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-check <vn-check
vn-one
label="Active" label="Active"
ng-model="$ctrl.item.isActive"> ng-model="$ctrl.item.isActive"
vn-name="isActive">
</vn-check> </vn-check>
<vn-check <vn-check
vn-one
label="Price in kg" label="Price in kg"
ng-model="$ctrl.item.hasKgPrice"> ng-model="$ctrl.item.hasKgPrice"
vn-name="priceInKg">
</vn-check> </vn-check>
<vn-check <vn-check
vn-one
label="Fragile" label="Fragile"
ng-model="$ctrl.item.isFragile" ng-model="$ctrl.item.isFragile"
vn-name="isFragile"
info="Is shown at website, app that this item cannot travel (wreath, palms, ...)"> info="Is shown at website, app that this item cannot travel (wreath, palms, ...)">
</vn-check> </vn-check>
<vn-check <vn-check
vn-one
label="Do photo" label="Do photo"
ng-model="$ctrl.item.isPhotoRequested" ng-model="$ctrl.item.isPhotoRequested"
vn-name="isPhotoRequested"
info="This item does need a photo"> info="This item does need a photo">
</vn-check> </vn-check>
</vn-horizontal> </vn-horizontal>
@ -211,16 +221,19 @@
message="New intrastat"> message="New intrastat">
<tpl-body> <tpl-body>
<vn-horizontal> <vn-horizontal>
<vn-input-number vn-one vn-focus <vn-input-number
vn-focus
label="Identifier" label="Identifier"
ng-model="$ctrl.newIntrastat.intrastatId" ng-model="$ctrl.newIntrastat.intrastatId"
vn-name="id"
required="true"> required="true">
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textfield vn-one <vn-textfield
label="Description" label="Description"
ng-model="$ctrl.newIntrastat.description" ng-model="$ctrl.newIntrastat.description"
vn-name="description"
required="true"> required="true">
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>

View File

@ -18,6 +18,7 @@
<vn-textfield <vn-textfield
label="Name" label="Name"
ng-model="$ctrl.item.provisionalName" ng-model="$ctrl.item.provisionalName"
vn-name="name"
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete
@ -25,20 +26,23 @@
url="Tags" url="Tags"
show-field="name" show-field="name"
value-field="id" value-field="id"
label="Tag"> label="Tag"
vn-name="tag">
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
data="$ctrl.validPriorities" data="$ctrl.validPriorities"
label="Priority" label="Priority"
ng-model="$ctrl.item.priority" ng-model="$ctrl.item.priority"
show-field="priority" show-field="priority"
value-field="priority"> value-field="priority"
vn-name="priority">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-autocomplete <vn-autocomplete
label="Type" label="Type"
ng-model="$ctrl.item.typeFk" ng-model="$ctrl.item.typeFk"
vn-name="type"
url="ItemTypes" url="ItemTypes"
fields="['code', 'categoryFk']" fields="['code', 'categoryFk']"
search-function="{or: [{code: {like: $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}" search-function="{or: [{code: {like: $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
@ -56,20 +60,24 @@
<vn-autocomplete <vn-autocomplete
label="Intrastat" label="Intrastat"
ng-model="$ctrl.item.intrastatFk" ng-model="$ctrl.item.intrastatFk"
vn-name="intrastat"
url="Intrastats" url="Intrastats"
show-field="description" show-field="description"
search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}"> search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}">
<tpl-item style="display: flex;"> <tpl-item>
<div style="width: 6em; text-align: right; padding-right: 1em;">{{::id}}</div>
<div>{{::description}}</div> <div>{{::description}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-autocomplete vn-one <vn-autocomplete
data="originsData" data="originsData"
label="Origin" label="Origin"
ng-model="$ctrl.item.originFk"> ng-model="$ctrl.item.originFk"
vn-name="origin">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>

View File

@ -81,6 +81,7 @@
class="dense" class="dense"
url="Items/withName" url="Items/withName"
ng-model="price.itemFk" ng-model="price.itemFk"
fields="['name']"
show-field="id" show-field="id"
value-field="id" value-field="id"
search-function="$ctrl.itemSearchFunc($search)" search-function="$ctrl.itemSearchFunc($search)"

View File

@ -19,13 +19,17 @@
vn-one vn-one
url="Clients" url="Clients"
label="Client" label="Client"
search-function="{or: [{id: $search}, {name: {like: '%'+$search+'%'}}]}" search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="$ctrl.order.clientFk" ng-model="$ctrl.order.clientFk"
vn-name="client"
selection="$ctrl.selection" selection="$ctrl.selection"
fields="['defaultAddressFk']"> fields="['defaultAddressFk']">
<tpl-item>{{::id}}: {{::name}}</tpl-item> <tpl-item>
<div>{{::name}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
@ -36,6 +40,7 @@
show-field="nickname" show-field="nickname"
value-field="id" value-field="id"
ng-model="$ctrl.order.addressFk" ng-model="$ctrl.order.addressFk"
vn-name="address"
on-change="$ctrl.getAvailableAgencies()"> on-change="$ctrl.getAvailableAgencies()">
<tpl-item>{{::nickname}}</tpl-item> <tpl-item>{{::nickname}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>
@ -45,6 +50,7 @@
vn-one vn-one
label="Landed" label="Landed"
ng-model="$ctrl.order.landed" ng-model="$ctrl.order.landed"
vn-name="landed"
on-change="$ctrl.getAvailableAgencies()"> on-change="$ctrl.getAvailableAgencies()">
</vn-date-picker> </vn-date-picker>
<vn-autocomplete <vn-autocomplete
@ -53,7 +59,8 @@
label="Agency" label="Agency"
show-field="agencyMode" show-field="agencyMode"
value-field="agencyModeFk" value-field="agencyModeFk"
ng-model="$ctrl.order.agencyModeFk"> ng-model="$ctrl.order.agencyModeFk"
vn-name="agencyMode">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
@ -61,6 +68,7 @@
vn-one vn-one
label="Notes" label="Notes"
ng-model="$ctrl.order.note" ng-model="$ctrl.order.note"
vn-name="note"
rule> rule>
</vn-textarea> </vn-textarea>
</vn-horizontal> </vn-horizontal>

View File

@ -7,6 +7,7 @@
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="$ctrl.clientFk" ng-model="$ctrl.clientFk"
vn-name="client"
order="id"> order="id">
<tpl-item>{{id}}: {{name}}</tpl-item> <tpl-item>{{id}}: {{name}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>
@ -15,6 +16,7 @@
url="{{ $ctrl.clientFk ? 'Clients/'+ $ctrl.clientFk +'/addresses' : null }}" url="{{ $ctrl.clientFk ? 'Clients/'+ $ctrl.clientFk +'/addresses' : null }}"
fields="['nickname', 'street', 'city']" fields="['nickname', 'street', 'city']"
ng-model="$ctrl.addressFk" ng-model="$ctrl.addressFk"
vn-name="address"
show-field="nickname" show-field="nickname"
value-field="id" value-field="id"
label="Address"> label="Address">
@ -22,7 +24,8 @@
</vn-autocomplete> </vn-autocomplete>
<vn-date-picker <vn-date-picker
label="Landed" label="Landed"
ng-model="$ctrl.landed"> ng-model="$ctrl.landed"
vn-name="landed">
</vn-date-picker> </vn-date-picker>
<vn-autocomplete <vn-autocomplete
disabled="!$ctrl.clientFk || !$ctrl.landed" disabled="!$ctrl.clientFk || !$ctrl.landed"
@ -30,5 +33,6 @@
label="Agency" label="Agency"
show-field="agencyMode" show-field="agencyMode"
value-field="agencyModeFk" value-field="agencyModeFk"
ng-model="$ctrl.order.agencyModeFk"> ng-model="$ctrl.order.agencyModeFk"
vn-name="agencyMode">
</vn-autocomplete> </vn-autocomplete>

View File

@ -9,76 +9,80 @@
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal> <vn-horizontal>
<vn-autocomplete <vn-autocomplete
vn-one
ng-model="$ctrl.route.workerFk" ng-model="$ctrl.route.workerFk"
url="Workers/activeWithInheritedRole" url="Workers/activeWithInheritedRole"
show-field="nickname" show-field="nickname"
search-function="{firstName: $search}" search-function="{firstName: $search}"
value-field="id" value-field="id"
where="{role: 'employee'}" where="{role: 'employee'}"
label="Worker"> label="Worker"
vn-name="worker">
<tpl-item> <tpl-item>
<div>{{name}} - {{nickname}}</div> <div>{{::nickname}}</div>
<div class="text-secondary text-caption">{{::name}}</div>
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one
ng-model="$ctrl.route.vehicleFk" ng-model="$ctrl.route.vehicleFk"
url="Vehicles" url="Vehicles"
show-field="numberPlate" show-field="numberPlate"
value-field="id" value-field="id"
label="Vehicle"> label="Vehicle"
vn-name="vehicle">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-date-picker <vn-date-picker
vn-one
label="Created" label="Created"
ng-model="$ctrl.route.created"> ng-model="$ctrl.route.created"
vn-name="created">
</vn-date-picker> </vn-date-picker>
<vn-autocomplete <vn-autocomplete
vn-one
ng-model="$ctrl.route.agencyModeFk" ng-model="$ctrl.route.agencyModeFk"
url="AgencyModes" url="AgencyModes"
show-field="name" show-field="name"
value-field="id" value-field="id"
label="Agency"> label="Agency"
vn-name="agencyMode">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-input-number <vn-input-number
vn-one
label="Km start" label="Km start"
ng-model="$ctrl.route.kmStart" ng-model="$ctrl.route.kmStart"
vn-name="kmStart"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one
label="Km end" label="Km end"
ng-model="$ctrl.route.kmEnd" ng-model="$ctrl.route.kmEnd"
vn-name="kmEnd"
rule> rule>
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-input-time <vn-input-time
label="Hour started" label="Hour started"
ng-model="$ctrl.route.started"> ng-model="$ctrl.route.started"
vn-name="started">
</vn-input-time> </vn-input-time>
<vn-input-time <vn-input-time
label="Hour finished" label="Hour finished"
ng-model="$ctrl.route.finished"> ng-model="$ctrl.route.finished"
</vn-input-time> vn-name="finished">
<vn-check </vn-input-time>
class="vn-mr-md" <vn-check
label="Is served" class="vn-mr-md"
ng-model="$ctrl.route.isOk"> label="Is served"
</vn-check> ng-model="$ctrl.route.isOk"
vn-name="isOk">
</vn-check>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textArea <vn-textArea
vn-one
label="Description" label="Description"
ng-model="$ctrl.route.description" ng-model="$ctrl.route.description"
vn-name="description"
rule rule
vn-focus> vn-focus>
</vn-textArea> </vn-textArea>

View File

@ -42,7 +42,7 @@
vn-two vn-two
vn-focus vn-focus
label="Social name" label="Social name"
name="socialName" vn-name="socialName"
ng-model="$ctrl.supplier.name" ng-model="$ctrl.supplier.name"
info="Only letters, numbers and spaces can be used" info="Only letters, numbers and spaces can be used"
required="true" required="true"
@ -51,18 +51,17 @@
<vn-textfield <vn-textfield
vn-one vn-one
label="Tax number" label="Tax number"
name="taxNumber" vn-name="taxNumber"
ng-model="$ctrl.supplier.nif" ng-model="$ctrl.supplier.nif"
required="true" required="true"
rule rule>
>
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textfield <vn-textfield
vn-one vn-one
label="Account" label="Account"
name="account" vn-name="account"
ng-model="$ctrl.supplier.account" ng-model="$ctrl.supplier.account"
insertable="true" insertable="true"
max-length="10" max-length="10"
@ -71,7 +70,7 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Sage tax type" label="Sage tax type"
name="sageTaxType" vn-name="sageTaxType"
ng-model="$ctrl.supplier.sageTaxTypeFk" ng-model="$ctrl.supplier.sageTaxTypeFk"
data="sageTaxTypes" data="sageTaxTypes"
show-field="vat" show-field="vat"
@ -83,7 +82,7 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Sage withholding" label="Sage withholding"
name="sageWithholding" vn-name="sageWithholding"
ng-model="$ctrl.supplier.sageWithholdingFk" ng-model="$ctrl.supplier.sageWithholdingFk"
data="sageWithholdings" data="sageWithholdings"
show-field="withholding" show-field="withholding"
@ -93,7 +92,7 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Sage transaction type" label="Sage transaction type"
name="sageTransactionType" vn-name="sageTransactionType"
ng-model="$ctrl.supplier.sageTransactionTypeFk" ng-model="$ctrl.supplier.sageTransactionTypeFk"
url="SageTransactionTypes" url="SageTransactionTypes"
show-field="transaction" show-field="transaction"
@ -108,7 +107,7 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Supplier activity" label="Supplier activity"
name="supplierActivity" vn-name="supplierActivity"
ng-model="$ctrl.supplier.supplierActivityFk" ng-model="$ctrl.supplier.supplierActivityFk"
data="supplierActivities" data="supplierActivities"
show-field="name" show-field="name"
@ -133,7 +132,7 @@
<vn-datalist <vn-datalist
vn-one vn-one
label="Postcode" label="Postcode"
name="postcode" vn-name="postcode"
ng-model="$ctrl.supplier.postCode" ng-model="$ctrl.supplier.postCode"
selection="$ctrl.postcode" selection="$ctrl.postcode"
url="Postcodes/location" url="Postcodes/location"
@ -162,7 +161,7 @@
vn-one vn-one
vn-id="town" vn-id="town"
label="City" label="City"
name="city" vn-name="city"
ng-model="$ctrl.supplier.city" ng-model="$ctrl.supplier.city"
selection="$ctrl.town" selection="$ctrl.town"
url="Towns/location" url="Towns/location"
@ -180,7 +179,7 @@
vn-one vn-one
vn-id="province" vn-id="province"
label="Province" label="Province"
name="province" vn-name="province"
ng-model="$ctrl.supplier.provinceFk" ng-model="$ctrl.supplier.provinceFk"
selection="$ctrl.province" selection="$ctrl.province"
data="provincesLocation" data="provincesLocation"
@ -196,7 +195,7 @@
vn-two vn-two
vn-id="country" vn-id="country"
label="Country" label="Country"
name="country" vn-name="country"
ng-model="$ctrl.supplier.countryFk" ng-model="$ctrl.supplier.countryFk"
data="countries" data="countries"
show-field="country" show-field="country"

View File

@ -4,7 +4,8 @@
data="warehouses" data="warehouses"
order="name"> order="name">
</vn-crud-model> </vn-crud-model>
<vn-autocomplete vn-focus <vn-autocomplete
vn-focus
vn-id="client" vn-id="client"
url="Clients" url="Clients"
label="Client" label="Client"
@ -12,8 +13,12 @@
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="$ctrl.clientId" ng-model="$ctrl.clientId"
vn-name="client"
order="id"> order="id">
<tpl-item>{{id}}: {{name}}</tpl-item> <tpl-item>
<div>{{::name}}</div>
<div class="text-secondary text-caption">#{{::id}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
disabled="!$ctrl.clientId" disabled="!$ctrl.clientId"
@ -21,18 +26,24 @@
fields="['nickname', 'street', 'city']" fields="['nickname', 'street', 'city']"
where="{isActive: true}" where="{isActive: true}"
ng-model="$ctrl.addressId" ng-model="$ctrl.addressId"
vn-name="address"
show-field="nickname" show-field="nickname"
value-field="id" value-field="id"
label="Address"> label="Address">
<tpl-item>{{nickname}}: {{street}}, {{city}}</tpl-item> <tpl-item>
<div>{{::nickname}}</div>
<div class="text-secondary text-caption">{{::street}}, {{::city}}</div>
</tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-date-picker <vn-date-picker
label="Landed" label="Landed"
ng-model="$ctrl.landed"> ng-model="$ctrl.landed"
vn-name="landed">
</vn-date-picker> </vn-date-picker>
<vn-autocomplete <vn-autocomplete
disabled="!$ctrl.warehouseId && (!$ctrl.clientId || !$ctrl.landed)" disabled="!$ctrl.warehouseId && (!$ctrl.clientId || !$ctrl.landed)"
ng-model="$ctrl.warehouseId" ng-model="$ctrl.warehouseId"
vn-name="warehouse"
data="warehouses" data="warehouses"
show-field="name" show-field="name"
value-field="id" value-field="id"
@ -44,5 +55,6 @@
label="Agency" label="Agency"
show-field="agencyMode" show-field="agencyMode"
value-field="agencyModeFk" value-field="agencyModeFk"
ng-model="$ctrl.agencyModeId"> ng-model="$ctrl.agencyModeId"
vn-name="agencyMode">
</vn-autocomplete> </vn-autocomplete>

View File

@ -15,7 +15,6 @@
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal ng-repeat="package in packages track by $index"> <vn-horizontal ng-repeat="package in packages track by $index">
<vn-autocomplete <vn-autocomplete
vn-one
vn-focus vn-focus
url="Packagings/listPackaging" url="Packagings/listPackaging"
label="Package" label="Package"
@ -23,17 +22,19 @@
value-field="packagingFk" value-field="packagingFk"
search-function="{or: [{itemFk: $search}, {'name': {like: '%'+ $search +'%'}}]}" search-function="{or: [{itemFk: $search}, {'name': {like: '%'+ $search +'%'}}]}"
ng-model="package.packagingFk"> ng-model="package.packagingFk">
<tpl-item>{{itemFk}} : {{name}}</tpl-item> <tpl-item>
<div>{{::name}}</div>
<div class="text-secondary text-caption">
#{{itemFk}}
</div>
</vn-autocomplete> </vn-autocomplete>
<vn-input-number <vn-input-number
vn-one
step="1" step="1"
label="Quantity" label="Quantity"
ng-model="package.quantity" ng-model="package.quantity"
rule="TicketPackaging"> rule="TicketPackaging">
</vn-input-number> </vn-input-number>
<vn-date-picker <vn-date-picker
vn-one
label="Added" label="Added"
ng-model="package.created" ng-model="package.created"
disabled="true" disabled="true"
@ -60,12 +61,13 @@
disabled="!watcher.dataChanged()" disabled="!watcher.dataChanged()"
label="Save"> label="Save">
</vn-submit> </vn-submit>
<!-- # #2680 Undo changes button bugs --> <!-- #2680 Undo changes button bug
<!-- <vn-button <vn-button
class="cancel" class="cancel"
label="Undo changes" label="Undo changes"
disabled="!watcher.dataChanged()" disabled="!watcher.dataChanged()"
ng-click="watcher.loadOriginalData()"> ng-click="watcher.loadOriginalData()">
</vn-button> --> </vn-button>
-->
</vn-button-bar> </vn-button-bar>
</form> </form>