#1864 added restrictions, send rocketchat message
This commit is contained in:
parent
05c4c9e96a
commit
1b70721b0e
|
@ -0,0 +1,88 @@
|
|||
const request = require('request-promise-native');
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('sendMessage', {
|
||||
description: 'Send a RocketChat message',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'to',
|
||||
type: 'String',
|
||||
required: true,
|
||||
description: 'user (@) or channel (#) to send the message'
|
||||
}, {
|
||||
arg: 'message',
|
||||
type: 'String',
|
||||
required: true,
|
||||
description: 'The message'
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/sendMessage`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.sendMessage = async(ctx, to, message) => {
|
||||
const models = Self.app.models;
|
||||
const accessToken = ctx.req.accessToken;
|
||||
const sender = await models.Account.findById(accessToken.userId);
|
||||
|
||||
return sendMessage(to, `@${sender.name}: ${message}`);
|
||||
};
|
||||
|
||||
async function sendMessage(name, message) {
|
||||
const models = Self.app.models;
|
||||
const chatConfig = await models.ChatConfig.findOne();
|
||||
|
||||
if (!Self.token)
|
||||
Self.token = await login();
|
||||
|
||||
const uri = `${chatConfig.uri}/chat.postMessage`;
|
||||
return send(uri, {
|
||||
'channel': name,
|
||||
'text': message
|
||||
}).catch(async error => {
|
||||
if (error.statusCode === 401 && !Self.loginAttempted) {
|
||||
Self.token = await login();
|
||||
Self.loginAttempted = true;
|
||||
|
||||
return sendMessage(name, message);
|
||||
}
|
||||
|
||||
throw new Error(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rocketchat token
|
||||
* @return {Object} userId and authToken
|
||||
*/
|
||||
async function login() {
|
||||
const models = Self.app.models;
|
||||
const chatConfig = await models.ChatConfig.findOne();
|
||||
const uri = `${chatConfig.uri}/login`;
|
||||
return send(uri, {
|
||||
user: chatConfig.user,
|
||||
password: chatConfig.password
|
||||
}).then(res => res.data);
|
||||
}
|
||||
|
||||
function send(uri, body) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
uri: uri,
|
||||
body: body,
|
||||
headers: {'content-type': 'application/json'},
|
||||
json: true
|
||||
};
|
||||
|
||||
if (Self.token) {
|
||||
options.headers['X-Auth-Token'] = Self.token.authToken;
|
||||
options.headers['X-User-Id'] = Self.token.userId;
|
||||
}
|
||||
|
||||
return request(options);
|
||||
}
|
||||
};
|
|
@ -14,6 +14,12 @@
|
|||
"Container": {
|
||||
"dataSource": "storage"
|
||||
},
|
||||
"Chat": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ChatConfig": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Delivery": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "ChatConfig",
|
||||
"description": "Chat API config",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "chatConfig"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"uri": {
|
||||
"type": "String"
|
||||
},
|
||||
"user": {
|
||||
"type": "String"
|
||||
},
|
||||
"password": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"acls": [{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/chat/sendMessage')(Self);
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Chat",
|
||||
"base": "VnModel",
|
||||
"acls": [{
|
||||
"property": "validations",
|
||||
"accessType": "EXECUTE",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE `vn`.`chatConfig` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`uri` VARCHAR(255) NOT NULL,
|
||||
`user` VARCHAR(50) NOT NULL,
|
||||
`password` VARCHAR(50) NOT NULL,
|
||||
PRIMARY KEY (`id`));
|
||||
|
||||
|
||||
INSERT INTO `vn`.`chatConfig` (`uri`, `user`, `password`) VALUES ('https://chat.verdnatura.es/api/v1', 'VnBot', 'Ub606cux7op.');
|
|
@ -56,5 +56,6 @@
|
|||
"You can't delete a confirmed order": "You can't delete a confirmed order",
|
||||
"Value has an invalid format": "Value has an invalid 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}}})"
|
||||
}
|
|
@ -110,8 +110,11 @@
|
|||
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto",
|
||||
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
|
||||
"This phone already exists": "Este teléfono ya existe",
|
||||
"You cannot move a parent to any of its sons": "You cannot move a parent to any of its sons",
|
||||
"You cannot move a parent to its own sons": "You cannot move a parent to its own sons",
|
||||
"You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos",
|
||||
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado",
|
||||
"AMOUNT_NOT_MATCH_GROUPING": "AMOUNT_NOT_MATCH_GROUPING"
|
||||
"You cannot delete this ticket because is already invoiced, deleted or prepared": "No puedes eliminar este tiquet porque ya está facturado, eliminado o preparado",
|
||||
"You cannot delete a ticket that it's being prepared": "No puedes eliminar un ticket que está siendo preparado",
|
||||
"You must delete all the buy requests first": "Debes eliminar todas las peticiones de compra primero",
|
||||
"Has deleted the ticket id": "Ha eliminado el ticket id [#{{id}}]({{{url}}})",
|
||||
"You cannot remove this ticket because is already invoiced, deleted or prepared": "You cannot remove this ticket because is already invoiced, deleted or prepared"
|
||||
}
|
|
@ -43,6 +43,11 @@
|
|||
"model": "Client",
|
||||
"foreignKey": "clientFk"
|
||||
},
|
||||
"ticket": {
|
||||
"type": "belongsTo",
|
||||
"model": "Ticket",
|
||||
"foreignKey": "ticketFk"
|
||||
},
|
||||
"greugeType": {
|
||||
"type": "belongsTo",
|
||||
"model": "GreugeType",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"ItemTypeTag": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ItemShelvingSale": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Origin": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "ItemShelvingSale",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "itemShelvingSale"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "Number"
|
||||
},
|
||||
"created": {
|
||||
"type": "Date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"sale": {
|
||||
"type": "belongsTo",
|
||||
"model": "Sale",
|
||||
"foreignKey": "saleFk"
|
||||
},
|
||||
"user": {
|
||||
"type": "belongsTo",
|
||||
"model": "Account",
|
||||
"foreignKey": "userFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('setDeleted', {
|
||||
Self.remoteMethodCtx('setDeleted', {
|
||||
description: 'Sets true the isDeleted value of a ticket',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
|
@ -21,16 +21,82 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.setDeleted = async id => {
|
||||
try {
|
||||
let claimOfATicket = await Self.app.models.Claim.findOne({where: {ticketFk: id}});
|
||||
if (claimOfATicket)
|
||||
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
|
||||
Self.setDeleted = async(ctx, id) => {
|
||||
const models = Self.app.models;
|
||||
const isEditable = await Self.isEditable(ctx, id);
|
||||
const $t = ctx.req.__; // $translate
|
||||
|
||||
let currentTicket = await Self.app.models.Ticket.findById(id);
|
||||
return await currentTicket.updateAttributes({isDeleted: true});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
if (!isEditable)
|
||||
throw new UserError('You cannot delete this ticket because is already invoiced, deleted or prepared');
|
||||
|
||||
// Check if has sales with shelving
|
||||
const sales = await models.Sale.find({
|
||||
include: {relation: 'itemShelving'},
|
||||
where: {ticketFk: id}
|
||||
});
|
||||
const hasItemShelvingSales = sales.some(sale => {
|
||||
return sale.itemShelving();
|
||||
});
|
||||
if (hasItemShelvingSales)
|
||||
throw new UserError(`You cannot delete a ticket that it's being prepared`);
|
||||
|
||||
// Check for existing claim
|
||||
const claimOfATicket = await models.Claim.count({ticketFk: id});
|
||||
if (claimOfATicket)
|
||||
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
|
||||
|
||||
// Check for existing purchase requests
|
||||
const hasPurchaseRequests = await models.TicketRequest.count({
|
||||
ticketFk: id,
|
||||
isOk: true
|
||||
});
|
||||
|
||||
if (hasPurchaseRequests)
|
||||
throw new UserError('You must delete all the buy requests first');
|
||||
|
||||
// Remove ticket greuges
|
||||
const ticketGreuges = await models.Greuge.find({where: {ticketFk: id}});
|
||||
const ownGreuges = ticketGreuges.every(greuge => {
|
||||
return greuge.ticketFk = id;
|
||||
});
|
||||
if (ownGreuges) {
|
||||
for (const greuge of ticketGreuges) {
|
||||
const instance = await models.Greuge.findById(greuge.id);
|
||||
|
||||
await instance.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'salesPersonFk'],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
fields: ['id', 'userFk'],
|
||||
include: {
|
||||
relation: 'user'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Send notification to salesPerson
|
||||
const salesPerson = ticket.client().salesPerson();
|
||||
if (salesPerson) {
|
||||
const salesPersonUser = salesPerson.user().name;
|
||||
const origin = ctx.req.headers.origin;
|
||||
const message = $t(`Has deleted the ticket id`, {
|
||||
id: id,
|
||||
url: `${origin}/#!/ticket/${id}/summary`
|
||||
});
|
||||
await models.Chat.sendMessage(ctx, `@${salesPersonUser}`, message);
|
||||
}
|
||||
|
||||
return ticket.updateAttribute('isDeleted', true);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -72,6 +72,11 @@
|
|||
"type": "hasOne",
|
||||
"model": "SaleTracking",
|
||||
"foreignKey": "saleFk"
|
||||
},
|
||||
"itemShelving": {
|
||||
"type": "hasOne",
|
||||
"model": "ItemShelvingSale",
|
||||
"foreignKey": "saleFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue