client module changes for transactions
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2021-07-08 15:53:30 +02:00
parent 10c7aa70d6
commit 3b2b4e3819
55 changed files with 1715 additions and 1178 deletions

View File

@ -21,8 +21,9 @@ module.exports = Self => {
}); });
Self.removeFile = async(ctx, id, options) => { Self.removeFile = async(ctx, id, options) => {
const models = Self.app.models;
let tx; let tx;
let myOptions = {}; const myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
@ -33,7 +34,6 @@ module.exports = Self => {
} }
try { try {
const models = Self.app.models;
const dms = await models.Dms.findById(id, null, myOptions); const dms = await models.Dms.findById(id, null, myOptions);
const trashDmsType = await models.DmsType.findOne({ const trashDmsType = await models.DmsType.findOne({
where: {code: 'trash'} where: {code: 'trash'}

View File

@ -25,8 +25,9 @@ module.exports = Self => {
}); });
Self.createFromSales = async(ctx, ticketId, sales, options) => { Self.createFromSales = async(ctx, ticketId, sales, options) => {
const models = Self.app.models;
let tx; let tx;
let myOptions = {}; const myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
@ -35,7 +36,6 @@ module.exports = Self => {
tx = await Self.beginTransaction({}); tx = await Self.beginTransaction({});
myOptions.transaction = tx; myOptions.transaction = tx;
} }
const models = Self.app.models;
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
try { try {

View File

@ -4,12 +4,12 @@ module.exports = Self => {
accessType: 'WRITE', accessType: 'WRITE',
accepts: { accepts: {
arg: 'id', arg: 'id',
type: 'Number', type: 'number',
description: 'The document id', description: 'The document id',
http: {source: 'path'} http: {source: 'path'}
}, },
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -18,13 +18,33 @@ module.exports = Self => {
} }
}); });
Self.removeFile = async(ctx, id) => { Self.removeFile = async(ctx, id, options) => {
const models = Self.app.models; const models = Self.app.models;
const clientDms = await Self.findById(id); let tx;
const myOptions = {};
await models.Dms.removeFile(ctx, clientDms.dmsFk); if (typeof options == 'object')
Object.assign(myOptions, options);
return clientDms.destroy(); if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const clientDms = await Self.findById(id, null, myOptions);
await models.Dms.removeFile(ctx, clientDms.dmsFk, myOptions);
const destroyedClient = await clientDms.destroy(myOptions);
if (tx) await tx.commit();
return destroyedClient;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -1,17 +1,24 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('ClientDms removeFile()', () => { describe('ClientDms removeFile()', () => {
const clientDmsFk = 3;
it(`should return an error for a user without enough privileges`, async() => { it(`should return an error for a user without enough privileges`, async() => {
let clientId = 1101; const tx = await models.Client.beginTransaction({});
let ctx = {req: {accessToken: {userId: clientId}}};
let error; let error;
await app.models.ClientDms.removeFile(ctx, clientDmsFk).catch(e => {
try {
const options = {transaction: tx};
const clientDmsFk = 3;
const clientId = 1101;
const ctx = {req: {accessToken: {userId: clientId}}};
await models.ClientDms.removeFile(ctx, clientDmsFk, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e; error = e;
}).finally(() => { }
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined(); expect(error).toBeDefined();
}); });

View File

@ -12,7 +12,7 @@ module.exports = function(Self) {
}, },
{ {
arg: 'data', arg: 'data',
type: 'Object', type: 'object',
required: true, required: true,
description: 'data with new value', description: 'data with new value',
http: {source: 'body'} http: {source: 'body'}
@ -29,12 +29,21 @@ module.exports = function(Self) {
} }
}); });
Self.addressesPropagateRe = async(id, data) => { Self.addressesPropagateRe = async(id, data, options) => {
if (data.hasOwnProperty('isEqualizated')) { const models = Self.app.models;
let client = await Self.app.models.Client.findById(id); const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const isEqualizated = Object.prototype.hasOwnProperty.call(data, 'isEqualizated');
if (isEqualizated) {
const client = await models.Client.findById(id, null, myOptions);
if (client) { if (client) {
await Self.app.models.Address.updateAll({clientFk: id}, data); await models.Address.updateAll({clientFk: id}, data, myOptions);
await client.updateAttributes({hasToInvoiceByAddress: false}); await client.updateAttributes({hasToInvoiceByAddress: false}, myOptions);
return true; return true;
} }
} }

View File

@ -20,8 +20,15 @@ module.exports = Self => {
} }
}); });
Self.canCreateTicket = async id => { Self.canCreateTicket = async(id, options) => {
const client = await Self.app.models.Client.findById(id); const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const client = await models.Client.findById(id, null, myOptions);
const canCreateTicket = client && client.isActive; const canCreateTicket = client && client.isActive;
if (!canCreateTicket) if (!canCreateTicket)
return false; return false;

View File

@ -9,7 +9,7 @@ module.exports = Self => {
description: 'Transaction id' description: 'Transaction id'
}], }],
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -18,23 +18,32 @@ module.exports = Self => {
} }
}); });
Self.confirmTransaction = async(ctx, id) => { Self.confirmTransaction = async(ctx, id, options) => {
let userId = ctx.req.accessToken.userId; const models = Self.app.models;
let tx = await Self.beginTransaction({}); const userId = ctx.req.accessToken.userId;
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 oldTpvTransaction = await models.TpvTransaction.findById(id, null, myOptions);
let oldTpvTransaction = await Self.app.models.TpvTransaction.findById(id, null, options); const confirm = await Self.rawSql('CALL hedera.tpvTransaction_confirmById(?)', [id], myOptions);
let confirm = await Self.rawSql('CALL hedera.tpvTransaction_confirmById(?)', [id], options); const tpvTransaction = await models.TpvTransaction.findById(id, null, myOptions);
let tpvTransaction = await Self.app.models.TpvTransaction.findById(id, null, options); const oldInstance = {status: oldTpvTransaction.status};
const newInstance = {status: tpvTransaction.status};
let oldInstance = {status: oldTpvTransaction.status}; const logRecord = {
let newInstance = {status: tpvTransaction.status};
let logRecord = {
originFk: tpvTransaction.clientFk, originFk: tpvTransaction.clientFk,
userFk: userId, userFk: userId,
action: 'update', action: 'update',
@ -44,12 +53,13 @@ module.exports = Self => {
newInstance: newInstance newInstance: newInstance
}; };
await Self.app.models.ClientLog.create(logRecord, options); await models.ClientLog.create(logRecord, myOptions);
if (tx) await tx.commit();
await tx.commit();
return confirm; return confirm;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -10,44 +10,52 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
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 name` description: `If it's and integer searchs by id, otherwise it searchs by name`
}, { },
{
arg: 'itemId', arg: 'itemId',
type: 'Number', type: 'number',
description: 'Item id' description: 'Item id'
}, { },
{
arg: 'categoryId', arg: 'categoryId',
type: 'Number', type: 'number',
description: 'Category id' description: 'Category id'
}, { },
{
arg: 'typeId', arg: 'typeId',
type: 'Number', type: 'number',
description: 'Item type id', description: 'Item type id',
}, { },
{
arg: 'buyerId', arg: 'buyerId',
type: 'Number', type: 'number',
description: 'Buyer id' description: 'Buyer id'
}, { },
{
arg: 'from', arg: 'from',
type: 'Date', type: 'date',
description: `The from date filter` description: `The from date filter`
}, { },
{
arg: 'to', arg: 'to',
type: 'Date', type: 'date',
description: `The to date filter` description: `The to date filter`
}, { },
{
arg: 'grouped', arg: 'grouped',
type: 'Boolean', type: 'boolean',
description: 'Group by item' description: 'Group by item'
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -56,7 +64,12 @@ module.exports = Self => {
} }
}); });
Self.consumption = async(ctx, filter) => { Self.consumption = async(ctx, filter, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const args = ctx.args; const args = ctx.args;
const where = buildFilter(ctx.args, (param, value) => { const where = buildFilter(ctx.args, (param, value) => {
@ -83,7 +96,7 @@ module.exports = Self => {
}); });
filter = mergeFilters(filter, {where}); filter = mergeFilters(filter, {where});
let stmt = new ParameterizedSQL('SELECT'); const stmt = new ParameterizedSQL('SELECT');
if (args.grouped) if (args.grouped)
stmt.merge(`SUM(s.quantity) AS quantity,`); stmt.merge(`SUM(s.quantity) AS quantity,`);
else else
@ -121,6 +134,6 @@ module.exports = Self => {
stmt.merge(conn.makePagination(filter)); stmt.merge(conn.makePagination(filter));
return conn.executeStmt(stmt); return conn.executeStmt(stmt, myOptions);
}; };
}; };

View File

@ -62,7 +62,7 @@ module.exports = function(Self) {
}], }],
returns: { returns: {
root: true, root: true,
type: 'Object' type: 'object'
}, },
http: { http: {
verb: 'post', verb: 'post',
@ -70,18 +70,26 @@ module.exports = function(Self) {
} }
}); });
Self.createAddress = async(ctx, clientFk) => { Self.createAddress = async(ctx, clientFk, 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;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try { try {
const options = {transaction: tx};
const province = await models.Province.findById(args.provinceFk, { const province = await models.Province.findById(args.provinceFk, {
include: { include: {
relation: 'country' relation: 'country'
} }
}, options); }, myOptions);
const isUeeMember = province.country().isUeeMember; const isUeeMember = province.country().isUeeMember;
if (!isUeeMember && !args.incotermsFk) if (!isUeeMember && !args.incotermsFk)
@ -91,19 +99,20 @@ module.exports = function(Self) {
throw new UserError(`Customs agent is required for a non UEE member`); throw new UserError(`Customs agent is required for a non UEE member`);
delete args.ctx; // Remove unwanted properties delete args.ctx; // Remove unwanted properties
const newAddress = await models.Address.create(args, options); const newAddress = await models.Address.create(args, myOptions);
const client = await Self.findById(clientFk, null, options); const client = await Self.findById(clientFk, null, myOptions);
if (args.isDefaultAddress) { if (args.isDefaultAddress) {
await client.updateAttributes({ await client.updateAttributes({
defaultAddressFk: newAddress.id defaultAddressFk: newAddress.id
}, options); }, myOptions);
} }
await tx.commit(); if (tx) await tx.commit();
return newAddress; return newAddress;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -48,19 +48,26 @@ module.exports = function(Self) {
} }
}); });
Self.createReceipt = async ctx => { Self.createReceipt = 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;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try { try {
const options = {transaction: tx};
delete args.ctx; // Remove unwanted properties delete args.ctx; // Remove unwanted properties
const newReceipt = await models.Receipt.create(args, options); const newReceipt = await models.Receipt.create(args, myOptions);
const clientOriginal = await models.Client.findById(args.clientFk); const originalClient = await models.Client.findById(args.clientFk, myOptions);
const bank = await models.Bank.findById(args.bankFk); const bank = await models.Bank.findById(args.bankFk, null, myOptions);
const accountingType = await models.AccountingType.findById(bank.accountingTypeFk); const accountingType = await models.AccountingType.findById(bank.accountingTypeFk, null, myOptions);
if (accountingType.code == 'compensation') { if (accountingType.code == 'compensation') {
if (!args.compensationAccount) if (!args.compensationAccount)
@ -70,14 +77,16 @@ module.exports = function(Self) {
where: { where: {
account: args.compensationAccount account: args.compensationAccount
} }
}); }, myOptions);
let clientCompensation = {}; let clientCompensation = {};
if (!supplierCompensation) { if (!supplierCompensation) {
clientCompensation = await models.Client.findOne({ clientCompensation = await models.Client.findOne({
where: { where: {
accountingAccount: args.compensationAccount accountingAccount: args.compensationAccount
} }
}); }, myOptions);
} }
if (!supplierCompensation && !clientCompensation) if (!supplierCompensation && !clientCompensation)
throw new UserError('Invalid account'); throw new UserError('Invalid account');
@ -87,20 +96,21 @@ module.exports = function(Self) {
[ [
args.compensationAccount, args.compensationAccount,
args.bankFk, args.bankFk,
accountingType.receiptDescription + clientOriginal.accountingAccount, accountingType.receiptDescription + originalClient.accountingAccount,
args.amountPaid, args.amountPaid,
args.companyFk, args.companyFk,
clientOriginal.accountingAccount originalClient.accountingAccount
], ],
options); myOptions
);
} else if (accountingType.isAutoConciliated == true) { } else if (accountingType.isAutoConciliated == true) {
const description = `${clientOriginal.id} : ${clientOriginal.socialName} - ${accountingType.receiptDescription}`; const description = `${originalClient.id} : ${originalClient.socialName} - ${accountingType.receiptDescription}`;
const [xdiarioNew] = await Self.rawSql( const [xdiarioNew] = await Self.rawSql(
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`, `SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`,
[ [
null, null,
bank.account, bank.account,
clientOriginal.accountingAccount, originalClient.accountingAccount,
description, description,
args.amountPaid, args.amountPaid,
0, 0,
@ -112,13 +122,14 @@ module.exports = function(Self) {
false, false,
args.companyFk args.companyFk
], ],
options); myOptions
);
await Self.rawSql( await Self.rawSql(
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, `SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`,
[ [
xdiarioNew.ledger, xdiarioNew.ledger,
clientOriginal.accountingAccount, originalClient.accountingAccount,
bank.account, bank.account,
description, description,
0, 0,
@ -131,13 +142,15 @@ module.exports = function(Self) {
false, false,
args.companyFk args.companyFk
], ],
options); myOptions
);
} }
await tx.commit(); if (tx) await tx.commit();
return newReceipt; return newReceipt;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -16,22 +16,29 @@ module.exports = function(Self) {
} }
}); });
Self.createWithUser = async data => { Self.createWithUser = async(data, options) => {
let firstEmail = data.email ? data.email.split(',')[0] : null; const models = Self.app.models;
let user = { let tx;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const firstEmail = data.email ? data.email.split(',')[0] : null;
const user = {
name: data.userName, name: data.userName,
email: firstEmail, email: firstEmail,
password: parseInt(Math.random() * 100000000000000) password: parseInt(Math.random() * 100000000000000)
}; };
const Account = Self.app.models.Account;
const Address = Self.app.models.Address;
const tx = await Account.beginTransaction({});
try { try {
let options = {transaction: tx}; const account = await models.Account.create(user, myOptions);
const client = await Self.create({
let account = await Account.create(user, options);
let client = await Self.create({
id: account.id, id: account.id,
name: data.name, name: data.name,
fi: data.fi, fi: data.fi,
@ -44,9 +51,9 @@ module.exports = function(Self) {
provinceFk: data.provinceFk, provinceFk: data.provinceFk,
countryFk: data.countryFk, countryFk: data.countryFk,
isEqualizated: data.isEqualizated isEqualizated: data.isEqualizated
}, options); }, myOptions);
let address = await Address.create({ const address = await models.Address.create({
clientFk: client.id, clientFk: client.id,
nickname: client.name, nickname: client.name,
city: client.city, city: client.city,
@ -55,16 +62,17 @@ module.exports = function(Self) {
provinceFk: client.provinceFk, provinceFk: client.provinceFk,
isEqualizated: client.isEqualizated, isEqualizated: client.isEqualizated,
isActive: true isActive: true
}, options); }, myOptions);
await client.updateAttributes({ await client.updateAttributes({
defaultAddressFk: address.id defaultAddressFk: address.id
}, options); }, myOptions);
if (tx) await tx.commit();
await tx.commit();
return client; return client;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getAverageInvoiced = async clientFk => { Self.getAverageInvoiced = async(clientFk, options) => {
let query = `SELECT invoiced FROM vn.annualAverageInvoiced WHERE clientFk = ?`; const myOptions = {};
let [invoiced] = await Self.rawSql(query, [clientFk]);
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT invoiced FROM vn.annualAverageInvoiced WHERE clientFk = ?`;
const [invoiced] = await Self.rawSql(query, [clientFk], myOptions);
return invoiced; return invoiced;
}; };

View File

@ -9,7 +9,7 @@ module.exports = function(Self) {
http: {source: 'path'} http: {source: 'path'}
}, },
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -18,8 +18,13 @@ module.exports = function(Self) {
} }
}); });
Self.getCard = async function(id) { Self.getCard = async(id, options) => {
let client = await Self.findOne({ const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const client = await Self.findOne({
where: { where: {
id: id id: id
}, },
@ -29,38 +34,44 @@ module.exports = function(Self) {
scope: { scope: {
fields: ['id', 'name'] fields: ['id', 'name']
} }
}, { },
{
relation: 'province', relation: 'province',
scope: { scope: {
fields: ['id', 'name'] fields: ['id', 'name']
} }
}, { },
}, { {
relation: 'salesPersonUser', relation: 'salesPersonUser',
scope: { scope: {
fields: ['id', 'name'] fields: ['id', 'name']
} }
}, { },
{
relation: 'country', relation: 'country',
scope: { scope: {
fields: ['id', 'country'] fields: ['id', 'country']
} }
}, { },
{
relation: 'payMethod', relation: 'payMethod',
scope: { scope: {
fields: ['id', 'name'] fields: ['id', 'name']
} }
}, { },
{
relation: 'account', relation: 'account',
scope: { scope: {
fields: ['id', 'name', 'active'] fields: ['id', 'name', 'active']
} }
} }
] ]
}); }, myOptions);
let query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`; const query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`;
client.debt = (await Self.rawSql(query, [id]))[0].debt; const data = await Self.rawSql(query, [id], myOptions);
client.debt = data[0].debt;
return client; return client;
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getDebt = async clientFk => { Self.getDebt = async(clientFk, options) => {
let query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`; const myOptions = {};
let [debt] = await Self.rawSql(query, [clientFk]);
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`;
const [debt] = await Self.rawSql(query, [clientFk], myOptions);
return debt; return debt;
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getMana = async clientFk => { Self.getMana = async(clientFk, options) => {
let query = `SELECT vn.clientGetMana(?) AS mana`; const myOptions = {};
let [mana] = await Self.rawSql(query, [clientFk]);
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT vn.clientGetMana(?) AS mana`;
const [mana] = await Self.rawSql(query, [clientFk], myOptions);
return mana; return mana;
}; };

View File

@ -7,12 +7,12 @@ module.exports = Self => {
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [{
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',
http: {source: 'query'} http: {source: 'query'}
}], }],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -21,9 +21,14 @@ module.exports = Self => {
} }
}); });
Self.getTransactions = async filter => { Self.getTransactions = async(filter, options) => {
let conn = Self.dataSource.connector; const myOptions = {};
let stmt = new ParameterizedSQL(`
if (typeof options == 'object')
Object.assign(myOptions, options);
const conn = Self.dataSource.connector;
const stmt = new ParameterizedSQL(`
SELECT SELECT
t.id, t.id,
t.clientFk, t.clientFk,
@ -39,6 +44,6 @@ module.exports = Self => {
stmt.merge(conn.makeSuffix(filter, 't')); stmt.merge(conn.makeSuffix(filter, 't'));
return await Self.rawStmt(stmt); return Self.rawStmt(stmt, myOptions);
}; };
}; };

View File

@ -2,23 +2,13 @@ module.exports = Self => {
Self.remoteMethod('hasCustomerRole', { Self.remoteMethod('hasCustomerRole', {
description: 'Comprueba si un usuario tiene el rol de cliente', description: 'Comprueba si un usuario tiene el rol de cliente',
accessType: 'READ', accessType: 'READ',
accepts: [ accepts: [{
{ arg: 'id',
arg: 'id', type: 'string',
type: 'string', required: true,
required: true, description: 'The user id',
description: 'The user id', http: {source: 'path'}
http: {source: 'path'} }],
}, {
arg: 'context',
type: 'object',
required: true,
description: 'Filter defining where',
http: function(context) {
return context.req.query;
}
}
],
returns: { returns: {
type: 'boolean', type: 'boolean',
root: true root: true
@ -29,17 +19,19 @@ module.exports = Self => {
} }
}); });
Self.hasCustomerRole = (id, context, callback) => { Self.hasCustomerRole = (id, options) => {
let query = ` const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `
SELECT COUNT(*) > 0 isCustomer SELECT COUNT(*) > 0 isCustomer
FROM salix.Account A FROM salix.Account A
JOIN salix.Role r ON r.id = A.roleFK JOIN salix.Role r ON r.id = A.roleFK
WHERE r.name = 'customer' WHERE r.name = 'customer'
AND A.id IN (?)`; AND A.id IN (?)`;
Self.rawSql(query, [id]).then( return Self.rawSql(query, [id], myOptions);
instances => callback(null, instances[0]),
err => callback(err)
);
}; };
}; };

View File

@ -9,14 +9,6 @@ module.exports = Self => {
required: true, required: true,
description: 'The user id', description: 'The user id',
http: {source: 'path'} http: {source: 'path'}
}, {
arg: 'context',
type: 'object',
required: true,
description: 'Filter defining where',
http: function(context) {
return context.req.query;
}
} }
], ],
returns: { returns: {
@ -29,8 +21,13 @@ module.exports = Self => {
} }
}); });
Self.isValidClient = async id => { Self.isValidClient = async(id, options) => {
let query = ` const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `
SELECT r.name SELECT r.name
FROM salix.Account a FROM salix.Account a
JOIN vn.client c ON a.id = c.id JOIN vn.client c ON a.id = c.id
@ -38,9 +35,9 @@ module.exports = Self => {
JOIN salix.Role r ON r.id = rm.roleId JOIN salix.Role r ON r.id = rm.roleId
WHERE a.id = ? AND c.isActive AND c.isTaxDataChecked`; WHERE a.id = ? AND c.isActive AND c.isTaxDataChecked`;
let roleNames = await Self.rawSql(query, [id]); const roleNames = await Self.rawSql(query, [id], myOptions);
let isEmployee = roleNames.findIndex(role => { const isEmployee = roleNames.findIndex(role => {
return role.name === 'employee'; return role.name === 'employee';
}); });

View File

@ -2,19 +2,22 @@ module.exports = Self => {
Self.remoteMethod('lastActiveTickets', { Self.remoteMethod('lastActiveTickets', {
description: 'Returns the last three active tickets of a client', description: 'Returns the last three active tickets of a client',
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [
arg: 'id', {
type: 'Number', arg: 'id',
required: true, type: 'number',
description: 'Client id', required: true,
http: {source: 'path'} description: 'Client id',
}, { http: {source: 'path'}
arg: 'ticketId', },
type: 'Number', {
required: true arg: 'ticketId',
}], type: 'number',
required: true
}
],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -23,8 +26,13 @@ module.exports = Self => {
} }
}); });
Self.lastActiveTickets = async(id, ticketId) => { Self.lastActiveTickets = async(id, ticketId, options) => {
const ticket = await Self.app.models.Ticket.findById(ticketId); const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const ticket = await Self.app.models.Ticket.findById(ticketId, null, myOptions);
const query = ` const query = `
SELECT SELECT
t.id, t.id,
@ -47,7 +55,7 @@ module.exports = Self => {
ORDER BY t.shipped ORDER BY t.shipped
LIMIT 10`; LIMIT 10`;
return Self.rawSql(query, [id, ticketId, ticket.warehouseFk]); return Self.rawSql(query, [id, ticketId, ticket.warehouseFk], myOptions);
}; };
}; };

View File

@ -5,23 +5,23 @@ module.exports = Self => {
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [{
arg: 'id', arg: 'id',
type: 'Number', type: 'number',
required: true, required: true,
description: 'The ticket id', description: 'The ticket id',
http: {source: 'path'} http: {source: 'path'}
}, },
{ {
arg: 'destination', arg: 'destination',
type: 'String', type: 'string',
required: true, required: true,
}, },
{ {
arg: 'message', arg: 'message',
type: 'String', type: 'string',
required: true, required: true,
}], }],
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -30,11 +30,17 @@ module.exports = Self => {
} }
}); });
Self.sendSms = async(ctx, id, destination, message) => { Self.sendSms = async(ctx, id, destination, message, options) => {
const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
let sms = await Self.app.models.Sms.send(ctx, id, destination, message); const sms = await models.Sms.send(ctx, id, destination, message);
let logRecord = { const logRecord = {
originFk: id, originFk: id,
userFk: userId, userFk: userId,
action: 'insert', action: 'insert',
@ -48,7 +54,7 @@ module.exports = Self => {
} }
}; };
const clientLog = await Self.app.models.ClientLog.create(logRecord); const clientLog = await models.ClientLog.create(logRecord, myOptions);
sms.logId = clientLog.id; sms.logId = clientLog.id;

View File

@ -1,40 +1,30 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client addressesPropagateRe', () => { describe('Client addressesPropagateRe', () => {
let client;
beforeEach(async() => {
client = await app.models.Client.findById(1101);
await app.models.Address.update({clientFk: 1101}, {isEqualizated: false});
await client.updateAttributes({hasToInvoiceByAddress: true});
});
afterAll(async done => {
await app.models.Address.update({clientFk: 1101}, {isEqualizated: false});
await client.updateAttributes({hasToInvoiceByAddress: true});
done();
});
it('should propagate the isEqualizated on both addresses of Mr Wayne and set hasToInvoiceByAddress to false', async() => { it('should propagate the isEqualizated on both addresses of Mr Wayne and set hasToInvoiceByAddress to false', async() => {
let id = 1101; const tx = await models.Client.beginTransaction({});
let data = {
isEqualizated: true
};
let resultAddress = await app.models.Address.find({where: {clientFk: id}}); try {
let resultClient = await app.models.Client.find({where: {id: id}}); const options = {transaction: tx};
expect(resultAddress[0].isEqualizated).toBeFalsy(); let id = 1101;
expect(resultAddress[1].isEqualizated).toBeFalsy(); let data = {
expect(resultClient[0].hasToInvoiceByAddress).toBeTruthy(); isEqualizated: true
};
await app.models.Client.addressesPropagateRe(id, data); await models.Client.addressesPropagateRe(id, data, options);
resultAddress = await app.models.Address.find({where: {clientFk: id}}); const addresses = await models.Address.find({where: {clientFk: id}}, options);
resultClient = await app.models.Client.find({where: {id: id}}); const client = await models.Client.findById(id, null, options);
expect(resultAddress[0].isEqualizated).toBeTruthy(); expect(addresses[0].isEqualizated).toBeTruthy();
expect(resultAddress[1].isEqualizated).toBeTruthy(); expect(addresses[1].isEqualizated).toBeTruthy();
expect(resultClient[0].hasToInvoiceByAddress).toBeFalsy(); expect(client.hasToInvoiceByAddress).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,4 +1,4 @@
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('client canBeInvoiced()', () => { describe('client canBeInvoiced()', () => {
@ -7,7 +7,6 @@ describe('client canBeInvoiced()', () => {
const activeCtx = { const activeCtx = {
accessToken: {userId: userId} accessToken: {userId: userId}
}; };
const models = app.models;
beforeAll(async done => { beforeAll(async done => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
@ -18,7 +17,7 @@ describe('client canBeInvoiced()', () => {
}); });
it('should return falsy for a client without the data checked', async() => { it('should return falsy for a client without the data checked', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Client.beginTransaction({});
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
@ -37,7 +36,7 @@ describe('client canBeInvoiced()', () => {
}); });
it('should return falsy for a client with invoicing disabled', async() => { it('should return falsy for a client with invoicing disabled', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Client.beginTransaction({});
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
@ -56,8 +55,18 @@ describe('client canBeInvoiced()', () => {
}); });
it('should return truthy for an invoiceable client', async() => { it('should return truthy for an invoiceable client', async() => {
const canBeInvoiced = await models.Client.canBeInvoiced(clientId); const tx = await models.Client.beginTransaction({});
expect(canBeInvoiced).toEqual(true); try {
const options = {transaction: tx};
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, options);
expect(canBeInvoiced).toEqual(true);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,17 +1,37 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client canCreateTicket', () => { describe('Client canCreateTicket', () => {
it('should receive true if the client is active', async() => { it('should receive true if the client is active', async() => {
let id = 1105; const tx = await models.Client.beginTransaction({});
let canCreateTicket = await app.models.Client.canCreateTicket(id);
expect(canCreateTicket).toBeTruthy(); try {
const options = {transaction: tx};
const id = 1105;
const canCreateTicket = await models.Client.canCreateTicket(id, null, options);
expect(canCreateTicket).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it(`should receive false if the client isn't active`, async() => { it(`should receive false if the client isn't active`, async() => {
let id = 1106; const tx = await models.Client.beginTransaction({});
let canCreateTicket = await app.models.Client.canCreateTicket(id);
expect(canCreateTicket).toBe(false); try {
const options = {transaction: tx};
const id = 1106;
const canCreateTicket = await models.Client.canCreateTicket(id, null, options);
expect(canCreateTicket).toBe(false);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,24 +1,26 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client confirmTransaction', () => { describe('Client confirmTransaction', () => {
const transactionId = 2;
afterAll(async done => {
await app.models.Client.rawSql(`
CALL hedera.tpvTransaction_undo(?)`, [transactionId]);
done();
});
it('should call confirmTransaction() method to mark transaction as confirmed', async() => { it('should call confirmTransaction() method to mark transaction as confirmed', async() => {
let ctx = {req: {accessToken: {userId: 1}}}; const tx = await models.Client.beginTransaction({});
await app.models.Client.confirmTransaction(ctx, transactionId); const transactionId = 2;
let [receipt] = await app.models.Client.rawSql( try {
`SELECT receiptFk const options = {transaction: tx};
FROM hedera.tpvTransaction
WHERE id = ?`, [transactionId]);
expect(receipt.receiptFk).toBeGreaterThan(0); let ctx = {req: {accessToken: {userId: 1}}};
await models.Client.confirmTransaction(ctx, transactionId, options);
let [receipt] = await models.Client.rawSql(
`SELECT receiptFk
FROM hedera.tpvTransaction
WHERE id = ?`, [transactionId], options);
expect(receipt.receiptFk).toBeGreaterThan(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,60 +1,90 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client consumption() filter', () => { describe('client consumption() filter', () => {
it('should return a list of buyed items by ticket', async() => { it('should return a list of buyed items by ticket', async() => {
const ctx = {req: {accessToken: {userId: 9}}, args: {}}; const tx = await models.Client.beginTransaction({});
const filter = {
where: {
clientFk: 1101
},
order: 'itemTypeFk, itemName, itemSize'
};
const result = await app.models.Client.consumption(ctx, filter);
expect(result.length).toEqual(10); try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 9}}, args: {}};
const filter = {
where: {
clientFk: 1101
},
order: 'itemTypeFk, itemName, itemSize'
};
const result = await app.models.Client.consumption(ctx, filter, options);
expect(result.length).toEqual(10);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a list of tickets grouped by item', async() => { it('should return a list of tickets grouped by item', async() => {
const ctx = {req: {accessToken: {userId: 9}}, const tx = await models.Client.beginTransaction({});
args: {
grouped: true
}
};
const filter = {
where: {
clientFk: 1101
},
order: 'itemFk'
};
const result = await app.models.Client.consumption(ctx, filter);
const firstRow = result[0]; try {
const secondRow = result[1]; const options = {transaction: tx};
const thirdRow = result[2];
expect(result.length).toEqual(3); const ctx = {req: {accessToken: {userId: 9}},
expect(firstRow.quantity).toEqual(10); args: {
expect(secondRow.quantity).toEqual(15); grouped: true
expect(thirdRow.quantity).toEqual(20); }
};
const filter = {
where: {
clientFk: 1101
},
order: 'itemFk'
};
const result = await app.models.Client.consumption(ctx, filter, options);
const firstRow = result[0];
const secondRow = result[1];
const thirdRow = result[2];
expect(result.length).toEqual(3);
expect(firstRow.quantity).toEqual(10);
expect(secondRow.quantity).toEqual(15);
expect(thirdRow.quantity).toEqual(20);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a list of tickets from the item id 4', async() => { it('should return a list of tickets from the item id 4', async() => {
const ctx = {req: {accessToken: {userId: 9}}, const tx = await models.Client.beginTransaction({});
args: {
itemId: 4
}
};
const filter = {
where: {
clientFk: 1101
},
order: 'itemTypeFk, itemName, itemSize'
};
const result = await app.models.Client.consumption(ctx, filter);
const expectedItemId = 4; try {
const firstRow = result[0]; const options = {transaction: tx};
expect(firstRow.itemFk).toEqual(expectedItemId); const ctx = {req: {accessToken: {userId: 9}},
args: {
itemId: 4
}
};
const filter = {
where: {
clientFk: 1101
},
order: 'itemTypeFk, itemName, itemSize'
};
const result = await app.models.Client.consumption(ctx, filter, options);
const expectedItemId = 4;
const firstRow = result[0];
expect(firstRow.itemFk).toEqual(expectedItemId);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Address createAddress', () => { describe('Address createAddress', () => {
const clientFk = 1101; const clientFk = 1101;
@ -7,107 +7,131 @@ describe('Address createAddress', () => {
const customAgentOneId = 1; const customAgentOneId = 1;
it('should throw a non uee member error if no incoterms is defined', async() => { it('should throw a non uee member error if no incoterms is defined', async() => {
const expectedResult = 'My edited address'; const tx = await models.Client.beginTransaction({});
const ctx = {
args: { let error;
provinceFk: provinceFk,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
customsAgentFk: customAgentOneId
}
};
try { try {
await app.models.Client.createAddress(ctx, clientFk); const options = {transaction: tx};
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceFk: provinceFk,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
customsAgentFk: customAgentOneId
}
};
await models.Client.createAddress(ctx, clientFk, options);
await tx.rollback();
} catch (e) { } catch (e) {
err = e; await tx.rollback();
error = e;
} }
expect(err).toBeDefined(); expect(error).toBeDefined();
expect(err.message).toEqual('Incoterms is required for a non UEE member'); expect(error.message).toEqual('Incoterms is required for a non UEE member');
}); });
it('should throw a non uee member error if no customsAgent is defined', async() => { it('should throw a non uee member error if no customsAgent is defined', async() => {
const expectedResult = 'My edited address'; const tx = await models.Client.beginTransaction({});
const ctx = {
args: { let error;
provinceFk: provinceFk,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
incotermsFk: incotermsFk
}
};
try { try {
await app.models.Client.createAddress(ctx, clientFk); const options = {transaction: tx};
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceFk: provinceFk,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
incotermsFk: incotermsFk
}
};
await models.Client.createAddress(ctx, clientFk, options);
await tx.rollback();
} catch (e) { } catch (e) {
err = e; await tx.rollback();
error = e;
} }
expect(err).toBeDefined(); expect(error).toBeDefined();
expect(err.message).toEqual('Customs agent is required for a non UEE member'); expect(error.message).toEqual('Customs agent is required for a non UEE member');
});
it('should verify that client defaultAddressFk is untainted', async() => {
const client = await app.models.Client.findById(clientFk);
expect(client.defaultAddressFk).toEqual(1);
}); });
it('should create a new address and set as a client default address', async() => { it('should create a new address and set as a client default address', async() => {
const ctx = { const tx = await models.Client.beginTransaction({});
args: {
clientFk: 1101,
provinceFk: 1,
nickname: 'My address',
street: 'Wall Street',
city: 'New York',
phone: 678678678,
mobile: 678678678,
postalCode: 46680,
agencyModeFk: 1,
incotermsFk: incotermsFk,
customsAgentFk: customAgentOneId,
isDefaultAddress: true
}
};
const address = await app.models.Client.createAddress(ctx, clientFk); try {
const client = await app.models.Client.findById(clientFk); const options = {transaction: tx};
expect(client.defaultAddressFk).toEqual(address.id); const ctx = {
args: {
clientFk: 1101,
provinceFk: 1,
nickname: 'My address',
street: 'Wall Street',
city: 'New York',
phone: 678678678,
mobile: 678678678,
postalCode: 46680,
agencyModeFk: 1,
incotermsFk: incotermsFk,
customsAgentFk: customAgentOneId,
isDefaultAddress: true
}
};
// restores const address = await models.Client.createAddress(ctx, clientFk, options);
await client.updateAttributes({defaultAddressFk: 1}); const client = await models.Client.findById(clientFk, null, options);
await address.destroy();
expect(client.defaultAddressFk).toEqual(address.id);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should create a new address and set all properties', async() => { it('should create a new address and set all properties', async() => {
const ctx = { const tx = await models.Client.beginTransaction({});
args: {
clientFk: 1101,
provinceFk: 1,
nickname: 'My address',
street: 'Wall Street',
city: 'New York',
phone: '678678678',
mobile: '678678678',
postalCode: '46680',
agencyModeFk: 1,
incotermsFk: incotermsFk,
customsAgentFk: customAgentOneId,
isDefaultAddress: true
}
};
address = await app.models.Client.createAddress(ctx, clientFk); try {
const options = {transaction: tx};
expect(address).toEqual(jasmine.objectContaining(ctx.args)); const ctx = {
// restores args: {
const client = await app.models.Client.findById(clientFk); clientFk: 1101,
await client.updateAttributes({defaultAddressFk: 1}); provinceFk: 1,
await address.destroy(); nickname: 'My address',
street: 'Wall Street',
city: 'New York',
phone: '678678678',
mobile: '678678678',
postalCode: '46680',
agencyModeFk: 1,
incotermsFk: incotermsFk,
customsAgentFk: customAgentOneId,
isDefaultAddress: true
}
};
address = await models.Client.createAddress(ctx, clientFk, options);
expect(address).toEqual(jasmine.objectContaining(ctx.args));
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,4 +1,4 @@
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('Client createReceipt', () => { describe('Client createReceipt', () => {
@ -27,49 +27,55 @@ describe('Client createReceipt', () => {
}); });
it('should create a new receipt', async() => { it('should create a new receipt', async() => {
const bankFk = 1; const tx = await models.Client.beginTransaction({});
ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description
};
const receipt = await app.models.Client.createReceipt(ctx); try {
delete ctx.args.payed; const options = {transaction: tx};
const till = await app.models.Till.findOne({ const bankFk = 1;
where: { ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk, bankFk: bankFk,
in: amountPaid, amountPaid: amountPaid,
number: clientFk description: description
} };
});
expect(receipt).toEqual(jasmine.objectContaining(ctx.args)); const receipt = await models.Client.createReceipt(ctx, options);
delete ctx.args.payed;
// restores expect(receipt).toEqual(jasmine.objectContaining(ctx.args));
await receipt.destroy();
await till.destroy(); await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should throw Compensation account is empty', async() => { it('should throw Compensation account is empty', async() => {
const bankFk = 3; const tx = await models.Client.beginTransaction({});
ctx.args = { let error;
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description
};
try { try {
await app.models.Client.createReceipt(ctx); const options = {transaction: tx};
const bankFk = 3;
ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description
};
await models.Client.createReceipt(ctx, options);
await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback();
error = e; error = e;
} }
@ -78,21 +84,29 @@ describe('Client createReceipt', () => {
}); });
it('should throw Invalid account if compensationAccount does not belongs to a client nor a supplier', async() => { it('should throw Invalid account if compensationAccount does not belongs to a client nor a supplier', async() => {
const tx = await models.Client.beginTransaction({});
let error; let error;
const bankFk = 3;
ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description,
compensationAccount: 'non existing account'
};
try { try {
await app.models.Client.createReceipt(ctx); const options = {transaction: tx};
const bankFk = 3;
ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description,
compensationAccount: 'non existing account'
};
await models.Client.createReceipt(ctx, options);
await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback();
error = e; error = e;
} }
@ -101,84 +115,78 @@ describe('Client createReceipt', () => {
}); });
it('should create a new receipt with a compensation for a client', async() => { it('should create a new receipt with a compensation for a client', async() => {
const bankFk = 3; const tx = await models.Client.beginTransaction({});
ctx.args = { try {
clientFk: clientFk, const options = {transaction: tx};
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description,
compensationAccount: '4300000001'
};
const receipt = await app.models.Client.createReceipt(ctx);
const receiptCompensated = await app.models.Receipt.findOne({
where: {
clientFk: 1,
bankFk: ctx.args.bankFk
}
});
const till = await app.models.Till.findOne({ const bankFk = 3;
where: {
ctx.args = {
clientFk: clientFk,
payed: payed,
companyFk: companyFk,
bankFk: bankFk, bankFk: bankFk,
in: amountPaid, amountPaid: amountPaid,
number: clientFk description: description,
} compensationAccount: '4300000001'
}); };
const receipt = await models.Client.createReceipt(ctx, options);
const receiptCompensated = await models.Receipt.findOne({
where: {
clientFk: 1,
bankFk: ctx.args.bankFk
}
}, options);
delete ctx.args.payed; delete ctx.args.payed;
expect(receipt).toEqual(jasmine.objectContaining(ctx.args)); expect(receipt).toEqual(jasmine.objectContaining(ctx.args));
expect(receipt.amountPaid).toEqual(-receiptCompensated.amountPaid); expect(receipt.amountPaid).toEqual(-receiptCompensated.amountPaid);
// restores await tx.rollback();
await receipt.destroy(); } catch (e) {
await receiptCompensated.destroy(); await tx.rollback();
await till.destroy(); }
}); });
it('should create a new receipt with a compensation for a supplier', async() => { it('should create a new receipt with a compensation for a supplier', async() => {
const bankFk = 3; const tx = await models.Client.beginTransaction({});
ctx.args = { try {
clientFk: clientFk, const options = {transaction: tx};
payed: payed,
companyFk: companyFk,
bankFk: bankFk,
amountPaid: amountPaid,
description: description,
compensationAccount: '4100000001'
};
const receipt = await app.models.Client.createReceipt(ctx);
const paymentCompensated = await app.models.Payment.findOne({ const bankFk = 3;
where: {
clientFk: ctx.args.sale,
payed: ctx.args.payed,
amountPaid: ctx.args.amountPaid,
bankFk: ctx.args.bankFk
}
});
const till = await app.models.Till.findOne({ ctx.args = {
where: { clientFk: clientFk,
bankFk: ctx.args.bankFk, payed: payed,
in: amountPaid, companyFk: companyFk,
number: clientFk bankFk: bankFk,
} amountPaid: amountPaid,
}); description: description,
compensationAccount: '4100000001'
};
const receipt = await models.Client.createReceipt(ctx, options);
delete ctx.args.payed; const paymentCompensated = await models.Payment.findOne({
where: {
clientFk: ctx.args.sale,
payed: ctx.args.payed,
amountPaid: ctx.args.amountPaid,
bankFk: ctx.args.bankFk
}
}, options);
expect(receipt).toEqual(jasmine.objectContaining(ctx.args)); delete ctx.args.payed;
expect(paymentCompensated.amountPaid).toEqual(paymentCompensated.amountPaid); expect(receipt).toEqual(jasmine.objectContaining(ctx.args));
// restores expect(paymentCompensated.amountPaid).toEqual(paymentCompensated.amountPaid);
await receipt.destroy();
await paymentCompensated.destroy(); await tx.rollback();
await till.destroy(); } catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,28 +1,7 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client Create', () => { describe('Client Create', () => {
const clientName = 'Wade'; const newAccount = {
const AccountName = 'Deadpool';
afterEach(async done => {
let address = await app.models.Address.findOne({where: {nickname: clientName}});
let client = await app.models.Client.findOne({where: {name: clientName}});
let account = await app.models.Account.findOne({where: {name: AccountName}});
if (address && client && account) {
try {
await app.models.Address.destroyById(address.id);
await app.models.Client.destroyById(client.id);
await app.models.Account.destroyById(account.id);
} catch (error) {
console.error(error);
}
}
done();
});
let newAccount = {
userName: 'Deadpool', userName: 'Deadpool',
email: 'Deadpool@marvel.com', email: 'Deadpool@marvel.com',
fi: '16195279J', fi: '16195279J',
@ -33,34 +12,66 @@ describe('Client Create', () => {
}; };
it(`should not find Deadpool as he's not created yet`, async() => { it(`should not find Deadpool as he's not created yet`, async() => {
let account = await app.models.Account.findOne({where: {name: newAccount.userName}}); const tx = await models.Client.beginTransaction({});
let client = await app.models.Client.findOne({where: {name: newAccount.name}});
expect(account).toEqual(null); try {
expect(client).toEqual(null); const options = {transaction: tx};
const account = await models.Account.findOne({where: {name: newAccount.userName}}, options);
const client = await models.Client.findOne({where: {name: newAccount.name}}, options);
expect(account).toEqual(null);
expect(client).toEqual(null);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should create a new account', async() => { it('should create a new account', async() => {
let client = await app.models.Client.createWithUser(newAccount); const tx = await models.Client.beginTransaction({});
let account = await app.models.Account.findOne({where: {name: newAccount.userName}});
expect(account.name).toEqual(newAccount.userName); try {
const options = {transaction: tx};
expect(client.id).toEqual(account.id); const client = await models.Client.createWithUser(newAccount, options);
expect(client.name).toEqual(newAccount.name); const account = await models.Account.findOne({where: {name: newAccount.userName}}, options);
expect(client.email).toEqual(newAccount.email);
expect(client.fi).toEqual(newAccount.fi); expect(account.name).toEqual(newAccount.userName);
expect(client.socialName).toEqual(newAccount.socialName); expect(client.id).toEqual(account.id);
expect(client.name).toEqual(newAccount.name);
expect(client.email).toEqual(newAccount.email);
expect(client.fi).toEqual(newAccount.fi);
expect(client.socialName).toEqual(newAccount.socialName);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should not be able to create a user if exists', async() => { it('should not be able to create a user if exists', async() => {
await app.models.Client.createWithUser(newAccount); const tx = await models.Client.beginTransaction({});
let error;
try { try {
let client = await app.models.Client.createWithUser(newAccount); const options = {transaction: tx};
await models.Client.createWithUser(newAccount, options);
const client = await models.Client.createWithUser(newAccount, options);
expect(client).toBeNull(); expect(client).toBeNull();
} catch (err) {
expect(err.details.codes.name[0]).toEqual('uniqueness'); await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
} }
const errorName = error.details.codes.name[0];
expect(errorName).toEqual('uniqueness');
}); });
}); });

View File

@ -1,9 +1,19 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client getAverageInvoiced()', () => { describe('client getAverageInvoiced()', () => {
it('should call the getAverageInvoiced method', async() => { it('should call the getAverageInvoiced method', async() => {
const {invoiced} = await app.models.Client.getAverageInvoiced(1101); const tx = await models.Client.beginTransaction({});
expect(invoiced).toEqual(1500); try {
const options = {transaction: tx};
const {invoiced} = await models.Client.getAverageInvoiced(1101, options);
expect(invoiced).toEqual(1500);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,12 +1,22 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client getCard()', () => { describe('Client getCard()', () => {
it('should receive a formated card of Bruce Wayne', async() => { it('should receive a formated card of Bruce Wayne', async() => {
let id = 1101; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.getCard(id);
expect(result.id).toEqual(id); try {
expect(result.name).toEqual('Bruce Wayne'); const options = {transaction: tx};
expect(result.debt).toEqual(jasmine.any(Number));
const id = 1101;
const result = await models.Client.getCard(id, options);
expect(result.id).toEqual(id);
expect(result.name).toEqual('Bruce Wayne');
expect(result.debt).toEqual(jasmine.any(Number));
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,10 +1,20 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client getDebt()', () => { describe('client getDebt()', () => {
it('should return the client debt', async() => { it('should return the client debt', async() => {
let result = await app.models.Client.getDebt(1101); const tx = await models.Client.beginTransaction({});
expect(result.debt).toEqual(jasmine.any(Number)); try {
const options = {transaction: tx};
const result = await models.Client.getDebt(1101, options);
expect(result.debt).toEqual(jasmine.any(Number));
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,9 +1,19 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client getMana()', () => { describe('client getMana()', () => {
it('should call the getMana method', async() => { it('should call the getMana method', async() => {
let result = await app.models.Client.getMana(1105); const tx = await models.Client.beginTransaction({});
expect(result.mana).toEqual(0.34); try {
const options = {transaction: tx};
const result = await models.Client.getMana(1105, options);
expect(result.mana).toEqual(0.34);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,10 +1,20 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client getTransations', () => { describe('Client getTransations', () => {
it('should call getTransations() method to receive a list of Web Payments from Bruce Wayne', async() => { it('should call getTransations() method to receive a list of Web Payments from Bruce Wayne', async() => {
let filter = {where: {clientFk: 1101}}; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.getTransactions(filter);
expect(result[1].id).toBeTruthy(); try {
const options = {transaction: tx};
const filter = {where: {clientFk: 1101}};
const result = await models.Client.getTransactions(filter, options);
expect(result[1].id).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,59 +1,74 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client hasCustomerRole', () => { describe('Client hasCustomerRole', () => {
it('should call the hasCustomerRole() method with a customer id', done => { it('should call the hasCustomerRole() method with a customer id', async() => {
let id = 1101; const tx = await models.Client.beginTransaction({});
let params = {};
let callback = (error, result) => { try {
if (error) return done.fail(error); const options = {transaction: tx};
const id = 1101;
const [result] = await models.Client.hasCustomerRole(id, options);
expect(result).toEqual(jasmine.objectContaining({isCustomer: 1})); expect(result).toEqual(jasmine.objectContaining({isCustomer: 1}));
done();
};
app.models.Client.hasCustomerRole(id, params, callback); await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the hasCustomerRole() method with a non customer id', done => { it('should call the hasCustomerRole() method with a non customer id', async() => {
let id = 8; const tx = await models.Client.beginTransaction({});
let params = {};
let callback = (error, result) => { try {
if (error) return done.fail(error); const options = {transaction: tx};
const id = 8;
const [result] = await models.Client.hasCustomerRole(id, options);
expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); expect(result).toEqual(jasmine.objectContaining({isCustomer: 0}));
done();
};
app.models.Client.hasCustomerRole(id, params, callback); await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the hasCustomerRole() method with an unreal id', done => { it('should call the hasCustomerRole() method with an unreal id', async() => {
let id = 999; const tx = await models.Client.beginTransaction({});
let params = {};
let callback = (error, result) => { try {
if (error) return done.fail(error); const options = {transaction: tx};
const id = 999;
const [result] = await models.Client.hasCustomerRole(id, options);
expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); expect(result).toEqual(jasmine.objectContaining({isCustomer: 0}));
done();
};
app.models.Client.hasCustomerRole(id, params, callback); await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the hasCustomerRole() method with an invalid id', done => { it('should call the hasCustomerRole() method with an invalid id', async() => {
let id = 'WRONG!'; const tx = await models.Client.beginTransaction({});
let params = {};
let callback = (error, result) => { try {
if (error) return done.fail(error); const options = {transaction: tx};
const id = 'WRONG!';
const [result] = await models.Client.hasCustomerRole(id, options);
expect(result).toEqual(jasmine.objectContaining({isCustomer: 0})); expect(result).toEqual(jasmine.objectContaining({isCustomer: 0}));
done();
};
app.models.Client.hasCustomerRole(id, params, callback); await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,45 +1,105 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client isValidClient', () => { describe('Client isValidClient', () => {
it('should call the isValidClient() method with a client id and receive true', async() => { it('should call the isValidClient() method with a client id and receive true', async() => {
let id = 1101; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeTruthy(); try {
const options = {transaction: tx};
const id = 1101;
const result = await models.Client.isValidClient(id, options);
expect(result).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the isValidClient() method with an employee id to receive false', async() => { it('should call the isValidClient() method with an employee id to receive false', async() => {
let id = 1; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeFalsy(); try {
const options = {transaction: tx};
const id = 1;
const result = await models.Client.isValidClient(id, options);
expect(result).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the isValidClient() method with an unexistant id and receive false', async() => { it('should call the isValidClient() method with an unexistant id and receive false', async() => {
let id = 999; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeFalsy(); try {
const options = {transaction: tx};
const id = 999;
const result = await models.Client.isValidClient(id, options);
expect(result).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the isValidClient() method with an invalid id and receive false', async() => { it('should call the isValidClient() method with an invalid id and receive false', async() => {
let id = 'Pepinillos'; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeFalsy(); try {
const options = {transaction: tx};
const id = 'Pepinillos';
const result = await models.Client.isValidClient(id, options);
expect(result).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the isValidClient() method with a customer id which isnt active and return false', async() => { it('should call the isValidClient() method with a customer id which isnt active and return false', async() => {
let id = '1106'; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeFalsy(); try {
const options = {transaction: tx};
const id = '1106';
const result = await models.Client.isValidClient(id, options);
expect(result).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should call the isValidClient() method with a customer id which his data isnt verified and return false', async() => { it('should call the isValidClient() method with a customer id which his data isnt verified and return false', async() => {
let id = '110'; const tx = await models.Client.beginTransaction({});
let result = await app.models.Client.isValidClient(id);
expect(result).toBeFalsy(); try {
const options = {transaction: tx};
const id = '110';
const result = await models.Client.isValidClient(id, options);
expect(result).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,18 +1,27 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client last active tickets', () => { describe('Client last active tickets', () => {
it('should receive an array of last active tickets of Bruce Wayne', async() => { it('should receive an array of last active tickets of Bruce Wayne', async() => {
const ticketId = 22; const tx = await models.Client.beginTransaction({});
const clientId = 1109;
const warehouseId = 5;
const result = await app.models.Client.lastActiveTickets(clientId, ticketId, warehouseId);
const length = result.length; try {
const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; const options = {transaction: tx};
const ticketId = 22;
const clientId = 1109;
const properties = Object.keys(anyResult); const result = await models.Client.lastActiveTickets(clientId, ticketId, options);
expect(properties.length).toEqual(9); const length = result.length;
expect(result.length).toEqual(3); const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
const properties = Object.keys(anyResult);
expect(properties.length).toEqual(9);
expect(result.length).toEqual(3);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,29 +1,28 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const soap = require('soap'); const soap = require('soap');
describe('client sendSms()', () => { describe('client sendSms()', () => {
let createdLog;
afterAll(async done => {
await app.models.ClientLog.destroyById(createdLog.id);
done();
});
it('should now send a message and log it', async() => { it('should now send a message and log it', async() => {
spyOn(soap, 'createClientAsync').and.returnValue('a so fake client'); spyOn(soap, 'createClientAsync').and.returnValue('a so fake client');
let ctx = {req: {accessToken: {userId: 9}}}; const tx = await models.Client.beginTransaction({});
let id = 1101;
let destination = 222222222;
let message = 'this is the message created in a test';
let sms = await app.models.Client.sendSms(ctx, id, destination, message); try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 9}}};
const id = 1101;
const destination = 222222222;
const message = 'this is the message created in a test';
logId = sms.logId; const sms = await models.Client.sendSms(ctx, id, destination, message, options);
createdLog = await app.models.ClientLog.findById(logId); const createdLog = await models.ClientLog.findById(sms.logId);
let json = JSON.parse(JSON.stringify(createdLog.newInstance)); const json = JSON.parse(JSON.stringify(createdLog.newInstance));
expect(json.message).toEqual(message); expect(json.message).toEqual(message);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,46 +1,123 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client summary()', () => { describe('client summary()', () => {
it('should return a summary object containing data', async() => { it('should return a summary object containing data', async() => {
let result = await app.models.Client.summary(1101); const clientId = 1101;
const tx = await models.Client.beginTransaction({});
expect(result.id).toEqual(1101); try {
expect(result.name).toEqual('Bruce Wayne'); const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.id).toEqual(clientId);
expect(result.name).toEqual('Bruce Wayne');
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object containing mana', async() => { it('should return a summary object containing mana', async() => {
let result = await app.models.Client.summary(1105); const clientId = 1105;
const tx = await models.Client.beginTransaction({});
expect(result.mana.mana).toEqual(0.34); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.mana.mana).toEqual(0.34);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object containing debt', async() => { it('should return a summary object containing debt', async() => {
let result = await app.models.Client.summary(1101); const clientId = 1101;
const tx = await models.Client.beginTransaction({});
expect(result.debt.debt).toEqual(jasmine.any(Number)); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.debt.debt).toEqual(jasmine.any(Number));
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object containing averageInvoiced', async() => { it('should return a summary object containing averageInvoiced', async() => {
let result = await app.models.Client.summary(1101); const clientId = 1101;
const tx = await models.Client.beginTransaction({});
expect(result.averageInvoiced.invoiced).toEqual(1500); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.averageInvoiced.invoiced).toEqual(1500);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object containing totalGreuge', async() => { it('should return a summary object containing totalGreuge', async() => {
let result = await app.models.Client.summary(1101); const clientId = 1101;
const tx = await models.Client.beginTransaction({});
expect(result.totalGreuge).toEqual(203.71); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.totalGreuge).toEqual(203.71);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object without containing active recoveries', async() => { it('should return a summary object without containing active recoveries', async() => {
let result = await app.models.Client.summary(1101); const clientId = 1101;
const tx = await models.Client.beginTransaction({});
expect(result.recovery).toEqual(null); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.recovery).toEqual(null);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return a summary object containing active recoveries', async() => { it('should return a summary object containing active recoveries', async() => {
let result = await app.models.Client.summary(1102); const clientId = 1102;
const tx = await models.Client.beginTransaction({});
expect(result.recovery.id).toEqual(3); try {
const options = {transaction: tx};
const result = await models.Client.summary(clientId, options);
expect(result.recovery.id).toEqual(3);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,12 +0,0 @@
const app = require('vn-loopback/server/server');
describe('client lastActiveTickets()', () => {
it('should return the last three active tickets', async() => {
const clientId = 1109;
const ticketId = 19;
let result = await app.models.Client.lastActiveTickets(clientId, ticketId);
expect(result.length).toEqual(3);
});
});

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Address updateAddress', () => { describe('Address updateAddress', () => {
const clientId = 1101; const clientId = 1101;
@ -8,93 +8,105 @@ describe('Address updateAddress', () => {
const customAgentOneId = 1; const customAgentOneId = 1;
it('should throw the non uee member error if no incoterms is defined', async() => { it('should throw the non uee member error if no incoterms is defined', async() => {
let err; const tx = await models.Client.beginTransaction({});
const ctx = {
args: { let error;
provinceFk: provinceId,
customsAgentFk: customAgentOneId
}
};
try { try {
await app.models.Client.updateAddress(ctx, clientId, addressId); const options = {transaction: tx};
const ctx = {
args: {
provinceFk: provinceId,
customsAgentFk: customAgentOneId
}
};
await models.Client.updateAddress(ctx, clientId, addressId, options);
await tx.rollback();
} catch (e) { } catch (e) {
err = e; await tx.rollback();
error = e;
} }
expect(err).toBeDefined(); expect(error).toBeDefined();
expect(err.message).toEqual('Incoterms is required for a non UEE member'); expect(error.message).toEqual('Incoterms is required for a non UEE member');
}); });
it('should throw a non uee member error if no customsAgent is defined', async() => { it('should throw a non uee member error if no customsAgent is defined', async() => {
let err; const tx = await models.Client.beginTransaction({});
const ctx = {
args: { let error;
provinceFk: provinceId,
incotermsFk: incotermsId
}
};
try { try {
await app.models.Client.updateAddress(ctx, clientId, addressId); const options = {transaction: tx};
const ctx = {
args: {
provinceFk: provinceId,
incotermsFk: incotermsId
}
};
await models.Client.updateAddress(ctx, clientId, addressId, options);
await tx.rollback();
} catch (e) { } catch (e) {
err = e; await tx.rollback();
error = e;
} }
expect(err).toBeDefined(); expect(error).toBeDefined();
expect(err.message).toEqual('Customs agent is required for a non UEE member'); expect(error.message).toEqual('Customs agent is required for a non UEE member');
}); });
it('should update the adress from a non uee member with no error thrown', async() => { it('should update the adress from a non uee member with no error thrown', async() => {
const expectedResult = 'My edited address'; const tx = await models.Client.beginTransaction({});
const ctx = {
args: {
provinceFk: provinceId,
nickname: expectedResult,
incotermsFk: incotermsId,
customsAgentFk: customAgentOneId
}
};
let oldAddress = await app.models.Address.findById(addressId); try {
const options = {transaction: tx};
const ctx = {
args: {
provinceFk: provinceId,
nickname: expectedResult,
incotermsFk: incotermsId,
customsAgentFk: customAgentOneId
}
};
const expectedResult = 'My edited address';
await app.models.Client.updateAddress(ctx, clientId, addressId); await models.Client.updateAddress(ctx, clientId, addressId, options);
let address = await app.models.Address.findById(addressId); const address = await models.Address.findById(addressId, null, options);
expect(address.nickname).toEqual(expectedResult); expect(address.nickname).toEqual(expectedResult);
// restores await tx.rollback();
await address.updateAttributes({ } catch (e) {
nickname: oldAddress.nickname, await tx.rollback();
provinceFk: oldAddress.provinceFk, }
customsAgentFk: null,
incotermsFk: null
});
}); });
it('should update the address', async() => { it('should update the address', async() => {
const expectedResult = 'My second time edited address'; const tx = await models.Client.beginTransaction({});
const ctx = {
args: {
nickname: expectedResult
}
};
oldAddress = await app.models.Address.findById(addressId); try {
const options = {transaction: tx};
const ctx = {
args: {
nickname: expectedResult
}
};
const expectedResult = 'My second time edited address';
await app.models.Client.updateAddress(ctx, clientId, addressId); await models.Client.updateAddress(ctx, clientId, addressId, options);
address = await app.models.Address.findById(addressId); const address = await models.Address.findById(addressId, null, options);
expect(address.nickname).toEqual(expectedResult); expect(address.nickname).toEqual(expectedResult);
// restores await tx.rollback();
await address.updateAttributes({ } catch (e) {
nickname: oldAddress.nickname, await tx.rollback();
provinceFk: oldAddress.provinceFk, }
customsAgentFk: null,
incotermsFk: null
});
}); });
}); });

View File

@ -1,61 +1,76 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client updateFiscalData', () => { describe('Client updateFiscalData', () => {
const clientId = 1101; const clientId = 1101;
const employeeId = 1; const employeeId = 1;
const salesAssistantId = 21; const salesAssistantId = 21;
const administrativeId = 5; const administrativeId = 5;
afterAll(async done => {
const ctx = {req: {accessToken: {userId: administrativeId}}};
ctx.args = {postcode: 46460};
await app.models.Client.updateFiscalData(ctx, clientId);
done();
});
it('should return an error if the user is not salesAssistant and the isTaxDataChecked value is true', async() => { it('should return an error if the user is not salesAssistant and the isTaxDataChecked value is true', async() => {
const ctx = {req: {accessToken: {userId: employeeId}}}; const tx = await models.Client.beginTransaction({});
ctx.args = {};
let error; let error;
await app.models.Client.updateFiscalData(ctx, clientId)
.catch(e => { try {
error = e; const options = {transaction: tx};
}); const ctx = {req: {accessToken: {userId: employeeId}}};
ctx.args = {};
await models.Client.updateFiscalData(ctx, clientId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toEqual(`You can't make changes on a client with verified data`); expect(error.message).toEqual(`You can't make changes on a client with verified data`);
}); });
it('should return an error if the salesAssistant did not fill the sage data before checking verified data', async() => { it('should return an error if the salesAssistant did not fill the sage data before checking verified data', async() => {
const client = await app.models.Client.findById(clientId); const tx = await models.Client.beginTransaction({});
await client.updateAttribute('isTaxDataChecked', false);
const ctx = {req: {accessToken: {userId: salesAssistantId}}};
ctx.args = {isTaxDataChecked: true};
let error; let error;
await app.models.Client.updateFiscalData(ctx, clientId)
.catch(e => { try {
error = e; const options = {transaction: tx};
});
const client = await models.Client.findById(clientId, options);
await client.updateAttribute('isTaxDataChecked', false, options);
const ctx = {req: {accessToken: {userId: salesAssistantId}}};
ctx.args = {isTaxDataChecked: true};
await models.Client.updateFiscalData(ctx, clientId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toEqual('You need to fill sage information before you check verified data'); expect(error.message).toEqual('You need to fill sage information before you check verified data');
// Restores
await client.updateAttribute('isTaxDataChecked', true);
}); });
it('should update the client fiscal data and return the count if changes made', async() => { it('should update the client fiscal data', async() => {
const ctx = {req: {accessToken: {userId: administrativeId}}}; const tx = await models.Client.beginTransaction({});
ctx.args = {postcode: 46680};
const client = await app.models.Client.findById(clientId); try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: administrativeId}}};
ctx.args = {postcode: 46680};
expect(client.postcode).toEqual('46460'); const client = await models.Client.findById(clientId, null, options);
const result = await app.models.Client.updateFiscalData(ctx, clientId); expect(client.postcode).toEqual('46460');
expect(result.postcode).toEqual('46680'); const result = await models.Client.updateFiscalData(ctx, clientId, options);
expect(result.postcode).toEqual('46680');
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,19 +1,26 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Client uploadFile()', () => { describe('Client uploadFile()', () => {
it(`should return an error for a user without enough privileges`, async() => { it(`should return an error for a user without enough privileges`, async() => {
let clientId = 1101; const tx = await models.Client.beginTransaction({});
let currentUserId = 1102;
let paymentLawTypeId = 12;
let ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: paymentLawTypeId}};
let error; let error;
await app.models.Client.uploadFile(ctx, clientId).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`You don't have enough privileges`);
});
expect(error).toBeDefined(); try {
const options = {transaction: tx};
const clientId = 1101;
const currentUserId = 1102;
const paymentLawTypeId = 12;
const ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: paymentLawTypeId}};
await models.Client.uploadFile(ctx, clientId, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e;
}
expect(error.message).toEqual(`You don't have enough privileges`);
}); });
}); });

