Merge pull request '3006-item_filter_category' (#683) from 3006-item_filter_category into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #683
Reviewed-by: Joan Sanchez <joan@verdnatura.es>
This commit is contained in:
Joan Sanchez 2021-07-01 11:16:47 +00:00
commit e61244d11b
3 changed files with 107 additions and 59 deletions

View File

@ -10,73 +10,73 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'filter', arg: 'filter',
type: 'Object', type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'search', arg: 'search',
type: 'String', type: 'string',
description: 'Searchs the invoiceOut by id', description: 'Searchs the invoiceOut by id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'clientFk', arg: 'clientFk',
type: 'Integer', type: 'integer',
description: 'The client id', description: 'The client id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'fi', arg: 'fi',
type: 'String', type: 'string',
description: 'The client fiscal id', description: 'The client fiscal id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'hasPdf', arg: 'hasPdf',
type: 'Boolean', type: 'boolean',
description: 'Whether the the invoiceOut has PDF or not', description: 'Whether the the invoiceOut has PDF or not',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'amount', arg: 'amount',
type: 'Number', type: 'number',
description: 'The amount filter', description: 'The amount filter',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'min', arg: 'min',
type: 'Number', type: 'number',
description: 'The minimun amount flter', description: 'The minimun amount flter',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'max', arg: 'max',
type: 'Number', type: 'number',
description: 'The maximun amount flter', description: 'The maximun amount flter',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'issued', arg: 'issued',
type: 'Date', type: 'date',
description: 'The issued date filter', description: 'The issued date filter',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'created', arg: 'created',
type: 'Date', type: 'date',
description: 'The created date filter', description: 'The created date filter',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'dued', arg: 'dued',
type: 'Date', type: 'date',
description: 'The due date filter', description: 'The due date filter',
http: {source: 'query'} http: {source: 'query'}
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {

View File

@ -10,48 +10,57 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'filter', arg: 'filter',
type: 'Object', type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
}, { },
{
arg: 'tags', arg: 'tags',
type: ['Object'], type: ['object'],
description: 'List of tags to filter with', description: 'List of tags to filter with',
}, { },
{
arg: 'search', arg: 'search',
type: 'String', type: 'string',
description: `If it's and integer searchs by id, otherwise it searchs by name`, description: `If it's and integer searchs by id, otherwise it searchs by name`,
}, { },
{
arg: 'id', arg: 'id',
type: 'Integer', type: 'integer',
description: 'Item id', description: 'Item id',
}, { },
{
arg: 'categoryFk', arg: 'categoryFk',
type: 'Integer', type: 'integer',
description: 'Category id', description: 'Category id',
}, { },
{
arg: 'typeFk', arg: 'typeFk',
type: 'Integer', type: 'integer',
description: 'Type id', description: 'Type id',
}, { },
{
arg: 'isActive', arg: 'isActive',
type: 'Boolean', type: 'boolean',
description: 'Whether the the item is or not active', description: 'Whether the the item is or not active',
}, { },
{
arg: 'salesPersonFk', arg: 'salesPersonFk',
type: 'Integer', type: 'integer',
description: 'The buyer of the item', description: 'The buyer of the item',
}, { },
{
arg: 'description', arg: 'description',
type: 'String', type: 'string',
description: 'The item description', description: 'The item description',
}, { },
{
arg: 'stemMultiplier', arg: 'stemMultiplier',
type: 'Integer', type: 'integer',
description: 'The item multiplier', description: 'The item multiplier',
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -60,23 +69,28 @@ module.exports = Self => {
} }
}); });
Self.filter = async(ctx, filter) => { Self.filter = async(ctx, filter, options) => {
let conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
let myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
let codeWhere; let codeWhere;
if (ctx.args.search) { if (ctx.args.search) {
let items = await Self.app.models.ItemBarcode.find({ const items = await Self.app.models.ItemBarcode.find({
where: {code: ctx.args.search}, where: {code: ctx.args.search},
fields: ['itemFk'] fields: ['itemFk']
}); }, myOptions);
let itemIds = []; const itemIds = [];
for (const item of items) for (const item of items)
itemIds.push(item.itemFk); itemIds.push(item.itemFk);
codeWhere = {'i.id': {inq: itemIds}}; codeWhere = {'i.id': {inq: itemIds}};
} }
let where = buildFilter(ctx.args, (param, value) => { const where = buildFilter(ctx.args, (param, value) => {
switch (param) { switch (param) {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
@ -90,8 +104,8 @@ module.exports = Self => {
return {'i.stemMultiplier': value}; return {'i.stemMultiplier': value};
case 'typeFk': case 'typeFk':
return {'i.typeFk': value}; return {'i.typeFk': value};
case 'category': case 'categoryFk':
return {'ic.name': value}; return {'ic.id': value};
case 'salesPersonFk': case 'salesPersonFk':
return {'it.workerFk': value}; return {'it.workerFk': value};
case 'origin': case 'origin':
@ -104,7 +118,7 @@ module.exports = Self => {
}); });
filter = mergeFilters(filter, {where}); filter = mergeFilters(filter, {where});
let stmts = []; const stmts = [];
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
@ -173,9 +187,10 @@ module.exports = Self => {
stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeWhere(filter.where));
stmt.merge(conn.makePagination(filter)); stmt.merge(conn.makePagination(filter));
let itemsIndex = stmts.push(stmt) - 1; const itemsIndex = stmts.push(stmt) - 1;
let sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql); const result = await conn.executeStmt(sql, myOptions);
return itemsIndex === 0 ? result : result[itemsIndex]; return itemsIndex === 0 ? result : result[itemsIndex];
}; };
}; };

View File

@ -2,29 +2,62 @@ const app = require('vn-loopback/server/server');
describe('item filter()', () => { describe('item filter()', () => {
it('should return 1 result filtering by id', async() => { it('should return 1 result filtering by id', async() => {
let filter = {}; const tx = await app.models.Item.beginTransaction({});
let result = await app.models.Item.filter({args: {filter: filter, search: 1}}); const options = {transaction: tx};
try {
const filter = {};
const ctx = {args: {filter: filter, search: 1}};
const result = await app.models.Item.filter(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
expect(result[0].id).toEqual(1); expect(result[0].id).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return 1 result filtering by barcode', async() => { it('should return 1 result filtering by barcode', async() => {
let filter = {}; const tx = await app.models.Item.beginTransaction({});
let result = await app.models.Item.filter({args: {filter: filter, search: 4444444444}}); const options = {transaction: tx};
try {
const filter = {};
const ctx = {args: {filter: filter, search: 4444444444}};
const result = await app.models.Item.filter(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
expect(result[0].id).toEqual(2); expect(result[0].id).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return 2 results using filter and tags', async() => { it('should return 2 results using filter and tags', async() => {
let filter = { const tx = await app.models.Item.beginTransaction({});
const options = {transaction: tx};
try {
const filter = {
order: 'isActive ASC, name', order: 'isActive ASC, name',
limit: 8 limit: 8
}; };
let tags = [{value: 'medical box', tagFk: 58}]; const tags = [{value: 'medical box', tagFk: 58}];
let result = await app.models.Item.filter({args: {filter: filter, typeFk: 5, tags: tags}}); const ctx = {args: {filter: filter, typeFk: 5, tags: tags}};
const result = await app.models.Item.filter(ctx, filter, options);
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });