Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3339-entry_latest-buys-search-panel
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Alex Moreno 2021-11-24 07:30:10 +01:00
commit e319af6556
12 changed files with 106 additions and 83 deletions

View File

@ -71,7 +71,7 @@
color: $color-font; color: $color-font;
&::placeholder { &::placeholder {
color: $color-font-bg; color: $color-font-bg-marginal;
} }
&[type=time], &[type=time],
&[type=date], &[type=date],

View File

@ -15,6 +15,7 @@
<div class="icons pre"> <div class="icons pre">
<vn-icon <vn-icon
icon="clear" icon="clear"
ng-show="::$ctrl.clearDisabled != true"
translate-attr="{title: 'Clear'}" translate-attr="{title: 'Clear'}"
ng-click="$ctrl.onClear($event)"> ng-click="$ctrl.onClear($event)">
</vn-icon> </vn-icon>

View File

@ -85,6 +85,7 @@ ngModule.vnComponent('vnInputNumber', {
min: '<?', min: '<?',
max: '<?', max: '<?',
step: '<?', step: '<?',
displayControls: '<?' displayControls: '<?',
clearDisabled: '<?'
} }
}); });

View File

@ -5,7 +5,7 @@
limit="20" limit="20"
user-params="::$ctrl.filterParams" user-params="::$ctrl.filterParams"
data="sales" data="sales"
order="itemTypeFk, itemName, itemSize"> order="itemTypeFk, itemName, itemSize, description">
</vn-crud-model> </vn-crud-model>
<vn-portal slot="topbar"> <vn-portal slot="topbar">
<vn-searchbar <vn-searchbar
@ -42,7 +42,7 @@
<vn-th field="itemFk" number>Item</vn-th> <vn-th field="itemFk" number>Item</vn-th>
<vn-th field="ticketFk" number>Ticket</vn-th> <vn-th field="ticketFk" number>Ticket</vn-th>
<vn-th field="shipped" expand>Fecha</vn-th> <vn-th field="shipped" expand>Fecha</vn-th>
<vn-th expand>Description</vn-th> <vn-th field="description" expand>Description</vn-th>
<vn-th field="quantity" number>Quantity</vn-th> <vn-th field="quantity" number>Quantity</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>

View File

@ -109,18 +109,21 @@
on-change="itemTag.value = null"> on-change="itemTag.value = null">
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
ng-show="tag.selection.isFree !== false" ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
vn-id="text" vn-id="text"
label="Value" label="Value"
ng-model="itemTag.value"> ng-model="itemTag.value">
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete
vn-one
ng-show="tag.selection.isFree === false" ng-show="tag.selection.isFree === false"
url="{{$ctrl.getSourceTable(tag.selection)}}" url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
search-function="{value: $search}"
label="Value" label="Value"
ng-model="itemTag.value" ng-model="itemTag.value"
show-field="name" show-field="value"
value-field="name"> value-field="value"
rule>
</vn-autocomplete> </vn-autocomplete>
<vn-icon-button <vn-icon-button
vn-none vn-none

View File

@ -55,21 +55,9 @@ class Controller extends SearchPanel {
this.$.filter = value; this.$.filter = value;
} }
getSourceTable(selection) {
if (!selection || selection.isFree === true)
return null;
if (selection.sourceTable) {
return ''
+ selection.sourceTable.charAt(0).toUpperCase()
+ selection.sourceTable.substring(1) + 's';
} else if (selection.sourceTable == null)
return `ItemTags/filterItemTags/${selection.id}`;
}
removeField(index, field) { removeField(index, field) {
this.fieldFilters.splice(index, 1); this.fieldFilters.splice(index, 1);
this.$.filter[field] = undefined; delete this.$.filter[field];
} }
} }

View File

