-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMeals.js
142 lines (107 loc) · 3.26 KB
/
Meals.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
export default class Meals {
constructor(model, models = {}, sequelize = null) {
this.model = model;
this.models = models;
this.sequelize = sequelize;
/*
* Get meal's eaters
*/
this.model.belongsToMany(this.models.members, {
as: 'Eaters',
through: 'meals_members',
foreignKey: 'meals_id',
otherKey: 'members_id',
constraints: false
});
/*
* Get chat members where meal was created
*/
this.model.hasMany(this.models.members, {
as: 'Members',
foreignKey: 'chats_id',
sourceKey: 'chats_id',
constraints: false
});
this.model.belongsTo(this.models.members, {
as: 'Payer',
foreignKey: 'payers_id',
constraints: false
})
}
/**
* Create new meal in chat
* Attach it to message
* @param chats_id
* @returns {Promise<void>}
*/
async create({chats_id}) {
return this.model.create({chats_id})
};
/**
* Get meal from chat
* @param meals_id
* @param raw
* @returns {Promise<Model>}
*/
async get({meals_id, raw = false}) {
return this.model.findOne({
where: {id: meals_id},
include: ['Eaters', 'Members', 'Payer'],
raw
});
};
/**
* Clear all meals from chat
* @param chats_id
* @returns {Promise<Array<Model>>}
*/
async clear({chats_id}) {
return this.model.destroy({
where: {chats_id}
});
}
/**
* Update payer
* @param meals_id
* @param chats_id
* @returns {Promise<*>}
*/
async payer({meals_id, chats_id}) {
const meal = await this.get({meals_id});
const eaters = meal.Eaters instanceof Array ? meal.Eaters.map(e => e.id) : [];
const paid = (await this.sequelize.query(`
select
m.id,
count(mm.members_id) as eaters,
m.payers_id
from meals as m
inner join meals_members as mm on m.id = mm.meals_id
where m.id != :meals_id and m.confirmed = 1 and m.chats_id = :chats_id
group by m.id
HAVING (SUM(mm.members_id NOT IN (:eaters)) = 0 AND SUM(mm.members_id IN (:eaters)) = :eaters_number)
order by m.createdAt desc
limit :meals_limit`,
{
replacements: {
chats_id,
eaters: eaters,
meals_id: meal.id,
eaters_number: eaters.length,
meals_limit: (eaters.length - 1) < 0 ? 0 : (eaters.length - 1),
}, type: this.sequelize.QueryTypes.SELECT
}
)).map(p => p.payers_id);
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
/*
* Get eaters who are not pay yet
* In last meals
*/
const payers = eaters.diff(paid);
/*
* Get payers_id and update meal
*/
return meal.updateAttributes({payers_id: payers[0] ? payers[0] : null})
}
}