refactor(order): catalogFilter, confirm and filter transactions
This commit is contained in:
parent
b055618577
commit
f62814e81e
|
@ -7,28 +7,28 @@ module.exports = Self => {
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'orderFk',
|
arg: 'orderFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'orderBy',
|
arg: 'orderBy',
|
||||||
type: 'Object',
|
type: 'object',
|
||||||
description: 'Items order',
|
description: 'Items order',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
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: 'tagGroups',
|
arg: 'tagGroups',
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
description: 'Filter by tag'
|
description: 'Filter by tag'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true,
|
root: true,
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -37,8 +37,13 @@ module.exports = Self => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups) => {
|
Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups, options) => {
|
||||||
let conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
|
@ -85,7 +90,7 @@ module.exports = Self => {
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
// Calculate items
|
// Calculate items
|
||||||
const order = await Self.findById(orderFk);
|
const order = await Self.findById(orderFk, null, myOptions);
|
||||||
stmts.push(new ParameterizedSQL(
|
stmts.push(new ParameterizedSQL(
|
||||||
'CALL vn.catalog_calculate(?, ?, ?)', [
|
'CALL vn.catalog_calculate(?, ?, ?)', [
|
||||||
order.landed,
|
order.landed,
|
||||||
|
@ -131,9 +136,9 @@ module.exports = Self => {
|
||||||
params: [orderBy.field],
|
params: [orderBy.field],
|
||||||
});
|
});
|
||||||
|
|
||||||
let way = orderBy.way == 'DESC' ? 'DESC' : 'ASC';
|
const way = orderBy.way == 'DESC' ? 'DESC' : 'ASC';
|
||||||
let tag = await Self.app.models.Tag.findById(orderBy.field);
|
const tag = await Self.app.models.Tag.findById(orderBy.field, null, myOptions);
|
||||||
let orderSql = `
|
const orderSql = `
|
||||||
ORDER BY
|
ORDER BY
|
||||||
itg.value IS NULL,
|
itg.value IS NULL,
|
||||||
${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'}
|
${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'}
|
||||||
|
@ -181,7 +186,7 @@ module.exports = Self => {
|
||||||
stmts.push('CALL vn.ticketCalculatePurge()');
|
stmts.push('CALL vn.ticketCalculatePurge()');
|
||||||
|
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const result = await conn.executeStmt(sql);
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
// Add prices to items
|
// Add prices to items
|
||||||
result[itemsIndex].forEach(item => {
|
result[itemsIndex].forEach(item => {
|
||||||
|
|
|
@ -19,9 +19,29 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.confirm = async(ctx, orderFk) => {
|
Self.confirm = async(ctx, orderFk, option) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
let query = `CALL hedera.order_confirmWithUser(?, ?)`;
|
const myOptions = {};
|
||||||
return await Self.rawSql(query, [orderFk, userId]);
|
let tx;
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const query = `CALL hedera.order_confirmWithUser(?, ?)`;
|
||||||
|
const response = await Self.rawSql(query, [orderFk, userId], myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,60 +9,60 @@ module.exports = Self => {
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'ctx',
|
arg: 'ctx',
|
||||||
type: 'Object',
|
type: 'object',
|
||||||
http: {source: 'context'}
|
http: {source: 'context'}
|
||||||
}, {
|
}, {
|
||||||
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: 'search',
|
arg: 'search',
|
||||||
type: 'String',
|
type: 'string',
|
||||||
description: `If it's and integer searchs by id, otherwise it searchs by nickname`
|
description: `If it's and integer searchs by id, otherwise it searchs by nickname`
|
||||||
}, {
|
}, {
|
||||||
arg: 'from',
|
arg: 'from',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: `The from date`
|
description: 'The from date'
|
||||||
}, {
|
}, {
|
||||||
arg: 'to',
|
arg: 'to',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: `The to date`
|
description: 'The to date'
|
||||||
}, {
|
}, {
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'Integer',
|
type: 'integer',
|
||||||
description: `The ticket id`
|
description: 'The ticket id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'clientFk',
|
arg: 'clientFk',
|
||||||
type: 'Integer',
|
type: 'integer',
|
||||||
description: `The client id`
|
description: 'The client id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'ticketFk',
|
arg: 'ticketFk',
|
||||||
type: 'Integer',
|
type: 'integer',
|
||||||
description: `The ticket id`
|
description: 'The ticket id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'agencyModeFk',
|
arg: 'agencyModeFk',
|
||||||
type: 'Integer',
|
type: 'integer',
|
||||||
description: `The agency mode id`
|
description: 'The agency mode id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'workerFk',
|
arg: 'workerFk',
|
||||||
type: 'Integer',
|
type: 'integer',
|
||||||
description: `The salesperson id`
|
description: 'The salesperson id'
|
||||||
}, {
|
}, {
|
||||||
arg: 'myTeam',
|
arg: 'myTeam',
|
||||||
type: 'Boolean',
|
type: 'boolean',
|
||||||
description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)`
|
description: 'Whether to show only tickets for the current logged user team (currently user tickets)'
|
||||||
}, {
|
}, {
|
||||||
arg: 'isConfirmed',
|
arg: 'isConfirmed',
|
||||||
type: 'Boolean',
|
type: 'boolean',
|
||||||
description: `Order is confirmed`
|
description: 'Order is confirmed'
|
||||||
}, {
|
}, {
|
||||||
arg: 'showEmpty',
|
arg: 'showEmpty',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: `Show empty orders`
|
description: 'Show empty orders'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -71,14 +71,20 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(ctx, filter) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
let conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
let worker = await Self.app.models.Worker.findOne({
|
let worker = await Self.app.models.Worker.findOne({
|
||||||
where: {userFk: ctx.req.accessToken.userId},
|
where: {userFk: ctx.req.accessToken.userId},
|
||||||
include: [
|
include: [
|
||||||
{relation: 'collegues'}
|
{relation: 'collegues'}
|
||||||
]
|
]
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const args = ctx.args;
|
const args = ctx.args;
|
||||||
let teamIds = [];
|
let teamIds = [];
|
||||||
|
|
||||||
|
@ -92,13 +98,15 @@ module.exports = Self => {
|
||||||
worker = await Self.app.models.Worker.findOne({
|
worker = await Self.app.models.Worker.findOne({
|
||||||
fields: ['id'],
|
fields: ['id'],
|
||||||
where: {userFk: ctx.req.accessToken.userId}
|
where: {userFk: ctx.req.accessToken.userId}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
teamIds = [worker && worker.id];
|
teamIds = [worker && worker.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args && args.myTeam)
|
if (args && args.myTeam)
|
||||||
args.teamIds = teamIds;
|
args.teamIds = teamIds;
|
||||||
let where = buildFilter(args, (param, value) => {
|
|
||||||
|
const where = buildFilter(args, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
|
@ -133,7 +141,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(
|
||||||
|
@ -183,7 +191,7 @@ module.exports = Self => {
|
||||||
stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
|
stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
|
||||||
|
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const result = await conn.executeStmt(sql);
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
return result[ordersIndex];
|
return result[ordersIndex];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,51 +1,73 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('order catalogFilter()', () => {
|
describe('order catalogFilter()', () => {
|
||||||
const colorTagId = 1;
|
const colorTagId = 1;
|
||||||
const categoryTagId = 67;
|
const categoryTagId = 67;
|
||||||
|
|
||||||
it('should return an array of items', async() => {
|
it('should return an array of items', async() => {
|
||||||
let filter = {
|
const tx = await models.Order.beginTransaction({});
|
||||||
where: {
|
|
||||||
categoryFk: 1,
|
|
||||||
typeFk: 2
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let 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(4);
|
try {
|
||||||
expect(firstItemId).toEqual(1);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
categoryFk: 1,
|
||||||
|
typeFk: 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const tags = [];
|
||||||
|
const orderFk = 11;
|
||||||
|
const orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
|
||||||
|
const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tags, options);
|
||||||
|
const firstItemId = result[0].id;
|
||||||
|
|
||||||
|
expect(result.length).toEqual(4);
|
||||||
|
expect(firstItemId).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should now return an array of items based on tag filter', async() => {
|
it('should now return an array of items based on tag filter', async() => {
|
||||||
const filter = {
|
const tx = await models.Order.beginTransaction({});
|
||||||
where: {
|
|
||||||
categoryFk: 1,
|
|
||||||
typeFk: 2
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const tagGroups = [
|
try {
|
||||||
{tagFk: colorTagId, values: [{value: 'Silver'}, {value: 'Brown'}]},
|
const options = {transaction: tx};
|
||||||
{tagFk: categoryTagId, values: [{value: 'Concussion'}]}
|
|
||||||
];
|
|
||||||
const orderFk = 11;
|
|
||||||
const orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
|
|
||||||
const result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups);
|
|
||||||
|
|
||||||
const randomIndex = Math.round(Math.random());
|
const filter = {
|
||||||
const item = result[randomIndex];
|
where: {
|
||||||
const itemTags = item.tags;
|
categoryFk: 1,
|
||||||
|
typeFk: 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const colorTag = itemTags.find(tag => tag.tagFk == colorTagId);
|
const tagGroups = [
|
||||||
const categoryTag = itemTags.find(tag => tag.tagFk == categoryTagId);
|
{tagFk: colorTagId, values: [{value: 'Silver'}, {value: 'Brown'}]},
|
||||||
|
{tagFk: categoryTagId, values: [{value: 'Concussion'}]}
|
||||||
|
];
|
||||||
|
const orderFk = 11;
|
||||||
|
const orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
|
||||||
|
const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(2);
|
const randomIndex = Math.round(Math.random());
|
||||||
expect(colorTag.value).toEqual('Silver');
|
const item = result[randomIndex];
|
||||||
expect(categoryTag.value).toEqual('Concussion');
|
const itemTags = item.tags;
|
||||||
|
|
||||||
|
const colorTag = itemTags.find(tag => tag.tagFk == colorTagId);
|
||||||
|
const categoryTag = itemTags.find(tag => tag.tagFk == categoryTagId);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
expect(colorTag.value).toEqual('Silver');
|
||||||
|
expect(categoryTag.value).toEqual('Concussion');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue