-
Notifications
You must be signed in to change notification settings - Fork 6
/
e_media_notification.js
187 lines (166 loc) · 8.11 KB
/
e_media_notification.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
var builder = require('../utils/model_builder');
var fs = require('fs-extra');
var attributes_origin = require("./attributes/e_media_notification.json");
var associations = require("./options/e_media_notification.json");
var socket;
var models;
var moment = require('moment');
module.exports = (sequelize, DataTypes) => {
var attributes = builder.buildForModel(attributes_origin, DataTypes);
var options = {
tableName: 'ID_APPLICATION_e_media_notification',
timestamps: true
};
var Model = sequelize.define('E_media_notification', attributes, options);
Model.associate = builder.buildAssociation('E_media_notification', associations);
// Return an array of all the field that need to be replaced by values. Array used to include what's needed for media execution
// Ex: ['r_project.r_ticket.f_name', 'r_user.r_children.r_parent.f_name', 'r_user.r_children.r_grandparent']
Model.prototype.parseForInclude = function() {
var fieldsToParse = ['f_title', 'f_description'];
var valuesForInclude = [];
for (var i = 0; i < fieldsToParse.length; i++) {
var regex = new RegExp(/{field\|([^}]*)}/g), matches = null;
while ((matches = regex.exec(this[fieldsToParse[i]])) != null)
valuesForInclude.push(matches[1]);
}
var regex = new RegExp(/{(user_target\|[^}]*)}/g), matches = null;
while ((matches = regex.exec(this.f_targets)) != null) {
var placeholderParts = matches[1].split('|');
var userFieldPath = placeholderParts[placeholderParts.length-1];
valuesForInclude.push(userFieldPath+'.id');
}
return valuesForInclude;
}
Model.prototype.execute = function(resolve, reject, dataInstance) {
var self = this;
if (!models)
models = require('./index');
async function getGroupAndUserID() {
property = 'f_targets';
var userIds = [];
// EXTRACT GROUP USERS
// Placeholder ex: {group|Admin|1}
{
var groupIds = [];
// Exctract all group IDs from property to find them all at once
var groupRegex = new RegExp(/{(group\|[^}]*)}/g);
while ((match = groupRegex.exec(self[property])) != null) {
var placeholderParts = match[1].split('|');
var groupId = parseInt(placeholderParts[placeholderParts.length-1]);
groupIds.push(groupId);
}
// Fetch all groups found and their users
var groups = await sequelize.models.E_group.findAll({
where: {id: {$in: groupIds}},
include: {model: sequelize.models.E_user, as: 'r_user'}
});
// Exctract email and build intermediateData object used to replace placeholders
for (var i = 0; i < groups.length; i++) {
for (var j = 0; j < groups[i].r_user.length; j++)
userIds.push(groups[i].r_user[j].id);
}
}
// EXTRACT USERS
// Placeholder ex: {user|Jeremy|4}
{
// Exctract all user IDs from property to find them all at once
var userRegex = new RegExp(/{(user\|[^}]*)}/g);
while ((match = userRegex.exec(self[property])) != null) {
var placeholderParts = match[1].split('|');
var userId = parseInt(placeholderParts[placeholderParts.length-1]);
userIds.push(userId);
}
}
// EXTRACT USER TARGETED THROUGH RELATION
// Placeholder ex: {user_target|Enfant|r_parent.r_enfant}
{
function findAndPushUser(object, path, depth = 0) {
if (depth < path.length && (!path[depth] || !object[path[depth]]))
return;
if (depth < path.length)
return findAndPushUser(object[path[depth]], path, ++depth);
var targetedUser = object;
if (targetedUser instanceof Array)
for (var i = 0; i < targetedUser.length; i++)
userIds.push(targetedUser[i].id);
else
userIds.push(targetedUser.id)
}
var userRegex = new RegExp(/{(user_target\|[^}]*)}/g);
while ((match = userRegex.exec(self[property])) != null) {
var placeholderParts = match[1].split('|');
var userFieldPath = placeholderParts[placeholderParts.length-1];
// Dive in dataInstance to find targeted user
findAndPushUser(dataInstance, userFieldPath.split('.'));
}
}
// Remove duplicate id from array
userIds = userIds.filter(function(item, pos) {
return userIds.indexOf(item) == pos;
});
return userIds;
}
function insertVariablesValue(property) {
function diveData(object, depths, idx) {
if (!object[depths[idx]])
return "";
else if (typeof object[depths[idx]] === 'object') {
if (object[depths[idx]] instanceof Date)
return moment(object[depths[idx]]).format("DD/MM/YYYY");
// Case where targeted field is in an array.
// Ex: r_projet.r_participants.f_name <- Loop through r_participants and join all f_name
else if (object[depths[idx]] instanceof Array && depths.length-2 == idx) {
var values = [];
for (var i = 0; i < object[depths[idx]].length; i++)
if (typeof object[depths[idx]][i][depths[idx+1]] !== 'undefined')
values.push(object[depths[idx]][i][depths[idx+1]]);
return values.join(' ');
}
return diveData(object[depths[idx]], depths, ++idx);
} else
return object[depths[idx]];
}
var newString = self[property];
var regex = new RegExp(/{field\|([^}]*)}/g),
matches = null;
while ((matches = regex.exec(self[property])) != null)
newString = newString.replace(matches[0], diveData(dataInstance, matches[1].split('.'), 0));
return newString || "";
}
getGroupAndUserID().then(function(targetIds) {
var entityUrl, notificationObj;
try {
try {
// Build show url of targeted entity
var tableName = dataInstance.constructor.getTableName();
var prefixIdx = tableName.indexOf('_e_')+('_e_'.length);
// Remove table ID and prefix: 10_e_user -> user
entityUrl = tableName.substring(prefixIdx);
entityUrl = '/' + entityUrl + '/show?id=' + dataInstance.id;
} catch(e) {
console.log(e);
// Will redirect to current page
entityUrl = '#';
}
notificationObj = {
f_color: self.f_color,
f_icon: insertVariablesValue('f_icon'),
f_title: insertVariablesValue('f_title'),
f_description: insertVariablesValue('f_description'),
f_url: entityUrl
};
} catch (e) {
return reject(e);
}
models.E_notification.create(notificationObj).then(function(notification) {
notification.setR_user(targetIds);
if (!socket)
socket = require('../services/socket')();
socket.sendNotification(notification, targetIds);
resolve();
}).catch(reject);
});
}
builder.addHooks(Model, 'e_media_notification', attributes_origin);
return Model;
};