#1212 refactor claim filter
gitea/salix/dev This commit looks good Details

This commit is contained in:
Bernat 2019-04-15 11:06:42 +02:00
parent 79f9dfb515
commit 6a68003d84
6 changed files with 161 additions and 59 deletions

View File

@ -0,0 +1,118 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {
Self.remoteMethodCtx('filter', {
description: 'Find all instances of the model matched by filter from the data source.',
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: 'tags',
type: ['Object'],
description: 'List of tags to filter with',
http: {source: 'query'}
}, {
arg: 'search',
type: 'String',
description: `If it's and integer searchs by id, otherwise it searchs by client name`,
http: {source: 'query'}
}, {
arg: 'client',
type: 'String',
description: 'The worker name',
http: {source: 'query'}
}, {
arg: 'id',
type: 'Integer',
description: 'The claim id',
http: {source: 'query'}
}, {
arg: 'clientFk',
type: 'Integer',
description: 'The client id',
http: {source: 'query'}
}, {
arg: 'claimStateFk',
type: 'Integer',
description: 'The claim state id',
http: {source: 'query'}
}, {
arg: 'workerFk',
type: 'Integer',
description: 'The worker id',
http: {source: 'query'}
}, {
arg: 'created',
type: 'Date',
description: 'The to date filter',
http: {source: 'query'}
}
],
returns: {
type: ['Object'],
root: true
},
http: {
path: `/filter`,
verb: 'GET'
}
});
Self.filter = async(ctx, filter) => {
let conn = Self.dataSource.connector;
let where = buildFilter(ctx.args, (param, value) => {
switch (param) {
case 'search':
return /^\d+$/.test(value)
? {'cl.id': value}
: {
or: [
{'c.name': {like: `%${value}%`}}
]
};
case 'client':
return {'c.name': {like: `%${value}%`}};
case 'id':
return {'cl.id': value};
case 'clientFk':
return {'c.id': value};
case 'claimStateFk':
return {'cl.claimStateFk': value};
case 'workerFk':
return {'cl.workerFk': value};
case 'created':
return {'cl.created': value};
}
});
filter = mergeFilters(ctx.args.filter, {where});
let stmts = [];
let stmt;
stmt = new ParameterizedSQL(
`SELECT cl.id, c.name, u.nickName, cs.description, cl.created
FROM claim cl
LEFT JOIN client c ON c.id = cl.clientFk
LEFT JOIN worker w ON w.id = cl.workerFk
LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk`
);
stmt.merge(conn.makeSuffix(filter));
let itemsIndex = stmts.push(stmt) - 1;
let sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql);
return itemsIndex === 0 ? result : result[itemsIndex];
};
};

View File

@ -0,0 +1,27 @@
const app = require('vn-loopback/server/server');
describe('claim filter()', () => {
it('should return 1 result filtering by id', async() => {
let result = await app.models.Claim.filter({args: {filter: {}, search: 1}});
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(1);
});
it('should return 1 result filtering by string', async() => {
let result = await app.models.Claim.filter({args: {filter: {}, search: 'Tony Stark'}});
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(4);
});
it('should return 4 results filtering by worker id', async() => {
let result = await app.models.Claim.filter({args: {filter: {}, workerFk: 18}});
expect(result.length).toEqual(4);
expect(result[0].id).toEqual(1);
expect(result[1].id).toEqual(2);
expect(result[2].id).toEqual(3);
expect(result[3].id).toEqual(4);
});
});

View File

@ -3,4 +3,5 @@ module.exports = Self => {
require('../methods/claim/createFromSales')(Self); require('../methods/claim/createFromSales')(Self);
require('../methods/claim/updateClaim')(Self); require('../methods/claim/updateClaim')(Self);
require('../methods/claim/regularizeClaim')(Self); require('../methods/claim/regularizeClaim')(Self);
require('../methods/claim/filter')(Self);
}; };

View File

