Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2014-remove_bi_from_db
gitea/salix/2014-remove_bi_from_db This commit looks good
Details
gitea/salix/2014-remove_bi_from_db This commit looks good
Details
This commit is contained in:
commit
b244df4807
|
@ -7,7 +7,7 @@ module.exports = Self => {
|
||||||
arg: 'to',
|
arg: 'to',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'user (@) or channel (#) to send the message'
|
description: 'User (@) or channel (#) to send the message'
|
||||||
}, {
|
}, {
|
||||||
arg: 'message',
|
arg: 'message',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
|
@ -31,26 +31,23 @@ module.exports = Self => {
|
||||||
const recipient = to.replace('@', '');
|
const recipient = to.replace('@', '');
|
||||||
|
|
||||||
if (sender.name != recipient)
|
if (sender.name != recipient)
|
||||||
return sendMessage(to, `@${sender.name}: ${message}`);
|
return sendMessage(sender, to, `@${sender.name}: ${message} `);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function sendMessage(name, message) {
|
async function sendMessage(sender, channel, message) {
|
||||||
const models = Self.app.models;
|
const config = await getConfig();
|
||||||
const chatConfig = await models.ChatConfig.findOne();
|
const avatar = `${config.host}/avatar/${sender.name}`;
|
||||||
|
const uri = `${config.api}/chat.postMessage`;
|
||||||
|
|
||||||
if (!Self.token)
|
return sendAuth(uri, {
|
||||||
Self.token = await login();
|
'channel': channel,
|
||||||
|
'avatar': avatar,
|
||||||
const uri = `${chatConfig.uri}/chat.postMessage`;
|
|
||||||
return makeRequest(uri, {
|
|
||||||
'channel': name,
|
|
||||||
'text': message
|
'text': message
|
||||||
}).catch(async error => {
|
}).catch(async error => {
|
||||||
if (error.statusCode === 401 && !Self.loginAttempted) {
|
if (error.statusCode === 401 && !this.resendAttempted) {
|
||||||
Self.token = await login();
|
this.resendAttempted = true;
|
||||||
Self.loginAttempted = true;
|
|
||||||
|
|
||||||
return sendMessage(name, message);
|
return sendMessage(sender, channel, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(error.message);
|
throw new Error(error.message);
|
||||||
|
@ -61,24 +58,51 @@ module.exports = Self => {
|
||||||
* Returns a rocketchat token
|
* Returns a rocketchat token
|
||||||
* @return {Object} userId and authToken
|
* @return {Object} userId and authToken
|
||||||
*/
|
*/
|
||||||
async function login() {
|
async function getAuthToken() {
|
||||||
const models = Self.app.models;
|
if (!this.auth || this.auth && !this.auth.authToken) {
|
||||||
const chatConfig = await models.ChatConfig.findOne();
|
const config = await getConfig();
|
||||||
const uri = `${chatConfig.uri}/login`;
|
const uri = `${config.api}/login`;
|
||||||
return makeRequest(uri, {
|
const res = await send(uri, {
|
||||||
user: chatConfig.user,
|
user: config.user,
|
||||||
password: chatConfig.password
|
password: config.password
|
||||||
}).then(res => res.data);
|
});
|
||||||
|
|
||||||
|
this.auth = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeRequest(uri, body) {
|
/**
|
||||||
|
* Returns a rocketchat config
|
||||||
|
* @return {Object} Auth config
|
||||||
|
*/
|
||||||
|
async function getConfig() {
|
||||||
|
if (!this.chatConfig) {
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
|
this.chatConfig = await models.ChatConfig.findOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.chatConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send unauthenticated request
|
||||||
|
* @param {*} uri - Request uri
|
||||||
|
* @param {*} body - Request params
|
||||||
|
* @param {*} options - Request options
|
||||||
|
*
|
||||||
|
* @return {Object} Request response
|
||||||
|
*/
|
||||||
|
async function send(uri, body, options) {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
return resolve({statusCode: 200, message: 'Fake notification sent'});
|
return resolve({statusCode: 200, message: 'Fake notification sent'});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const defaultOptions = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
uri: uri,
|
uri: uri,
|
||||||
body: body,
|
body: body,
|
||||||
|
@ -86,11 +110,29 @@ module.exports = Self => {
|
||||||
json: true
|
json: true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Self.token) {
|
if (options) Object.assign(defaultOptions, options);
|
||||||
options.headers['X-Auth-Token'] = Self.token.authToken;
|
|
||||||
options.headers['X-User-Id'] = Self.token.userId;
|
return request(defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send authenticated request
|
||||||
|
* @param {*} uri - Request uri
|
||||||
|
* @param {*} body - Request params
|
||||||
|
*
|
||||||
|
* @return {Object} Request response
|
||||||
|
*/
|
||||||
|
async function sendAuth(uri, body) {
|
||||||
|
const login = await getAuthToken();
|
||||||
|
const options = {
|
||||||
|
headers: {'content-type': 'application/json'}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (login) {
|
||||||
|
options.headers['X-Auth-Token'] = login.authToken;
|
||||||
|
options.headers['X-User-Id'] = login.userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return request(options);
|
return send(uri, body, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethodCtx('send', {
|
|
||||||
description: 'Send message to user',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'data',
|
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
description: 'recipientFk, message',
|
|
||||||
http: {source: 'body'}
|
|
||||||
}, {
|
|
||||||
arg: 'context',
|
|
||||||
type: 'object',
|
|
||||||
http: function(ctx) {
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: 'boolean',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/:recipient/send`,
|
|
||||||
verb: 'post'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.send = async(ctx, data, options) => {
|
|
||||||
const accessToken = ctx.options && ctx.options.accessToken || ctx.req && ctx.req.accessToken;
|
|
||||||
const userId = accessToken.userId;
|
|
||||||
const models = Self.app.models;
|
|
||||||
const sender = await models.Account.findById(userId, null, options);
|
|
||||||
const recipient = await models.Account.findById(data.recipientFk, null, options);
|
|
||||||
|
|
||||||
await Self.create({
|
|
||||||
sender: sender.name,
|
|
||||||
recipient: recipient.name,
|
|
||||||
message: data.message
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
return await models.MessageInbox.create({
|
|
||||||
sender: sender.name,
|
|
||||||
recipient: recipient.name,
|
|
||||||
finalRecipient: recipient.name,
|
|
||||||
message: data.message
|
|
||||||
}, options);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,14 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('message send()', () => {
|
|
||||||
it('should return a response containing the same message in params', async() => {
|
|
||||||
let ctx = {req: {accessToken: {userId: 1}}};
|
|
||||||
let params = {
|
|
||||||
recipientFk: 1,
|
|
||||||
message: 'I changed something'
|
|
||||||
};
|
|
||||||
let response = await app.models.Message.send(ctx, params, {transaction: 'You'});
|
|
||||||
|
|
||||||
expect(response.message).toEqual(params.message);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -23,12 +23,6 @@
|
||||||
"Delivery": {
|
"Delivery": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Message": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"MessageInbox": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"Province": {
|
"Province": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
{
|
|
||||||
"name": "MessageInbox",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "messageInbox"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "Number",
|
|
||||||
"id": true,
|
|
||||||
"description": "Identifier"
|
|
||||||
},
|
|
||||||
"sender": {
|
|
||||||
"type": "String",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"recipient": {
|
|
||||||
"type": "String",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"finalRecipient": {
|
|
||||||
"type": "String",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"type": "String"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"relations": {
|
|
||||||
"remitter": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "User",
|
|
||||||
"foreignKey": "sender"
|
|
||||||
},
|
|
||||||
"receptor": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "User",
|
|
||||||
"foreignKey": "recipient"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
require('../methods/message/send')(Self);
|
|
||||||
};
|
|
|
@ -1,39 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Message",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "message"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "Number",
|
|
||||||
"id": true,
|
|
||||||
"description": "Identifier"
|
|
||||||
},
|
|
||||||
"sender": {
|
|
||||||
"type": "String",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"recipient": {
|
|
||||||
"type": "String",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"type": "String"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"relations": {
|
|
||||||
"remitter": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "User",
|
|
||||||
"foreignKey": "sender"
|
|
||||||
},
|
|
||||||
"receptor": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "User",
|
|
||||||
"foreignKey": "recipient"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -57,5 +57,9 @@
|
||||||
"The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format",
|
"The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format",
|
||||||
"Can't create stowaway for this ticket": "Can't create stowaway for this ticket",
|
"Can't create stowaway for this ticket": "Can't create stowaway for this ticket",
|
||||||
"Has deleted the ticket id": "Has deleted the ticket id [#{{id}}]({{{url}}})",
|
"Has deleted the ticket id": "Has deleted the ticket id [#{{id}}]({{{url}}})",
|
||||||
"Swift / BIC can't be empty": "Swift / BIC can't be empty"
|
"Swift / BIC can't be empty": "Swift / BIC can't be empty",
|
||||||
|
"MESSAGE_BOUGHT_UNITS": "Bought {{quantity}} units of {{concept}} (#{{itemId}}) for the ticket id [#{{ticketId}}]({{{url}}})",
|
||||||
|
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} (#{{clientId}})]({{{url}}}) to *{{credit}} €*",
|
||||||
|
"MESSAGE_CHANGED_PAYMETHOD": "I have changed the pay method for client [{{clientName}} (#{{clientId}})]({{{url}}})",
|
||||||
|
"MESSAGE_CLAIM_ITEM_REGULARIZE": "I sent *{{quantity}}* units of [{{concept}} (#{{itemId}})]({{{itemUrl}}}) to {{nickname}} coming from ticket id [#{{ticketId}}]({{{ticketUrl}}})"
|
||||||
}
|
}
|
|
@ -118,5 +118,9 @@
|
||||||
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín",
|
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín",
|
||||||
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín",
|
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín",
|
||||||
"You should mark at least one week day": "Debes marcar al menos un día de la semana",
|
"You should mark at least one week day": "Debes marcar al menos un día de la semana",
|
||||||
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío"
|
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío",
|
||||||
|
"MESSAGE_BOUGHT_UNITS": "Se ha comprado {{quantity}} unidades de {{concept}} (#{{itemId}}) para el ticket id [#{{ticketId}}]({{{url}}})",
|
||||||
|
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} (#{{clientId}})]({{{url}}}) a *{{credit}} €*",
|
||||||
|
"MESSAGE_CHANGED_PAYMETHOD": "He cambiado la forma de pago del cliente [{{clientName}} (#{{clientId}})]({{{url}}})",
|
||||||
|
"MESSAGE_CLAIM_ITEM_REGULARIZE": "Envio *{{quantity}}* unidades de [{{concept}} (#{{itemId}})]({{{itemUrl}}}) a {{nickname}} provenientes del ticket id [#{{ticketId}}]({{{ticketUrl}}})"
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.regularizeClaim = async(ctx, params) => {
|
Self.regularizeClaim = async(ctx, params) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
const resolvedState = 3;
|
const resolvedState = 3;
|
||||||
|
|
||||||
let tx = await Self.beginTransaction({});
|
let tx = await Self.beginTransaction({});
|
||||||
|
@ -38,8 +39,7 @@ module.exports = Self => {
|
||||||
const destination = claimEnd.claimDestination();
|
const destination = claimEnd.claimDestination();
|
||||||
const addressFk = destination && destination.addressFk;
|
const addressFk = destination && destination.addressFk;
|
||||||
|
|
||||||
if (!addressFk)
|
if (!addressFk) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
let sale = await getSale(claimEnd.saleFk, options);
|
let sale = await getSale(claimEnd.saleFk, options);
|
||||||
let ticketFk = await getTicketId({
|
let ticketFk = await getTicketId({
|
||||||
|
@ -70,15 +70,19 @@ module.exports = Self => {
|
||||||
discount: 100
|
discount: 100
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
if (sale.ticket().client().salesPerson()) {
|
const salesPerson = sale.ticket().client().salesPerson();
|
||||||
await sendMessage(ctx, {
|
if (salesPerson) {
|
||||||
itemFk: sale.itemFk,
|
const origin = ctx.req.headers.origin;
|
||||||
ticketFk: sale.ticketFk,
|
const message = $t('MESSAGE_CLAIM_ITEM_REGULARIZE', {
|
||||||
recipientFk: sale.ticket().client().salesPerson().userFk,
|
|
||||||
quantity: sale.quantity,
|
quantity: sale.quantity,
|
||||||
concept: sale.concept,
|
concept: sale.concept,
|
||||||
nickname: address.nickname
|
itemId: sale.itemFk,
|
||||||
}, options);
|
ticketId: sale.ticketFk,
|
||||||
|
nickname: address.nickname,
|
||||||
|
ticketUrl: `${origin}/#!/ticket/${sale.ticketFk}/summary`,
|
||||||
|
itemUrl: `${origin}/#!/item/${sale.itemFk}/summary`
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,14 +160,4 @@ module.exports = Self => {
|
||||||
|
|
||||||
return ticket.id;
|
return ticket.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendMessage(ctx, params, options) {
|
|
||||||
const message = `Envio ${params.quantity} unidades de "${params.concept}" (#${params.itemFk}) a `
|
|
||||||
+ `"${params.nickname}" provenientes del ticket #${params.ticketFk}`;
|
|
||||||
|
|
||||||
await Self.app.models.Message.send(ctx, {
|
|
||||||
recipientFk: params.recipientFk,
|
|
||||||
message: message
|
|
||||||
}, options);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,13 @@ describe('regularizeClaim()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change claim state to resolved', async() => {
|
it('should change claim state to resolved', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
const ctx = {req: {
|
||||||
|
accessToken: {userId: 18},
|
||||||
|
headers: {origin: 'http://localhost'}}
|
||||||
|
};
|
||||||
|
ctx.req.__ = value => {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
let params = {claimFk: claimFk};
|
let params = {claimFk: claimFk};
|
||||||
|
|
||||||
claimEnds = await app.models.ClaimEnd.importTicketSales(ctx, {
|
claimEnds = await app.models.ClaimEnd.importTicketSales(ctx, {
|
||||||
|
|
|
@ -23,23 +23,25 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.createWithInsurance = async(data, ctx) => {
|
Self.createWithInsurance = async(data, ctx) => {
|
||||||
let tx = await Self.beginTransaction({});
|
const tx = await Self.beginTransaction({});
|
||||||
|
const models = Self.app.models;
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
let options = {transaction: tx};
|
||||||
|
|
||||||
let classificationSchema = {client: data.clientFk, started: data.started};
|
const newClassification = await Self.create({
|
||||||
let newClassification = await Self.create(classificationSchema, options);
|
client: data.clientFk,
|
||||||
let CreditInsurance = Self.app.models.CreditInsurance;
|
started: data.started
|
||||||
let insuranceSchema = {
|
}, options);
|
||||||
|
|
||||||
|
await models.CreditInsurance.create({
|
||||||
creditClassification: newClassification.id,
|
creditClassification: newClassification.id,
|
||||||
credit: data.credit,
|
credit: data.credit,
|
||||||
grade: data.grade
|
grade: data.grade
|
||||||
};
|
}, options);
|
||||||
|
|
||||||
let newCreditInsurance = await CreditInsurance.create(insuranceSchema, options);
|
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
await CreditInsurance.messageSend(newCreditInsurance, ctx.req.accessToken);
|
|
||||||
|
|
||||||
return newClassification;
|
return newClassification;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Client createWithInsurance', () => {
|
describe('Client createWithInsurance', () => {
|
||||||
let classificationId;
|
let classificationId;
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 101},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
activeCtx.http.req.__ = value => {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
afterAll(async done => {
|
afterAll(async done => {
|
||||||
await app.models.CreditClassification.destroyById(classificationId);
|
await app.models.CreditClassification.destroyById(classificationId);
|
||||||
|
@ -20,7 +33,9 @@ describe('Client createWithInsurance', () => {
|
||||||
it('should not create the insurance if couldnt create the classification', async() => {
|
it('should not create the insurance if couldnt create the classification', async() => {
|
||||||
let error;
|
let error;
|
||||||
let data = {clientFk: null, started: Date.now(), credit: 999, grade: 255};
|
let data = {clientFk: null, started: Date.now(), credit: 999, grade: 255};
|
||||||
let ctx = {req: {accessToken: {userId: 101}}};
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
await app.models.CreditClassification.createWithInsurance(data, ctx)
|
await app.models.CreditClassification.createWithInsurance(data, ctx)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
|
@ -37,7 +52,9 @@ describe('Client createWithInsurance', () => {
|
||||||
|
|
||||||
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: 101, started: Date.now(), credit: 999, grade: 255};
|
let data = {clientFk: 101, started: Date.now(), credit: 999, grade: 255};
|
||||||
let ctx = {req: {accessToken: {userId: 101}}};
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
let result = await app.models.CreditClassification.createWithInsurance(data, ctx);
|
let result = await app.models.CreditClassification.createWithInsurance(data, ctx);
|
||||||
|
|
||||||
classificationId = result.id;
|
classificationId = result.id;
|
||||||
|
|
|
@ -225,34 +225,38 @@ module.exports = Self => {
|
||||||
const newInstance = hookState.newInstance;
|
const newInstance = hookState.newInstance;
|
||||||
const oldInstance = hookState.oldInstance;
|
const oldInstance = hookState.oldInstance;
|
||||||
const instance = ctx.instance;
|
const instance = ctx.instance;
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
const payMethodChanged = oldInstance.payMethodFk != newInstance.payMethodFk;
|
const payMethodChanged = oldInstance.payMethodFk != newInstance.payMethodFk;
|
||||||
const ibanChanged = oldInstance.iban != newInstance.iban;
|
const ibanChanged = oldInstance.iban != newInstance.iban;
|
||||||
const dueDayChanged = oldInstance.dueDay != newInstance.dueDay;
|
const dueDayChanged = oldInstance.dueDay != newInstance.dueDay;
|
||||||
|
|
||||||
if (payMethodChanged || ibanChanged || dueDayChanged) {
|
if (payMethodChanged || ibanChanged || dueDayChanged) {
|
||||||
const message = `La forma de pago del cliente con id ${instance.id} ha cambiado`;
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
const salesPersonFk = instance.salesPersonFk;
|
const httpCtx = {req: loopBackContext.active};
|
||||||
|
const httpRequest = httpCtx.req.http.req;
|
||||||
|
const $t = httpRequest.__;
|
||||||
|
const origin = httpRequest.headers.origin;
|
||||||
|
|
||||||
if (salesPersonFk) {
|
const salesPersonId = instance.salesPersonFk;
|
||||||
const salesPerson = await Self.app.models.Worker.findById(salesPersonFk);
|
|
||||||
await Self.app.models.Message.send(ctx, {
|
if (salesPersonId) {
|
||||||
recipientFk: salesPerson.userFk,
|
const fullUrl = `${origin}/#!/client/${instance.id}/billing-data`;
|
||||||
message: message
|
const message = $t('MESSAGE_CHANGED_PAYMETHOD', {
|
||||||
|
clientId: instance.id,
|
||||||
|
clientName: instance.name,
|
||||||
|
url: fullUrl
|
||||||
});
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(httpCtx, salesPersonId, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send email to client
|
// Send email to client
|
||||||
|
|
||||||
if (!instance.email) return;
|
if (!instance.email) return;
|
||||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
const serializedParams = httpParamSerializer({
|
||||||
const headers = loopBackContext.active.http.req.headers;
|
|
||||||
const params = {
|
|
||||||
clientId: instance.id,
|
clientId: instance.id,
|
||||||
recipient: instance.email
|
recipient: instance.email
|
||||||
};
|
});
|
||||||
const serializedParams = httpParamSerializer(params);
|
const query = `${origin}/api/email/payment-update?${serializedParams}`;
|
||||||
const query = `${headers.origin}/api/email/payment-update?${serializedParams}`;
|
|
||||||
await request.get(query);
|
await request.get(query);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
Self.validateCredit = function(credit) {
|
Self.validateCredit = function(credit) {
|
||||||
return credit >= 0;
|
return credit >= 0;
|
||||||
|
@ -38,54 +40,31 @@ module.exports = function(Self) {
|
||||||
message: 'The grade must be similar to the last one'
|
message: 'The grade must be similar to the last one'
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.messageSend = async function(data, accessToken) {
|
|
||||||
let filter = {
|
|
||||||
include: {
|
|
||||||
relation: 'classification',
|
|
||||||
scope: {
|
|
||||||
fields: ['client'],
|
|
||||||
include: {
|
|
||||||
relation: 'customer',
|
|
||||||
scope: {
|
|
||||||
fields: ['name', 'salesPersonFk'],
|
|
||||||
include: {
|
|
||||||
relation: 'salesPerson',
|
|
||||||
scope: {
|
|
||||||
fields: 'userFk',
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ctx = {req: {accessToken: accessToken}};
|
|
||||||
let insurance = await Self.findById(data.id, filter);
|
|
||||||
let customer = insurance.classification().customer();
|
|
||||||
|
|
||||||
if (!customer.salesPerson()) return;
|
|
||||||
let salesPersonId = customer.salesPerson().user().id;
|
|
||||||
let grade = data.grade ? `(Grado ${data.grade})` : '(Sin grado)';
|
|
||||||
let params = {
|
|
||||||
recipientFk: salesPersonId,
|
|
||||||
message: `He cambiado el crédito asegurado del `
|
|
||||||
+ `cliente "${customer.name}" a ${data.credit} € ${grade}`
|
|
||||||
};
|
|
||||||
|
|
||||||
Self.app.models.Message.send(ctx, params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update from transaction misses ctx accessToken.
|
|
||||||
// Fixed passing accessToken from method messageSend()
|
|
||||||
Self.observe('after save', async function(ctx) {
|
Self.observe('after save', async function(ctx) {
|
||||||
if (ctx.options.accessToken)
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
await Self.messageSend(ctx.instance, ctx.options.accessToken);
|
const httpCtx = {req: loopBackContext.active};
|
||||||
|
const options = ctx.options ? ctx.options : null;
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
|
if (!ctx.isNewInstance) return;
|
||||||
|
|
||||||
|
const data = ctx.instance;
|
||||||
|
const insurance = await Self.findById(data.id, null, options);
|
||||||
|
const client = insurance.classification().customer();
|
||||||
|
const salesPerson = client.salesPerson();
|
||||||
|
|
||||||
|
if (!salesPerson) return;
|
||||||
|
|
||||||
|
const httpRequest = httpCtx.req.http.req;
|
||||||
|
const $t = httpRequest.__;
|
||||||
|
const origin = httpRequest.headers.origin;
|
||||||
|
const fullPath = `${origin}/#!/client/${client.id}`;
|
||||||
|
const message = $t('MESSAGE_INSURANCE_CHANGE', {
|
||||||
|
clientId: client.id,
|
||||||
|
clientName: client.name,
|
||||||
|
credit: data.credit,
|
||||||
|
url: fullPath
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(httpCtx, salesPerson.id, message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,5 +32,31 @@
|
||||||
"model": "CreditClassification",
|
"model": "CreditClassification",
|
||||||
"foreignKey": "creditClassification"
|
"foreignKey": "creditClassification"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"include": {
|
||||||
|
"relation": "classification",
|
||||||
|
"scope": {
|
||||||
|
"fields": ["client"],
|
||||||
|
"include": {
|
||||||
|
"relation": "customer",
|
||||||
|
"scope": {
|
||||||
|
"fields": ["name", "salesPersonFk"],
|
||||||
|
"include": {
|
||||||
|
"relation": "salesPerson",
|
||||||
|
"scope": {
|
||||||
|
"fields": "userFk",
|
||||||
|
"include": {
|
||||||
|
"relation": "user",
|
||||||
|
"scope": {
|
||||||
|
"fields": ["name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,8 +32,9 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.confirm = async ctx => {
|
Self.confirm = async ctx => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const tx = await Self.beginTransaction({});
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
let sale;
|
let sale;
|
||||||
let tx = await Self.beginTransaction({});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
let options = {transaction: tx};
|
||||||
|
@ -59,7 +60,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
if (request.saleFk) {
|
if (request.saleFk) {
|
||||||
sale = await models.Sale.findById(request.saleFk, null, options);
|
sale = await models.Sale.findById(request.saleFk, null, options);
|
||||||
sale.updateAttributes({
|
await sale.updateAttributes({
|
||||||
itemFk: ctx.args.itemFk,
|
itemFk: ctx.args.itemFk,
|
||||||
quantity: ctx.args.quantity,
|
quantity: ctx.args.quantity,
|
||||||
concept: item.name,
|
concept: item.name,
|
||||||
|
@ -71,7 +72,7 @@ module.exports = Self => {
|
||||||
quantity: ctx.args.quantity,
|
quantity: ctx.args.quantity,
|
||||||
concept: item.name
|
concept: item.name
|
||||||
}, options);
|
}, options);
|
||||||
request.updateAttributes({
|
await request.updateAttributes({
|
||||||
saleFk: sale.id,
|
saleFk: sale.id,
|
||||||
itemFk: sale.itemFk,
|
itemFk: sale.itemFk,
|
||||||
isOk: true
|
isOk: true
|
||||||
|
@ -81,13 +82,16 @@ module.exports = Self => {
|
||||||
query = `CALL vn.ticketCalculateSale(?)`;
|
query = `CALL vn.ticketCalculateSale(?)`;
|
||||||
await Self.rawSql(query, [sale.id], options);
|
await Self.rawSql(query, [sale.id], options);
|
||||||
|
|
||||||
const message = `Se ha comprado ${sale.quantity} unidades de "${sale.concept}" (#${sale.itemFk}) `
|
const origin = ctx.req.headers.origin;
|
||||||
+ `para el ticket #${sale.ticketFk}`;
|
const requesterId = request.requesterFk;
|
||||||
|
const message = $t('MESSAGE_BOUGHT_UNITS', {
|
||||||
await models.Message.send(ctx, {
|
quantity: sale.quantity,
|
||||||
recipientFk: request.requesterFk,
|
concept: sale.concept,
|
||||||
message: message
|
itemId: sale.itemFk,
|
||||||
}, options);
|
ticketId: sale.ticketFk,
|
||||||
|
url: `${origin}/#!/ticket/${sale.ticketFk}/summary`
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, requesterId, message);
|
||||||
|
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,15 @@ describe('ticket-request confirm()', () => {
|
||||||
let originalRequest;
|
let originalRequest;
|
||||||
let originalSale;
|
let originalSale;
|
||||||
let createdSaleId;
|
let createdSaleId;
|
||||||
|
let ctx = {
|
||||||
|
req: {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.req.__ = value => {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
afterAll(async done => {
|
afterAll(async done => {
|
||||||
await originalRequest.updateAttributes(originalRequest);
|
await originalRequest.updateAttributes(originalRequest);
|
||||||
|
@ -13,9 +22,9 @@ describe('ticket-request confirm()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should throw an error if the item doesn't exist`, async() => {
|
it(`should throw an error if the item doesn't exist`, async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}, args: {itemFk: 999}};
|
ctx.args = {itemFk: 999};
|
||||||
let error;
|
|
||||||
|
|
||||||
|
let error;
|
||||||
try {
|
try {
|
||||||
await app.models.TicketRequest.confirm(ctx);
|
await app.models.TicketRequest.confirm(ctx);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -30,11 +39,12 @@ describe('ticket-request confirm()', () => {
|
||||||
const itemId = 4;
|
const itemId = 4;
|
||||||
const quantity = 99999;
|
const quantity = 99999;
|
||||||
|
|
||||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
ctx.args = {
|
||||||
itemFk: itemId,
|
itemFk: itemId,
|
||||||
id: requestId,
|
id: requestId,
|
||||||
quantity: quantity
|
quantity: quantity
|
||||||
}};
|
};
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -52,18 +62,17 @@ describe('ticket-request confirm()', () => {
|
||||||
const itemId = 1;
|
const itemId = 1;
|
||||||
const quantity = 10;
|
const quantity = 10;
|
||||||
|
|
||||||
|
ctx.args = {
|
||||||
|
itemFk: itemId,
|
||||||
|
id: requestId,
|
||||||
|
quantity: quantity
|
||||||
|
};
|
||||||
|
|
||||||
originalRequest = await app.models.TicketRequest.findById(requestId);
|
originalRequest = await app.models.TicketRequest.findById(requestId);
|
||||||
originalSale = await app.models.Sale.findById(saleId);
|
originalSale = await app.models.Sale.findById(saleId);
|
||||||
|
|
||||||
const request = await app.models.TicketRequest.findById(requestId);
|
const request = await app.models.TicketRequest.findById(requestId);
|
||||||
await request.updateAttributes({saleFk: saleId});
|
await request.updateAttributes({saleFk: saleId});
|
||||||
|
|
||||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
|
||||||
itemFk: itemId,
|
|
||||||
id: requestId,
|
|
||||||
quantity: quantity
|
|
||||||
}};
|
|
||||||
|
|
||||||
await app.models.TicketRequest.confirm(ctx);
|
await app.models.TicketRequest.confirm(ctx);
|
||||||
|
|
||||||
let updatedSale = await app.models.Sale.findById(saleId);
|
let updatedSale = await app.models.Sale.findById(saleId);
|
||||||
|
@ -77,16 +86,14 @@ describe('ticket-request confirm()', () => {
|
||||||
const itemId = 1;
|
const itemId = 1;
|
||||||
const quantity = 10;
|
const quantity = 10;
|
||||||
|
|
||||||
const request = await app.models.TicketRequest.findById(requestId);
|
ctx.args = {
|
||||||
await request.updateAttributes({saleFk: null});
|
|
||||||
|
|
||||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
|
||||||
itemFk: itemId,
|
itemFk: itemId,
|
||||||
id: requestId,
|
id: requestId,
|
||||||
quantity: quantity,
|
quantity: quantity
|
||||||
ticketFk: 1
|
};
|
||||||
}};
|
|
||||||
|
|
||||||
|
const request = await app.models.TicketRequest.findById(requestId);
|
||||||
|
await request.updateAttributes({saleFk: null});
|
||||||
await app.models.TicketRequest.confirm(ctx);
|
await app.models.TicketRequest.confirm(ctx);
|
||||||
|
|
||||||
let updatedRequest = await app.models.TicketRequest.findById(requestId);
|
let updatedRequest = await app.models.TicketRequest.findById(requestId);
|
||||||
|
|
|
@ -4,7 +4,7 @@ const smtp = require('../core/smtp');
|
||||||
const config = require('../core/config');
|
const config = require('../core/config');
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
app.get('/api/closure', async function(req, res) {
|
app.get('/api/closure', async function(request, response) {
|
||||||
const failedtickets = [];
|
const failedtickets = [];
|
||||||
const tickets = await db.rawSql(`
|
const tickets = await db.rawSql(`
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -59,7 +59,7 @@ module.exports = app => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({
|
response.status(200).json({
|
||||||
message: 'Closure executed successfully'
|
message: 'Closure executed successfully'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue