[IMP] better badge views and checks
bzr revid: mat@openerp.com-20130412085452-mnecqo80cgmo2ecs
This commit is contained in:
parent
28761467fc
commit
252365095a
|
@ -26,6 +26,9 @@ from openerp.tools.safe_eval import safe_eval
|
|||
|
||||
from templates import TemplateHelper
|
||||
from datetime import date
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class gamification_badge_user(osv.Model):
|
||||
|
@ -130,6 +133,24 @@ class gamification_badge(osv.Model):
|
|||
('create_date', '>=', first_month_day)], context=context))
|
||||
return result
|
||||
|
||||
def _remaining_sending_calc(self, cr, uid, ids, name, args, context=None):
|
||||
"""Computes the number of badges remaining the user can send
|
||||
|
||||
0 if not allowed or no remaining
|
||||
integer if limited sending
|
||||
-1 if infinite (should not be displayed)
|
||||
"""
|
||||
result = dict.fromkeys(ids, False)
|
||||
for badge in self.browse(cr, uid, ids, context=context):
|
||||
if self.can_grant_badge(cr, uid, uid, badge.id, context) != 1:
|
||||
result[badge.id] = 0
|
||||
elif not badge.rule_max:
|
||||
result[badge.id] = -1
|
||||
else:
|
||||
result[badge.id] = badge.rule_max_number - badge.stat_my_monthly_sending
|
||||
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Badge', required=True, translate=True),
|
||||
'description': fields.text('Description'),
|
||||
|
@ -161,6 +182,8 @@ class gamification_badge(osv.Model):
|
|||
type="integer",
|
||||
string='My Monthly Sending Total',
|
||||
help="The number of time the current user has sent this badge this month."),
|
||||
'remaining_sending': fields.function(_remaining_sending_calc, type='integer',
|
||||
string='Remaining Sending Allowed', help="If a maxium is set"),
|
||||
|
||||
'rule_automatic': fields.selection([
|
||||
('goals', 'List of goals to reach'),
|
||||
|
@ -338,22 +361,46 @@ class gamification_badge(osv.Model):
|
|||
|
||||
return True
|
||||
|
||||
def check_granting(self, cr, uid, user_from_id, badge_id, context=None):
|
||||
"""Check the user can grant a badge and raise the appropriate exception
|
||||
if not"""
|
||||
context = context or {}
|
||||
status_code = self.can_grant_badge(cr, uid, user_from_id, badge_id, context)
|
||||
if status_code == 1:
|
||||
return True
|
||||
elif status_code == 2:
|
||||
raise osv.except_osv(_('Warning!'), _('This badge can not be sent by users.'))
|
||||
elif status_code == 3:
|
||||
raise osv.except_osv(_('Warning!'), _('You are not in the user allowed list.'))
|
||||
elif status_code == 4:
|
||||
raise osv.except_osv(_('Warning!'), _('You do not have the required badges.'))
|
||||
elif status_code == 5:
|
||||
raise osv.except_osv(_('Warning!'), _('You have already sent this badge too many time this month.'))
|
||||
else:
|
||||
_logger.exception("Unknown badge status code: %d" % int(status_code))
|
||||
return False
|
||||
|
||||
def can_grant_badge(self, cr, uid, user_from_id, badge_id, context=None):
|
||||
"""Check if a user can grant a badge to another user
|
||||
|
||||
:param user_from_id: the id of the res.users trying to send the badge
|
||||
:param badge_id: the granted badge id
|
||||
:return: boolean, True if succeeded to send, False otherwise
|
||||
:return: integer representing the permission.
|
||||
1: can grant
|
||||
2: nobody can send
|
||||
3: user not in the allowed list
|
||||
4: don't have the required badges
|
||||
5: user's monthly limit reached
|
||||
"""
|
||||
context = context or {}
|
||||
badge = self.browse(cr, uid, badge_id, context=context)
|
||||
|
||||
if badge.rule_auth == 'nobody':
|
||||
raise osv.except_osv(_('Warning!'), _('This badge can not be sent by users.'))
|
||||
return 2
|
||||
|
||||
elif badge.rule_auth == 'list':
|
||||
elif badge.rule_auth == 'users':
|
||||
if user_from_id not in [user.id for user in badge.rule_auth_user_ids]:
|
||||
raise osv.except_osv(_('Warning!'), _('You are not in the user allowed list.'))
|
||||
return 3
|
||||
|
||||
elif badge.rule_auth == 'having':
|
||||
badge_users = self.pool.get('gamification.badge.user').search(
|
||||
|
@ -361,23 +408,24 @@ class gamification_badge(osv.Model):
|
|||
|
||||
if len(badge_users) == 0:
|
||||
# the user_from has no badges
|
||||
raise osv.except_osv(_('Warning!'), _('You do not have the required badges.'))
|
||||
return 4
|
||||
|
||||
owners = [owner.id for owner in badge.owner_ids]
|
||||
granted = False
|
||||
for badge_user in badge_users:
|
||||
if badge_user.id in owners:
|
||||
if badge_user in owners:
|
||||
granted = True
|
||||
break
|
||||
if not granted:
|
||||
raise osv.except_osv(_('Warning!'), _('You do not have the required badges.'))
|
||||
return 4
|
||||
|
||||
# else badge.rule_auth == 'everyone' -> no check
|
||||
|
||||
if badge.rule_max and badge.stat_my_monthly_sending >= badge.rule_max_number:
|
||||
# sent the maximum number of time this month
|
||||
raise osv.except_osv(_('Warning!'), _('You have already sent this badge too many time this month.'))
|
||||
return 5
|
||||
|
||||
return True
|
||||
return 1
|
||||
|
||||
|
||||
class grant_badge_wizard(osv.TransientModel):
|
||||
|
@ -400,7 +448,7 @@ class grant_badge_wizard(osv.TransientModel):
|
|||
if uid == wiz.user_id.id:
|
||||
raise osv.except_osv(_('Warning!'), _('You can not send a badge to yourself'))
|
||||
|
||||
if badge_obj.can_grant_badge(cr, uid,
|
||||
if badge_obj.check_granting(cr, uid,
|
||||
user_from_id=uid,
|
||||
badge_id=wiz.badge_id.id,
|
||||
context=context):
|
||||
|
|
|
@ -93,8 +93,16 @@
|
|||
<field name="rule_auth_badge_ids" attrs="{'invisible': [('rule_auth','!=','having')]}" widget="many2many_tags" />
|
||||
<field name="rule_max" attrs="{'invisible': [('rule_auth','=','nobody')]}" />
|
||||
<field name="rule_max_number" attrs="{'invisible': ['|',('rule_max','=',False),('rule_auth','=','nobody')]}"/>
|
||||
<field name="stat_my_monthly_sending" attrs="{'invisible': [('rule_auth','=','nobody')]}"/>
|
||||
|
||||
<label for="stat_my_monthly_sending"/>
|
||||
<div>
|
||||
<field name="stat_my_monthly_sending" attrs="{'invisible': [('rule_auth','=','nobody')]}" />
|
||||
<div attrs="{'invisible': [('remaining_sending','=',-1)]}" class="oe_grey">
|
||||
You can still send <field name="remaining_sending" class="oe_inline"/> badges this month
|
||||
</div>
|
||||
<div attrs="{'invisible': [('remaining_sending','!=',-1)]}" class="oe_grey">
|
||||
No monthly sending limit
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Automatic Rules">
|
||||
<field name="rule_automatic" widget="radio"/>
|
||||
|
@ -110,7 +118,6 @@
|
|||
<group>
|
||||
<field name="stat_my"/>
|
||||
<field name="stat_my_this_month"/>
|
||||
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
|
@ -129,25 +136,45 @@
|
|||
<field name="image"/>
|
||||
<field name="stat_my"/>
|
||||
<field name="stat_count"/>
|
||||
<field name="stat_count_distinct"/>
|
||||
<field name="stat_this_month"/>
|
||||
<field name="unique_owner_ids"/>
|
||||
<field name="remaining_sending" />
|
||||
<field name="rule_max_number" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="#{record.stat_my.raw_value ? 'oe_kanban_color_5' : 'oe_kanban_color_white'} oe_kanban_card oe_kanban_global_click oe_kanban_badge">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="oe_kanban_left">
|
||||
<a type="open"><img t-att-src="kanban_image('gamification.badge', 'image', record.image.raw_value)" t-att-title="record.name.value" width="24" height="24" /></a>
|
||||
<a type="open"><img t-att-src="kanban_image('gamification.badge', 'image', record.image.raw_value)" t-att-title="record.name.value" width="100" height="100" /></a>
|
||||
<div class="oe_kanban_badge_avatars">
|
||||
<t t-foreach="record.unique_owner_ids.raw_value.slice(0,11)" t-as="owner">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', owner)" t-att-data-member_id="owner"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<h4><a type="open"><field name="name"/></a></h4>
|
||||
<t t-if="record.description.value">
|
||||
<em><field name="description"/></em>
|
||||
</t>
|
||||
<p>Granted <t t-esc="record.stat_count.raw_value" />x (<t t-esc="record.stat_count_distinct.raw_value"/> pers.)</p>
|
||||
<div class="oe_kanban_badge_avatars">
|
||||
<t t-foreach="record.unique_owner_ids.raw_value.slice(0,11)" t-as="owner">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', owner)" t-att-data-member_id="owner"/>
|
||||
<div>
|
||||
<h4><a type="open"><field name="name"/></a></h4>
|
||||
<t t-if="record.description.value">
|
||||
<em><field name="description"/></em>
|
||||
</t>
|
||||
</div>
|
||||
<p>
|
||||
Total: <t t-esc="record.stat_count.raw_value"/> (<t t-esc="record.stat_this_month.raw_value"/> this month)
|
||||
</p>
|
||||
<t t-if="record.remaining_sending.value != 0">
|
||||
<button type="action" name="%(action_grant_wizard)d" class="oe_highlight">Grant</button>
|
||||
<p class="oe_grey">
|
||||
<t t-if="record.remaining_sending.value != -1">
|
||||
<t t-esc="record.remaining_sending.value"/>/<t t-esc="record.rule_max_number.value"/> remaining
|
||||
</t>
|
||||
<t t-if="record.remaining_sending.value == -1">
|
||||
∞
|
||||
</t>
|
||||
</p>
|
||||
</t>
|
||||
<t t-if="record.remaining_sending.value == 0">
|
||||
<div class="oe_grey">You can not send this badge</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
@ -171,7 +198,7 @@
|
|||
<field name="create_date"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_card oe_kanban_global_click oe_kanban_goal oe_kanban_color_white">
|
||||
<div class="oe_kanban_card oe_kanban_global_click oe_kanban_badge oe_kanban_color_white">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="oe_kanban_left">
|
||||
<a type="open"><img t-att-src="kanban_image('gamification.badge', 'image', record.badge_id.raw_value)" t-att-title="record.badge_name.value" width="24" height="24" /></a>
|
||||
|
|
|
@ -25,9 +25,6 @@ from openerp.tools.safe_eval import safe_eval
|
|||
from templates import TemplateHelper
|
||||
|
||||
from datetime import date, datetime, timedelta
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class gamification_goal_type(osv.Model):
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
/* Kanban views */
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_goal,
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_badge {
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_goal {
|
||||
width: 220px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.openerp .oe_kanban_view .oe_kanban_card.oe_kanban_badge {
|
||||
width: 250px;
|
||||
min-height: 150px;
|
||||
}
|
||||
.oe_kanban_badge_avatars {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
@ -21,7 +24,8 @@
|
|||
margin: auto;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
.oe_kanban_goal .oe_goal_state_block,p {
|
||||
.oe_kanban_goal .oe_goal_state_block,
|
||||
.oe_kanban_goal p {
|
||||
text-align: center;
|
||||
}
|
||||
.oe_kanban_goal .oe_goal_state_block .oe_goal_state {
|
||||
|
|
|
@ -125,7 +125,7 @@ openerp.gamification = function(instance) {
|
|||
self.$el.find('.oe_goal_gauge').attr('id', unique_id);
|
||||
var g = new JustGage({
|
||||
id: unique_id,
|
||||
node: self.$el.find('.oe_goal_gauge').empty().get(0),
|
||||
node: self.$('.oe_goal_gauge').empty().get(0),
|
||||
value: self.record.current.raw_value,
|
||||
min: 0,
|
||||
max: self.record.target_goal.raw_value,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
|
||||
class hr_gamification_badge_user(osv.Model):
|
||||
|
@ -56,7 +57,7 @@ class gamification_badge(osv.Model):
|
|||
badge = self.browse(cr, uid, context['badge_id'], context=context)
|
||||
badge_user = context['badge_user']
|
||||
if badge_user.employee_id:
|
||||
return self.pool.get('hr.employee').message_post(cr, uid,
|
||||
return self.pool.get('hr.employee').message_post(cr, SUPERUSER_ID,
|
||||
badge_user.employee_id.id, context=context, **kwargs)
|
||||
return super(gamification_badge, self).message_post(cr, uid, thread_id, context=context, **kwargs)
|
||||
|
||||
|
|
Loading…
Reference in New Issue