Merge pull request '4846-claim.search-panel' (!1174) from 4846-claim.search-panel into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #1174
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
Vicent Llopis 2023-01-10 13:09:19 +00:00
commit ef40c15a4e
5 changed files with 131 additions and 33 deletions

View File

@ -1779,7 +1779,7 @@ INSERT INTO `vn`.`claimDestination`(`id`, `description`, `addressFk`)
INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`) INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`)
VALUES VALUES
(1, 1, 1, 21, 1, 1, 2, 5), (1, 1, 1, 21, 1, 1, 2, 5),
(2, 1, 1, 21, 7, 2, 2, 5), (2, 1, 2, 21, 7, 2, 2, 5),
(3, 2, 7, 21, 9, 3, 2, 5), (3, 2, 7, 21, 9, 3, 2, 5),
(4, 3, 7, 21, 15, 8, 2, 5), (4, 3, 7, 21, 15, 8, 2, 5),
(5, 4, 7, 21, 7, 8, 2, 5); (5, 4, 7, 21, 7, 8, 2, 5);

View File

@ -23,7 +23,7 @@ module.exports = Self => {
{ {
arg: 'search', arg: 'search',
type: 'string', type: 'string',
description: `If it's and integer searchs by id, otherwise it searchs by client name`, description: `If it's a number searchs by id, otherwise it searchs by client name`,
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
@ -34,31 +34,31 @@ module.exports = Self => {
}, },
{ {
arg: 'id', arg: 'id',
type: 'integer', type: 'number',
description: 'The claim id', description: 'The claim id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'clientFk', arg: 'clientFk',
type: 'integer', type: 'number',
description: 'The client id', description: 'The client id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'claimStateFk', arg: 'claimStateFk',
type: 'integer', type: 'number',
description: 'The claim state id', description: 'The claim state id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'salesPersonFk', arg: 'salesPersonFk',
type: 'integer', type: 'number',
description: 'The salesPerson id', description: 'The salesPerson id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'attenderFk', arg: 'attenderFk',
type: 'integer', type: 'number',
description: 'The attender worker id', description: 'The attender worker id',
http: {source: 'query'} http: {source: 'query'}
}, },
@ -67,6 +67,18 @@ module.exports = Self => {
type: 'date', type: 'date',
description: 'The to date filter', description: 'The to date filter',
http: {source: 'query'} http: {source: 'query'}
},
{
arg: 'itemFk',
type: 'number',
description: 'The item id',
http: {source: 'query'}
},
{
arg: 'claimResponsibleFk',
type: 'number',
description: 'The claimResponsible id',
http: {source: 'query'}
} }
], ],
returns: { returns: {
@ -80,33 +92,58 @@ module.exports = Self => {
}); });
Self.filter = async(ctx, filter, options) => { Self.filter = async(ctx, filter, options) => {
const models = Self.app.models;
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const args = ctx.args;
const myOptions = {}; const myOptions = {};
let to; let to;
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const where = buildFilter(ctx.args, (param, value) => { let claimIdsByItemFk = [];
let claimIdsByClaimResponsibleFk = [];
if (args.itemFk) {
query = `SELECT cb.claimFk
FROM claimBeginning cb
LEFT JOIN sale s ON s.id = cb.saleFk
WHERE s.itemFk = ?`;
const claims = await Self.rawSql(query, [args.itemFk], myOptions);
claimIdsByItemFk = claims.map(claim => claim.claimFk);
}
if (args.claimResponsibleFk) {
const claims = await models.ClaimDevelopment.find({
fields: ['claimFk'],
where: {claimResponsibleFk: args.claimResponsibleFk}
}, myOptions);
claimIdsByClaimResponsibleFk = claims.map(claim => claim.claimFk);
}
const where = buildFilter(args, (param, value) => {
switch (param) { switch (param) {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {'cl.id': value} ? {'cl.id': value}
: { : {
or: [ or: [
{'cl.clientName': {like: `%${value}%`}} {'c.name': {like: `%${value}%`}}
] ]
}; };
case 'clientName': case 'clientName':
return {'cl.clientName': {like: `%${value}%`}}; return {'c.name': {like: `%${value}%`}};
case 'clientFk': case 'clientFk':
return {'cl.clientFk': value};
case 'id': case 'id':
case 'claimStateFk': case 'claimStateFk':
case 'priority': case 'priority':
return {[`cl.${param}`]: value}; return {[`cl.${param}`]: value};
case 'itemFk':
return {'cl.id': {inq: claimIdsByItemFk}};
case 'claimResponsibleFk':
return {'cl.id': {inq: claimIdsByClaimResponsibleFk}};
case 'salesPersonFk': case 'salesPersonFk':
return {'cl.salesPersonFk': value}; return {'c.salesPersonFk': value};
case 'attenderFk': case 'attenderFk':
return {'cl.workerFk': value}; return {'cl.workerFk': value};
case 'created': case 'created':
@ -118,29 +155,23 @@ module.exports = Self => {
} }
}); });
filter = mergeFilters(ctx.args.filter, {where}); filter = mergeFilters(args.filter, {where});
const stmts = []; const stmts = [];
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT * `SELECT
FROM (
SELECT
cl.id, cl.id,
cl.clientFk, cl.clientFk,
c.name AS clientName, c.name AS clientName,
cl.workerFk, cl.workerFk,
u.name AS workerName, u.name AS workerName,
cs.description, cs.description,
cl.created, cl.created
cs.priority,
cl.claimStateFk,
c.salesPersonFk
FROM claim cl FROM claim cl
LEFT JOIN client c ON c.id = cl.clientFk 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 = cl.workerFk
LEFT JOIN account.user u ON u.id = w.userFk LEFT JOIN claimState cs ON cs.id = cl.claimStateFk`
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk ) cl`
); );
stmt.merge(conn.makeSuffix(filter)); stmt.merge(conn.makeSuffix(filter));

View File

@ -57,4 +57,44 @@ describe('claim filter()', () => {
throw e; throw e;
} }
}); });
it('should return 3 results filtering by item id', async() => {
const tx = await app.models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Claim.filter({args: {filter: {}, itemFk: 2}}, null, options);
expect(result.length).toEqual(3);
expect(result[0].id).toEqual(1);
expect(result[1].id).toEqual(2);
expect(result[2].id).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return 3 results filtering by claimResponsible id', async() => {
const tx = await app.models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Claim.filter({args: {filter: {}, claimResponsibleFk: 7}}, null, options);
expect(result.length).toEqual(3);
expect(result[0].id).toEqual(2);
expect(result[1].id).toEqual(3);
expect(result[2].id).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
}); });

View File

@ -58,6 +58,26 @@
ng-model="filter.created"> ng-model="filter.created">
</vn-date-picker> </vn-date-picker>
</vn-horizontal> </vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one class="dense"
label="Item"
url="Items/withName"
ng-model="filter.itemFk"
show-field="name"
value-field="id"
search-function="$ctrl.itemSearchFunc($search)"
order="id DESC">
<tpl-item>{{::id}} - {{::name}}</tpl-item>
</vn-autocomplete>
<vn-autocomplete
vn-one
ng-model="filter.claimResponsibleFk"
url="ClaimResponsibles"
show-field="description"
value-field="id"
label="Responsible">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal class="vn-mt-lg"> <vn-horizontal class="vn-mt-lg">
<vn-submit label="Search"></vn-submit> <vn-submit label="Search"></vn-submit>
</vn-horizontal> </vn-horizontal>

View File

@ -1,7 +1,14 @@
import ngModule from '../module'; import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel'; import SearchPanel from 'core/components/searchbar/search-panel';
class Controller extends SearchPanel {
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
}
ngModule.vnComponent('vnClaimSearchPanel', { ngModule.vnComponent('vnClaimSearchPanel', {
template: require('./index.html'), template: require('./index.html'),
controller: SearchPanel controller: Controller
}); });