Merge lp:~openerp-dev/openobject-addons/saas-4-gamification-fixes-mat into lp:~openerp/openobject-addons/saas-4

Proposed by Martin Trigaux (OpenERP)
Status: Merged
Merged at revision: 9362
Proposed branch: lp:~openerp-dev/openobject-addons/saas-4-gamification-fixes-mat
Merge into: lp:~openerp/openobject-addons/saas-4
Diff against target: 360 lines (+98/-79)
9 files modified
gamification/data/goal_base.xml (+2/-2)
gamification/models/challenge.py (+89/-70)
gamification/models/res_users.py (+0/-1)
gamification/views/challenge.xml (+1/-0)
gamification_sale_crm/sale_crm_goals.xml (+2/-2)
website_forum/data/badges_answer.xml (+1/-1)
website_forum/data/badges_moderation.xml (+1/-1)
website_forum/data/badges_participation.xml (+1/-1)
website_forum/data/badges_question.xml (+1/-1)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/saas-4-gamification-fixes-mat
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+216452@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'gamification/data/goal_base.xml'
2--- gamification/data/goal_base.xml 2014-04-16 15:10:26 +0000
3+++ gamification/data/goal_base.xml 2014-04-22 07:53:23 +0000
4@@ -164,7 +164,7 @@
5 <field name="period">once</field>
6 <field name="visibility_mode">personal</field>
7 <field name="report_message_frequency">never</field>
8- <field name="user_domain">[('groups_id', 'in', ref('base.group_user'))]</field>
9+ <field name="user_domain" eval="[('groups_id', '=', ref('base.group_user'))]" />
10 <field name="state">inprogress</field>
11 <field name="category">other</field>
12 </record>
13@@ -174,7 +174,7 @@
14 <field name="period">once</field>
15 <field name="visibility_mode">personal</field>
16 <field name="report_message_frequency">never</field>
17- <field name="user_domain">[('groups_id', 'in', ref('base.user_root'))]</field>
18+ <field name="user_domain" eval="[('groups_id', '=', ref('base.group_erp_manager'))]" />
19 <field name="state">inprogress</field>
20 <field name="category">other</field>
21 </record>
22
23=== modified file 'gamification/models/challenge.py'
24--- gamification/models/challenge.py 2014-04-18 09:05:20 +0000
25+++ gamification/models/challenge.py 2014-04-22 07:53:23 +0000
26@@ -21,14 +21,13 @@
27
28 from openerp import SUPERUSER_ID
29 from openerp.osv import fields, osv
30-from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
31+from openerp.tools import ustr, DEFAULT_SERVER_DATE_FORMAT as DF
32 from openerp.tools.safe_eval import safe_eval as eval
33 from openerp.tools.translate import _
34
35 from datetime import date, datetime, timedelta
36 import calendar
37 import logging
38-import functools
39 _logger = logging.getLogger(__name__)
40
41 # display top 3 in ranking, could be db variable
42@@ -117,12 +116,6 @@
43 except ValueError:
44 return False
45
46- def _get_challenger_users(self, cr, uid, domain, context=None):
47- ref = functools.partial(self.pool['ir.model.data'].xmlid_to_res_id, cr, uid)
48- user_domain = eval(domain, {'ref': ref})
49- return self.pool['res.users'].search(cr, uid, user_domain, context=context)
50-
51-
52 _order = 'end_date, start_date, name, id'
53 _columns = {
54 'name': fields.char('Challenge Name', required=True, translate=True),
55@@ -218,7 +211,6 @@
56 def create(self, cr, uid, vals, context=None):
57 """Overwrite the create method to add the user of groups"""
58
59- # add users when change the group auto-subscription
60 if vals.get('user_domain'):
61 user_ids = self._get_challenger_users(cr, uid, vals.get('user_domain'), context=context)
62
63@@ -240,14 +232,18 @@
64 if isinstance(ids, (int,long)):
65 ids = [ids]
66
67+ if vals.get('user_domain'):
68+ user_ids = self._get_challenger_users(cr, uid, vals.get('user_domain'), context=context)
69+
70+ if not vals.get('user_ids'):
71+ vals['user_ids'] = []
72+ vals['user_ids'] += [(4, user_id) for user_id in user_ids]
73+
74+ write_res = super(gamification_challenge, self).write(cr, uid, ids, vals, context=context)
75+
76 if vals.get('state') == 'inprogress':
77- for challenge in self.browse(cr, uid, ids, context=context):
78- user_ids = self._get_challenger_users(cr, uid, challenge.user_domain, context=context)
79- write_op = [(4, user_id) for user_id in user_ids]
80- self.write(cr, uid, [challenge.id], {'user_ids': write_op}, context=context)
81- self.message_subscribe_users(cr, uid, [challenge.id], user_ids, context=context)
82-
83- self.generate_goals_from_challenge(cr, uid, ids, context=context)
84+ self._recompute_challenge_users(cr, uid, ids, context=context)
85+ self._generate_goals_from_challenge(cr, uid, ids, context=context)
86
87 elif vals.get('state') == 'done':
88 self.check_challenge_reward(cr, uid, ids, force=True, context=context)
89@@ -256,9 +252,6 @@
90 # resetting progress
91 if self.pool.get('gamification.goal').search(cr, uid, [('challenge_id', 'in', ids), ('state', '=', 'inprogress')], context=context):
92 raise osv.except_osv("Error", "You can not reset a challenge with unfinished goals.")
93-
94- write_res = super(gamification_challenge, self).write(cr, uid, ids, vals, context=context)
95-
96
97 return write_res
98
99@@ -314,18 +307,10 @@
100 # update every running goal already generated linked to selected challenges
101 goal_obj.update(cr, uid, goal_ids, context=context)
102
103+ self._recompute_challenge_users(cr, uid, ids, context=context)
104+ self._generate_goals_from_challenge(cr, uid, ids, context=context)
105+
106 for challenge in self.browse(cr, uid, ids, context=context):
107- # in case of new users matching the domain
108- old_user_ids = [user.id for user in challenge.user_ids]
109- new_user_ids = self._get_challenger_users(cr, uid, challenge.user_domain, context=context)
110- to_remove_ids = list(set(old_user_ids) - set(new_user_ids))
111- to_add_ids = list(set(new_user_ids) - set(old_user_ids))
112-
113- write_op = [(3, user_id) for user_id in to_remove_ids]
114- write_op += [(4, user_id) for user_id in to_add_ids]
115- self.write(cr, uid, [challenge.id], {'user_ids': write_op}, context=context)
116-
117- self.generate_goals_from_challenge(cr, uid, [challenge.id], context=context)
118
119 # goals closed but still opened at the last report date
120 closed_goals_to_report = goal_obj.search(cr, uid, [
121@@ -345,11 +330,36 @@
122 return True
123
124 def quick_update(self, cr, uid, challenge_id, context=None):
125- """Update all the goals of a challenge, no generation of new goals"""
126+ """Update all the goals of a specific challenge, no generation of new goals"""
127 goal_ids = self.pool.get('gamification.goal').search(cr, uid, [('challenge_id', '=', challenge_id)], context=context)
128 self.pool.get('gamification.goal').update(cr, uid, goal_ids, context=context)
129 return True
130
131+ def _get_challenger_users(self, cr, uid, domain, context=None):
132+ user_domain = eval(ustr(domain))
133+ return self.pool['res.users'].search(cr, uid, user_domain, context=context)
134+
135+ def _recompute_challenge_users(self, cr, uid, challenge_ids, context=None):
136+ """Recompute the domain to add new users and remove the one no longer matching the domain"""
137+ for challenge in self.browse(cr, uid, challenge_ids, context=context):
138+ if challenge.user_domain:
139+
140+ old_user_ids = [user.id for user in challenge.user_ids]
141+ new_user_ids = self._get_challenger_users(cr, uid, challenge.user_domain, context=context)
142+ to_remove_ids = list(set(old_user_ids) - set(new_user_ids))
143+ to_add_ids = list(set(new_user_ids) - set(old_user_ids))
144+
145+ write_op = [(3, user_id) for user_id in to_remove_ids]
146+ write_op += [(4, user_id) for user_id in to_add_ids]
147+ self.write(cr, uid, [challenge.id], {'user_ids': write_op}, context=context)
148+
149+ if to_remove_ids:
150+ self.message_unsubscribe_users(cr, uid, [challenge.id], to_remove_ids, context=None)
151+ if to_add_ids:
152+ self.message_subscribe_users(cr, uid, [challenge.id], new_user_ids, context=context)
153+
154+ return True
155+
156
157 def action_check(self, cr, uid, ids, context=None):
158 """Check a challenge
159@@ -370,6 +380,10 @@
160 ##### Automatic actions #####
161
162 def generate_goals_from_challenge(self, cr, uid, ids, context=None):
163+ _logger.warning("Deprecated, use private method _generate_goals_from_challenge(...) instead.")
164+ return self._generate_goals_from_challenge(cr, uid, ids, context=context)
165+
166+ def _generate_goals_from_challenge(self, cr, uid, ids, context=None):
167 """Generate the goals for each line and user.
168
169 If goals already exist for this line and user, the line is skipped. This
170@@ -388,44 +402,49 @@
171 end_date = challenge.end_date
172
173 for line in challenge.line_ids:
174- # FIXME: allow to restrict to a subset of users
175- for user in challenge.user_ids:
176-
177- domain = [('line_id', '=', line.id), ('user_id', '=', user.id)]
178- if start_date:
179- domain.append(('start_date', '=', start_date))
180-
181- # goal already existing for this line ?
182- if len(goal_obj.search(cr, uid, domain, context=context)) > 0:
183-
184- # resume canceled goals
185- domain.append(('state', '=', 'canceled'))
186- canceled_goal_ids = goal_obj.search(cr, uid, domain, context=context)
187- if canceled_goal_ids:
188- goal_obj.write(cr, uid, canceled_goal_ids, {'state': 'inprogress'}, context=context)
189- to_update.extend(canceled_goal_ids)
190-
191- # skip to next user
192- continue
193-
194- values = {
195- 'definition_id': line.definition_id.id,
196- 'line_id': line.id,
197- 'user_id': user.id,
198- 'target_goal': line.target_goal,
199- 'state': 'inprogress',
200- }
201-
202- if start_date:
203- values['start_date'] = start_date
204- if end_date:
205- values['end_date'] = end_date
206-
207- if challenge.remind_update_delay:
208- values['remind_update_delay'] = challenge.remind_update_delay
209-
210- new_goal_id = goal_obj.create(cr, uid, values, context=context)
211- to_update.append(new_goal_id)
212+
213+ # there is potentially a lot of users
214+ # detect the ones with no goal linked to this line
215+ date_clause = ""
216+ query_params = [line.id]
217+ if start_date:
218+ date_clause += "AND g.start_date = %s"
219+ query_params.append(start_date)
220+ if end_date:
221+ date_clause += "AND g.end_date = %s"
222+ query_params.append(end_date)
223+
224+ query = """SELECT u.id AS user_id
225+ FROM res_users u
226+ LEFT JOIN gamification_goal g
227+ ON (u.id = g.user_id)
228+ WHERE line_id = %s
229+ {date_clause}
230+ """.format(date_clause=date_clause)
231+
232+ cr.execute(query, query_params)
233+ user_with_goal_ids = cr.dictfetchall()
234+ user_without_goal_ids = list(set([user.id for user in challenge.user_ids]) - set([user['user_id'] for user in user_with_goal_ids]))
235+
236+ values = {
237+ 'definition_id': line.definition_id.id,
238+ 'line_id': line.id,
239+ 'target_goal': line.target_goal,
240+ 'state': 'inprogress',
241+ }
242+
243+ if start_date:
244+ values['start_date'] = start_date
245+ if end_date:
246+ values['end_date'] = end_date
247+
248+ if challenge.remind_update_delay:
249+ values['remind_update_delay'] = challenge.remind_update_delay
250+
251+ for user_id in user_without_goal_ids:
252+ values.update({'user_id': user_id})
253+ goal_id = goal_obj.create(cr, uid, values, context=context)
254+ to_update.append(goal_id)
255
256 goal_obj.update(cr, uid, to_update, context=context)
257
258@@ -638,7 +657,7 @@
259 message = "%s has joined the challenge" % user.name
260 self.message_post(cr, SUPERUSER_ID, challenge_ids, body=message, context=context)
261 self.write(cr, SUPERUSER_ID, challenge_ids, {'invited_user_ids': [(3, user_id)], 'user_ids': [(4, user_id)]}, context=context)
262- return self.generate_goals_from_challenge(cr, SUPERUSER_ID, challenge_ids, context=context)
263+ return self._generate_goals_from_challenge(cr, SUPERUSER_ID, challenge_ids, context=context)
264
265 # TODO in trunk, remove unused parameter user_id
266 def discard_challenge(self, cr, uid, challenge_ids, context=None, user_id=None):
267
268=== modified file 'gamification/models/res_users.py'
269--- gamification/models/res_users.py 2014-04-16 15:10:26 +0000
270+++ gamification/models/res_users.py 2014-04-22 07:53:23 +0000
271@@ -19,7 +19,6 @@
272 #
273 ##############################################################################
274
275-from openerp import SUPERUSER_ID
276 from openerp.osv import osv
277 from challenge import MAX_VISIBILITY_RANKING
278
279
280=== modified file 'gamification/views/challenge.xml'
281--- gamification/views/challenge.xml 2014-04-16 15:22:08 +0000
282+++ gamification/views/challenge.xml 2014-04-22 07:53:23 +0000
283@@ -48,6 +48,7 @@
284 <label for="user_domain" class="oe_edit_only" string="Assign Challenge To"/>
285 <div>
286 <field name="user_domain" widget="char_domain" options="{'model': 'res.users'}" />
287+ <field name="user_ids" groups="base.group_no_one" widget="many2many_tags" />
288 </div>
289 </div>
290
291
292=== modified file 'gamification_sale_crm/sale_crm_goals.xml'
293--- gamification_sale_crm/sale_crm_goals.xml 2014-04-16 15:34:28 +0000
294+++ gamification_sale_crm/sale_crm_goals.xml 2014-04-22 07:53:23 +0000
295@@ -130,7 +130,7 @@
296 <field name="name">Monthly Sales Targets</field>
297 <field name="period">monthly</field>
298 <field name="visibility_mode">ranking</field>
299- <field name="user_domain">[('groups_id', 'in', ref('base.group_sale_salesman'))]</field>
300+ <field name="user_domain" eval="[('groups_id', 'in', ref('base.group_sale_salesman'))]" />
301 <field name="report_message_frequency">weekly</field>
302 </record>
303
304@@ -138,7 +138,7 @@
305 <field name="name">Lead Acquisition</field>
306 <field name="period">monthly</field>
307 <field name="visibility_mode">ranking</field>
308- <field name="user_domain">[('groups_id', 'in', ref('base.group_sale_salesman'))]</field>
309+ <field name="user_domain" eval="[('groups_id', 'in', ref('base.group_sale_salesman'))]" />"
310 <field name="report_message_frequency">weekly</field>
311 </record>
312
313
314=== modified file 'website_forum/data/badges_answer.xml'
315--- website_forum/data/badges_answer.xml 2014-04-16 15:10:26 +0000
316+++ website_forum/data/badges_answer.xml 2014-04-22 07:53:23 +0000
317@@ -1,6 +1,6 @@
318 <?xml version="1.0" encoding="utf-8"?>
319 <openerp>
320- <data>
321+ <data noupdate="1">
322
323 <!-- QUALITY (VOTES) -->
324 <!-- Teacher: at least 3 upvotes -->
325
326=== modified file 'website_forum/data/badges_moderation.xml'
327--- website_forum/data/badges_moderation.xml 2014-04-16 15:14:10 +0000
328+++ website_forum/data/badges_moderation.xml 2014-04-22 07:53:23 +0000
329@@ -1,6 +1,6 @@
330 <?xml version="1.0" encoding="utf-8"?>
331 <openerp>
332- <data>
333+ <data noupdate="1">
334
335 <!-- Cleanup: answer or question edition -->
336 <!-- Not rollback feature in forum -->
337
338=== modified file 'website_forum/data/badges_participation.xml'
339--- website_forum/data/badges_participation.xml 2014-04-16 15:22:08 +0000
340+++ website_forum/data/badges_participation.xml 2014-04-22 07:53:23 +0000
341@@ -1,6 +1,6 @@
342 <?xml version="1.0" encoding="utf-8"?>
343 <openerp>
344- <data>
345+ <data noupdate="1">
346
347 <!-- Biography: complet your profile -->
348 <record id="badge_p_1" model="gamification.badge">
349
350=== modified file 'website_forum/data/badges_question.xml'
351--- website_forum/data/badges_question.xml 2014-04-16 15:14:10 +0000
352+++ website_forum/data/badges_question.xml 2014-04-22 07:53:23 +0000
353@@ -1,6 +1,6 @@
354 <!-- <?xml version="1.0" encoding="utf-8"?> -->
355 <openerp>
356- <data>
357+ <data noupdate="1">
358
359 <!-- POPULARITY (VIEWS) -->
360 <!-- Popular: 150 views -->

Subscribers

People subscribed via source and target branches