View File

@ -19,21 +19,26 @@ module.exports = Self => {
} }
}); });
Self.summary = async clientFk => { Self.summary = async(clientFk, options) => {
let models = Self.app.models; const models = Self.app.models;
let summaryObj = await getSummary(models.Client, clientFk); const myOptions = {};
summaryObj.mana = await models.Client.getMana(clientFk); if (typeof options == 'object')
summaryObj.debt = await models.Client.getDebt(clientFk); Object.assign(myOptions, options);
summaryObj.averageInvoiced = await models.Client.getAverageInvoiced(clientFk);
summaryObj.totalGreuge = await models.Greuge.sumAmount(clientFk); const summaryObj = await getSummary(models.Client, clientFk, myOptions);
summaryObj.recovery = await getRecoveries(models.Recovery, clientFk);
summaryObj.mana = await models.Client.getMana(clientFk, myOptions);
summaryObj.debt = await models.Client.getDebt(clientFk, myOptions);
summaryObj.averageInvoiced = await models.Client.getAverageInvoiced(clientFk, myOptions);
summaryObj.totalGreuge = await models.Greuge.sumAmount(clientFk, myOptions);
summaryObj.recovery = await getRecoveries(models.Recovery, clientFk, myOptions);
return summaryObj; return summaryObj;
}; };
async function getSummary(client, clientId) { async function getSummary(clientModel, clientId, options) {
let filter = { const filter = {
include: [ include: [
{ {
relation: 'account', relation: 'account',
@ -115,17 +120,17 @@ module.exports = Self => {
where: {id: clientId} where: {id: clientId}
}; };
return await client.findOne(filter); return clientModel.findOne(filter, options);
} }
async function getRecoveries(recovery, clientId) { async function getRecoveries(recoveryModel, clientId, options) {
let filter = { const filter = {
where: { where: {
and: [{clientFk: clientId}, {or: [{finished: null}, {finished: {gt: Date.now()}}]}] and: [{clientFk: clientId}, {or: [{finished: null}, {finished: {gt: Date.now()}}]}]
}, },
limit: 1 limit: 1
}; };
return await recovery.findOne(filter); return recoveryModel.findOne(filter, options);
} }
}; };

View File

@ -3,71 +3,73 @@ const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) { module.exports = function(Self) {
Self.remoteMethod('updateAddress', { Self.remoteMethod('updateAddress', {
description: 'Updates a client address updating default address', description: 'Updates a client address updating default address',
accepts: [{ accepts: [
arg: 'ctx', {
type: 'object', arg: 'ctx',
http: {source: 'context'} type: 'object',
}, http: {source: 'context'}
{ },
arg: 'clientId', {
type: 'number', arg: 'clientId',
description: 'The client id', type: 'number',
http: {source: 'path'} description: 'The client id',
}, http: {source: 'path'}
{ },
arg: 'addressId', {
type: 'number', arg: 'addressId',
description: 'The address id', type: 'number',
http: {source: 'path'} description: 'The address id',
}, http: {source: 'path'}
{ },
arg: 'nickname', {
type: 'string' arg: 'nickname',
}, type: 'string'
{ },
arg: 'city', {
type: 'string' arg: 'city',
}, type: 'string'
{ },
arg: 'street', {
type: 'string' arg: 'street',
}, type: 'string'
{ },
arg: 'phone', {
type: 'any' arg: 'phone',
}, type: 'any'
{ },
arg: 'mobile', {
type: 'any' arg: 'mobile',
}, type: 'any'
{ },
arg: 'postalCode', {
type: 'any' arg: 'postalCode',
}, type: 'any'
{ },
arg: 'provinceFk', {
type: 'any' arg: 'provinceFk',
}, type: 'any'
{ },
arg: 'agencyModeFk', {
type: 'any' arg: 'agencyModeFk',
}, type: 'any'
{ },
arg: 'incotermsFk', {
type: 'any' arg: 'incotermsFk',
}, type: 'any'
{ },
arg: 'customsAgentFk', {
type: 'any' arg: 'customsAgentFk',
}, type: 'any'
{ },
arg: 'isActive', {
type: 'boolean' arg: 'isActive',
}, type: 'boolean'
{ },
arg: 'isEqualizated', {
type: 'boolean' arg: 'isEqualizated',
}], type: 'boolean'
}
],
returns: { returns: {
root: true, root: true,
type: 'object' type: 'object'
@ -78,26 +80,37 @@ module.exports = function(Self) {
} }
}); });
Self.updateAddress = async(ctx, clientId, addressId) => { Self.updateAddress = async(ctx, clientId, addressId, 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;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try { try {
const options = {transaction: tx};
const address = await models.Address.findOne({ const address = await models.Address.findOne({
where: { where: {
id: addressId, id: addressId,
clientFk: clientId clientFk: clientId
} }
}); }, myOptions);
const provinceId = args.provinceFk || address.provinceFk; const provinceId = args.provinceFk || address.provinceFk;
const province = await models.Province.findById(provinceId, { const province = await models.Province.findById(provinceId, {
include: { include: {
relation: 'country' relation: 'country'
} }
}, options); }, myOptions);
const isUeeMember = province.country().isUeeMember; const isUeeMember = province.country().isUeeMember;
const incotermsId = args.incotermsFk || address.incotermsFk; const incotermsId = args.incotermsFk || address.incotermsFk;
if (!isUeeMember && !incotermsId) if (!isUeeMember && !incotermsId)
throw new UserError(`Incoterms is required for a non UEE member`); throw new UserError(`Incoterms is required for a non UEE member`);
@ -107,12 +120,14 @@ module.exports = function(Self) {
throw new UserError(`Customs agent is required for a non UEE member`); throw new UserError(`Customs agent is required for a non UEE member`);
delete args.ctx; // Remove unwanted properties delete args.ctx; // Remove unwanted properties
const updatedAddress = await address.updateAttributes(ctx.args, options);
await tx.commit(); const updatedAddress = await address.updateAttributes(ctx.args, myOptions);
if (tx) await tx.commit();
return updatedAddress; return updatedAddress;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -4,97 +4,99 @@ module.exports = Self => {
Self.remoteMethod('updateFiscalData', { Self.remoteMethod('updateFiscalData', {
description: 'Updates fiscal data of a client', description: 'Updates fiscal data of a client',
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 client id', type: 'number',
http: {source: 'path'} description: 'The client id',
}, http: {source: 'path'}
{ },
arg: 'socialName', {
type: 'string' arg: 'socialName',
}, type: 'string'
{ },
arg: 'fi', {
type: 'string' arg: 'fi',
}, type: 'string'
{ },
arg: 'street', {
type: 'string' arg: 'street',
}, type: 'string'
{ },
arg: 'postcode', {
type: 'string' arg: 'postcode',
}, type: 'string'
{ },
arg: 'city', {
type: 'string' arg: 'city',
}, type: 'string'
{ },
arg: 'countryFk', {
type: 'number' arg: 'countryFk',
}, type: 'number'
{ },
arg: 'provinceFk', {
type: 'number' arg: 'provinceFk',
}, type: 'number'
{ },
arg: 'sageTaxTypeFk', {
type: 'any' arg: 'sageTaxTypeFk',
}, type: 'any'
{ },
arg: 'sageTransactionTypeFk', {
type: 'any' arg: 'sageTransactionTypeFk',
}, type: 'any'
{ },
arg: 'transferorFk', {
type: 'any' arg: 'transferorFk',
}, type: 'any'
{ },
arg: 'hasToInvoiceByAddress', {
type: 'boolean' arg: 'hasToInvoiceByAddress',
}, type: 'boolean'
{ },
arg: 'hasToInvoice', {
type: 'boolean' arg: 'hasToInvoice',
}, type: 'boolean'
{ },
arg: 'isActive', {
type: 'boolean' arg: 'isActive',
}, type: 'boolean'
{ },
arg: 'isFreezed', {
type: 'boolean' arg: 'isFreezed',
}, type: 'boolean'
{ },
arg: 'isVies', {
type: 'boolean' arg: 'isVies',
}, type: 'boolean'
{ },
arg: 'isToBeMailed', {
type: 'boolean' arg: 'isToBeMailed',
}, type: 'boolean'
{ },
arg: 'isEqualizated', {
type: 'boolean' arg: 'isEqualizated',
}, type: 'boolean'
{ },
arg: 'isTaxDataVerified', {
type: 'boolean' arg: 'isTaxDataVerified',
}, type: 'boolean'
{ },
arg: 'isTaxDataChecked', {
type: 'boolean' arg: 'isTaxDataChecked',
}, type: 'boolean'
{ },
arg: 'despiteOfClient', {
type: 'number' arg: 'despiteOfClient',
}], type: 'number'
}
],
returns: { returns: {
arg: 'res', arg: 'res',
type: 'string', type: 'string',
@ -106,46 +108,65 @@ module.exports = Self => {
} }
}); });
Self.updateFiscalData = async(ctx, clientId) => { Self.updateFiscalData = async(ctx, clientId, options) => {
let tx;
const myOptions = {};
const models = Self.app.models; const models = Self.app.models;
const args = ctx.args; const args = ctx.args;
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant');
const $t = ctx.req.__; const $t = ctx.req.__;
const client = await models.Client.findById(clientId); if (typeof options == 'object')
Object.assign(myOptions, options);
if (!isSalesAssistant && client.isTaxDataChecked) if (!myOptions.transaction) {
throw new UserError(`You can't make changes on a client with verified data`); tx = await Self.beginTransaction({});
myOptions.transaction = tx;
// Sage data validation
const taxDataChecked = args.isTaxDataChecked;
const sageTaxChecked = client.sageTaxTypeFk || args.sageTaxTypeFk;
const sageTransactionChecked = client.sageTransactionTypeFk || args.sageTransactionTypeFk;
const hasSageData = sageTaxChecked && sageTransactionChecked;
if (taxDataChecked && !hasSageData)
throw new UserError(`You need to fill sage information before you check verified data`);
if (args.despiteOfClient) {
const logRecord = {
originFk: clientId,
userFk: userId,
action: 'update',
changedModel: 'Client',
changedModelId: clientId,
description: $t(`Client checked as validated despite of duplication`, {
clientId: args.despiteOfClient
})
};
await models.ClientLog.create(logRecord);
} }
// Remove unwanted properties try {
delete args.ctx; const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', myOptions);
delete args.id; const client = await models.Client.findById(clientId, null, myOptions);
return client.updateAttributes(args); if (!isSalesAssistant && client.isTaxDataChecked)
throw new UserError(`You can't make changes on a client with verified data`);
// Sage data validation
const taxDataChecked = args.isTaxDataChecked;
const sageTaxChecked = client.sageTaxTypeFk || args.sageTaxTypeFk;
const sageTransactionChecked = client.sageTransactionTypeFk || args.sageTransactionTypeFk;
const hasSageData = sageTaxChecked && sageTransactionChecked;
if (taxDataChecked && !hasSageData)
throw new UserError(`You need to fill sage information before you check verified data`);
if (args.despiteOfClient) {
const logRecord = {
originFk: clientId,
userFk: userId,
action: 'update',
changedModel: 'Client',
changedModelId: clientId,
description: $t(`Client checked as validated despite of duplication`, {
clientId: args.despiteOfClient
})
};
await models.ClientLog.create(logRecord, myOptions);
}
// Remove unwanted properties
delete args.ctx;
delete args.id;
const updatedClient = await client.updateAttributes(args, myOptions);
if (tx) await tx.commit();
return updatedClient;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -2,42 +2,50 @@ module.exports = Self => {
Self.remoteMethodCtx('uploadFile', { Self.remoteMethodCtx('uploadFile', {
description: 'Upload and attach a file to a client', description: 'Upload and attach a file to a client',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [
arg: 'id', {
type: 'Number', arg: 'id',
description: 'The client id', type: 'number',
http: {source: 'path'} description: 'The client id',
}, { http: {source: 'path'}
arg: 'warehouseId', },
type: 'Number', {
description: 'The warehouse id', arg: 'warehouseId',
required: true type: 'number',
}, { description: 'The warehouse id',
arg: 'companyId', required: true
type: 'Number', },
description: 'The company id', {
required: true arg: 'companyId',
}, { type: 'number',
arg: 'dmsTypeId', description: 'The company id',
type: 'Number', required: true
description: 'The dms type id', },
required: true {
}, { arg: 'dmsTypeId',
arg: 'reference', type: 'number',
type: 'String', description: 'The dms type id',
required: true required: true
}, { },
arg: 'description', {
type: 'String', arg: 'reference',
required: true type: 'string',
}, { required: true
arg: 'hasFile', },
type: 'Boolean', {
description: 'True if has an attached file', arg: 'description',
required: true type: 'string',
}], required: true
},
{
arg: 'hasFile',
type: 'boolean',
description: 'True if has an attached file',
required: true
}
],
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -46,31 +54,39 @@ module.exports = Self => {
} }
}); });
Self.uploadFile = async(ctx, id) => { Self.uploadFile = async(ctx, id, options) => {
const models = Self.app.models; const models = Self.app.models;
let tx;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const promises = []; const promises = [];
const tx = await Self.beginTransaction({});
try { try {
const options = {transaction: tx}; const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions);
const uploadedFiles = await models.Dms.uploadFile(ctx, options);
uploadedFiles.forEach(dms => { uploadedFiles.forEach(dms => {
const newClientDms = models.ClientDms.create({ const newClientDms = models.ClientDms.create({
clientFk: id, clientFk: id,
dmsFk: dms.id dmsFk: dms.id
}, options); }, myOptions);
promises.push(newClientDms); promises.push(newClientDms);
}); });
const resolvedPromises = await Promise.all(promises); const resolvedPromises = await Promise.all(promises, myOptions);
await tx.commit(); if (tx) await tx.commit();
return resolvedPromises; return resolvedPromises;
} catch (err) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw err; throw e;
} }
}; };
}; };

View File

@ -1,17 +1,13 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('createWithInsurance', { Self.remoteMethod('createWithInsurance', {
description: 'Creates both classification and one insurance', description: 'Creates both classification and one insurance',
accepts: [{ accepts: [
arg: 'data', {
type: 'object', arg: 'data',
http: {source: 'body'} type: 'object',
}, { http: {source: 'body'}
arg: 'context',
type: 'object',
http: function(ctx) {
return ctx;
} }
}], ],
returns: { returns: {
root: true, root: true,
type: 'boolean' type: 'boolean'
@ -22,29 +18,36 @@ module.exports = Self => {
} }
}); });
Self.createWithInsurance = async(data, ctx) => { Self.createWithInsurance = async(data, options) => {
const tx = await Self.beginTransaction({});
const models = Self.app.models; const models = Self.app.models;
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 newClassification = await Self.create({ const newClassification = await Self.create({
client: data.clientFk, client: data.clientFk,
started: data.started started: data.started
}, options); }, myOptions);
await models.CreditInsurance.create({ await models.CreditInsurance.create({
creditClassification: newClassification.id, creditClassification: newClassification.id,
credit: data.credit, credit: data.credit,
grade: data.grade grade: data.grade
}, options); }, myOptions);
await tx.commit(); if (tx) await tx.commit();
return newClassification; return newClassification;
} catch (e) { } catch (e) {
await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };

View File

@ -1,64 +1,26 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Client createWithInsurance', () => { describe('Client createWithInsurance', () => {
const activeCtx = {
accessToken: {userId: 1101},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
const ctx = {req: activeCtx};
activeCtx.http.req.__ = value => {
return value;
};
it('should verify the classifications and insurances are untainted', async() => {
let classifications = await app.models.CreditClassification.find();
let insurances = await app.models.CreditInsurance.find();
expect(classifications.length).toEqual(5);
expect(insurances.length).toEqual(3);
});
it('should not create the insurance if couldnt create the classification', async() => {
let error;
let data = {clientFk: null, started: Date.now(), credit: 999, grade: 255};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
await app.models.CreditClassification.createWithInsurance(data, ctx)
.catch(e => {
error = e;
});
expect(error.toString()).toBe('Error: ER_BAD_NULL_ERROR: Column \'client\' cannot be null');
let classifications = await app.models.CreditClassification.find();
let insurances = await app.models.CreditInsurance.find();
expect(classifications.length).toEqual(5);
expect(insurances.length).toEqual(3);
});
it('should create a new client credit classification with insurance', async() => { it('should create a new client credit classification with insurance', async() => {
let data = {clientFk: 1101, started: Date.now(), credit: 999, grade: 255}; const tx = await models.Client.beginTransaction({});
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
let result = await app.models.CreditClassification.createWithInsurance(data, ctx);
expect(result.client).toEqual(1101); try {
const options = {transaction: tx};
const data = {clientFk: 1101, started: Date.now(), credit: 999, grade: 255};
let classifications = await app.models.CreditClassification.find(); const result = await models.CreditClassification.createWithInsurance(data, options);
let insurances = await app.models.CreditInsurance.find();
expect(classifications.length).toEqual(6); expect(result.client).toEqual(1101);
expect(insurances.length).toEqual(4);
// restore const classifications = await models.CreditClassification.find();
await app.models.CreditClassification.destroyById(result.id); const insurances = await models.CreditInsurance.find();
expect(classifications.length).toEqual(6);
expect(insurances.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -1,14 +1,21 @@
const totalGreuge = require('../sumAmount'); const models = require('vn-loopback/server/server').models;
describe('Greuge totalGreuge()', () => { describe('Greuge totalGreuge()', () => {
it('should call the sumAmount method', async() => { it('should call the sumAmount method', async() => {
let clientFk = 1; const tx = await models.Client.beginTransaction({});
let self = jasmine.createSpyObj('self', ['remoteMethod', 'rawSql']);
self.rawSql.and.returnValue(Promise.resolve([{sumAmount: 6000}]));
totalGreuge(self);
let result = await self.sumAmount(clientFk); try {
const options = {transaction: tx};
expect(result).toBe(6000); const clientId = 1;
const result = await models.Client.sumAmount(clientId, options);
expect(result).toBe(6000);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -18,10 +18,15 @@ module.exports = Self => {
} }
}); });
Self.sumAmount = async clientFk => { Self.sumAmount = async(clientFk, options) => {
let query = `SELECT SUM(amount) AS sumAmount FROM vn.greuge WHERE clientFk = ?`; const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT SUM(amount) AS sumAmount FROM vn.greuge WHERE clientFk = ?`;
try { try {
let [response] = await Self.rawSql(query, [clientFk]); const [response] = await Self.rawSql(query, [clientFk], myOptions);
return response ? response.sumAmount : 0; return response ? response.sumAmount : 0;
} catch (e) { } catch (e) {

View File

@ -7,23 +7,25 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
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',
http: {source: 'query'} http: {source: 'query'}
}, { },
{
arg: 'clientId', arg: 'clientId',
type: 'Number', type: 'number',
description: 'The client id', description: 'The client id',
required: true, required: true,
}, { },
{
arg: 'companyId', arg: 'companyId',
type: 'Number', type: 'number',
description: 'The company id', description: 'The company id',
required: true, required: true,
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -32,51 +34,56 @@ module.exports = Self => {
} }
}); });
Self.filter = async(filter, clientId, companyId) => { Self.filter = async(filter, clientId, companyId, options) => {
let stmt = new ParameterizedSQL( const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmt = new ParameterizedSQL(
`SELECT * FROM ( `SELECT * FROM (
SELECT SELECT
r.id, r.id,
r.isConciliate, r.isConciliate,
r.payed, r.payed,
r.workerFk, r.workerFk,
c.code company, c.code company,
r.created, r.created,
r.invoiceFk description, r.invoiceFk description,
NULL debit, NULL debit,
r.amountPaid credit, r.amountPaid credit,
r.bankFk, r.bankFk,
u.name userName, u.name userName,
r.clientFk, r.clientFk,
FALSE hasPdf, FALSE hasPdf,
FALSE isInvoice FALSE isInvoice
FROM vn.receipt r FROM vn.receipt r
LEFT JOIN vn.worker w ON w.id = r.workerFk LEFT JOIN vn.worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.userFk LEFT JOIN account.user u ON u.id = w.userFk
JOIN vn.company c ON c.id = r.companyFk JOIN vn.company c ON c.id = r.companyFk
WHERE r.clientFk = ? AND r.companyFk = ? WHERE r.clientFk = ? AND r.companyFk = ?
UNION ALL UNION ALL
SELECT SELECT
i.id, i.id,
TRUE, TRUE,
i.issued, i.issued,
NULL, NULL,
c.code, c.code,
i.created, i.created,
i.ref, i.ref,
i.amount, i.amount,
NULL, NULL,
NULL, NULL,
NULL, NULL,
i.clientFk, i.clientFk,
i.hasPdf, i.hasPdf,
TRUE isInvoice TRUE isInvoice
FROM vn.invoiceOut i FROM vn.invoiceOut i
JOIN vn.company c ON c.id = i.companyFk JOIN vn.company c ON c.id = i.companyFk
WHERE i.clientFk = ? AND i.companyFk = ? WHERE i.clientFk = ? AND i.companyFk = ?
ORDER BY payed DESC, created DESC ORDER BY payed DESC, created DESC
) t ) t ORDER BY payed DESC, created DESC`,
ORDER BY payed DESC, created DESC`, [ [
clientId, clientId,
companyId, companyId,
clientId, clientId,
@ -85,6 +92,7 @@ module.exports = Self => {
); );
stmt.merge(Self.makeLimit(filter)); stmt.merge(Self.makeLimit(filter));
return await Self.rawStmt(stmt);
return Self.rawStmt(stmt, myOptions);
}; };
}; };

View File

@ -1,12 +1,22 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('receipt filter()', () => { describe('receipt filter()', () => {
it('should return the receipts', async() => { it('should return the receipts', async() => {
const filter = {limit: 20}; const tx = await models.Client.beginTransaction({});
const clientId = 1101;
const companyId = 442;
let result = await app.models.Receipt.filter(filter, clientId, companyId);
expect(result.length).toBeGreaterThan(0); try {
const options = {transaction: tx};
const filter = {limit: 20};
const clientId = 1101;
const companyId = 442;
const result = await models.Receipt.filter(filter, clientId, companyId, options);
expect(result.length).toBeGreaterThan(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -21,14 +21,20 @@ module.exports = Self => {
} }
}); });
Self.hasActiveRecovery = async id => { Self.hasActiveRecovery = async(id, options) => {
let result = await Self.rawSql( const myOptions = {};
`SELECT count(*) AS hasActiveRecovery
FROM vn.recovery if (typeof options == 'object')
WHERE clientFk = ? Object.assign(myOptions, options);
AND IFNULL(finished,CURDATE()) >= CURDATE();`,
[id] const query = `
); SELECT count(*) AS hasActiveRecovery
return result[0].hasActiveRecovery != 0; FROM vn.recovery
WHERE clientFk = ?
AND IFNULL(finished,CURDATE()) >= CURDATE();
`;
const [result] = await Self.rawSql(query, [id], myOptions);
return result.hasActiveRecovery != 0;
}; };
}; };

View File

@ -1,15 +1,35 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('client hasActiveRecovery', () => { describe('client hasActiveRecovery', () => {
it(`should return false if the client doesn't owes`, async() => { it(`should return false if the client doesn't owes`, async() => {
let hasActiveRecovery = await app.models.Recovery.hasActiveRecovery(1101); const tx = await models.Client.beginTransaction({});
expect(hasActiveRecovery).toBeFalsy(); try {
const options = {transaction: tx};
const hasActiveRecovery = await models.Recovery.hasActiveRecovery(1101, options);
expect(hasActiveRecovery).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
it('should return true if the client owes', async() => { it('should return true if the client owes', async() => {
let hasActiveRecovery = await app.models.Recovery.hasActiveRecovery(1102); const tx = await models.Client.beginTransaction({});
expect(hasActiveRecovery).toBeTruthy(); try {
const options = {transaction: tx};
const hasActiveRecovery = await models.Recovery.hasActiveRecovery(1102, options);
expect(hasActiveRecovery).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
}
}); });
}); });

View File

@ -6,22 +6,24 @@ module.exports = Self => {
Self.remoteMethod('send', { Self.remoteMethod('send', {
description: 'Sends SMS to a destination phone', description: 'Sends SMS to a destination phone',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [
arg: 'destinationFk', {
type: 'Integer' arg: 'destinationFk',
}, type: 'integer'
{ },
arg: 'destination', {
type: 'String', arg: 'destination',
required: true, type: 'string',
}, required: true,
{ },
arg: 'message', {
type: 'String', arg: 'message',
required: true, type: 'string',
}], required: true,
}
],
returns: { returns: {
type: 'Object', type: 'object',
root: true root: true
}, },
http: { http: {
@ -82,6 +84,7 @@ module.exports = Self => {
}; };
const sms = await Self.create(newSms); const sms = await Self.create(newSms);
if (statusCode != 200) if (statusCode != 200)
throw new UserError(`We weren't able to send this SMS`); throw new UserError(`We weren't able to send this SMS`);