item module transactions
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
parent
dd3473b93d
commit
21e34de1dd
|
@ -80,12 +80,12 @@ module.exports = Self => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'mine',
|
arg: 'mine',
|
||||||
type: 'Boolean',
|
type: 'boolean',
|
||||||
description: `Search requests attended by the current user`
|
description: `Search requests attended by the current user`
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -94,9 +94,13 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(ctx, filter) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
let userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (ctx.args.mine)
|
if (ctx.args.mine)
|
||||||
ctx.args.buyerFk = userId;
|
ctx.args.buyerFk = userId;
|
||||||
|
@ -128,36 +132,35 @@ module.exports = Self => {
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
const stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(`
|
||||||
`SELECT fp.id,
|
SELECT fp.id,
|
||||||
fp.itemFk,
|
fp.itemFk,
|
||||||
fp.warehouseFk,
|
fp.warehouseFk,
|
||||||
fp.rate2,
|
fp.rate2,
|
||||||
fp.rate3,
|
fp.rate3,
|
||||||
fp.started,
|
fp.started,
|
||||||
fp.ended,
|
fp.ended,
|
||||||
i.minPrice,
|
i.minPrice,
|
||||||
i.hasMinPrice,
|
i.hasMinPrice,
|
||||||
i.name,
|
i.name,
|
||||||
i.subName,
|
i.subName,
|
||||||
i.tag5,
|
i.tag5,
|
||||||
i.value5,
|
i.value5,
|
||||||
i.tag6,
|
i.tag6,
|
||||||
i.value6,
|
i.value6,
|
||||||
i.tag7,
|
i.tag7,
|
||||||
i.value7,
|
i.value7,
|
||||||
i.tag8,
|
i.tag8,
|
||||||
i.value8,
|
i.value8,
|
||||||
i.tag9,
|
i.tag9,
|
||||||
i.value9,
|
i.value9,
|
||||||
i.tag10,
|
i.tag10,
|
||||||
i.value10
|
i.value10
|
||||||
FROM priceFixed fp
|
FROM priceFixed fp
|
||||||
JOIN item i ON i.id = fp.itemFk
|
JOIN item i ON i.id = fp.itemFk
|
||||||
JOIN itemType it ON it.id = i.typeFk`
|
JOIN itemType it ON it.id = i.typeFk
|
||||||
);
|
`);
|
||||||
|
|
||||||
if (ctx.args.tags) {
|
if (ctx.args.tags) {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
|
@ -186,7 +189,8 @@ module.exports = Self => {
|
||||||
|
|
||||||
const fixedPriceIndex = stmts.push(stmt) - 1;
|
const fixedPriceIndex = stmts.push(stmt) - 1;
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const result = await conn.executeStmt(sql);
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
return fixedPriceIndex === 0 ? result : result[fixedPriceIndex];
|
return fixedPriceIndex === 0 ? result : result[fixedPriceIndex];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,86 +1,136 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('fixed price filter()', () => {
|
describe('fixed price filter()', () => {
|
||||||
it('should return 1 result filtering by item ID', async() => {
|
it('should return 1 result filtering by item ID', async() => {
|
||||||
const itemID = 3;
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
const ctx = {
|
|
||||||
req: {accessToken: {userId: 1}},
|
|
||||||
args: {
|
|
||||||
search: itemID
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const result = await app.models.FixedPrice.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
try {
|
||||||
expect(result[0].id).toEqual(2);
|
const options = {transaction: tx};
|
||||||
expect(result[0].itemFk).toEqual(itemID);
|
const itemID = 3;
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 1}},
|
||||||
|
args: {
|
||||||
|
search: itemID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(result[0].id).toEqual(2);
|
||||||
|
expect(result[0].itemFk).toEqual(itemID);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 1 result filtering by item type code', async() => {
|
it('should return 1 result filtering by item type code', async() => {
|
||||||
const itemCode = 'CRI';
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
const ctx = {
|
|
||||||
req: {accessToken: {userId: 1}},
|
|
||||||
args: {
|
|
||||||
search: itemCode
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const itemType = await app.models.ItemType.findOne({
|
|
||||||
where: {code: itemCode},
|
|
||||||
fields: ['id']
|
|
||||||
});
|
|
||||||
const items = await app.models.Item.find({
|
|
||||||
where: {typeFk: itemType.id},
|
|
||||||
fields: ['id']
|
|
||||||
});
|
|
||||||
const IDs = items.map(item => {
|
|
||||||
return item.id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await app.models.FixedPrice.filter(ctx);
|
try {
|
||||||
const firstResult = result[0];
|
const options = {transaction: tx};
|
||||||
|
const itemCode = 'CRI';
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 1}},
|
||||||
|
args: {
|
||||||
|
search: itemCode
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const itemType = await models.ItemType.findOne({
|
||||||
|
where: {code: itemCode},
|
||||||
|
fields: ['id']
|
||||||
|
}, options);
|
||||||
|
const items = await models.Item.find({
|
||||||
|
where: {typeFk: itemType.id},
|
||||||
|
fields: ['id']
|
||||||
|
}, options);
|
||||||
|
const IDs = items.map(item => {
|
||||||
|
return item.id;
|
||||||
|
});
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
expect(firstResult.id).toEqual(2);
|
const firstResult = result[0];
|
||||||
expect(IDs).toContain(firstResult.itemFk);
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(firstResult.id).toEqual(2);
|
||||||
|
expect(IDs).toContain(firstResult.itemFk);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 2 results filtering by warehouse', async() => {
|
it('should return 2 results filtering by warehouse', async() => {
|
||||||
const warehouseID = 1;
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
const ctx = {
|
|
||||||
req: {accessToken: {userId: 1}},
|
|
||||||
args: {
|
|
||||||
warehouseFk: warehouseID
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const result = await app.models.FixedPrice.filter(ctx);
|
|
||||||
const length = result.length;
|
|
||||||
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
|
||||||
|
|
||||||
expect(result.length).toEqual(2);
|
try {
|
||||||
expect(anyResult.warehouseFk).toEqual(warehouseID);
|
const options = {transaction: tx};
|
||||||
|
const warehouseID = 1;
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 1}},
|
||||||
|
args: {
|
||||||
|
warehouseFk: warehouseID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
|
const length = result.length;
|
||||||
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
expect(anyResult.warehouseFk).toEqual(warehouseID);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no results filtering by hasMinPrice', async() => {
|
it('should return no results filtering by hasMinPrice', async() => {
|
||||||
const ctx = {
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
req: {accessToken: {userId: 1}},
|
|
||||||
args: {
|
|
||||||
hasMinPrice: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const result = await app.models.FixedPrice.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(0);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 1}},
|
||||||
|
args: {
|
||||||
|
hasMinPrice: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no results filtering by typeFk', async() => {
|
it('should return no results filtering by typeFk', async() => {
|
||||||
const ctx = {
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
req: {accessToken: {userId: 1}},
|
|
||||||
args: {
|
|
||||||
typeFk: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const result = await app.models.FixedPrice.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 1}},
|
||||||
|
args: {
|
||||||
|
typeFk: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,62 +1,75 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('upsertFixedPrice()', () => {
|
describe('upsertFixedPrice()', () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const fixedPriceId = 1;
|
const fixedPriceId = 1;
|
||||||
let originalFixedPrice;
|
let originalFixedPrice;
|
||||||
let originalItem;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
originalFixedPrice = await app.models.FixedPrice.findById(fixedPriceId);
|
originalFixedPrice = await models.FixedPrice.findById(fixedPriceId);
|
||||||
originalItem = await app.models.Item.findById(originalFixedPrice.itemFk);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await originalFixedPrice.save();
|
|
||||||
await originalItem.save();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should toggle the hasMinPrice boolean if there's a minPrice and update the rest of the data`, async() => {
|
it(`should toggle the hasMinPrice boolean if there's a minPrice and update the rest of the data`, async() => {
|
||||||
const ctx = {args: {
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
id: fixedPriceId,
|
|
||||||
itemFk: originalFixedPrice.itemFk,
|
|
||||||
warehouseFk: 1,
|
|
||||||
rate2: 100,
|
|
||||||
rate3: 300,
|
|
||||||
started: now,
|
|
||||||
ended: now,
|
|
||||||
minPrice: 100,
|
|
||||||
hasMinPrice: false
|
|
||||||
}};
|
|
||||||
|
|
||||||
const result = await app.models.FixedPrice.upsertFixedPrice(ctx, ctx.args.id);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {args: {
|
||||||
|
id: fixedPriceId,
|
||||||
|
itemFk: originalFixedPrice.itemFk,
|
||||||
|
warehouseFk: 1,
|
||||||
|
rate2: 100,
|
||||||
|
rate3: 300,
|
||||||
|
started: now,
|
||||||
|
ended: now,
|
||||||
|
minPrice: 100,
|
||||||
|
hasMinPrice: false
|
||||||
|
}};
|
||||||
|
|
||||||
delete ctx.args.started;
|
const result = await models.FixedPrice.upsertFixedPrice(ctx, options);
|
||||||
delete ctx.args.ended;
|
|
||||||
ctx.args.hasMinPrice = true;
|
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.objectContaining(ctx.args));
|
delete ctx.args.started;
|
||||||
|
delete ctx.args.ended;
|
||||||
|
ctx.args.hasMinPrice = true;
|
||||||
|
|
||||||
|
expect(result).toEqual(jasmine.objectContaining(ctx.args));
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should toggle the hasMinPrice boolean if there's no minPrice and update the rest of the data`, async() => {
|
it(`should toggle the hasMinPrice boolean if there's no minPrice and update the rest of the data`, async() => {
|
||||||
const ctx = {args: {
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
id: fixedPriceId,
|
|
||||||
itemFk: originalFixedPrice.itemFk,
|
|
||||||
warehouseFk: 1,
|
|
||||||
rate2: 2.5,
|
|
||||||
rate3: 2,
|
|
||||||
started: now,
|
|
||||||
ended: now,
|
|
||||||
minPrice: 0,
|
|
||||||
hasMinPrice: true
|
|
||||||
}};
|
|
||||||
|
|
||||||
const result = await app.models.FixedPrice.upsertFixedPrice(ctx, ctx.args.id);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {args: {
|
||||||
|
id: fixedPriceId,
|
||||||
|
itemFk: originalFixedPrice.itemFk,
|
||||||
|
warehouseFk: 1,
|
||||||
|
rate2: 2.5,
|
||||||
|
rate3: 2,
|
||||||
|
started: now,
|
||||||
|
ended: now,
|
||||||
|
minPrice: 0,
|
||||||
|
hasMinPrice: true
|
||||||
|
}};
|
||||||
|
|
||||||
delete ctx.args.started;
|
const result = await models.FixedPrice.upsertFixedPrice(ctx, options);
|
||||||
delete ctx.args.ended;
|
|
||||||
ctx.args.hasMinPrice = false;
|
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.objectContaining(ctx.args));
|
delete ctx.args.started;
|
||||||
|
delete ctx.args.ended;
|
||||||
|
ctx.args.hasMinPrice = false;
|
||||||
|
|
||||||
|
expect(result).toEqual(jasmine.objectContaining(ctx.args));
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,48 +2,50 @@ module.exports = Self => {
|
||||||
Self.remoteMethod('upsertFixedPrice', {
|
Self.remoteMethod('upsertFixedPrice', {
|
||||||
description: 'Inserts or updates a fixed price for an item',
|
description: 'Inserts or updates a fixed price for an item',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [
|
||||||
arg: 'ctx',
|
{
|
||||||
type: 'object',
|
arg: 'ctx',
|
||||||
http: {source: 'context'}
|
type: 'object',
|
||||||
},
|
http: {source: 'context'}
|
||||||
{
|
},
|
||||||
arg: 'id',
|
{
|
||||||
type: 'number',
|
arg: 'id',
|
||||||
description: 'The fixed price id'
|
type: 'number',
|
||||||
},
|
description: 'The fixed price id'
|
||||||
{
|
},
|
||||||
arg: 'itemFk',
|
{
|
||||||
type: 'number'
|
arg: 'itemFk',
|
||||||
},
|
type: 'number'
|
||||||
{
|
},
|
||||||
arg: 'warehouseFk',
|
{
|
||||||
type: 'number'
|
arg: 'warehouseFk',
|
||||||
},
|
type: 'number'
|
||||||
{
|
},
|
||||||
arg: 'started',
|
{
|
||||||
type: 'date'
|
arg: 'started',
|
||||||
},
|
type: 'date'
|
||||||
{
|
},
|
||||||
arg: 'ended',
|
{
|
||||||
type: 'date'
|
arg: 'ended',
|
||||||
},
|
type: 'date'
|
||||||
{
|
},
|
||||||
arg: 'rate2',
|
{
|
||||||
type: 'number'
|
arg: 'rate2',
|
||||||
},
|
type: 'number'
|
||||||
{
|
},
|
||||||
arg: 'rate3',
|
{
|
||||||
type: 'number'
|
arg: 'rate3',
|
||||||
},
|
type: 'number'
|
||||||
{
|
},
|
||||||
arg: 'minPrice',
|
{
|
||||||
type: 'number'
|
arg: 'minPrice',
|
||||||
},
|
type: 'number'
|
||||||
{
|
},
|
||||||
arg: 'hasMinPrice',
|
{
|
||||||
type: 'any'
|
arg: 'hasMinPrice',
|
||||||
}],
|
type: 'any'
|
||||||
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
root: true
|
root: true
|
||||||
|
@ -54,21 +56,29 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.upsertFixedPrice = async ctx => {
|
Self.upsertFixedPrice = async(ctx, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const args = ctx.args;
|
const args = ctx.args;
|
||||||
const tx = await models.Address.beginTransaction({});
|
let tx;
|
||||||
try {
|
const myOptions = {};
|
||||||
const options = {transaction: tx};
|
|
||||||
delete args.ctx; // removed unwanted data
|
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
delete args.ctx; // removed unwanted data
|
||||||
const fixedPrice = await models.FixedPrice.upsert(args, options);
|
const fixedPrice = await models.FixedPrice.upsert(args, options);
|
||||||
const targetItem = await models.Item.findById(args.itemFk, null, options);
|
const targetItem = await models.Item.findById(args.itemFk, null, options);
|
||||||
|
|
||||||
await targetItem.updateAttributes({
|
await targetItem.updateAttributes({
|
||||||
minPrice: args.minPrice,
|
minPrice: args.minPrice,
|
||||||
hasMinPrice: args.minPrice ? true : false
|
hasMinPrice: args.minPrice ? true : false
|
||||||
}, options);
|
}, myOptions);
|
||||||
|
|
||||||
const itemFields = [
|
const itemFields = [
|
||||||
'minPrice',
|
'minPrice',
|
||||||
|
@ -99,16 +109,17 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await models.FixedPrice.findById(fixedPrice.id, filter, options);
|
const result = await models.FixedPrice.findById(fixedPrice.id, filter, myOptions);
|
||||||
const item = result.item();
|
const item = result.item();
|
||||||
|
|
||||||
for (let key of itemFields)
|
for (let key of itemFields)
|
||||||
result[key] = item[key];
|
result[key] = item[key];
|
||||||
|
|
||||||
await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item-barcode toItem()', () => {
|
describe('item-barcode toItem()', () => {
|
||||||
it('should return the same number if there is a barcode and a item with the same ID', async() => {
|
it('should return the same number if there is a barcode and a item with the same ID', async() => {
|
||||||
let barcode = 3;
|
const tx = await models.Item.beginTransaction({});
|
||||||
let result = await app.models.ItemBarcode.toItem(barcode);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result).toBe(3);
|
try {
|
||||||
|
const barcode = 3;
|
||||||
|
const result = await models.ItemBarcode.toItem(barcode, options);
|
||||||
|
|
||||||
|
expect(result).toBe(3);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,12 +4,12 @@ module.exports = Self => {
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'barcode',
|
arg: 'barcode',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'barcode'
|
description: 'barcode'
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -18,11 +18,18 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.toItem = async barcode => {
|
Self.toItem = async(barcode, options) => {
|
||||||
let query = `SELECT vn.barcodeToItem(?)`;
|
const myOptions = {};
|
||||||
let [item] = await Self.rawSql(query, [barcode]);
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const query = `SELECT vn.barcodeToItem(?)`;
|
||||||
|
let [item] = await Self.rawSql(query, [barcode], myOptions);
|
||||||
|
|
||||||
if (item)
|
if (item)
|
||||||
item = Object.values(item);
|
item = Object.values(item)[0];
|
||||||
return item[0];
|
|
||||||
|
return item;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,17 +5,19 @@ module.exports = Self => {
|
||||||
Self.remoteMethod('filterItemTags', {
|
Self.remoteMethod('filterItemTags', {
|
||||||
description: 'Returns the distinct values of a tag property',
|
description: 'Returns the distinct values of a tag property',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [
|
||||||
arg: 'tagFk',
|
{
|
||||||
type: 'number',
|
arg: 'tagFk',
|
||||||
required: true,
|
type: 'number',
|
||||||
description: 'The foreign key from tag table',
|
required: true,
|
||||||
http: {source: 'path'}
|
description: 'The foreign key from tag table',
|
||||||
}, {
|
http: {source: 'path'}
|
||||||
arg: 'filter',
|
}, {
|
||||||
type: 'Object',
|
arg: 'filter',
|
||||||
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
type: 'object',
|
||||||
}],
|
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
||||||
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
root: true,
|
root: true,
|
||||||
type: ['object']
|
type: ['object']
|
||||||
|
@ -26,16 +28,21 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filterItemTags = async(tagFk, filter) => {
|
Self.filterItemTags = async(tagFk, filter, options) => {
|
||||||
let conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
let where = {tagFk: tagFk};
|
const myOptions = {};
|
||||||
myFilter = mergeFilters(filter, {where});
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const where = {tagFk: tagFk};
|
||||||
|
const myFilter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`SELECT DISTINCT(value)
|
`SELECT DISTINCT(value)
|
||||||
FROM itemTag`);
|
FROM itemTag`);
|
||||||
stmt.merge(conn.makeSuffix(myFilter));
|
stmt.merge(conn.makeSuffix(myFilter));
|
||||||
|
|
||||||
return await conn.executeStmt(stmt);
|
return conn.executeStmt(stmt, myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item filterItemTags()', () => {
|
describe('item filterItemTags()', () => {
|
||||||
it('should filter ItemTags table', async() => {
|
it('should filter ItemTags table', async() => {
|
||||||
let [result] = await app.models.ItemTag.filterItemTags(1, {});
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.value).toEqual('Black');
|
try {
|
||||||
|
const [result] = await models.ItemTag.filterItemTags(1, null, options);
|
||||||
|
|
||||||
|
expect(result.value).toEqual('Black');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = Self => {
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'Object',
|
type: 'object',
|
||||||
description: 'new cloned itemId',
|
description: 'new cloned itemId',
|
||||||
root: true,
|
root: true,
|
||||||
},
|
},
|
||||||
|
@ -22,13 +22,21 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.clone = async itemId => {
|
Self.clone = async(itemId, options) => {
|
||||||
let tx = await Self.beginTransaction({});
|
let tx;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
const origin = await Self.findById(itemId, null, myOptions);
|
||||||
|
|
||||||
const origin = await Self.findById(itemId, null, options);
|
|
||||||
if (!origin)
|
if (!origin)
|
||||||
throw new UserError(`This item doesn't exists`);
|
throw new UserError(`This item doesn't exists`);
|
||||||
|
|
||||||
|
@ -38,16 +46,17 @@ module.exports = Self => {
|
||||||
origin.comment = undefined;
|
origin.comment = undefined;
|
||||||
origin.size = undefined;
|
origin.size = undefined;
|
||||||
|
|
||||||
const newItem = await Self.create(origin, options);
|
const newItem = await Self.create(origin, myOptions);
|
||||||
|
|
||||||
await cloneTaxes(origin.id, newItem.id, options);
|
await cloneTaxes(origin.id, newItem.id, myOptions);
|
||||||
await cloneBotanical(origin.id, newItem.id, options);
|
await cloneBotanical(origin.id, newItem.id, myOptions);
|
||||||
await cloneTags(origin.id, newItem.id, options);
|
await cloneTags(origin.id, newItem.id, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
await tx.commit();
|
|
||||||
return newItem;
|
return newItem;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,23 +2,25 @@ module.exports = Self => {
|
||||||
Self.remoteMethod('createIntrastat', {
|
Self.remoteMethod('createIntrastat', {
|
||||||
description: 'Creates a new item intrastat',
|
description: 'Creates a new item intrastat',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [
|
||||||
arg: 'id',
|
{
|
||||||
type: 'number',
|
arg: 'id',
|
||||||
required: true,
|
type: 'number',
|
||||||
description: 'The item id',
|
required: true,
|
||||||
http: {source: 'path'}
|
description: 'The item id',
|
||||||
},
|
http: {source: 'path'}
|
||||||
{
|
},
|
||||||
arg: 'intrastatId',
|
{
|
||||||
type: 'number',
|
arg: 'intrastatId',
|
||||||
required: true
|
type: 'number',
|
||||||
},
|
required: true
|
||||||
{
|
},
|
||||||
arg: 'description',
|
{
|
||||||
type: 'string',
|
arg: 'description',
|
||||||
required: true
|
type: 'string',
|
||||||
}],
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
root: true
|
root: true
|
||||||
|
@ -29,31 +31,52 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.createIntrastat = async(id, intrastatId, description) => {
|
Self.createIntrastat = async(id, intrastatId, description, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const country = await models.Country.findOne({
|
const myOptions = {};
|
||||||
where: {code: 'ES'}
|
let tx;
|
||||||
});
|
|
||||||
|
|
||||||
const itemTaxCountry = await models.ItemTaxCountry.findOne({
|
if (typeof options == 'object')
|
||||||
where: {
|
Object.assign(myOptions, options);
|
||||||
itemFk: id,
|
|
||||||
countryFk: country.id
|
|
||||||
},
|
|
||||||
order: 'effectived DESC'
|
|
||||||
});
|
|
||||||
const taxClassCode = await models.TaxClassCode.findOne({
|
|
||||||
where: {
|
|
||||||
taxClassFk: itemTaxCountry.taxClassFk
|
|
||||||
},
|
|
||||||
order: 'effectived DESC'
|
|
||||||
});
|
|
||||||
|
|
||||||
return models.Intrastat.create({
|
if (!myOptions.transaction) {
|
||||||
id: intrastatId,
|
tx = await Self.beginTransaction({});
|
||||||
description: description,
|
myOptions.transaction = tx;
|
||||||
taxClassFk: itemTaxCountry.taxClassFk,
|
}
|
||||||
taxCodeFk: taxClassCode.taxCodeFk
|
|
||||||
});
|
try {
|
||||||
|
const country = await models.Country.findOne({
|
||||||
|
where: {code: 'ES'}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const itemTaxCountry = await models.ItemTaxCountry.findOne({
|
||||||
|
where: {
|
||||||
|
itemFk: id,
|
||||||
|
countryFk: country.id
|
||||||
|
},
|
||||||
|
order: 'effectived DESC'
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const taxClassCode = await models.TaxClassCode.findOne({
|
||||||
|
where: {
|
||||||
|
taxClassFk: itemTaxCountry.taxClassFk
|
||||||
|
},
|
||||||
|
order: 'effectived DESC'
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const intrastat = await models.Intrastat.create({
|
||||||
|
id: intrastatId,
|
||||||
|
description: description,
|
||||||
|
taxClassFk: itemTaxCountry.taxClassFk,
|
||||||
|
taxCodeFk: taxClassCode.taxCodeFk
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return intrastat;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,7 +71,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.filter = async(ctx, filter, options) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
let myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
@ -83,7 +83,9 @@ module.exports = Self => {
|
||||||
where: {code: ctx.args.search},
|
where: {code: ctx.args.search},
|
||||||
fields: ['itemFk']
|
fields: ['itemFk']
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const itemIds = [];
|
const itemIds = [];
|
||||||
|
|
||||||
for (const item of items)
|
for (const item of items)
|
||||||
itemIds.push(item.itemFk);
|
itemIds.push(item.itemFk);
|
||||||
|
|
||||||
|
@ -116,12 +118,11 @@ module.exports = Self => {
|
||||||
return {'intr.description': value};
|
return {'intr.description': value};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
const stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
const stmt = new ParameterizedSQL(
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
|
||||||
`SELECT
|
`SELECT
|
||||||
i.id,
|
i.id,
|
||||||
i.image,
|
i.image,
|
||||||
|
|
|
@ -19,9 +19,15 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getBalance = async filter => {
|
Self.getBalance = async(filter, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const where = filter.where;
|
const where = filter.where;
|
||||||
let [diary] = await Self.rawSql(`CALL vn.item_getBalance(?, ?)`, [where.itemFk, where.warehouseFk]);
|
const query = 'CALL vn.item_getBalance(?, ?)';
|
||||||
|
const [diary] = await Self.rawSql(query, [where.itemFk, where.warehouseFk], myOptions);
|
||||||
|
|
||||||
for (const entry of diary)
|
for (const entry of diary)
|
||||||
if (entry.clientType === 'loses') entry.highlighted = true;
|
if (entry.clientType === 'loses') entry.highlighted = true;
|
||||||
|
|
|
@ -19,12 +19,13 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getCard = async id => {
|
Self.getCard = async(id, options) => {
|
||||||
let item = {};
|
const myOptions = {};
|
||||||
|
|
||||||
// Item basic data
|
if (typeof options == 'object')
|
||||||
let filter = {
|
Object.assign(myOptions, options);
|
||||||
where: {id: id},
|
|
||||||
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'itemType',
|
relation: 'itemType',
|
||||||
|
@ -58,8 +59,8 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
[item] = await Self.app.models.Item.find(filter);
|
const item = await Self.app.models.Item.findById(id, filter, myOptions);
|
||||||
|
|
||||||
return item;
|
return item ? item : {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,14 +19,18 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getSummary = async(ctx, id) => {
|
Self.getSummary = async(ctx, id, options) => {
|
||||||
let promises = [];
|
|
||||||
let summary = {};
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
const summary = {};
|
||||||
|
|
||||||
// Item basic data and taxes
|
// Item basic data and taxes
|
||||||
let filter = {
|
let filter = {
|
||||||
where: {id: id},
|
|
||||||
include: [
|
include: [
|
||||||
{relation: 'itemType',
|
{relation: 'itemType',
|
||||||
scope: {
|
scope: {
|
||||||
|
@ -67,7 +71,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
promises.push(models.Item.find(filter));
|
promises.push(models.Item.findById(id, filter, myOptions));
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
filter = {
|
filter = {
|
||||||
|
@ -79,35 +83,36 @@ module.exports = Self => {
|
||||||
relation: 'tag'
|
relation: 'tag'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
promises.push(models.ItemTag.find(filter));
|
promises.push(models.ItemTag.find(filter, myOptions));
|
||||||
|
|
||||||
// Botanical
|
// Botanical
|
||||||
filter = {
|
filter = {
|
||||||
where: {itemFk: id},
|
where: {itemFk: id},
|
||||||
include: [{relation: 'genus'}, {relation: 'specie'}]
|
include: [{relation: 'genus'}, {relation: 'specie'}]
|
||||||
};
|
};
|
||||||
promises.push(models.ItemBotanical.find(filter));
|
promises.push(models.ItemBotanical.find(filter, myOptions));
|
||||||
|
|
||||||
// Niches
|
// Niches
|
||||||
filter = {
|
filter = {
|
||||||
where: {itemFk: id},
|
where: {itemFk: id},
|
||||||
include: {relation: 'warehouse'}
|
include: {relation: 'warehouse'}
|
||||||
};
|
};
|
||||||
promises.push(models.ItemNiche.find(filter));
|
promises.push(models.ItemNiche.find(filter, myOptions));
|
||||||
|
|
||||||
let res = await Promise.all(promises);
|
let res = await Promise.all(promises);
|
||||||
|
|
||||||
[summary.item] = res[0];
|
summary.item = res[0];
|
||||||
summary.tags = res[1];
|
summary.tags = res[1];
|
||||||
[summary.botanical] = res[2];
|
[summary.botanical] = res[2];
|
||||||
summary.niches = res[3];
|
summary.niches = res[3];
|
||||||
|
|
||||||
const userConfig = await models.UserConfig.getUserConfig(ctx);
|
const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions);
|
||||||
|
|
||||||
res = await models.Item.getVisibleAvailable(summary.item.id, userConfig.warehouseFk);
|
res = await models.Item.getVisibleAvailable(summary.item.id, userConfig.warehouseFk, null, myOptions);
|
||||||
|
|
||||||
summary.available = res.available;
|
summary.available = res.available;
|
||||||
summary.visible = res.visible;
|
summary.visible = res.visible;
|
||||||
|
|
||||||
return summary;
|
return summary;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,19 +5,20 @@ module.exports = Self => {
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'warehouseFk',
|
arg: 'warehouseFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'dated',
|
arg: 'dated',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
required: false,
|
required: false,
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
|
@ -28,32 +29,43 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getVisibleAvailable = async(id, warehouseFk, dated = new Date()) => {
|
Self.getVisibleAvailable = async(id, warehouseFk, dated = new Date(), options) => {
|
||||||
let stmts = [];
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const stmts = [];
|
||||||
|
|
||||||
stmts.push(new ParameterizedSQL(
|
stmts.push(new ParameterizedSQL(
|
||||||
'CALL cache.available_refresh(@availableCalc, FALSE, ?, ?)', [
|
'CALL cache.available_refresh(@availableCalc, FALSE, ?, ?)',
|
||||||
|
[
|
||||||
warehouseFk,
|
warehouseFk,
|
||||||
dated
|
dated
|
||||||
]
|
],
|
||||||
|
myOptions
|
||||||
));
|
));
|
||||||
|
|
||||||
stmts.push(new ParameterizedSQL(
|
stmts.push(new ParameterizedSQL(
|
||||||
'CALL cache.visible_refresh(@visibleCalc, FALSE,?)', [
|
'CALL cache.visible_refresh(@visibleCalc, FALSE,?)', [
|
||||||
warehouseFk
|
warehouseFk
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
const visibleIndex = stmts.push(new ParameterizedSQL(
|
const visibleIndex = stmts.push(new ParameterizedSQL(
|
||||||
'SELECT visible FROM cache.visible WHERE calc_id = @visibleCalc AND item_id = ?', [
|
'SELECT visible FROM cache.visible WHERE calc_id = @visibleCalc AND item_id = ?',
|
||||||
id
|
[id],
|
||||||
]
|
myOptions
|
||||||
)) - 1;
|
)) - 1;
|
||||||
|
|
||||||
const availableIndex = stmts.push(new ParameterizedSQL(
|
const availableIndex = stmts.push(new ParameterizedSQL(
|
||||||
'SELECT available FROM cache.available WHERE calc_id = @availableCalc AND item_id = ?', [
|
'SELECT available FROM cache.available WHERE calc_id = @availableCalc AND item_id = ?',
|
||||||
id
|
[id],
|
||||||
]
|
myOptions
|
||||||
)) - 1;
|
)) - 1;
|
||||||
|
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
let res = await Self.rawStmt(sql);
|
const res = await Self.rawStmt(sql, myOptions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
available: res[availableIndex][0] ? res[availableIndex][0].available : 0,
|
available: res[availableIndex][0] ? res[availableIndex][0].available : 0,
|
||||||
|
|
|
@ -17,7 +17,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -26,7 +26,12 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getWasteByItem = async(buyer, family) => {
|
Self.getWasteByItem = async(buyer, family, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const wastes = await Self.rawSql(`
|
const wastes = await Self.rawSql(`
|
||||||
SELECT *, 100 * dwindle / total AS percentage
|
SELECT *, 100 * dwindle / total AS percentage
|
||||||
FROM (
|
FROM (
|
||||||
|
@ -41,7 +46,7 @@ module.exports = Self => {
|
||||||
AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1)
|
AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1)
|
||||||
GROUP BY buyer, itemFk
|
GROUP BY buyer, itemFk
|
||||||
) sub
|
) sub
|
||||||
ORDER BY family, percentage DESC`, [buyer, family]);
|
ORDER BY family, percentage DESC`, [buyer, family], myOptions);
|
||||||
|
|
||||||
const details = [];
|
const details = [];
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ module.exports = Self => {
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [],
|
accepts: [],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -13,7 +13,12 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getWasteByWorker = async() => {
|
Self.getWasteByWorker = async options => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const wastes = await Self.rawSql(`
|
const wastes = await Self.rawSql(`
|
||||||
SELECT *, 100 * dwindle / total AS percentage
|
SELECT *, 100 * dwindle / total AS percentage
|
||||||
FROM (
|
FROM (
|
||||||
|
@ -26,7 +31,7 @@ module.exports = Self => {
|
||||||
AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1)
|
AND week = WEEK(TIMESTAMPADD(WEEK,-1,CURDATE()), 1)
|
||||||
GROUP BY buyer, family
|
GROUP BY buyer, family
|
||||||
) sub
|
) sub
|
||||||
ORDER BY percentage DESC`);
|
ORDER BY percentage DESC`, null, myOptions);
|
||||||
|
|
||||||
const details = [];
|
const details = [];
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,13 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.lastEntriesFilter = async filter => {
|
Self.lastEntriesFilter = async(filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT
|
`SELECT
|
||||||
w.id AS warehouseFk,
|
w.id AS warehouseFk,
|
||||||
|
@ -64,6 +69,6 @@ module.exports = Self => {
|
||||||
LEFT JOIN edi.ekt ek ON b.ektFk = ek.id`);
|
LEFT JOIN edi.ekt ek ON b.ektFk = ek.id`);
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
||||||
return conn.executeStmt(stmt);
|
return conn.executeStmt(stmt, myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ let UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('new', {
|
Self.remoteMethod('new', {
|
||||||
description: 'Create a new item and returns the new ID',
|
description: 'returns the created item',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'params',
|
arg: 'params',
|
||||||
|
@ -19,8 +19,20 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.new = async params => {
|
Self.new = async(params, options) => {
|
||||||
let validUpdateParams = [
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validUpdateParams = [
|
||||||
'provisionalName',
|
'provisionalName',
|
||||||
'typeFk',
|
'typeFk',
|
||||||
'intrastatFk',
|
'intrastatFk',
|
||||||
|
@ -33,20 +45,21 @@ module.exports = Self => {
|
||||||
throw new UserError(`You don't have enough privileges to do that`);
|
throw new UserError(`You don't have enough privileges to do that`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx = await Self.beginTransaction({});
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
const provisionalName = params.provisionalName;
|
||||||
|
|
||||||
let provisionalName = params.provisionalName;
|
|
||||||
delete params.provisionalName;
|
delete params.provisionalName;
|
||||||
|
|
||||||
let item = await Self.app.models.Item.create(params, options);
|
const item = await models.Item.create(params, myOptions);
|
||||||
|
|
||||||
|
const typeTags = await models.ItemTypeTag.find({
|
||||||
|
where: {itemTypeFk: item.typeFk}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
let typeTags = await Self.app.models.ItemTypeTag.find({where: {itemTypeFk: item.typeFk}});
|
|
||||||
let query = `SET @isTriggerDisabled = TRUE`;
|
let query = `SET @isTriggerDisabled = TRUE`;
|
||||||
await Self.rawSql(query, null, options);
|
|
||||||
|
|
||||||
let nameTag = await Self.app.models.Tag.findOne({where: {name: 'Nombre temporal'}});
|
await Self.rawSql(query, null, myOptions);
|
||||||
|
|
||||||
|
let nameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}});
|
||||||
|
|
||||||
let newTags = [];
|
let newTags = [];
|
||||||
|
|
||||||
|
@ -55,17 +68,19 @@ module.exports = Self => {
|
||||||
newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority});
|
newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority});
|
||||||
});
|
});
|
||||||
|
|
||||||
await Self.app.models.ItemTag.create(newTags, options);
|
await models.ItemTag.create(newTags, myOptions);
|
||||||
|
|
||||||
query = `SET @isTriggerDisabled = FALSE`;
|
query = `SET @isTriggerDisabled = FALSE`;
|
||||||
await Self.rawSql(query, null, options);
|
await Self.rawSql(query, null, myOptions);
|
||||||
|
|
||||||
query = `CALL vn.itemRefreshTags(?)`;
|
query = `CALL vn.itemRefreshTags(?)`;
|
||||||
await Self.rawSql(query, [item.id], options);
|
await Self.rawSql(query, [item.id], myOptions);
|
||||||
await tx.commit();
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,22 +2,26 @@ module.exports = Self => {
|
||||||
Self.remoteMethodCtx('regularize', {
|
Self.remoteMethodCtx('regularize', {
|
||||||
description: 'Sends items to the trash',
|
description: 'Sends items to the trash',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [
|
||||||
arg: 'itemFk',
|
{
|
||||||
type: 'number',
|
arg: 'itemFk',
|
||||||
required: true,
|
type: 'number',
|
||||||
description: 'The item id',
|
required: true,
|
||||||
}, {
|
description: 'The item id',
|
||||||
arg: 'quantity',
|
},
|
||||||
type: 'number',
|
{
|
||||||
required: true,
|
arg: 'quantity',
|
||||||
description: 'The visible quantity',
|
type: 'number',
|
||||||
}, {
|
required: true,
|
||||||
arg: 'warehouseFk',
|
description: 'The visible quantity',
|
||||||
type: 'number',
|
},
|
||||||
required: true,
|
{
|
||||||
description: 'The id of the warehouse where the inventory happened',
|
arg: 'warehouseFk',
|
||||||
}],
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The id of the warehouse where the inventory happened',
|
||||||
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
root: true
|
root: true
|
||||||
|
@ -28,37 +32,44 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.regularize = async(ctx, itemFk, quantity, warehouseFk) => {
|
Self.regularize = async(ctx, itemFk, quantity, warehouseFk, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const itemDestination = await models.ClaimDestination.findOne({
|
if (typeof options == 'object')
|
||||||
include: {
|
Object.assign(myOptions, options);
|
||||||
relation: 'address',
|
|
||||||
scope: {
|
if (!myOptions.transaction) {
|
||||||
fields: ['clientFk']
|
tx = await Self.beginTransaction({});
|
||||||
}
|
myOptions.transaction = tx;
|
||||||
},
|
}
|
||||||
where: {description: 'Corregido'}
|
|
||||||
});
|
|
||||||
|
|
||||||
let tx = await Self.beginTransaction({});
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
const itemDestination = await models.ClaimDestination.findOne({
|
||||||
|
include: {
|
||||||
|
relation: 'address',
|
||||||
|
scope: {
|
||||||
|
fields: ['clientFk']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
where: {description: 'Corregido'}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
let item = await models.Item.findById(itemFk);
|
const item = await models.Item.findById(itemFk, null, myOptions);
|
||||||
|
|
||||||
let ticketFk = await getTicketId({
|
let ticketId = await getTicketId({
|
||||||
clientFk: itemDestination.address.clientFk,
|
clientFk: itemDestination.address.clientFk,
|
||||||
addressFk: itemDestination.addressFk,
|
addressFk: itemDestination.addressFk,
|
||||||
warehouseFk: warehouseFk
|
warehouseFk: warehouseFk
|
||||||
}, options);
|
}, myOptions);
|
||||||
|
|
||||||
if (!ticketFk) {
|
if (!ticketId) {
|
||||||
ticketFk = await createTicket(ctx, {
|
ticketId = await createTicket(ctx, {
|
||||||
clientId: itemDestination.address().clientFk,
|
clientId: itemDestination.address().clientFk,
|
||||||
warehouseId: warehouseFk,
|
warehouseId: warehouseFk,
|
||||||
addressId: itemDestination.addressFk
|
addressId: itemDestination.addressFk
|
||||||
}, options);
|
}, myOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = await models.Item.getVisibleAvailable(itemFk, warehouseFk);
|
res = await models.Item.getVisibleAvailable(itemFk, warehouseFk);
|
||||||
|
@ -66,17 +77,18 @@ module.exports = Self => {
|
||||||
let newQuantity = res.visible - quantity;
|
let newQuantity = res.visible - quantity;
|
||||||
|
|
||||||
await models.Sale.create({
|
await models.Sale.create({
|
||||||
ticketFk: ticketFk,
|
ticketFk: ticketId,
|
||||||
itemFk: itemFk,
|
itemFk: itemFk,
|
||||||
concept: item.name,
|
concept: item.name,
|
||||||
quantity: newQuantity,
|
quantity: newQuantity,
|
||||||
discount: 100
|
discount: 100
|
||||||
}, options);
|
}, myOptions);
|
||||||
|
|
||||||
await tx.commit();
|
if (tx) await tx.commit();
|
||||||
return ticketFk;
|
|
||||||
|
return ticketId;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item clone()', () => {
|
describe('item clone()', () => {
|
||||||
let nextItemId;
|
let nextItemId;
|
||||||
|
@ -8,30 +8,47 @@ describe('item clone()', () => {
|
||||||
LEFT JOIN vn.item i2 ON i1.id + 1 = i2.id
|
LEFT JOIN vn.item i2 ON i1.id + 1 = i2.id
|
||||||
WHERE i2.id IS NULL ORDER BY i1.id LIMIT 1`;
|
WHERE i2.id IS NULL ORDER BY i1.id LIMIT 1`;
|
||||||
|
|
||||||
[nextAvailableId] = await app.models.Item.rawSql(query);
|
[nextAvailableId] = await models.Item.rawSql(query);
|
||||||
nextItemId = nextAvailableId.id;
|
nextItemId = nextAvailableId.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should clone the given item and it should have the expected id', async() => {
|
it('should clone the given item and it should have the expected id', async() => {
|
||||||
let itemFk = 1;
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
let result = await app.models.Item.clone(itemFk);
|
|
||||||
|
|
||||||
expect(result.id).toEqual(nextItemId);
|
try {
|
||||||
expect(result.image).toBeUndefined();
|
const options = {transaction: tx};
|
||||||
expect(result.itemTag).toBeUndefined();
|
const itemFk = 1;
|
||||||
expect(result.comment).toBeUndefined();
|
const result = await models.Item.clone(itemFk, options);
|
||||||
expect(result.description).toBeUndefined();
|
|
||||||
|
expect(result.id).toEqual(nextItemId);
|
||||||
|
expect(result.image).toBeUndefined();
|
||||||
|
expect(result.itemTag).toBeUndefined();
|
||||||
|
expect(result.comment).toBeUndefined();
|
||||||
|
expect(result.description).toBeUndefined();
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should attempt to clone the given item but give an error as it doesnt exist', async() => {
|
it('should attempt to clone the given item but give an error as it doesnt exist', async() => {
|
||||||
let error;
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
let itemFk = 999;
|
|
||||||
await app.models.Item.clone(itemFk)
|
|
||||||
.catch(e => {
|
|
||||||
expect(e.message).toContain(`This item doesn't exists`);
|
|
||||||
error = e;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const itemFk = 999;
|
||||||
|
await models.Item.clone(itemFk, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toContain(`This item doesn't exists`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('createIntrastat()', () => {
|
describe('createIntrastat()', () => {
|
||||||
let newIntrastat;
|
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
await app.models.Intrastat.destroyById(newIntrastat.id);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a new intrastat', async() => {
|
it('should create a new intrastat', async() => {
|
||||||
const intrastatId = 588420239;
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
const description = 'Tropical Flowers';
|
|
||||||
const itemId = 9;
|
|
||||||
newIntrastat = await app.models.Item.createIntrastat(itemId, intrastatId, description);
|
|
||||||
|
|
||||||
expect(newIntrastat.description).toEqual(description);
|
try {
|
||||||
expect(newIntrastat.taxClassFk).toEqual(1);
|
const options = {transaction: tx};
|
||||||
expect(newIntrastat.taxCodeFk).toEqual(21);
|
const intrastatId = 588420239;
|
||||||
|
const description = 'Tropical Flowers';
|
||||||
|
const itemId = 9;
|
||||||
|
|
||||||
|
const newIntrastat = await models.Item.createIntrastat(itemId, intrastatId, description, options);
|
||||||
|
|
||||||
|
expect(newIntrastat.description).toEqual(description);
|
||||||
|
expect(newIntrastat.taxClassFk).toEqual(1);
|
||||||
|
expect(newIntrastat.taxCodeFk).toEqual(21);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item filter()', () => {
|
describe('item filter()', () => {
|
||||||
it('should return 1 result filtering by id', async() => {
|
it('should return 1 result filtering by id', async() => {
|
||||||
const tx = await app.models.Item.beginTransaction({});
|
const tx = await models.Item.beginTransaction({});
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const ctx = {args: {filter: filter, search: 1}};
|
const ctx = {args: {filter: filter, search: 1}};
|
||||||
const result = await app.models.Item.filter(ctx, filter, options);
|
const result = await 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);
|
||||||
|
@ -21,13 +21,13 @@ describe('item filter()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 1 result filtering by barcode', async() => {
|
it('should return 1 result filtering by barcode', async() => {
|
||||||
const tx = await app.models.Item.beginTransaction({});
|
const tx = await models.Item.beginTransaction({});
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const ctx = {args: {filter: filter, search: 4444444444}};
|
const ctx = {args: {filter: filter, search: 4444444444}};
|
||||||
const result = await app.models.Item.filter(ctx, filter, options);
|
const result = await 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);
|
||||||
|
@ -40,7 +40,7 @@ describe('item filter()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 2 results using filter and tags', async() => {
|
it('should return 2 results using filter and tags', async() => {
|
||||||
const tx = await app.models.Item.beginTransaction({});
|
const tx = await models.Item.beginTransaction({});
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -50,7 +50,7 @@ describe('item filter()', () => {
|
||||||
};
|
};
|
||||||
const tags = [{value: 'medical box', tagFk: 58}];
|
const tags = [{value: 'medical box', tagFk: 58}];
|
||||||
const ctx = {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);
|
const result = await models.Item.filter(ctx, filter, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(2);
|
expect(result.length).toEqual(2);
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,39 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
const LoopBackContext = require('loopback-context');
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('item getBalance()', () => {
|
describe('item getBalance()', () => {
|
||||||
it('should return the balance lines of a client type loses in which one has highlighted true', async() => {
|
it('should return the balance lines of a client type loses in which one has highlighted true', async() => {
|
||||||
const activeCtx = {
|
const tx = await models.Item.beginTransaction({});
|
||||||
accessToken: {userId: 9},
|
const options = {transaction: tx};
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
|
||||||
active: activeCtx
|
|
||||||
});
|
|
||||||
|
|
||||||
const losesClientId = 1111;
|
try {
|
||||||
const ticket = await app.models.Ticket.findById(7);
|
const activeCtx = {
|
||||||
const originalClientId = ticket.clientFk;
|
accessToken: {userId: 9},
|
||||||
await ticket.updateAttribute('clientFk', losesClientId);
|
};
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
const losesClientId = 1111;
|
||||||
|
const ticket = await models.Ticket.findById(7, null, options);
|
||||||
|
|
||||||
const filter = {
|
await ticket.updateAttribute('clientFk', losesClientId, options);
|
||||||
where: {
|
|
||||||
itemFk: 1,
|
|
||||||
warehouseFk: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const results = await app.models.Item.getBalance(filter);
|
|
||||||
|
|
||||||
const result = results.find(element => element.clientType == 'loses');
|
const filter = {
|
||||||
|
where: {
|
||||||
|
itemFk: 1,
|
||||||
|
warehouseFk: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const results = await models.Item.getBalance(filter, options);
|
||||||
|
|
||||||
expect(result.highlighted).toBe(true);
|
const result = results.find(element => element.clientType == 'loses');
|
||||||
|
|
||||||
// restores
|
expect(result.highlighted).toBe(true);
|
||||||
await ticket.updateAttribute('clientFk', originalClientId);
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('item getCard()', () => {
|
||||||
|
it('should return the item', async() => {
|
||||||
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const itemId = 1;
|
||||||
|
|
||||||
|
const result = await models.Item.getCard(itemId, options);
|
||||||
|
|
||||||
|
expect(result.id).toEqual(itemId);
|
||||||
|
expect(result.itemType()).toEqual(jasmine.any(Object));
|
||||||
|
expect(result.tags()).toEqual(jasmine.any(Array));
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,12 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('item getBalance()', () => {
|
|
||||||
it('should check the property balance of the 4 resultant entries', async() => {
|
|
||||||
let params = {where: {itemFk: 1, warehouseFk: 2}};
|
|
||||||
let result = await app.models.Item.getBalance(params);
|
|
||||||
|
|
||||||
expect(result.length).toBe(2);
|
|
||||||
expect(result[0].balance).toBe(-100);
|
|
||||||
expect(result[1].balance).toBe(-200);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,16 +1,27 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item getSummary()', () => {
|
describe('item getSummary()', () => {
|
||||||
it('should return summary with item, tags, botanical, niches, available and visible defined ', async() => {
|
it('should return summary with item, tags, botanical, niches, available and visible defined ', async() => {
|
||||||
const ctx = {req: {accessToken: {userId: 1}}};
|
const tx = await models.Item.beginTransaction({});
|
||||||
let result = await app.models.Item.getSummary(ctx, 1);
|
const options = {transaction: tx};
|
||||||
let keys = Object.keys(result);
|
|
||||||
|
|
||||||
expect(keys).toContain('item');
|
try {
|
||||||
expect(keys).toContain('tags');
|
const ctx = {req: {accessToken: {userId: 1}}};
|
||||||
expect(keys).toContain('botanical');
|
|
||||||
expect(keys).toContain('niches');
|
const result = await models.Item.getSummary(ctx, 1, options);
|
||||||
expect(keys).toContain('available');
|
const keys = Object.keys(result);
|
||||||
expect(keys).toContain('visible');
|
|
||||||
|
expect(keys).toContain('item');
|
||||||
|
expect(keys).toContain('tags');
|
||||||
|
expect(keys).toContain('botanical');
|
||||||
|
expect(keys).toContain('niches');
|
||||||
|
expect(keys).toContain('available');
|
||||||
|
expect(keys).toContain('visible');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,33 +1,46 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item getVisibleAvailable()', () => {
|
describe('item getVisibleAvailable()', () => {
|
||||||
it('should check available visible for today', async() => {
|
it('should check available visible for today', async() => {
|
||||||
const itemFk = 1;
|
const tx = await models.Item.beginTransaction({});
|
||||||
const warehouseFk = 1;
|
const options = {transaction: tx};
|
||||||
const dated = new Date();
|
|
||||||
let result = await app.models.Item.getVisibleAvailable(itemFk, warehouseFk, dated);
|
|
||||||
|
|
||||||
expect(result.available).toEqual(187);
|
try {
|
||||||
expect(result.visible).toEqual(92);
|
const itemFk = 1;
|
||||||
});
|
const warehouseFk = 1;
|
||||||
|
const dated = new Date();
|
||||||
|
|
||||||
it('should check available visible for no dated', async() => {
|
const result = await models.Item.getVisibleAvailable(itemFk, warehouseFk, dated, options);
|
||||||
const itemFk = 1;
|
|
||||||
const warehouseFk = 1;
|
|
||||||
let result = await app.models.Item.getVisibleAvailable(itemFk, warehouseFk);
|
|
||||||
|
|
||||||
expect(result.available).toEqual(187);
|
expect(result.available).toEqual(187);
|
||||||
expect(result.visible).toEqual(92);
|
expect(result.visible).toEqual(92);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check available visible for yesterday', async() => {
|
it('should check available visible for yesterday', async() => {
|
||||||
const itemFk = 1;
|
const tx = await models.Item.beginTransaction({});
|
||||||
const warehouseFk = 1;
|
const options = {transaction: tx};
|
||||||
let dated = new Date();
|
|
||||||
dated.setDate(dated.getDate() - 1);
|
|
||||||
let result = await app.models.Item.getVisibleAvailable(itemFk, warehouseFk, dated);
|
|
||||||
|
|
||||||
expect(result.available).toEqual(0);
|
try {
|
||||||
expect(result.visible).toEqual(92);
|
const itemFk = 1;
|
||||||
|
const warehouseFk = 1;
|
||||||
|
const dated = new Date();
|
||||||
|
dated.setDate(dated.getDate() - 1);
|
||||||
|
|
||||||
|
const result = await models.Item.getVisibleAvailable(itemFk, warehouseFk, dated, options);
|
||||||
|
|
||||||
|
expect(result.available).toEqual(0);
|
||||||
|
expect(result.visible).toEqual(92);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('Item getWasteByItem()', () => {
|
describe('Item getWasteByItem()', () => {
|
||||||
it('should check for the waste breakdown by worker and item', async() => {
|
it('should check for the waste breakdown by worker and item', async() => {
|
||||||
const result = await app.models.Item.getWasteByItem('CharlesXavier', 'Cymbidium');
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const length = result.length;
|
try {
|
||||||
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
const result = await models.Item.getWasteByItem('CharlesXavier', 'Cymbidium', options);
|
||||||
|
|
||||||
expect(anyResult.buyer).toEqual('CharlesXavier');
|
const length = result.length;
|
||||||
expect(anyResult.family).toEqual('Cymbidium');
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
expect(anyResult.lines.length).toBeGreaterThanOrEqual(2);
|
|
||||||
|
expect(anyResult.buyer).toEqual('CharlesXavier');
|
||||||
|
expect(anyResult.family).toEqual('Cymbidium');
|
||||||
|
expect(anyResult.lines.length).toBeGreaterThanOrEqual(2);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('Item getWasteByWorker()', () => {
|
describe('Item getWasteByWorker()', () => {
|
||||||
it('should check for the waste breakdown for every worker', async() => {
|
it('should check for the waste breakdown for every worker', async() => {
|
||||||
const result = await app.models.Item.getWasteByWorker();
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const length = result.length;
|
try {
|
||||||
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
const result = await models.Item.getWasteByWorker(options);
|
||||||
|
|
||||||
expect(anyResult.buyer).toMatch(/(CharlesXavier|HankPym|DavidCharlesHaller)/);
|
const length = result.length;
|
||||||
expect(anyResult.lines.length).toBeGreaterThanOrEqual(3);
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
|
expect(anyResult.buyer).toMatch(/(CharlesXavier|HankPym|DavidCharlesHaller)/);
|
||||||
|
expect(anyResult.lines.length).toBeGreaterThanOrEqual(3);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item lastEntriesFilter()', () => {
|
describe('item lastEntriesFilter()', () => {
|
||||||
const minDate = new Date(value);
|
const minDate = new Date(value);
|
||||||
|
@ -7,18 +7,38 @@ describe('item lastEntriesFilter()', () => {
|
||||||
maxHour.setHours(23, 59, 59, 59);
|
maxHour.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
it('should return one entry for a given item', async() => {
|
it('should return one entry for a given item', async() => {
|
||||||
const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
|
const tx = await models.Item.beginTransaction({});
|
||||||
const result = await app.models.Item.lastEntriesFilter(filter);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
try {
|
||||||
|
const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
|
||||||
|
const result = await models.Item.lastEntriesFilter(filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return five entries for a given item', async() => {
|
it('should return five entries for a given item', async() => {
|
||||||
minDate.setMonth(minDate.getMonth() - 2, 1);
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
|
try {
|
||||||
const result = await app.models.Item.lastEntriesFilter(filter);
|
minDate.setMonth(minDate.getMonth() - 2, 1);
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
|
||||||
|
const result = await models.Item.lastEntriesFilter(filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(5);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,45 +1,41 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item new()', () => {
|
describe('item new()', () => {
|
||||||
let item;
|
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
try {
|
|
||||||
let sql = 'DELETE FROM vn.itemLog WHERE originFk = ?';
|
|
||||||
await app.models.Item.rawSql(sql, [item.id]);
|
|
||||||
|
|
||||||
sql = 'DELETE FROM vn.item WHERE id = ?';
|
|
||||||
await app.models.Item.rawSql(sql, [item.id]);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a new item, adding the name as a tag', async() => {
|
it('should create a new item, adding the name as a tag', async() => {
|
||||||
let itemParams = {
|
const tx = await models.Item.beginTransaction({});
|
||||||
intrastatFk: 5080000,
|
const options = {transaction: tx};
|
||||||
originFk: 1,
|
|
||||||
provisionalName: 'planta',
|
|
||||||
typeFk: 2,
|
|
||||||
relevancy: 0
|
|
||||||
};
|
|
||||||
item = await app.models.Item.new(itemParams);
|
|
||||||
let temporalNameTag = await app.models.Tag.findOne({where: {name: 'Nombre temporal'}});
|
|
||||||
|
|
||||||
let temporalName = await app.models.ItemTag.findOne({
|
try {
|
||||||
where: {
|
const itemParams = {
|
||||||
itemFk: item.id,
|
intrastatFk: 5080000,
|
||||||
tagFk: temporalNameTag.id,
|
originFk: 1,
|
||||||
}
|
provisionalName: 'planta',
|
||||||
});
|
typeFk: 2,
|
||||||
item = await app.models.Item.findById(item.id);
|
relevancy: 0
|
||||||
|
};
|
||||||
|
|
||||||
expect(item.intrastatFk).toEqual(5080000);
|
let item = await models.Item.new(itemParams, options);
|
||||||
expect(item.originFk).toEqual(1);
|
const temporalNameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}}, options);
|
||||||
expect(item.typeFk).toEqual(2);
|
|
||||||
expect(item.name).toEqual('planta');
|
const temporalName = await models.ItemTag.findOne({
|
||||||
expect(temporalName.value).toEqual('planta');
|
where: {
|
||||||
|
itemFk: item.id,
|
||||||
|
tagFk: temporalNameTag.id,
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
item = await models.Item.findById(item.id, null, options);
|
||||||
|
|
||||||
|
expect(item.intrastatFk).toEqual(5080000);
|
||||||
|
expect(item.originFk).toEqual(1);
|
||||||
|
expect(item.typeFk).toEqual(2);
|
||||||
|
expect(item.name).toEqual('planta');
|
||||||
|
expect(temporalName.value).toEqual('planta');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,29 +1,32 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('regularize()', () => {
|
describe('regularize()', () => {
|
||||||
const itemFk = 1;
|
|
||||||
const warehouseFk = 1;
|
|
||||||
const trashAddress = 11;
|
|
||||||
let trashTicket;
|
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
await app.models.Ticket.destroyById(trashTicket.id);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a new ticket and add a line', async() => {
|
it('should create a new ticket and add a line', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
const tx = await models.Item.beginTransaction({});
|
||||||
let res = await app.models.Item.getVisibleAvailable(itemFk, warehouseFk);
|
const options = {transaction: tx};
|
||||||
let visible = res.visible;
|
|
||||||
let saleQuantity = visible - 11;
|
|
||||||
|
|
||||||
let ticketFk = await app.models.Item.regularize(ctx, itemFk, 11, warehouseFk);
|
try {
|
||||||
let sale = await app.models.Sale.findOne({where: {ticketFk: ticketFk}});
|
const ctx = {req: {accessToken: {userId: 18}}};
|
||||||
trashTicket = await app.models.Ticket.findById(ticketFk);
|
const itemId = 1;
|
||||||
|
const warehouseId = 1;
|
||||||
|
const quantity = 11;
|
||||||
|
const date = undefined;
|
||||||
|
|
||||||
expect(sale.quantity).toEqual(saleQuantity);
|
const res = await models.Item.getVisibleAvailable(itemId, warehouseId, date, options);
|
||||||
expect(sale.discount).toEqual(100);
|
|
||||||
expect(trashTicket.addressFk).toEqual(trashAddress);
|
const visible = res.visible;
|
||||||
|
const expectedQuantity = visible - quantity;
|
||||||
|
|
||||||
|
const ticketId = await models.Item.regularize(ctx, itemId, quantity, warehouseId, options);
|
||||||
|
const sale = await models.Sale.findOne({where: {ticketFk: ticketId}}, options);
|
||||||
|
|
||||||
|
expect(sale.quantity).toEqual(expectedQuantity);
|
||||||
|
expect(sale.discount).toEqual(100);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,34 +1,47 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('item updateTaxes()', () => {
|
describe('item updateTaxes()', () => {
|
||||||
let taxesInFixtures = [{id: 3, taxClassFk: 1}];
|
|
||||||
|
|
||||||
it('should throw an error if the taxClassFk is blank', async() => {
|
it('should throw an error if the taxClassFk is blank', async() => {
|
||||||
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
let taxes = [{id: 3, taxClassFk: undefined}];
|
|
||||||
|
|
||||||
await app.models.Item.updateTaxes(taxes)
|
try {
|
||||||
.catch(err => {
|
const taxes = [{id: 3, taxClassFk: undefined}];
|
||||||
expect(err.message).toEqual('Tax class cannot be blank');
|
|
||||||
error = err;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
await models.Item.updateTaxes(taxes, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual('Tax class cannot be blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the tax of a given country of an item', async() => {
|
it('should update the tax of a given country of an item', async() => {
|
||||||
let taxCountry = await app.models.ItemTaxCountry.findById(3);
|
const tx = await models.Item.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(taxCountry.taxClassFk).toEqual(1);
|
try {
|
||||||
|
let taxCountry = await models.ItemTaxCountry.findById(3, null, options);
|
||||||
|
|
||||||
let taxes = [{id: 3, taxClassFk: 2}];
|
expect(taxCountry.taxClassFk).toEqual(1);
|
||||||
|
|
||||||
await app.models.Item.updateTaxes(taxes);
|
const taxes = [{id: 3, taxClassFk: 2}];
|
||||||
taxCountry = await app.models.ItemTaxCountry.findById(3);
|
|
||||||
|
|
||||||
expect(taxCountry.taxClassFk).toEqual(2);
|
await models.Item.updateTaxes(taxes, options);
|
||||||
|
|
||||||
// restores
|
taxCountry = await models.ItemTaxCountry.findById(3, null, options);
|
||||||
await app.models.Item.updateTaxes(taxesInFixtures);
|
|
||||||
|
expect(taxCountry.taxClassFk).toEqual(2);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,18 +21,38 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updateTaxes = async taxes => {
|
Self.updateTaxes = async(taxes, options) => {
|
||||||
let promises = [];
|
const myOptions = {};
|
||||||
for (let tax of taxes) {
|
let tx;
|
||||||
if (!tax.taxClassFk)
|
|
||||||
throw new UserError('Tax class cannot be blank');
|
|
||||||
|
|
||||||
promises.push(Self.app.models.ItemTaxCountry.update(
|
if (typeof options == 'object')
|
||||||
{id: tax.id},
|
Object.assign(myOptions, options);
|
||||||
{taxClassFk: tax.taxClassFk}
|
|
||||||
));
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (let tax of taxes) {
|
||||||
|
if (!tax.taxClassFk)
|
||||||
|
throw new UserError('Tax class cannot be blank');
|
||||||
|
|
||||||
|
promises.push(Self.app.models.ItemTaxCountry.update(
|
||||||
|
{id: tax.id},
|
||||||
|
{taxClassFk: tax.taxClassFk}
|
||||||
|
), myOptions);
|
||||||
|
}
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,17 +3,20 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('filterValue', {
|
Self.remoteMethod('filterValue', {
|
||||||
description: 'Returns a list of tag values',
|
description: 'Returns a list of tag values',
|
||||||
accepts: [{
|
accepts: [
|
||||||
arg: 'id',
|
{
|
||||||
type: 'Number',
|
arg: 'id',
|
||||||
required: true,
|
type: 'number',
|
||||||
description: 'The tag id',
|
required: true,
|
||||||
http: {source: 'path'}
|
description: 'The tag id',
|
||||||
}, {
|
http: {source: 'path'}
|
||||||
arg: 'filter',
|
},
|
||||||
type: 'Object',
|
{
|
||||||
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
arg: 'filter',
|
||||||
}],
|
type: 'object',
|
||||||
|
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
||||||
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
|
@ -24,11 +27,16 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filterValue = async(id, filter) => {
|
Self.filterValue = async(id, filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
const tag = await Self.findById(id);
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const tag = await Self.findById(id);
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
if (!tag.isFree && tag.sourceTable) {
|
if (!tag.isFree && tag.sourceTable) {
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`SELECT value FROM (
|
`SELECT value FROM (
|
||||||
|
@ -36,7 +44,7 @@ module.exports = Self => {
|
||||||
} else
|
} else
|
||||||
stmt = new ParameterizedSQL(`SELECT value FROM itemTag`);
|
stmt = new ParameterizedSQL(`SELECT value FROM itemTag`);
|
||||||
|
|
||||||
let where = filter.where;
|
const where = filter.where;
|
||||||
if (where && where.value) {
|
if (where && where.value) {
|
||||||
stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}}));
|
stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}}));
|
||||||
stmt.merge(`
|
stmt.merge(`
|
||||||
|
@ -46,6 +54,6 @@ module.exports = Self => {
|
||||||
|
|
||||||
stmt.merge(conn.makeLimit(filter));
|
stmt.merge(conn.makeLimit(filter));
|
||||||
|
|
||||||
return conn.executeStmt(stmt);
|
return conn.executeStmt(stmt, myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,37 +1,76 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('tag filterValue()', () => {
|
describe('tag filterValue()', () => {
|
||||||
const colorTagId = 1;
|
const colorTagId = 1;
|
||||||
it('should return a list of color values', async() => {
|
it('should return a list of color values', async() => {
|
||||||
const filter = {limit: 5};
|
const tx = await models.Item.beginTransaction({});
|
||||||
const result = await app.models.Tag.filterValue(colorTagId, filter);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
try {
|
||||||
|
const filter = {limit: 5};
|
||||||
|
const result = await models.Tag.filterValue(colorTagId, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(5);
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the values matching color "Blue"', async() => {
|
it('should return the values matching color "Blue"', async() => {
|
||||||
const filter = {where: {value: 'Blue'}, limit: 5};
|
const tx = await models.Item.beginTransaction({});
|
||||||
const result = await app.models.Tag.filterValue(colorTagId, filter);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.length).toEqual(2);
|
try {
|
||||||
expect(result[0].value).toEqual('Blue');
|
const filter = {where: {value: 'Blue'}, limit: 5};
|
||||||
expect(result[1].value).toEqual('Blue/Silver');
|
const result = await models.Tag.filterValue(colorTagId, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
expect(result[0].value).toEqual('Blue');
|
||||||
|
expect(result[1].value).toEqual('Blue/Silver');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the values matching color "Blue/Silver"', async() => {
|
it('should return the values matching color "Blue/Silver"', async() => {
|
||||||
const filter = {where: {value: 'Blue/Silver'}, limit: 5};
|
const tx = await models.Item.beginTransaction({});
|
||||||
const result = await app.models.Tag.filterValue(colorTagId, filter);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
try {
|
||||||
expect(result[0].value).toEqual('Blue/Silver');
|
const filter = {where: {value: 'Blue/Silver'}, limit: 5};
|
||||||
|
const result = await models.Tag.filterValue(colorTagId, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(result[0].value).toEqual('Blue/Silver');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the values matching color "Silver"', async() => {
|
it('should return the values matching color "Silver"', async() => {
|
||||||
const filter = {where: {value: 'Silver'}, limit: 5};
|
const tx = await models.Item.beginTransaction({});
|
||||||
const result = await app.models.Tag.filterValue(colorTagId, filter);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(result.length).toEqual(2);
|
try {
|
||||||
expect(result[0].value).toEqual('Silver');
|
const filter = {where: {value: 'Silver'}, limit: 5};
|
||||||
expect(result[1].value).toEqual('Blue/Silver');
|
const result = await models.Tag.filterValue(colorTagId, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
expect(result[0].value).toEqual('Silver');
|
||||||
|
expect(result[1].value).toEqual('Blue/Silver');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue