4846-claim.search-panel #1174
|
@ -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);
|
||||||
|
|
|
@ -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`,
|
||||||
vicent marked this conversation as resolved
Outdated
|
|||||||
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}%`}};
|
||||||
vicent marked this conversation as resolved
jgallego
commented
revisar si falla, parece que deberia ser c.clientName revisar si falla, parece que deberia ser c.clientName
vicent
commented
Sí que funciona Sí que funciona
|
|||||||
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':
|
||||||
vicent marked this conversation as resolved
jgallego
commented
revisar si llamando a itemFk y claimResponsibleFk construye los dos revisar si llamando a itemFk y claimResponsibleFk construye los dos
vicent
commented
Construye los dos, con un and: Construye los dos, con un and:
{ and: [ { 'cl.id': [Object] }, { 'cl.id': [Object] } ] }
|
|||||||
|
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
|
||||||
vicent marked this conversation as resolved
jgallego
commented
usar loopback usar loopback
|
|||||||
FROM (
|
cl.id,
|
||||||
SELECT
|
cl.clientFk,
|
||||||
cl.id,
|
c.name AS clientName,
|
||||||
cl.clientFk,
|
cl.workerFk,
|
||||||
c.name AS clientName,
|
u.name AS workerName,
|
||||||
cl.workerFk,
|
cs.description,
|
||||||
u.name AS workerName,
|
cl.created
|
||||||
cs.description,
|
FROM claim cl
|
||||||
cl.created,
|
LEFT JOIN client c ON c.id = cl.clientFk
|
||||||
cs.priority,
|
LEFT JOIN account.user u ON u.id = cl.workerFk
|
||||||
vicent marked this conversation as resolved
Outdated
jgallego
commented
worker no es necesaria, directament en user. worker no es necesaria, directament en user.
|
|||||||
cl.claimStateFk,
|
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk`
|
||||||
c.salesPersonFk
|
|
||||||
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 ) cl`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
If it's a number