@ -12,33 +12,48 @@ describe('Entry', () => {
controller = $componentController('vnLatestBuysSearchPanel', {$element}); controller = $componentController('vnLatestBuysSearchPanel', {$element});
})); }));
describe('getSourceTable()', () => { describe('filter() setter', () => {
it(`should return null if there's no selection`, () => { it(`should set the tags property to the scope filter with an empty array`, () => {
let selection = null; const expectedFilter = {
let result = controller.getSourceTable(selection); tags: [{}]
};
controller.filter = null;
expect(result).toBeNull(); expect(controller.filter).toEqual(expectedFilter);
}); });
it(`should return null if there's a selection but its isFree property is truthy`, () => { it(`should set the tags property to the scope filter with an array of tags`, () => {
let selection = {isFree: true}; const expectedFilter = {
let result = controller.getSourceTable(selection); description: 'My item',
tags: [{}]
};
const expectedFieldFilter = [{
info: {
label: 'description',
name: 'description',
type: null
},
name: 'description',
value: 'My item'
}];
controller.filter = {
description: 'My item'
};
expect(result).toBeNull(); expect(controller.filter).toEqual(expectedFilter);
expect(controller.fieldFilters).toEqual(expectedFieldFilter);
});
}); });
it(`should return the formated sourceTable concatenated to a path`, () => { describe('removeField()', () => {
let selection = {sourceTable: 'hello guy'}; it(`should remove the description property from the fieldFilters and from the scope filter`, () => {
let result = controller.getSourceTable(selection); const expectedFilter = {tags: [{}]};
controller.filter = {description: 'My item'};
expect(result).toEqual('Hello guys'); controller.removeField(0, 'description');
});
it(`should return a path if there's no sourceTable and the selection has an id`, () => { expect(controller.filter).toEqual(expectedFilter);
let selection = {id: 99}; expect(controller.fieldFilters).toEqual([]);
let result = controller.getSourceTable(selection);
expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`);
}); });
}); });
}); });

View File

@ -47,9 +47,14 @@ module.exports = Self => {
const where = filter.where; const where = filter.where;
if (where && where.value) { if (where && where.value) {
stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}})); stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}}));
stmt.merge(`
ORDER BY value LIKE '${where.value}' DESC, const orderStmt = new ParameterizedSQL(
value LIKE '${where.value}%' DESC`); `ORDER BY value LIKE ? DESC,
value LIKE ? DESC`, [
where.value,
`${where.value}%`
]);
ParameterizedSQL.append(stmt, orderStmt);
} }
stmt.merge(conn.makeLimit(filter)); stmt.merge(conn.makeLimit(filter));

View File

@ -83,7 +83,7 @@
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
vn-one vn-one
ng-show="tag.selection.isFree !== false" ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
vn-id="text" vn-id="text"
label="Value" label="Value"
ng-model="itemTag.value"> ng-model="itemTag.value">
@ -91,11 +91,13 @@
<vn-autocomplete <vn-autocomplete
vn-one vn-one
ng-show="tag.selection.isFree === false" ng-show="tag.selection.isFree === false"
url="{{$ctrl.getSourceTable(tag.selection)}}" url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
search-function="{value: $search}"
label="Value" label="Value"
ng-model="itemTag.value" ng-model="itemTag.value"
show-field="name" show-field="value"
value-field="name"> value-field="value"
rule>
</vn-autocomplete> </vn-autocomplete>
<vn-icon-button <vn-icon-button
vn-none vn-none

View File

@ -55,21 +55,9 @@ class Controller extends SearchPanel {
this.$.filter = value; this.$.filter = value;
} }
getSourceTable(selection) {
if (!selection || selection.isFree === true)
return null;
if (selection.sourceTable) {
return ''
+ selection.sourceTable.charAt(0).toUpperCase()
+ selection.sourceTable.substring(1) + 's';
} else if (selection.sourceTable == null)
return `ItemTags/filterItemTags/${selection.id}`;
}
removeField(index, field) { removeField(index, field) {
this.fieldFilters.splice(index, 1); this.fieldFilters.splice(index, 1);
this.$.filter[field] = undefined; delete this.$.filter[field];
} }
} }

View File

@ -12,33 +12,48 @@ describe('Item', () => {
controller = $componentController('vnItemSearchPanel', {$element}); controller = $componentController('vnItemSearchPanel', {$element});
})); }));
describe('getSourceTable()', () => { describe('filter() setter', () => {
it(`should return null if there's no selection`, () => { it(`should set the tags property to the scope filter with an empty array`, () => {
let selection = null; const expectedFilter = {
let result = controller.getSourceTable(selection); tags: [{}]
};
controller.filter = null;
expect(result).toBeNull(); expect(controller.filter).toEqual(expectedFilter);
}); });
it(`should return null if there's a selection but its isFree property is truthy`, () => { it(`should set the tags property to the scope filter with an array of tags`, () => {
let selection = {isFree: true}; const expectedFilter = {
let result = controller.getSourceTable(selection); description: 'My item',
tags: [{}]
};
const expectedFieldFilter = [{
info: {
label: 'description',
name: 'description',
type: null
},
name: 'description',
value: 'My item'
}];
controller.filter = {
description: 'My item'
};
expect(result).toBeNull(); expect(controller.filter).toEqual(expectedFilter);
expect(controller.fieldFilters).toEqual(expectedFieldFilter);
});
}); });
it(`should return the formated sourceTable concatenated to a path`, () => { describe('removeField()', () => {
let selection = {sourceTable: 'hello guy'}; it(`should remove the description property from the fieldFilters and from the scope filter`, () => {
let result = controller.getSourceTable(selection); const expectedFilter = {tags: [{}]};
controller.filter = {description: 'My item'};
expect(result).toEqual('Hello guys'); controller.removeField(0, 'description');
});
it(`should return a path if there's no sourceTable and the selection has an id`, () => { expect(controller.filter).toEqual(expectedFilter);
let selection = {id: 99}; expect(controller.fieldFilters).toEqual([]);
let result = controller.getSourceTable(selection);
expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`);
}); });
}); });
}); });

View File

@ -153,7 +153,8 @@
<vn-input-number class="dense" <vn-input-number class="dense"
vn-focus vn-focus
ng-model="sale.quantity" ng-model="sale.quantity"
on-change="$ctrl.changeQuantity(sale)"> on-change="$ctrl.changeQuantity(sale)"
clear-disabled="true">
</vn-input-number> </vn-input-number>
</field> </field>
</vn-td-editable> </vn-td-editable>
@ -177,7 +178,8 @@
<vn-textfield class="dense" vn-focus <vn-textfield class="dense" vn-focus
vn-id="concept" vn-id="concept"
ng-model="sale.concept" ng-model="sale.concept"
on-change="$ctrl.updateConcept(sale)"> on-change="$ctrl.updateConcept(sale)"
clear-disabled="true">
</vn-textfield> </vn-textfield>
</field> </field>
</vn-td-editable> </vn-td-editable>
@ -251,6 +253,7 @@
ng-model="$ctrl.edit.price" ng-model="$ctrl.edit.price"
step="0.01" step="0.01"
on-change="$ctrl.updatePrice()" on-change="$ctrl.updatePrice()"
clear-disabled="true"
suffix="€"> suffix="€">
</vn-input-number> </vn-input-number>
<div class="simulator"> <div class="simulator">
@ -283,6 +286,7 @@
label="Discount" label="Discount"
ng-model="$ctrl.edit.discount" ng-model="$ctrl.edit.discount"
on-change="$ctrl.changeDiscount()" on-change="$ctrl.changeDiscount()"
clear-disabled="true"
suffix="%"> suffix="%">
</vn-input-number> </vn-input-number>
<div class="simulator"> <div class="simulator">
@ -311,6 +315,7 @@
label="Discount" label="Discount"
ng-model="$ctrl.edit.discount" ng-model="$ctrl.edit.discount"
on-change="$ctrl.changeMultipleDiscount()" on-change="$ctrl.changeMultipleDiscount()"
clear-disabled="true"
suffix="%"> suffix="%">
</vn-input-number> </vn-input-number>
</div> </div>