From 4dc3b139f3eedda39ff56bf24134981095a67732 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Wed, 9 Apr 2014 12:44:27 +0200 Subject: [PATCH 01/12] [IMP] ir_qweb, ir_ui_view: can use id insead of xml_id; can render ir.ui.view many2one with widget='qweb' in template bzr revid: chm@openerp.com-20140409104427-ut3r5acavyjsp6bj --- addons/website/models/ir_qweb.py | 4 ++++ addons/website/models/ir_ui_view.py | 2 -- addons/website/models/website.py | 11 +++++++---- addons/website_sale/models/product.py | 3 +++ addons/website_sale/views/website_sale.xml | 4 ++++ addons/website_sale/views/website_sale_backend.xml | 1 + 6 files changed, 19 insertions(+), 6 deletions(-) diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py index 8916968f7ca..ad2b63a6dd9 100644 --- a/addons/website/models/ir_qweb.py +++ b/addons/website/models/ir_qweb.py @@ -383,6 +383,10 @@ class Contact(orm.AbstractModel): _name = 'website.qweb.field.contact' _inherit = ['ir.qweb.field.contact', 'website.qweb.field.many2one'] +class QwebView(orm.AbstractModel): + _name = 'website.qweb.field.qweb' + _inherit = ['ir.qweb.field.qweb'] + def html_to_text(element): """ Converts HTML content with HTML-specified line breaks (br, p, div, ...) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index c9fadade6ed..f67f6ada4b9 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -128,8 +128,6 @@ class view(osv.osv): if isinstance(id_or_xml_id, list): id_or_xml_id = id_or_xml_id[0] - if isinstance(id_or_xml_id, (int, long)): - id_or_xml_id = self.get_view_xmlid(cr, uid, id_or_xml_id) if not context: context = {} diff --git a/addons/website/models/website.py b/addons/website/models/website.py index a516f5cb96f..8018e409f2c 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -221,10 +221,13 @@ class website(osv.osv): ) def get_template(self, cr, uid, ids, template, context=None): - if '.' not in template: - template = 'website.%s' % template - module, xmlid = template.split('.', 1) - model, view_id = request.registry["ir.model.data"].get_object_reference(cr, uid, module, xmlid) + if isinstance(template, (int, long)): + view_id = template + else: + if '.' not in template: + template = 'website.%s' % template + module, xmlid = template.split('.', 1) + model, view_id = request.registry["ir.model.data"].get_object_reference(cr, uid, module, xmlid) return self.pool["ir.ui.view"].browse(cr, uid, view_id, context=context) def _render(self, cr, uid, ids, template, values=None, context=None): diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index bfb3c142ca1..7b0f31d1cb5 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -60,6 +60,9 @@ class product_template(osv.Model): 'website_style_ids': fields.many2many('product.style', 'product_website_style_rel', 'product_id', 'style_id', 'Styles'), 'website_sequence': fields.integer('Sequence', help="Determine the display order in the Website E-commerce"), 'website_url': fields.function(_website_url, string="Website url", type="char"), + + + 'test_ir_ui_view': fields.many2one('ir.ui.view', 'test_ir_ui_view'), } def __defaults_website_sequence(self, cr, uid, *kwargs): diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 542147a0b2e..4c546745bf2 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -301,6 +301,10 @@ + ------------------------------- +
+ ------------------------------- +
diff --git a/addons/website_sale/views/website_sale_backend.xml b/addons/website_sale/views/website_sale_backend.xml index 863c47ac565..4794d9bb877 100644 --- a/addons/website_sale/views/website_sale_backend.xml +++ b/addons/website_sale/views/website_sale_backend.xml @@ -74,6 +74,7 @@ domain="[('attribute_id', '=', attribute_id)]"/> + From a52e13bd86aa55662235095f27b327a0a74d04e3 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 14 Apr 2014 15:17:20 +0200 Subject: [PATCH 02/12] [FIX] remove wrong required and readonly fields bzr revid: mat@openerp.com-20140414131720-bzqd1sv0j2t5wywd --- addons/gamification/views/challenge.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/gamification/views/challenge.xml b/addons/gamification/views/challenge.xml index b37ef0eb0d8..f177a55ac5d 100644 --- a/addons/gamification/views/challenge.xml +++ b/addons/gamification/views/challenge.xml @@ -81,12 +81,12 @@ - + - +

Badges are granted when a challenge is finished. This is either at the end of a running period (eg: end of the month for a monthly challenge), at the end date of a challenge (if no periodicity is set) or when the challenge is manually closed.

From 0c8539846aaf3c55f1f42f7dd48dc2643667bd18 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 14 Apr 2014 15:51:15 +0200 Subject: [PATCH 03/12] [ADD] website_forum: quality badges bzr revid: mat@openerp.com-20140414135115-onmywwurr03g21dw --- addons/gamification/models/goal.py | 4 +-- addons/website_forum/data/badges_answer.xml | 37 ++++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 6ab4259cca2..a24df6e5c2d 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -287,11 +287,9 @@ class gamification_goal(osv.Model): field_date_name = definition.field_date_id and definition.field_date_id.name or False if definition.computation_mode == 'count' and definition.batch_mode: - + # batch mode, trying to do as much as possible in one request general_domain = safe_eval(definition.domain) - # goal_distinct_values = {goal.id: safe_eval(definition.batch_user_expression, {'user': goal.user_id}) for goal in goals} field_name = definition.batch_distinctive_field.name - # general_domain.append((field_name, 'in', list(set(goal_distinct_values.keys())))) subqueries = {} for goal in goals: start_date = field_date_name and goal.start_date or False diff --git a/addons/website_forum/data/badges_answer.xml b/addons/website_forum/data/badges_answer.xml index 8b56a5ac02e..b88ac0945d1 100644 --- a/addons/website_forum/data/badges_answer.xml +++ b/addons/website_forum/data/badges_answer.xml @@ -4,7 +4,7 @@ - + - + - + - + From c40318a46a1fa8ebc5f8e66fc4d5e3cd094c40b4 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 14 Apr 2014 16:54:15 +0200 Subject: [PATCH 04/12] [ADD] website_forum: self_reply field and some badges bzr revid: mat@openerp.com-20140414145415-8g9jtp95d173183i --- addons/gamification/models/goal.py | 2 +- addons/website_forum/data/badges_answer.xml | 56 +++++++++++++-------- addons/website_forum/models/forum.py | 10 ++++ 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index a24df6e5c2d..268f27e3fe7 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -304,7 +304,7 @@ class gamification_goal(osv.Model): if end_date: subquery_domain.append((field_date_name, '>=', end_date)) - user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) + user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) for goal in [g for g in goals if g.id in query_goals.keys()]: for user_value in user_values: diff --git a/addons/website_forum/data/badges_answer.xml b/addons/website_forum/data/badges_answer.xml index b88ac0945d1..fa367e70ce8 100644 --- a/addons/website_forum/data/badges_answer.xml +++ b/addons/website_forum/data/badges_answer.xml @@ -61,6 +61,7 @@ personal never + True inprogress forum @@ -94,6 +95,7 @@ personal never + True inprogress forum @@ -127,6 +129,7 @@ personal never + True inprogress forum @@ -139,7 +142,7 @@ - + - + - + \ No newline at end of file diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 74f4d9e5393..cd22992f6b3 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -97,6 +97,12 @@ class Post(osv.Model): res[post.id] = any(answer.create_uid.id == uid for answer in post.child_ids) return res + def _is_self_reply(self, cr, uid, ids, field_name, arg, context=None): + res = dict.fromkeys(ids, False) + for post in self.browse(cr, uid, ids, context=context): + res[post.id] = post.parent_id and post.parent_id.create_uid == post.create_uid or False + return res + _columns = { 'name': fields.char('Title', size=128), 'forum_id': fields.many2one('forum.forum', 'Forum', required=True), @@ -137,6 +143,10 @@ class Post(osv.Model): }), # hierarchy 'parent_id': fields.many2one('forum.post', 'Question', ondelete='cascade'), + 'self_reply': fields.function(_is_self_reply, 'Reply to own question', type='boolean', + store={ + 'forum.post': (lambda self, cr, uid, ids, c={}: ids, ['parent_id', 'create_uid'], 10), + }), 'child_ids': fields.one2many('forum.post', 'parent_id', 'Answers'), 'child_count': fields.function( _get_child_count, string="Answers", type='integer', From 9f3a2f84e03862c57e80337103d35e12b19d539d Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 14 Apr 2014 17:53:44 +0200 Subject: [PATCH 05/12] [ADD] website_forum: more badges bzr revid: mat@openerp.com-20140414155344-v580tpy5l12z9v95 --- addons/website_forum/data/badges_answer.xml | 10 +- .../website_forum/data/badges_moderation.xml | 133 ++++++++---------- 2 files changed, 66 insertions(+), 77 deletions(-) diff --git a/addons/website_forum/data/badges_answer.xml b/addons/website_forum/data/badges_answer.xml index fa367e70ce8..9aed157df21 100644 --- a/addons/website_forum/data/badges_answer.xml +++ b/addons/website_forum/data/badges_answer.xml @@ -44,7 +44,7 @@ bronze - Nice Answer + Nice Answer (4) Answer voted up 4 times count boolean @@ -78,7 +78,7 @@ silver - Good Answer + Good Answer (6) Answer voted up 6 times count boolean @@ -112,7 +112,7 @@ gold - Great Answer + Great Answer (15) Answer voted up 15 times count boolean @@ -182,7 +182,7 @@ silver - Guru + Guru (15) Answer accepted with 15 or more votes count boolean @@ -194,7 +194,7 @@ user.id - Great Answer + Guru once personal never diff --git a/addons/website_forum/data/badges_moderation.xml b/addons/website_forum/data/badges_moderation.xml index c169e5bc668..0a6f2d9925d 100644 --- a/addons/website_forum/data/badges_moderation.xml +++ b/addons/website_forum/data/badges_moderation.xml @@ -3,38 +3,15 @@ + - + - + - + - - - - - - - - - - - - - - Supporter First upvote gold - --> - - + - - + \ No newline at end of file From 14ff39f96ee23d07b1de0ea7848f28a5464dbe26 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 15 Apr 2014 12:18:42 +0200 Subject: [PATCH 06/12] [FIX] website_forum: mooooore baaaaaadges bzr revid: mat@openerp.com-20140415101842-yf6vndw7h62q0b42 --- addons/gamification/models/goal.py | 6 +- .../data/badges_participation.xml | 77 ++++++++++--------- addons/website_forum/models/forum.py | 1 + 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 268f27e3fe7..e39427c6bdb 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -304,7 +304,11 @@ class gamification_goal(osv.Model): if end_date: subquery_domain.append((field_date_name, '>=', end_date)) - user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) + if field_name == 'id': + user_ids = obj.search(cr, uid, subquery_domain, context=context) + user_values = [{'id': user_id, 'id_count': 1} for user_id in user_ids] + else: + user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) for goal in [g for g in goals if g.id in query_goals.keys()]: for user_value in user_values: diff --git a/addons/website_forum/data/badges_participation.xml b/addons/website_forum/data/badges_participation.xml index 9d0c2139abe..04c2ab7e4d9 100644 --- a/addons/website_forum/data/badges_participation.xml +++ b/addons/website_forum/data/badges_participation.xml @@ -3,7 +3,7 @@ - + - + - + - + - + 1 + \ No newline at end of file diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index cd22992f6b3..4a368c361a4 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -293,4 +293,5 @@ class Tags(osv.Model): 'forum.post': (_get_tag_from_post, ['tag_ids'], 10), } ), + 'create_uid': fields.many2one('res.users', 'Created by', readonly=True), } From 15306066d0e0196001ab4afdb76901267b59553a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 15 Apr 2014 13:35:45 +0200 Subject: [PATCH 07/12] I love the smell of napalm in the morning. bzr revid: mat@openerp.com-20140415113545-31efpjddjwqr4ajl --- addons/website_forum/data/badges_question.xml | 177 +++++++++++------- 1 file changed, 111 insertions(+), 66 deletions(-) diff --git a/addons/website_forum/data/badges_question.xml b/addons/website_forum/data/badges_question.xml index 02e9a9f306e..fd9c56636ff 100644 --- a/addons/website_forum/data/badges_question.xml +++ b/addons/website_forum/data/badges_question.xml @@ -4,19 +4,22 @@ - + + - + - + - + - + - + - + - + - + - + - + \ No newline at end of file From 1c5ed2973e12c602477d583662761d13c5e8070e Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Tue, 15 Apr 2014 13:37:51 +0200 Subject: [PATCH 08/12] [FIX] mail template view - Set body_html field as simple text area without cke by default. Else, the mako code are considered as mal formatted and moved. bzr revid: jke@openerp.com-20140415113751-h0a1tg36tht1bys1 --- addons/product_email_template/views/email_template_view.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/product_email_template/views/email_template_view.xml b/addons/product_email_template/views/email_template_view.xml index 5b4600b9719..c1312d31132 100644 --- a/addons/product_email_template/views/email_template_view.xml +++ b/addons/product_email_template/views/email_template_view.xml @@ -12,8 +12,7 @@

Body

- + From bc0738e47e37be2e5c1c5d9f235adb62265bdc9e Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 15 Apr 2014 15:19:29 +0200 Subject: [PATCH 09/12] One morning I shot an elephant in my pajamas. How he got in my pajamas, I don't know. bzr revid: mat@openerp.com-20140415131929-6pktlodmlgr2fuwz --- addons/website_forum/controllers/main.py | 2 +- addons/website_forum/models/forum.py | 25 ++++++++++-------------- addons/website_forum/models/res_users.py | 2 ++ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index 90cbf0ba722..354aa52c8b3 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -348,7 +348,7 @@ class WebsiteForum(http.Controller): return {'error': 'own_post'} user = request.registry['res.users'].browse(request.cr, SUPERUSER_ID, request.uid, context=request.context) if user.karma <= 5: - return {'error': 'not_enough_karma', 'karma': 5} + return {'error': 'not_enough_karma', 'karma': 1} return request.registry['forum.post'].vote(request.cr, request.uid, [post.id], upvote=True, context=request.context) @http.route('/forum//post//downvote', type='json', auth="public", multilang=True, website=True) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 4a368c361a4..031ae4b33e1 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -176,15 +176,14 @@ class Post(osv.Model): context = {} create_context = dict(context, mail_create_nolog=True) post_id = super(Post, self).create(cr, uid, vals, context=create_context) - post = self.browse(cr, uid, post_id, context=context) # post message + subtype depending on parent_id if vals.get("parent_id"): parent = self.browse(cr, SUPERUSER_ID, vals['parent_id'], context=context) body = _('

New Answer Posted

' % (slug(parent.forum_id), slug(parent))) self.message_post(cr, uid, parent.id, subject=_('Re: %s') % parent.name, body=body, subtype='website_forum.mt_answer_new', context=context) else: - self.message_post(cr, uid, post.id, subject=post.name, body=_('New Question Created'), subtype='website_forum.mt_question_new', context=context) - self.pool['res.users'].write(cr, SUPERUSER_ID, [post.create_uid.id], {'karma': 2}, context=context) + self.message_post(cr, uid, post_id, subject=vals.get('name', ''), body=_('New Question Created'), subtype='website_forum.mt_question_new', context=context) + self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [uid], 2, context=context) return post_id def write(self, cr, uid, ids, vals, context=None): @@ -203,7 +202,7 @@ class Post(osv.Model): if 'correct' in vals: for post in self.browse(cr, uid, ids, context=context): karma_value = 15 if vals.get('correct') else -15 - self.pool['res.users'].write(cr, SUPERUSER_ID, [post.create_uid.id], {'karma': karma_value}, context=context) + self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [post.create_uid.id], {'karma': karma_value}, context=context) return res def vote(self, cr, uid, ids, upvote=True, context=None): @@ -241,7 +240,7 @@ class Vote(osv.Model): _description = 'Vote' _columns = { 'post_id': fields.many2one('forum.post', 'Post', ondelete='cascade', required=True), - 'user_id': fields.many2one('res.users', 'User'), + 'user_id': fields.many2one('res.users', 'User', required=True), 'vote': fields.selection([('1', '1'), ('-1', '-1'), ('0', '0')], 'Vote', required=True), 'create_date': fields.datetime('Create Date', select=True, readonly=True), } @@ -250,23 +249,19 @@ class Vote(osv.Model): 'vote': lambda *args: '1', } - def update_karma(self, cr, uid, ids, new_vote='0', old_vote='0', context=None): - karma_value = (int(new_vote) - int(old_vote)) * 10 - if karma_value: - for vote in self.browse(cr, uid, ids, context=context): - self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [vote.post_id.create_uid.id], karma_value, context=context) - return True - def create(self, cr, uid, vals, context=None): vote_id = super(Vote, self).create(cr, uid, vals, context=context) - self.update_karma(cr, uid, [vote_id], new_vote=vals.get('vote', '1'), context=context) + karma_value = int(vals.get('vote', '1')) * 10 + post = self.pool['forum.post'].browse(cr, uid, vals.get('post_id'), context=context) + self.pool['res.users'].add_karma(cr, SUPERUSER_ID, post.create_uid.id, karma_value, context=context) return vote_id def write(self, cr, uid, ids, values, context=None): - res = super(Vote, self).write(cr, uid, ids, values, context=context) if 'vote' in values: for vote in self.browse(cr, uid, ids, context=context): - self.update_karma(cr, uid, ids, new_vote=values['vote'], old_vote=vote.vote, context=context) + karma_value = (int(values.get('vote')) - int(vote.vote)) * 10 + self.pool['res.users'].add_karma(cr, SUPERUSER_ID, vote.post_id.create_uid.id, karma_value, context=context) + res = super(Vote, self).write(cr, uid, ids, values, context=context) return res diff --git a/addons/website_forum/models/res_users.py b/addons/website_forum/models/res_users.py index 89a23cc2901..3170fedf50a 100644 --- a/addons/website_forum/models/res_users.py +++ b/addons/website_forum/models/res_users.py @@ -32,6 +32,8 @@ class Users(osv.Model): } def add_karma(self, cr, uid, ids, karma, context=None): + if isinstance(ids, (int, long)): + ids = [ids] for user in self.browse(cr, uid, ids, context=context): self.write(cr, uid, [user.id], {'karma': user.karma + karma}, context=context) return True From 35c7f4814d08baa8772f0971051148398dab1e45 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 15 Apr 2014 15:48:09 +0200 Subject: [PATCH 10/12] Allow overwrite of the serialising method to exclude some categories in the challenge search bzr revid: mat@openerp.com-20140415134809-uconkvnp0z32jxjs --- addons/gamification/models/res_users.py | 15 ++++++++------- addons/website_forum/models/gamification.py | 1 + addons/website_forum/models/res_users.py | 8 ++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/addons/gamification/models/res_users.py b/addons/gamification/models/res_users.py index 85cc18636f0..faca484dfb3 100644 --- a/addons/gamification/models/res_users.py +++ b/addons/gamification/models/res_users.py @@ -61,13 +61,12 @@ class res_users_gamification_group(osv.Model): challenge_obj.generate_goals_from_challenge(cr, SUPERUSER_ID, challenge_ids, context=context) return write_res - # def get_goals_todo_info(self, cr, uid, context=None): + def get_serialised_gamification_summary(self, cr, uid, excluded_categories=None, context=None): + return self._serialised_goals_summary(cr, uid, user_id=uid, excluded_categories=excluded_categories, context=context) - def get_serialised_gamification_summary(self, cr, uid, context=None): - return self._serialised_goals_summary(cr, uid, user_id=uid, context=context) - - def _serialised_goals_summary(self, cr, uid, user_id, context=None): + def _serialised_goals_summary(self, cr, uid, user_id, excluded_categories=None, context=None): """Return a serialised list of goals assigned to the user, grouped by challenge + :excluded_categories: list of challenge categories to exclude in search [ { @@ -81,9 +80,11 @@ class res_users_gamification_group(osv.Model): """ all_goals_info = [] challenge_obj = self.pool.get('gamification.challenge') - + domain = [('user_ids', 'in', uid), ('state', '=', 'inprogress')] + if excluded_categories and isinstance(excluded_categories, list): + domain.append(('category', 'not in', excluded_categories)) user = self.browse(cr, uid, uid, context=context) - challenge_ids = challenge_obj.search(cr, uid, [('user_ids', 'in', uid), ('state', '=', 'inprogress')], context=context) + challenge_ids = challenge_obj.search(cr, uid, domain, context=context) for challenge in challenge_obj.browse(cr, uid, challenge_ids, context=context): # serialize goals info to be able to use it in javascript lines = challenge_obj._get_serialized_challenge_lines(cr, uid, challenge, user_id, restrict_top=MAX_VISIBILITY_RANKING, context=context) diff --git a/addons/website_forum/models/gamification.py b/addons/website_forum/models/gamification.py index cffe52c4848..20eaca9851e 100644 --- a/addons/website_forum/models/gamification.py +++ b/addons/website_forum/models/gamification.py @@ -12,6 +12,7 @@ class gamification_challenge(osv.Model): return res + class Badge(osv.Model): _inherit = 'gamification.badge' _columns = { diff --git a/addons/website_forum/models/res_users.py b/addons/website_forum/models/res_users.py index 3170fedf50a..58d43a58191 100644 --- a/addons/website_forum/models/res_users.py +++ b/addons/website_forum/models/res_users.py @@ -37,3 +37,11 @@ class Users(osv.Model): for user in self.browse(cr, uid, ids, context=context): self.write(cr, uid, [user.id], {'karma': user.karma + karma}, context=context) return True + + def get_serialised_gamification_summary(self, cr, uid, excluded_categories=None, context=None): + if isinstance(excluded_categories, list): + if 'forum' not in excluded_categories: + excluded_categories.append('forum') + else: + excluded_categories = ['forum'] + return super(Users, self).get_serialised_gamification_summary(cr, uid, excluded_categories=excluded_categories, context=context) \ No newline at end of file From 04436809528cba1f790262e103c5dd51e9282025 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 15 Apr 2014 18:15:38 +0200 Subject: [PATCH 11/12] [FIX] gamification: the subquery domain should use less than for ending dates bzr revid: mat@openerp.com-20140415161538-mdfadjjih90wuj3d --- addons/gamification/models/goal.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index e39427c6bdb..af9a763236d 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -296,23 +296,24 @@ class gamification_goal(osv.Model): end_date = field_date_name and goal.end_date or False subqueries.setdefault((start_date, end_date), {}).update({goal.id:safe_eval(definition.batch_user_expression, {'user': goal.user_id})}) + # the global query should be split by time periods (especially for recurrent goals) for (start_date, end_date), query_goals in subqueries.items(): subquery_domain = list(general_domain) subquery_domain.append((field_name, 'in', list(set(query_goals.values())))) if start_date: subquery_domain.append((field_date_name, '>=', start_date)) if end_date: - subquery_domain.append((field_date_name, '>=', end_date)) + subquery_domain.append((field_date_name, '<=', end_date)) if field_name == 'id': + # grouping on id does not work and is similar to search anyway user_ids = obj.search(cr, uid, subquery_domain, context=context) user_values = [{'id': user_id, 'id_count': 1} for user_id in user_ids] else: user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) - + # user_values has format of read_group: [{'partner_id': 42, 'partner_id_count': 3},...] for goal in [g for g in goals if g.id in query_goals.keys()]: for user_value in user_values: - # return format of read_group: [{'partner_id': 42, 'partner_id_count': 3},...] queried_value = field_name in user_value and user_value[field_name] or False if isinstance(queried_value, tuple) and len(queried_value) == 2 and isinstance(queried_value[0], (int, long)): queried_value = queried_value[0] From 15e151dca72dce4ed1c0a1c3580a036a25f67856 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 15 Apr 2014 18:23:21 +0200 Subject: [PATCH 12/12] [IMP] orm: postprocess function field values in batch bzr revid: chs@openerp.com-20140415162321-l8hgeh6s48252zhl --- openerp/osv/fields.py | 75 +++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 8273fe09830..c4673305b43 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1214,42 +1214,69 @@ class function(_column): return self._fnct_search(obj, cr, uid, obj, name, args, context=context) def postprocess(self, cr, uid, obj, field, value=None, context=None): + return self._postprocess_batch(cr, uid, obj, field, {0: value}, context=context)[0] + + def _postprocess_batch(self, cr, uid, obj, field, values, context=None): + if not values: + return values + if context is None: context = {} - result = value + field_type = obj._columns[field]._type - if field_type == "many2one": - # make the result a tuple if it is not already one - if isinstance(value, (int,long)) and hasattr(obj._columns[field], 'relation'): - obj_model = obj.pool[obj._columns[field].relation] - dict_names = dict(obj_model.name_get(cr, SUPERUSER_ID, [value], context)) - result = (value, dict_names[value]) + new_values = dict(values) - if field_type == 'binary': - if context.get('bin_size'): - # client requests only the size of binary fields - result = get_nice_size(value) - elif not context.get('bin_raw'): - result = sanitize_binary_value(value) - - if field_type == "integer" and value > xmlrpclib.MAXINT: + if field_type == "integer": # integer/long values greater than 2^31-1 are not supported # in pure XMLRPC, so we have to pass them as floats :-( # This is not needed for stored fields and non-functional integer # fields, as their values are constrained by the database backend # to the same 32bits signed int limit. - result = __builtin__.float(value) - return result + for rid, value in values.iteritems(): + if value and value > xmlrpclib.MAXINT: + new_values[rid] = __builtin__.float(value) + + elif field_type == 'binary': + if context.get('bin_size'): + # client requests only the size of binary fields + for rid, value in values.iteritems(): + if value: + new_values[rid] = get_nice_size(value) + elif not context.get('bin_raw'): + for rid, value in values.iteritems(): + if value: + new_values[rid] = sanitize_binary_value(value) + + elif field_type == "many2one" and hasattr(obj._columns[field], 'relation'): + # make the result a tuple if it is not already one + if all(isinstance(value, (int, long)) for value in values.values() if value): + obj_model = obj.pool[obj._columns[field].relation] + ids = [i for i in values.values() if i] + dict_names = dict(obj_model.name_get(cr, SUPERUSER_ID, ids, context)) + for rid, value in values.iteritems(): + if value: + new_values[rid] = (value, dict_names[value]) + + return new_values def get(self, cr, obj, ids, name, uid=False, context=None, values=None): result = self._fnct(obj, cr, uid, ids, name, self._arg, context) - for id in ids: - if self._multi and id in result: - for field, value in result[id].iteritems(): - if value: - result[id][field] = self.postprocess(cr, uid, obj, field, value, context) - elif result.get(id): - result[id] = self.postprocess(cr, uid, obj, name, result[id], context) + if self._multi: + swap = {} + for rid, values in result.iteritems(): + for f, v in values.iteritems(): + if f not in name: + continue + swap.setdefault(f, {})[rid] = v + + for field, values in swap.iteritems(): + new_values = self._postprocess_batch(cr, uid, obj, field, values, context) + for rid, value in new_values.iteritems(): + result[rid][field] = value + + else: + result = self._postprocess_batch(cr, uid, obj, name, result, context) + return result def set(self, cr, obj, id, name, value, user=None, context=None):