diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index b907a5261..8f9fcda57 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -1260,6 +1260,21 @@ export default {
importBuysButton: 'vn-entry-buy-import button[type="submit"]'
},
entryLatestBuys: {
+ table: 'tbody > tr:not(.empty-rows)',
+ chip: 'vn-chip > vn-icon',
+ generalSearchInput: 'vn-textfield[ng-model="$ctrl.filter.search"]',
+ firstReignIcon: 'vn-horizontal.item-category vn-one',
+ typeInput: 'vn-autocomplete[ng-model="$ctrl.filter.typeFk"]',
+ salesPersonInput: 'vn-autocomplete[ng-model="$ctrl.filter.salesPersonFk"]',
+ supplierInput: 'vn-autocomplete[ng-model="$ctrl.filter.supplierFk"]',
+ fromInput: 'vn-date-picker[ng-model="$ctrl.filter.from"]',
+ toInput: 'vn-date-picker[ng-model="$ctrl.filter.to"]',
+ activeCheck: 'vn-check[ng-model="$ctrl.filter.active"]',
+ floramondoCheck: 'vn-check[ng-model="$ctrl.filter.floramondo"]',
+ visibleCheck: 'vn-check[ng-model="$ctrl.filter.visible"]',
+ addTagButton: 'vn-icon-button[vn-tooltip="Add tag"]',
+ itemTagInput: 'vn-autocomplete[ng-model="itemTag.tagFk"]',
+ itemTagValueInput: 'vn-autocomplete[ng-model="itemTag.value"]',
firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)',
allBuysCheckBox: 'vn-entry-latest-buys thead vn-check',
secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]',
diff --git a/e2e/paths/12-entry/03_latestBuys.spec.js b/e2e/paths/12-entry/03_latestBuys.spec.js
index 553d41b95..a73e12659 100644
--- a/e2e/paths/12-entry/03_latestBuys.spec.js
+++ b/e2e/paths/12-entry/03_latestBuys.spec.js
@@ -4,10 +4,15 @@ import getBrowser from '../../helpers/puppeteer';
describe('Entry lastest buys path', () => {
let browser;
let page;
+ const httpRequests = [];
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
+ page.on('request', req => {
+ if (req.url().includes(`Buys/latestBuysFilter`))
+ httpRequests.push(req.url());
+ });
await page.loginAndModule('buyer', 'entry');
});
@@ -20,6 +25,87 @@ describe('Entry lastest buys path', () => {
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
});
+ it('should filter by name', async() => {
+ await page.write(selectors.entryLatestBuys.generalSearchInput, 'Melee');
+ await page.keyboard.press('Enter');
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('search=Melee')))).toBeDefined();
+ });
+
+ it('should filter by reign and type', async() => {
+ await page.click(selectors.entryLatestBuys.firstReignIcon);
+ await page.autocompleteSearch(selectors.entryLatestBuys.typeInput, 'Alstroemeria');
+ await page.click(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('categoryFk')))).toBeDefined();
+ expect(httpRequests.find(req => req.includes(('typeFk')))).toBeDefined();
+ });
+
+ it('should filter by from date', async() => {
+ await page.pickDate(selectors.entryLatestBuys.fromInput, new Date());
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('from')))).toBeDefined();
+ });
+
+ it('should filter by to date', async() => {
+ await page.pickDate(selectors.entryLatestBuys.toInput, new Date());
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('to')))).toBeDefined();
+ });
+
+ it('should filter by sales person', async() => {
+ await page.autocompleteSearch(selectors.entryLatestBuys.salesPersonInput, 'buyerNick');
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('salesPersonFk')))).toBeDefined();
+ });
+
+ it('should filter by supplier', async() => {
+ await page.autocompleteSearch(selectors.entryLatestBuys.supplierInput, 'Farmer King');
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('supplierFk')))).toBeDefined();
+ });
+
+ it('should filter by active', async() => {
+ await page.waitToClick(selectors.entryLatestBuys.activeCheck);
+ await page.waitToClick(selectors.entryLatestBuys.activeCheck);
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('active=true')))).toBeDefined();
+ expect(httpRequests.find(req => req.includes(('active=false')))).toBeDefined();
+ });
+
+ it('should filter by visible', async() => {
+ await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
+ await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('visible=true')))).toBeDefined();
+ expect(httpRequests.find(req => req.includes(('visible=false')))).toBeDefined();
+ });
+
+ it('should filter by floramondo', async() => {
+ await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
+ await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('floramondo=true')))).toBeDefined();
+ expect(httpRequests.find(req => req.includes(('floramondo=false')))).toBeDefined();
+ });
+
+ it('should filter by tag Color', async() => {
+ await page.waitToClick(selectors.entryLatestBuys.addTagButton);
+ await page.autocompleteSearch(selectors.entryLatestBuys.itemTagInput, 'Color');
+ await page.autocompleteSearch(selectors.entryLatestBuys.itemTagValueInput, 'Brown');
+ await page.waitToClick(selectors.entryLatestBuys.chip);
+
+ expect(httpRequests.find(req => req.includes(('tags')))).toBeDefined();
+ });
+
it('should select all lines but one and then check the edit buys button appears', async() => {
await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);
diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html
index 8cfab622a..bc04ccd7e 100644
--- a/modules/entry/front/latest-buys-search-panel/index.html
+++ b/modules/entry/front/latest-buys-search-panel/index.html
@@ -1,198 +1,243 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{name}}
+
+ {{category.name}}
+
>
+
+
+
+
+
+
+ {{name}}: {{nickname}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Id/Name: {{$ctrl.filter.search}}
+
+
+ {{category.selection.name}}
+
+
+ {{type.selection.name}}
+
+
+ Sales person: {{salesPerson.selection.nickname}}
+
+
+ Supplier: {{supplier.selection.name}}
+
+
+ From: {{$ctrl.filter.from | date:'dd/MM/yyyy'}}
+
+
+ To: {{$ctrl.filter.to | date:'dd/MM/yyyy'}}
+
+
+ Active: {{$ctrl.filter.active ? '✓' : '✗'}}
+
+
+ Floramondo: {{$ctrl.filter.floramondo ? '✓' : '✗'}}
+
+
+ Visible: {{$ctrl.filter.visible ? '✓' : '✗'}}
+
+
+ {{$ctrl.showTagInfo(chipTag)}}
+
+
+
+
diff --git a/modules/entry/front/latest-buys-search-panel/index.js b/modules/entry/front/latest-buys-search-panel/index.js
index 83dc88724..a5a062302 100644
--- a/modules/entry/front/latest-buys-search-panel/index.js
+++ b/modules/entry/front/latest-buys-search-panel/index.js
@@ -1,67 +1,61 @@
import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel';
+import './style.scss';
class Controller extends SearchPanel {
constructor($element, $) {
super($element, $);
- let model = 'Item';
- let moreFields = ['description', 'name'];
+ }
- let properties;
- let validations = window.validations;
+ $onInit() {
+ this.filter = {
+ isActive: true,
+ tags: []
+ };
+ }
- if (validations && validations[model])
- properties = validations[model].properties;
- else
- properties = {};
-
- this.moreFields = [];
- for (let field of moreFields) {
- let prop = properties[field];
- this.moreFields.push({
- name: field,
- label: prop ? prop.description : field,
- type: prop ? prop.type : null
- });
+ changeCategory(id) {
+ if (this.filter.categoryFk != id) {
+ this.filter.categoryFk = id;
+ this.applyFilters();
}
}
- get filter() {
- let filter = this.$.filter;
-
- for (let fieldFilter of this.fieldFilters)
- filter[fieldFilter.name] = fieldFilter.value;
-
- return filter;
+ removeItemFilter(param) {
+ this.filter[param] = null;
+ if (param == 'categoryFk') this.filter['typeFk'] = null;
+ this.applyFilters();
}
- set filter(value) {
- if (!value)
- value = {};
- if (!value.tags)
- value.tags = [{}];
+ removeTag(tag) {
+ const index = this.filter.tags.indexOf(tag);
+ if (index > -1) this.filter.tags.splice(index, 1);
+ this.applyFilters();
+ }
- this.fieldFilters = [];
- for (let field of this.moreFields) {
- if (value[field.name] != undefined) {
- this.fieldFilters.push({
- name: field.name,
- value: value[field.name],
- info: field
- });
- }
+ onKeyPress($event) {
+ if ($event.key === 'Enter')
+ this.applyFilters();
+ }
+
+ applyFilters() {
+ for (let i = 0; i < this.filter.tags.length; i++) {
+ if (!this.filter.tags[i].value)
+ this.filter.tags.splice(i, 1);
}
-
- this.$.filter = value;
+ return this.model.applyFilter({}, this.filter);
}
- removeField(index, field) {
- this.fieldFilters.splice(index, 1);
- delete this.$.filter[field];
+ showTagInfo(itemTag) {
+ if (!itemTag.tagFk) return itemTag.value;
+ return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`;
}
}
ngModule.component('vnLatestBuysSearchPanel', {
template: require('./index.html'),
- controller: Controller
+ controller: Controller,
+ bindings: {
+ model: '<'
+ }
});
diff --git a/modules/entry/front/latest-buys-search-panel/index.spec.js b/modules/entry/front/latest-buys-search-panel/index.spec.js
index 9e187a25a..4cc4aa6dc 100644
--- a/modules/entry/front/latest-buys-search-panel/index.spec.js
+++ b/modules/entry/front/latest-buys-search-panel/index.spec.js
@@ -10,50 +10,46 @@ describe('Entry', () => {
beforeEach(angular.mock.inject($componentController => {
$element = angular.element(``);
controller = $componentController('vnLatestBuysSearchPanel', {$element});
+ controller.model = {applyFilter: () => {}};
}));
- describe('filter() setter', () => {
- it(`should set the tags property to the scope filter with an empty array`, () => {
- const expectedFilter = {
- tags: [{}]
- };
- controller.filter = null;
+ describe('removeItemFilter()', () => {
+ it(`should remove param from filter`, () => {
+ controller.filter = {tags: [], categoryFk: 1, typeFk: 1};
+ const expectFilter = {tags: [], categoryFk: null, typeFk: null};
- expect(controller.filter).toEqual(expectedFilter);
- });
+ controller.removeItemFilter('categoryFk');
- it(`should set the tags property to the scope filter with an array of tags`, () => {
- const expectedFilter = {
- description: 'My item',
- tags: [{}]
- };
- const expectedFieldFilter = [{
- info: {
- label: 'description',
- name: 'description',
- type: null
- },
- name: 'description',
- value: 'My item'
- }];
- controller.filter = {
- description: 'My item'
- };
-
- expect(controller.filter).toEqual(expectedFilter);
- expect(controller.fieldFilters).toEqual(expectedFieldFilter);
+ expect(controller.filter).toEqual(expectFilter);
});
});
- describe('removeField()', () => {
- it(`should remove the description property from the fieldFilters and from the scope filter`, () => {
- const expectedFilter = {tags: [{}]};
- controller.filter = {description: 'My item'};
+ describe('removeTag()', () => {
+ it(`should remove tag from filter`, () => {
+ const tag = {tagFk: 1, value: 'Value'};
+ controller.filter = {tags: [tag]};
+ const expectFilter = {tags: []};
- controller.removeField(0, 'description');
+ controller.removeTag(tag);
- expect(controller.filter).toEqual(expectedFilter);
- expect(controller.fieldFilters).toEqual([]);
+ expect(controller.filter).toEqual(expectFilter);
+ });
+ });
+
+ describe('showTagInfo()', () => {
+ it(`should show tag value`, () => {
+ const tag = {value: 'Value'};
+ const result = controller.showTagInfo(tag);
+
+ expect(result).toEqual('Value');
+ });
+
+ it(`should show tag name and value`, () => {
+ const tag = {tagFk: 1, value: 'Value'};
+ controller.tags = [{id: 1, name: 'tagName'}];
+ const result = controller.showTagInfo(tag);
+
+ expect(result).toEqual('tagName: Value');
});
});
});
diff --git a/modules/entry/front/latest-buys-search-panel/style.scss b/modules/entry/front/latest-buys-search-panel/style.scss
new file mode 100644
index 000000000..ec189c7e4
--- /dev/null
+++ b/modules/entry/front/latest-buys-search-panel/style.scss
@@ -0,0 +1,70 @@
+@import "variables";
+
+vn-latest-buys-search-panel vn-side-menu div {
+ & > .input {
+ padding-left: $spacing-md;
+ padding-right: $spacing-md;
+ border-color: $color-spacer;
+ border-bottom: $border-thin;
+ }
+ & > .horizontal {
+ grid-auto-flow: column;
+ grid-column-gap: $spacing-sm;
+ align-items: center;
+ }
+ & > .checks {
+ padding: $spacing-md;
+ flex-wrap: wrap;
+ border-color: $color-spacer;
+ border-bottom: $border-thin;
+ }
+ & > .tags {
+ padding: $spacing-md;
+ padding-bottom: 0%;
+ padding-top: 0%;
+ align-items: center;
+ }
+ & > .chips {
+ display: flex;
+ flex-wrap: wrap;
+ padding: $spacing-md;
+ overflow: hidden;
+ max-width: 100%;
+ border-color: $color-spacer;
+ border-top: $border-thin;
+ }
+ & > .item-category {
+ padding: $spacing-sm;
+ justify-content: flex-start;
+ align-items: flex-start;
+ flex-wrap: wrap;
+
+ vn-autocomplete[vn-id="category"] {
+ display: none;
+ }
+
+ & > vn-one {
+ padding: $spacing-sm;
+ min-width: 33.33%;
+ text-align: center;
+ box-sizing: border-box;
+
+ & > vn-icon {
+ padding: $spacing-sm;
+ background-color: $color-font-secondary;
+ border-radius: 50%;
+ cursor: pointer;
+
+ &.active {
+ background-color: $color-main;
+ color: #fff;
+ }
+ & > i:before {
+ font-size: 2.6rem;
+ width: 16px;
+ height: 16px;
+ }
+ }
+ }
+ }
+}
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index e4eb37d3c..727b19220 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -7,17 +7,11 @@
on-data-change="$ctrl.reCheck()"
auto-load="true">
-
-
-
+
+
+