catalog order by tag #773
This commit is contained in:
parent
7398d20132
commit
bb50166e02
|
@ -18,5 +18,7 @@ module.exports.crudModel = {
|
|||
accept();
|
||||
});
|
||||
},
|
||||
refresh: () => {}
|
||||
refresh: () => {},
|
||||
addFilter: () => {},
|
||||
applyFilter: () => {}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<vn-crud-model
|
||||
<vn-crud-model auto-load="false"
|
||||
vn-id="model"
|
||||
url="/order/api/Orders/CatalogFilter"
|
||||
filter="$ctrl.filter"
|
||||
limit="50"
|
||||
data="items" auto-load="false">
|
||||
data="items" on-data-change="$ctrl.onDataChange()" >
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-horizontal>
|
||||
|
@ -11,17 +11,28 @@
|
|||
<vn-card>
|
||||
<vn-vertical>
|
||||
<vn-horizontal class="catalog-header" pad-medium-h>
|
||||
<vn-one>{{model.data.length}} <span translate>results</span></vn-one>
|
||||
<vn-one>{{model.data.length || 0}} <span translate>results</span></vn-one>
|
||||
<vn-one>
|
||||
<vn-autocomplete vn-none
|
||||
data="$ctrl.orderList"
|
||||
initial-data="$ctrl.orderBy"
|
||||
field="$ctrl.orderBy"
|
||||
on-change="$ctrl.setOrder(value)"
|
||||
show-field="name"
|
||||
value-field="order"
|
||||
label="Order by">
|
||||
</vn-autocomplete>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-id="field" vn-one
|
||||
data="$ctrl.fieldList"
|
||||
initial-data="$ctrl.field"
|
||||
field="$ctrl.field"
|
||||
translate-fields="['name']"
|
||||
show-field="name"
|
||||
value-field="field"
|
||||
label="Order by">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
data="$ctrl.wayList"
|
||||
initial-data="$ctrl.way"
|
||||
field="$ctrl.way"
|
||||
translate-fields="['name']"
|
||||
show-field="name"
|
||||
value-field="way"
|
||||
label="Order">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="catalog-list" pad-small>
|
||||
|
@ -78,14 +89,14 @@
|
|||
</vn-one>
|
||||
</section>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal ng-if="model.data.length == 0">
|
||||
<vn-horizontal ng-if="!model.data || model.data.length == 0">
|
||||
<vn-one pad-small translate style="text-align: center">
|
||||
No results
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-pagination
|
||||
<vn-pagination margin-small-v
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
|
|
|
@ -2,48 +2,104 @@ import ngModule from '../module';
|
|||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $state, $translate) {
|
||||
constructor($scope, $state) {
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.orderList = [
|
||||
{
|
||||
order: 'relevancy DESC, name',
|
||||
name: $translate.instant('Default order')
|
||||
},
|
||||
{
|
||||
order: 'name',
|
||||
name: $translate.instant('Ascendant name')
|
||||
},
|
||||
{
|
||||
order: 'name DESC',
|
||||
name: $translate.instant('Descendant name')
|
||||
},
|
||||
{
|
||||
order: 'price',
|
||||
name: $translate.instant('Ascendant price')
|
||||
},
|
||||
{
|
||||
order: 'price DESC',
|
||||
name: $translate.instant('Descendant price')
|
||||
}
|
||||
|
||||
// Static autocomplete data
|
||||
this.wayList = [
|
||||
{way: 'ASC', name: 'Ascendant'},
|
||||
{way: 'DESC', name: 'Descendant'},
|
||||
];
|
||||
this.orderBy = this.orderList[0].order;
|
||||
this.filter = {
|
||||
order: this.orderBy
|
||||
this.defaultFieldList = [
|
||||
{field: 'relevancy DESC, name', name: 'Name'},
|
||||
{field: 'price', name: 'Price'}
|
||||
];
|
||||
this.fieldList = [];
|
||||
this.fieldList = this.fieldList.concat(this.defaultFieldList);
|
||||
this._way = this.wayList[0].way;
|
||||
this._field = this.fieldList[0].field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills order autocomplete with tags
|
||||
* obtained from last filtered
|
||||
*/
|
||||
onDataChange() {
|
||||
const items = this.$scope.model.data;
|
||||
|
||||
if (!items) return;
|
||||
|
||||
this.fieldList = [];
|
||||
this.fieldList = this.fieldList.concat(this.defaultFieldList);
|
||||
|
||||
items.forEach(item => {
|
||||
item.tags.forEach(itemTag => {
|
||||
const alreadyAdded = this.fieldList.find(order => {
|
||||
return order.field == itemTag.tagFk;
|
||||
});
|
||||
|
||||
if (!alreadyAdded)
|
||||
this.fieldList.push({
|
||||
name: itemTag.name,
|
||||
field: itemTag.tagFk,
|
||||
isTag: true
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order way ASC/DESC
|
||||
*/
|
||||
get way() {
|
||||
return this._way;
|
||||
}
|
||||
|
||||
set way(value) {
|
||||
this._way = value;
|
||||
|
||||
if (value)
|
||||
this.applyOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order fields
|
||||
*/
|
||||
get field() {
|
||||
return this._field;
|
||||
}
|
||||
|
||||
set field(value) {
|
||||
this._field = value;
|
||||
|
||||
if (value)
|
||||
this.applyOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns order param
|
||||
*
|
||||
* @return {Object} - Order param
|
||||
*/
|
||||
getOrderBy() {
|
||||
let field = this.$scope.field;
|
||||
let args = {
|
||||
field: this.field,
|
||||
way: this.way
|
||||
};
|
||||
|
||||
if (field.selection && field.selection.isTag)
|
||||
args.isTag = true;
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
get orderBy() {
|
||||
return this._orderBy;
|
||||
}
|
||||
|
||||
set orderBy(value) {
|
||||
this._orderBy = value;
|
||||
}
|
||||
|
||||
setOrder(order) {
|
||||
this.$scope.model.filter.order = order;
|
||||
this.$scope.model.refresh();
|
||||
/**
|
||||
* Apply order to model
|
||||
*/
|
||||
applyOrder() {
|
||||
this.$scope.model.addFilter(null, {orderBy: this.getOrderBy()});
|
||||
}
|
||||
|
||||
preview(event, item) {
|
||||
|
@ -56,18 +112,17 @@ class Controller {
|
|||
}
|
||||
|
||||
$onChanges() {
|
||||
if (this.order && this.order.isConfirmed) {
|
||||
if (this.order && this.order.isConfirmed)
|
||||
this.$state.go('order.card.line');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$state', '$translate'];
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
|
||||
ngModule.component('vnOrderCatalog', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
order: '<'
|
||||
}
|
||||
order: '<',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,16 +15,49 @@ describe('Order', () => {
|
|||
$componentController = _$componentController_;
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$scope.field = {};
|
||||
controller = $componentController('vnOrderCatalog', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('setOrder()', () => {
|
||||
it(`should apply filter order and call model refresh() method`, () => {
|
||||
spyOn(controller.$scope.model, 'refresh');
|
||||
controller.setOrder('relevancy DESC');
|
||||
describe('onDataChange()', () => {
|
||||
it(`should return an object with order params`, () => {
|
||||
let expectedList = [
|
||||
{field: 'relevancy DESC, name', name: 'Name'},
|
||||
{field: 'price', name: 'Price'},
|
||||
{field: 4, name: 'Length', isTag: true}
|
||||
];
|
||||
$scope.model.data = [{id: 1, name: 'My Item', tags: [
|
||||
{tagFk: 4, name: 'Length'}
|
||||
]}];
|
||||
|
||||
expect(controller.$scope.model.filter.order).toEqual('relevancy DESC');
|
||||
expect(controller.$scope.model.refresh).toHaveBeenCalledWith();
|
||||
controller.onDataChange();
|
||||
|
||||
expect(controller.fieldList).toEqual(expectedList);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrderBy()', () => {
|
||||
it(`should return an object with order params`, () => {
|
||||
controller.field = 'relevancy DESC, name';
|
||||
controller.way = 'DESC';
|
||||
let expectedResult = {field: 'relevancy DESC, name', way: 'DESC'};
|
||||
let result = controller.getOrderBy();
|
||||
|
||||
expect(result).toEqual(expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyOrder()', () => {
|
||||
it(`should apply order param to model calling getOrderBy()`, () => {
|
||||
controller.field = 'relevancy DESC, name';
|
||||
controller.way = 'ASC';
|
||||
let expectedOrder = {orderBy: controller.getOrderBy()};
|
||||
spyOn(controller, 'getOrderBy').and.callThrough();
|
||||
spyOn(controller.$scope.model, 'addFilter');
|
||||
controller.applyOrder();
|
||||
|
||||
expect(controller.getOrderBy).toHaveBeenCalledWith();
|
||||
expect(controller.$scope.model.addFilter).toHaveBeenCalledWith(null, expectedOrder);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
|
||||
<vn-horizontal pad-medium class="catalog-header">
|
||||
<vn-autocomplete vn-one
|
||||
vn-id="type"
|
||||
|
|
|
@ -12,7 +12,7 @@ class Controller {
|
|||
this.itemTypes = [];
|
||||
this.tags = [];
|
||||
|
||||
/* $transitions.onSuccess({}, transition => {
|
||||
/* $transitions.onSuccess({}, transition => {
|
||||
let params = {};
|
||||
if (this.category)
|
||||
params.category = this.category;
|
||||
|
@ -42,12 +42,15 @@ class Controller {
|
|||
if (this.$stateParams.category)
|
||||
category = JSON.parse(this.$stateParams.category);
|
||||
|
||||
|
||||
if (this.$stateParams.type)
|
||||
type = JSON.parse(this.$stateParams.type);
|
||||
|
||||
|
||||
if (category && category.id)
|
||||
this.category = category;
|
||||
|
||||
|
||||
if (type && type.id)
|
||||
this.type = type;
|
||||
});
|
||||
|
@ -71,7 +74,7 @@ class Controller {
|
|||
this._category = value;
|
||||
this.updateStateParams();
|
||||
|
||||
let query = `/item/api/ItemCategories/${value.id}/itemTypes`;
|
||||
const query = `/item/api/ItemCategories/${value.id}/itemTypes`;
|
||||
this.$http.get(query).then(res => {
|
||||
this.itemTypes = res.data;
|
||||
});
|
||||
|
@ -99,42 +102,47 @@ class Controller {
|
|||
onSearch(event) {
|
||||
if (event.key !== 'Enter') return;
|
||||
this.tags.push({
|
||||
value: this.value
|
||||
value: this.value,
|
||||
});
|
||||
this.$scope.search.value = null;
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
applyFilters() {
|
||||
let newArgs = {orderFk: this.order.id};
|
||||
let model = this.catalog.$scope.model;
|
||||
|
||||
if (this.category)
|
||||
newArgs.categoryFk = this.category.id;
|
||||
|
||||
if (this.type)
|
||||
newArgs.typeFk = this.type.id;
|
||||
|
||||
model.params = {
|
||||
args: newArgs,
|
||||
tags: this.tags
|
||||
};
|
||||
|
||||
this.catalog.$scope.model.refresh();
|
||||
}
|
||||
|
||||
remove(index) {
|
||||
this.tags.splice(index, 1);
|
||||
|
||||
this.applyFilters();
|
||||
if (this.tags.length > 0)
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
applyFilters() {
|
||||
let newParams = {};
|
||||
const newFilter = {};
|
||||
const model = this.catalog.$scope.model;
|
||||
|
||||
if (this.category)
|
||||
newFilter.categoryFk = this.category.id;
|
||||
|
||||
|
||||
if (this.type)
|
||||
newFilter.typeFk = this.type.id;
|
||||
|
||||
|
||||
newParams = {
|
||||
orderFk: this.order.id,
|
||||
orderBy: this.catalog.getOrderBy(),
|
||||
tags: this.tags,
|
||||
};
|
||||
|
||||
model.applyFilter({where: newFilter}, newParams);
|
||||
}
|
||||
|
||||
openPanel(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
||||
this.$panel = this.$compile(`<vn-order-search-panel/>`)(this.$scope.$new());
|
||||
let panel = this.$panel.isolateScope().$ctrl;
|
||||
this.$panel = this.$compile(`<vn-order-catalog-search-panel/>`)(this.$scope.$new());
|
||||
const panel = this.$panel.isolateScope().$ctrl;
|
||||
panel.filter = this.filter;
|
||||
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||
|
||||
|
@ -156,16 +164,18 @@ class Controller {
|
|||
}
|
||||
|
||||
updateStateParams() {
|
||||
let params = {};
|
||||
const params = {};
|
||||
|
||||
if (this.category)
|
||||
params.category = JSON.stringify(this.category);
|
||||
|
||||
|
||||
if (this.type)
|
||||
params.type = JSON.stringify(this.type);
|
||||
else
|
||||
params.type = undefined;
|
||||
|
||||
|
||||
this.$state.go(this.$state.current.name, params);
|
||||
}
|
||||
}
|
||||
|
@ -176,9 +186,9 @@ ngModule.component('vnCatalogFilter', {
|
|||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
catalog: '^vnOrderCatalog'
|
||||
catalog: '^vnOrderCatalog',
|
||||
},
|
||||
bindings: {
|
||||
order: '<'
|
||||
}
|
||||
order: '<',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -26,7 +26,10 @@ describe('Order', () => {
|
|||
$state.current.name = 'my.current.state';
|
||||
controller = $componentController('vnCatalogFilter', {$scope: $scope, $state});
|
||||
controller.catalog = {
|
||||
$scope: $scope
|
||||
$scope: $scope,
|
||||
getOrderBy: () => {
|
||||
return {field: 'relevancy DESC, name', way: 'DESC'};
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
|
@ -101,15 +104,14 @@ describe('Order', () => {
|
|||
|
||||
describe('applyFilters()', () => {
|
||||
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||
spyOn(controller.catalog.$scope.model, 'refresh');
|
||||
spyOn(controller.catalog.$scope.model, 'applyFilter');
|
||||
controller.order = {id: 4};
|
||||
$scope.$digest();
|
||||
controller.applyFilters();
|
||||
|
||||
let result = {args: {orderFk: 4, categoryFk: 1, typeFk: 1}, tags: []};
|
||||
|
||||
expect(controller.catalog.$scope.model.params).toEqual(result);
|
||||
expect(controller.catalog.$scope.model.refresh).toHaveBeenCalledWith();
|
||||
expect(controller.catalog.$scope.model.applyFilter).toHaveBeenCalledWith(
|
||||
{where: {categoryFk: 1, typeFk: 1}},
|
||||
{orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@ Accessories: Complemento
|
|||
Category: Reino
|
||||
Search tag: Buscar etiqueta
|
||||
Order by: Ordenar por
|
||||
Default order: Orden predeterminado
|
||||
Ascendant name: Nombre ascendiente
|
||||
Descendant name: Nombre descendiente
|
||||
Ascendant price: Precio ascendiente
|
||||
Descendant price: Precio descendiente
|
||||
Order: Orden
|
||||
Price: Precio
|
||||
Ascendant: Ascendente
|
||||
Descendant: Descendente
|
||||
Created from: Creado desde
|
|
@ -79,4 +79,5 @@ INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`
|
|||
|
||||
|
||||
|
||||
INSERT INTO `salix`.`fieldAcl` (`model`, `property`, `actionType`, `role`) VALUES ('TicketWeekly', '*', '*', 'employee');
|
||||
INSERT INTO `salix`.`fieldAcl` (`model`, `property`, `actionType`, `role`) VALUES ('TicketWeekly', '*', '*', 'employee');
|
||||
INSERT INTO `salix`.`fieldAcl` (`model`, `property`, `actionType`, `role`) VALUES ('Receipt', '*', '*', 'administrative');
|
|
@ -25,6 +25,12 @@
|
|||
},
|
||||
"unit": {
|
||||
"type": "String"
|
||||
},
|
||||
"isQuantitative": {
|
||||
"type": "Boolean",
|
||||
"mysql": {
|
||||
"columnName": "isQuantitatif"
|
||||
}
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
|
|
|
@ -6,89 +6,87 @@ module.exports = Self => {
|
|||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
arg: 'orderFk',
|
||||
type: 'Number',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'args',
|
||||
arg: 'orderBy',
|
||||
type: 'Object',
|
||||
description: 'orderFk, categoryFk, typeFk',
|
||||
required: true,
|
||||
http: {source: 'query'}
|
||||
description: 'Items order',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string'
|
||||
},
|
||||
{
|
||||
arg: 'tags',
|
||||
type: ['Object'],
|
||||
description: 'Request tags',
|
||||
http: {source: 'query'}
|
||||
}
|
||||
description: 'Filter by tag'
|
||||
},
|
||||
],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
root: true,
|
||||
},
|
||||
http: {
|
||||
path: `/catalogFilter`,
|
||||
verb: 'GET'
|
||||
}
|
||||
verb: 'GET',
|
||||
},
|
||||
});
|
||||
|
||||
Self.catalogFilter = async (filter, args, tags) => {
|
||||
let stmts = [];
|
||||
Self.catalogFilter = async (orderFk, orderBy, filter, tags) => {
|
||||
let conn = Self.dataSource.connector;
|
||||
const stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.item');
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`CREATE TEMPORARY TABLE tmp.item
|
||||
(PRIMARY KEY (itemFk)) ENGINE = MEMORY
|
||||
SELECT DISTINCT
|
||||
(PRIMARY KEY (itemFk)) ENGINE = MEMORY
|
||||
SELECT DISTINCT
|
||||
i.id AS itemFk,
|
||||
i.typeFk,
|
||||
it.categoryFk
|
||||
FROM vn.item i
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType it ON it.id = i.typeFk
|
||||
JOIN vn.itemCategory ic ON ic.id = it.categoryFk`
|
||||
);
|
||||
JOIN vn.itemCategory ic ON ic.id = it.categoryFk`);
|
||||
|
||||
// Filter by tag
|
||||
if (tags) {
|
||||
let i = 1;
|
||||
for (let tag of tags) {
|
||||
let tAlias = `it${i++}`;
|
||||
for (const tag of tags) {
|
||||
const tAlias = `it${i++}`;
|
||||
|
||||
if (tag.tagFk) {
|
||||
if (tag.tagFk)
|
||||
stmt.merge({
|
||||
sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||
AND ${tAlias}.tagFk = ?
|
||||
AND ${tAlias}.value LIKE ?`,
|
||||
params: [tag.tagFk, `%${tag.value}%`]
|
||||
params: [tag.tagFk, `%${tag.value}%`],
|
||||
});
|
||||
} else {
|
||||
else
|
||||
stmt.merge({
|
||||
sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||
AND ${tAlias}.value LIKE ?`,
|
||||
params: [`%${tag.value}%`]
|
||||
params: [`%${tag.value}%`],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (args.typeFk)
|
||||
stmt.merge({
|
||||
sql: 'WHERE it.categoryFk = ? AND i.typeFk = ?',
|
||||
params: [args.categoryFk, args.typeFk]
|
||||
});
|
||||
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
stmts.push(stmt);
|
||||
|
||||
let order = await Self.findById(args.orderFk);
|
||||
// Calculate items
|
||||
const order = await Self.findById(orderFk);
|
||||
stmts.push(new ParameterizedSQL(
|
||||
'CALL vn.ticketCalculate(?, ?, ?)', [
|
||||
order.landed,
|
||||
order.address_id,
|
||||
order.agency_id
|
||||
order.agency_id,
|
||||
]
|
||||
));
|
||||
|
||||
|
@ -112,13 +110,39 @@ module.exports = Self => {
|
|||
FROM tmp.ticketCalculateItem tci
|
||||
JOIN vn.item i ON i.id = tci.itemFk
|
||||
JOIN vn.itemType it ON it.id = i.typeFk
|
||||
JOIN vn.worker w on w.id = it.workerFk`
|
||||
);
|
||||
stmt.merge(Self.buildSuffix(filter));
|
||||
// stmt.merge(Self.buildOrderBy(orderBy));
|
||||
let itemsIndex = stmts.push(stmt) - 1;
|
||||
JOIN vn.worker w on w.id = it.workerFk`);
|
||||
|
||||
let pricesIndex = stmts.push(
|
||||
// Apply order by tag
|
||||
if (orderBy.isTag) {
|
||||
stmt.merge({
|
||||
sql: `
|
||||
LEFT JOIN vn.itemTag itg
|
||||
LEFT JOIN vn.tag t ON t.id = itg.tagFk
|
||||
ON itg.itemFk = tci.itemFk AND itg.tagFk = ?`,
|
||||
params: [orderBy.field],
|
||||
});
|
||||
|
||||
let way = orderBy.way == 'DESC' ? 'DESC' : 'ASC';
|
||||
let tag = await Self.app.models.Tag.findById(orderBy.field);
|
||||
let orderSql = `
|
||||
ORDER BY
|
||||
itg.value IS NULL,
|
||||
${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'}
|
||||
${way}`;
|
||||
|
||||
stmt.merge(orderSql);
|
||||
} else {
|
||||
// Apply order by field
|
||||
let orderParam = `${orderBy.field} ${orderBy.way}`;
|
||||
orderParam = orderParam.split(/\s*,/).map(param => param.trim());
|
||||
stmt.merge(conn.makeOrderBy(orderParam));
|
||||
}
|
||||
|
||||
stmt.merge(Self.makeLimit(filter));
|
||||
const itemsIndex = stmts.push(stmt) - 1;
|
||||
|
||||
// Apply item prices
|
||||
const pricesIndex = stmts.push(
|
||||
`SELECT
|
||||
tcp.itemFk,
|
||||
tcp.grouping,
|
||||
|
@ -127,32 +151,51 @@ module.exports = Self => {
|
|||
tcp.warehouseFk,
|
||||
w.name AS warehouse
|
||||
FROM tmp.ticketComponentPrice tcp
|
||||
JOIN vn.warehouse w ON w.id = tcp.warehouseFk`
|
||||
) - 1;
|
||||
JOIN vn.warehouse w ON w.id = tcp.warehouseFk`) - 1;
|
||||
|
||||
// Get tags from all items
|
||||
const itemTagsIndex = stmts.push(
|
||||
`SELECT
|
||||
it.tagFk,
|
||||
it.itemFk,
|
||||
t.name
|
||||
FROM tmp.ticketCalculateItem tci
|
||||
JOIN vn.itemTag it ON it.itemFk = tci.itemFk
|
||||
JOIN vn.tag t ON t.id = it.tagFk`) - 1;
|
||||
|
||||
// Clean temporary tables
|
||||
stmts.push(
|
||||
`DROP TEMPORARY TABLE
|
||||
tmp.item,
|
||||
tmp.ticketCalculateItem,
|
||||
tmp.ticketComponentPrice`
|
||||
);
|
||||
tmp.ticketComponentPrice`);
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await Self.rawStmt(sql);
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const result = await conn.executeStmt(sql);
|
||||
|
||||
// Add prices to items
|
||||
result[itemsIndex].forEach(item => {
|
||||
result[pricesIndex].forEach(price => {
|
||||
if (item.id === price.itemFk) {
|
||||
if (item.prices) {
|
||||
if (item.prices)
|
||||
item.prices.push(price);
|
||||
} else {
|
||||
else
|
||||
item.prices = [price];
|
||||
}
|
||||
|
||||
item.available = price.grouping;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Attach item tags
|
||||
result[itemsIndex].forEach(item => {
|
||||
item.tags = [];
|
||||
result[itemTagsIndex].forEach(itemTag => {
|
||||
if (item.id === itemTag.itemFk)
|
||||
item.tags.push(itemTag);
|
||||
});
|
||||
});
|
||||
|
||||
return result[itemsIndex];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
const app = require(`${servicesDir}/order/server/server`);
|
||||
describe('order catalogFilter()', () => {
|
||||
it('should return an array of items', async() => {
|
||||
it('should return an array of items', async () => {
|
||||
let filter = {
|
||||
order: 'relevancy DESC, name'
|
||||
where: {
|
||||
categoryFk: 1,
|
||||
typeFk: 2
|
||||
}
|
||||
};
|
||||
let args = {
|
||||
orderFk: 11,
|
||||
categoryFk: 1,
|
||||
typeFk: 2
|
||||
};
|
||||
|
||||
let tags = [];
|
||||
let result = await app.models.Order.catalogFilter(filter, args, tags);
|
||||
let orderFk = 11;
|
||||
let orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
|
||||
let result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tags);
|
||||
let firstItemId = result[0].id;
|
||||
|
||||
expect(result.length).toEqual(2);
|
||||
expect(firstItemId).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return an array of items based on tag filter', async() => {
|
||||
it('should return an array of items based on tag filter', async () => {
|
||||
let filter = {
|
||||
order: 'relevancy DESC, name'
|
||||
};
|
||||
let args = {
|
||||
orderFk: 11,
|
||||
categoryFk: 1,
|
||||
typeFk: 2
|
||||
where: {
|
||||
categoryFk: 1,
|
||||
typeFk: 2
|
||||
}
|
||||
};
|
||||
|
||||
let tags = [{tagFk: 56, value: 'Object2'}];
|
||||
let result = await app.models.Order.catalogFilter(filter, args, tags);
|
||||
let orderFk = 11;
|
||||
let orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
|
||||
let result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tags);
|
||||
let firstItemId = result[0].id;
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
|
|
Loading…
Reference in New Issue