@ -1,19 +1,16 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="/claim/api/Claims" url="/claim/api/Claims/filter"
filter="::$ctrl.filter"
limit="20" limit="20"
data="claims" data="claims"
auto-load="false"> order="claimStateFk ASC, created DESC">
</vn-crud-model> </vn-crud-model>
<div class="content-block"> <div class="content-block">
<div class="vn-list"> <div class="vn-list">
<vn-card pad-medium-h> <vn-card pad-medium-h>
<vn-searchbar <vn-searchbar
panel="vn-claim-search-panel" panel="vn-claim-search-panel"
model="model" on-search="$ctrl.onSearch($params)"
expr-builder="$ctrl.exprBuilder(param, value)"
auto-load="true"
info="Search claim by id or client name" info="Search claim by id or client name"
vn-focus> vn-focus>
</vn-searchbar> </vn-searchbar>
@ -39,7 +36,7 @@
<vn-td number>{{::claim.id}}</vn-td> <vn-td number>{{::claim.id}}</vn-td>
<vn-td expand> <vn-td expand>
<span class="link" ng-click="$ctrl.showClientDescriptor($event, claim.client.id)"> <span class="link" ng-click="$ctrl.showClientDescriptor($event, claim.client.id)">
{{::claim.client.name}} {{::claim.name}}
</span> </span>
</vn-td> </vn-td>
<vn-td center>{{::claim.created | dateTime:'dd/MM/yyyy'}}</vn-td> <vn-td center>{{::claim.created | dateTime:'dd/MM/yyyy'}}</vn-td>
@ -47,12 +44,12 @@
<span <span
class="link" class="link"
ng-click="$ctrl.showWorkerDescriptor($event, claim.worker.user.id)"> ng-click="$ctrl.showWorkerDescriptor($event, claim.worker.user.id)">
{{::claim.worker.user.nickname}} {{::claim.nickName}}
</span> </span>
</vn-td> </vn-td>
<vn-td> <vn-td>
<span class="chip {{::$ctrl.stateColor(claim)}}"> <span class="chip {{::$ctrl.stateColor(claim)}}">
{{::claim.claimState.description}} {{::claim.description}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>

View File

@ -4,58 +4,10 @@ export default class Controller {
constructor($scope) { constructor($scope) {
this.$ = $scope; this.$ = $scope;
this.ticketSelected = null; this.ticketSelected = null;
this.filter = {
include: [
{
relation: 'client',
scope: {
fields: ['name']
}
},
{
relation: 'worker',
scope: {
fields: ['userFk'],
include: {
relation: 'user',
scope: {
fields: ['nickname']
}
}
}
},
{
relation: 'claimState',
scope: {
fields: ['description']
}
}
],
order: 'claimStateFk ASC, created DESC'
};
}
exprBuilder(param, value) {
switch (param) {
case 'search':
return /^\d+$/.test(value)
? {id: value}
: {client: {like: `%${value}%`}};
case 'client':
return {[param]: {like: `%${value}%`}};
case 'created':
return {created: {between: [value, value]}};
case 'id':
case 'clientFk':
case 'workerFk':
case 'claimStateFk':
return {[param]: value};
}
} }
stateColor(claim) { stateColor(claim) {
switch (claim.claimState.description) { switch (claim.description) {
case 'Pendiente': case 'Pendiente':
return 'warning'; return 'warning';
case 'Gestionado': case 'Gestionado':
@ -91,6 +43,13 @@ export default class Controller {
onDescriptorLoad() { onDescriptorLoad() {
this.$.popover.relocate(); this.$.popover.relocate();
} }
onSearch(params) {
if (params)
this.$.model.applyFilter(null, params);
else
this.$.model.clear();
}
} }
Controller.$inject = ['$scope']; Controller.$inject = ['$scope'];

View File

@ -1,6 +1,6 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="/agency/api/Workers/filter" url="/worker/api/Workers/filter"
limit="20" limit="20"
order="id" order="id"
data="workers"> data="workers">