[IMP] switch to challenges

bzr revid: mat@openerp.com-20130416102724-0ejrlecls30xhol3
This commit is contained in:
Martin Trigaux 2013-04-16 12:27:24 +02:00
parent 0222ae2a21
commit 8d23c604d9
10 changed files with 57 additions and 79 deletions

View File

@ -186,7 +186,7 @@ class gamification_badge(osv.Model):
string='Remaining Sending Allowed', help="If a maxium is set"),
'plan_ids': fields.one2many('gamification.goal.plan', 'reward_id',
string="Granted upon completion of"),
string="Reward for Challenges"),
'compute_code': fields.char('Compute Code',
help="The name of the python method that will be executed to verify if a user can receive this badge."),

View File

@ -83,7 +83,7 @@
<group>
<field name="description" nolabel="1" placeholder="Badge Description" />
</group>
<group string="Rules for User Granting">
<group string="Granting">
<field name="rule_auth" widget="radio" />
<field name="rule_auth_user_ids" attrs="{'invisible': [('rule_auth','!=','users')]}" widget="many2many_tags" />
<field name="rule_auth_badge_ids" attrs="{'invisible': [('rule_auth','!=','having')]}" widget="many2many_tags" />
@ -93,13 +93,16 @@
<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
You can still grant <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="Rewards for challenges">
<field name="plan_ids" widget="many2many_kanban" nolabel="1" />
</group>
<!-- <group string="Rules for Automatic Granting">
<field name="rule_automatic" widget="radio"/>
<field name="compute_code" attrs="{'invisible': [('rule_automatic','!=','python')]}"/>
@ -116,9 +119,6 @@
<field name="stat_my_this_month"/>
</group>
</group>
<group string="Reward for Challenges">
<field name="plan_ids" widget="many2many_kanban" nolabel="1" />
</group>
</sheet>
</form>
</field>

View File

@ -75,8 +75,11 @@ class gamification_goal_type(osv.Model):
],
string="Computation Mode",
required=True),
'ponctual': fields.boolean("Non-numerical Goal",
help="Instead of a progress, the goal is displayed with only two states: TODO or Done."),
'display_mode': fields.selection([
('progress', 'Progressive (using numerical values)'),
('checkbox', 'Checkbox (done or not-done)'),
],
string="Displayed as", required=True),
'model_id': fields.many2one('ir.model',
string='Model',
@ -118,7 +121,7 @@ class gamification_goal_type(osv.Model):
'computation_mode': 'manually',
'domain': "[]",
'monetary': False,
'ponctual': False,
'display_mode': 'progress',
}
@ -203,8 +206,8 @@ class gamification_goal(osv.Model):
type='char', string='Type Condition', readonly=True),
'type_suffix': fields.related('type_id', 'full_suffix',
type="char", string="Suffix", readonly=True),
'type_ponctual': fields.related('type_id', 'ponctual',
type="boolean", string="Ponctual Goal", readonly=True),
'type_display': fields.related('type_id', 'display_mode',
type="char", string="Display Mode", readonly=True),
}
_defaults = {

View File

@ -7,7 +7,7 @@
<field name="name">Set your Timezone</field>
<field name="description">Configure your profile and specify your timezone</field>
<field name="computation_mode">count</field>
<field name="ponctual">True</field>
<field name="display_mode">checkbox</field>
<field name="model_id" eval="ref('base.model_res_users')" />
<field name="domain">[('id','=',user_id),('partner_id.tz', '!=', False)]</field>
<field name="action_id" eval="ref('base.action_res_users_my')" />
@ -18,7 +18,7 @@
<field name="name">Set your Avatar</field>
<field name="description">In your user perference</field>
<field name="computation_mode">manually</field>
<field name="ponctual">True</field>
<field name="display_mode">checkbox</field>
<!-- problem : default avatar != False -> manually + check in write function -->
<field name="action_id" eval="ref('base.action_res_users_my')" />
<field name="res_id_field">id</field>
@ -29,7 +29,7 @@
<field name="name">Set your Company Data</field>
<field name="description">Specify at least a website</field>
<field name="computation_mode">count</field>
<field name="ponctual">True</field>
<field name="display_mode">checkbox</field>
<field name="model_id" eval="ref('base.model_res_company')" />
<field name="domain">[('user_ids', 'in', user_id), ('name', '!=', 'Your Company')]</field>
<field name="action_id" eval="ref('base.action_res_company_form')" />
@ -39,7 +39,7 @@
<record model="gamification.goal.type" id="type_base_company_logo">
<field name="name">Set your Company Logo</field>
<field name="computation_mode">count</field>
<field name="ponctual">True</field>
<field name="display_mode">checkbox</field>
<field name="model_id" eval="ref('base.model_res_company')" />
<field name="domain">[('user_ids', 'in', user_id),('logo', '!=', False)]</field>
<field name="action_id" eval="ref('base.action_res_company_form')" />
@ -49,7 +49,7 @@
<record model="gamification.goal.type" id="type_base_invite">
<field name="name">Invite new Users</field>
<field name="description">Create at least another user</field>
<field name="ponctual">True</field>
<field name="display_mode">checkbox</field>
<field name="computation_mode">count</field>
<field name="model_id" eval="ref('base.model_res_users')" />
<field name="domain">[('id', '!=', user_id)]</field>

View File

@ -137,7 +137,7 @@
<field name="target_goal"/>
<field name="type_condition"/>
<field name="type_suffix"/>
<field name="type_ponctual"/>
<field name="type_display"/>
<field name="start_date"/>
<field name="end_date"/>
<field name="last_update"/>
@ -154,13 +154,13 @@
</div>
<field name="user_id" />
<div class="oe_goal_state_block">
<t t-if="record.type_ponctual.value">
<t t-if="record.type_display.raw_value == 'checkbox'">
<div class="oe_goal_state oe_e"><t t-if="record.state.raw_value=='reached'"><span class="oe_green">W</span></t>
<t t-if="record.state.raw_value=='inprogress' || record.state.raw_value=='inprogress_update'">N</t>
<t t-if="record.state.raw_value=='failed'"><span class="oe_red">X</span></t>
</div>
</t>
<t t-if="!record.type_ponctual.value">
<t t-if="record.type_display.raw_value == 'progress'">
<t t-if="record.type_condition.raw_value =='higher'">
<div class="oe_goal_gauge"></div>
</t>
@ -245,11 +245,10 @@
<field name="field_date_id" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))]}" domain="[('ttype', 'in', ('date', 'datetime')), ('model_id','=',model_id)]" class="oe_inline"/>
<field name="domain" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}" class="oe_inline"/>
<field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}"/>
<field name="condition" widget="radio"/>
<field name="ponctual" />
</group>
<group string="Formating Options">
<field name="display_mode" widget="radio" />
<field name="unit" class="oe_inline"/>
<field name="monetary" class="oe_inline"/>
</group>

View File

@ -118,9 +118,9 @@ class gamification_goal_plan(osv.Model):
required=True),
'manager_id': fields.many2one('res.users',
string='Responsible', help="The user responsible for the challenge."),
'start_date': fields.date('Planned Start Date',
'start_date': fields.date('Start Date',
help="The day a new challenge will be automatically started. If no periodicity is set, will use this date as the goal start date."),
'end_date': fields.date('Planned End Date',
'end_date': fields.date('End Date',
help="The day a new challenge will be automatically closed. If no periodicity is set, will use this date as the goal end date."),
'user_ids': fields.many2many('res.users', 'user_ids',
@ -130,24 +130,8 @@ class gamification_goal_plan(osv.Model):
string='Auto-subscription Group',
help='Group of users whose members will automatically be added to the users'),
'subscription_action': fields.selection([
('automatic', 'The user is subscribed automatically'),
('approve', 'The user has to approve the challenge'),
],
string="Subscription approval",
help="What happens when the user is added to a challenge (manually or automatically) ?",
required=True),
'proposed_user_ids': fields.many2many('res.users', 'proposed_user_ids',
string="Propose to users"),
'proposed_mail_group_ids': fields.many2many('mail.group', 'proposed_mail_group_ids',
string="Propose to mail groups"),
'proposed_later_user_ids': fields.many2many('res.users', 'proposed_later_user_ids',
string='Users to Remind',
help="List of users that have asked to decide later if they approve the challenge"),
'proposed_refused_user_ids': fields.many2many('res.users', 'refused_approval_user_ids',
string='Discard Request Users',
help="List of users that have discared the approval request"),
'propose_after_login': fields.integer("Propose challenge after login", help="Number of minutes"),
'planline_ids': fields.one2many('gamification.goal.planline', 'plan_id',
string='Planline',
@ -155,9 +139,11 @@ class gamification_goal_plan(osv.Model):
required=True),
'planline_count': fields.function(_planline_count, type='integer', string="Planlines"),
'reward_id': fields.many2one('gamification.badge', string="Reward upon completion"),
'reward_bests': fields.integer('Number of Best Perforers Rewared'),
'reward_failure': fields.boolean('Grant if not succeed'),
'reward_id': fields.many2one('gamification.badge', string="For Every Succeding User"),
'reward_first_id': fields.many2one('gamification.badge', string="For 1st user"),
'reward_second_id': fields.many2one('gamification.badge', string="For 2nd user"),
'reward_third_id': fields.many2one('gamification.badge', string="For 3rd user"),
'reward_failure': fields.boolean('Reward Top 3 even if not succeed'),
'period': fields.selection([
('once', 'Non recurring'),
@ -210,7 +196,6 @@ class gamification_goal_plan(osv.Model):
'start_date': fields.date.today,
'manager_id': lambda s, cr, uid, c: uid,
'category': 'hr',
'subscription_action': 'automatic',
'reward_failure': False,
}
@ -232,17 +217,9 @@ class gamification_goal_plan(osv.Model):
if 'proposed_user_ids' in vals:
for plan in self.browse(cr, uid, ids, context=context):
if plan.subscription_action == 'approve':
puser_ids = [puser.id for puser in plan.proposed_user_ids]
ruser_ids = [ruser.id for ruser in plan.proposed_refused_user_ids if ruser.id in puser_ids]
if len(ruser_ids) > 0:
raise osv.except_osv(_('Error!'), _('Can not propose a challenge to an user that has refused it'))
auser_ids = [auser.id for auser in plan.proposed_later_user_ids if auser.id in puser_ids]
if len(auser_ids) > 0:
raise osv.except_osv(_('Error!'), _('Can not propose a challenge to an user that has cast aside it'))
user_ids = [user.id for user in plan.user_ids if user.id in puser_ids]
if len(user_ids) > 0:
raise osv.except_osv(_('Error!'), _('Can not propose a challenge to an user already assigned to it'))
puser_ids = [puser.id for puser in plan.proposed_user_ids]
if len([user for user in plan.user_ids if user.id in puser_ids]) > 0:
raise osv.except_osv(_('Error!'), _('Can not propose a challenge to an user already assigned to it'))
return write_res
@ -612,6 +589,9 @@ class gamification_goal_plan(osv.Model):
"""The user accept the suggested challenge"""
context = context or {}
user_id = user_id or uid
user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
message = "%s has joined the challenge" % user.name
self.message_post(cr, uid, plan_id, body=message, context=context)
self.write(cr, uid, [plan_id], {'proposed_user_ids': (3, user_id), 'user_id': (4, user_id)}, context=context)
return self.generate_goals_from_plan(cr, uid, [plan_id], context=context)
@ -619,13 +599,10 @@ class gamification_goal_plan(osv.Model):
"""The user discard the suggested challenge"""
context = context or {}
user_id = user_id or uid
return self.write(cr, uid, [plan_id], {'proposed_user_ids': (3, user_id), 'proposed_refused_user_ids': (4, user_id)}, context=context)
def postpone_challenge(self, cr, uid, plan_id, user_id=None, context=None):
"""The user ask to be reminded later for the suggested challenge"""
context = context or {}
user_id = user_id or uid
return self.write(cr, uid, [plan_id], {'proposed_user_ids': (3, user_id), 'proposed_later_user_ids': (4, user_id)}, context=context)
user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
message = "%s has refused the challenge" % user.name
self.message_post(cr, uid, plan_id, body=message, context=context)
return self.write(cr, uid, [plan_id], {'proposed_user_ids': (3, user_id)}, context=context)
def get_suggestions_info(self, cr, uid, context=None):
pass

View File

@ -102,18 +102,20 @@
<page string="Reward">
<group>
<field name="reward_id"/>
<field name="reward_bests" attrs="{'invisible': [('reward_id','=', False)]}" />
<field name="reward_failure" attrs="{'invisible': [('reward_id','=', False)]}" />
<field name="reward_first_id" />
<field name="reward_second_id" attrs="{'invisible': [('reward_first_id','=', False)]}" />
<field name="reward_third_id" attrs="{'invisible': ['|',('reward_first_id','=', False),('reward_second_id','=', False)]}" />
<field name="reward_failure" attrs="{'invisible': [('reward_first_id','=', False)]}" />
</group>
<div class="oe_grey">
<p>Badges are granted when a challenge is finished. This is either when at the end of a running period (eg: end of the month for a monthly challenge) or at the end date of a challenge (if no periodicity is set).</p>
<p>Ranking is done on the number of succeeded goals and the percentage of each one.</p>
</div>
</page>
<page string="Advanced Options">
<group string="Subscribe Users Automatically">
<group string="Subscriptions">
<field name="autojoin_group_id" />
<field name="subscription_action" />
<field name="proposed_user_ids" attrs="{'invisible':[('subscription_action','=','automatic')]}" widget="many2many_tags" />
<field name="proposed_mail_group_ids" attrs="{'invisible':[('subscription_action','=','automatic')]}" widget="many2many_tags" />
<field name="proposed_later_user_ids" attrs="{'invisible':[('subscription_action','=','automatic')]}" widget="many2many_tags" />
<field name="proposed_refused_user_ids" attrs="{'invisible':[('subscription_action','=','automatic')]}" widget="many2many_tags" />
<field name="proposed_user_ids" widget="many2many_tags" />
</group>
<group string="Notification Messages">
<field name="report_message_frequency" />
@ -131,7 +133,9 @@
</group>
</page>
</notebook>
<group>
<field name="description" placeholder="Describe the challenge: what is does, who it targets, why it matters..."/>
</group>
</sheet>
<div class="oe_chatter">

View File

@ -58,7 +58,7 @@ class res_users_gamification_group(osv.Model):
'type_monetary': planline_board['goal_type'].monetary,
'type_unit': planline_board['goal_type'].unit,
'type_action': True if planline_board['goal_type'].action_id else False,
'type_ponctual': planline_board['goal_type'].ponctual,
'type_display': planline_board['goal_type'].display_mode,
'target_goal': planline_board['target_goal'],
'goals': []}
for goal in planline_board['board_goals']:
@ -92,7 +92,7 @@ class res_users_gamification_group(osv.Model):
'type_monetary': goal.type_id.monetary,
'type_unit': goal.type_id.unit,
'type_action': True if goal.type_id.action_id else False,
'type_ponctual': goal.type_id.ponctual,
'type_display': goal.type_id.display_mode,
'state': goal.state,
'completeness': goal.completeness,
'computation_mode': goal.computation_mode,

View File

@ -105,7 +105,7 @@ openerp.gamification = function(instance) {
self.$(".oe_goal_sparkline_piechart").each(function() {
var completeness = parseInt( $(this).attr('data-completeness'), 10);
var values = [completeness, 100-completeness];
$(this).sparkline(values, {type: 'pie', offset: 180, sliceColors: ['#01922D','#ff0000']});
$(this).sparkline(values, {type: 'pie', offset: 180, sliceColors: ['#0B610B','#F78181']});
});
}
});

View File

@ -15,7 +15,7 @@
<t t-if="goal.computation_mode == 'manually' or goal.type_action">
<a class="oe_goal_action oe_e" t-att-id="goal.id">&amp;</a>
</t>
<t t-if="!goal.type_ponctual">
<t t-if="goal.type_display == 'progress'">
<t t-if="goal.type_condition == 'higher'">
<p>
<t t-esc="goal.current" />/<span t-attf-class="#{goal.type_monetary ? 'oe_goal_field_monetary' : ''}"><t t-esc="goal.target_goal"/></span>
@ -47,11 +47,6 @@
</t>
</th>
</tr>
<tr>
<th>#</th>
<th>Pers.</th>
<th>current</th>
</tr>
</thead>
<tbody>
<tr t-foreach="planline.goals" t-as="goal" t-attf-class="#{goal.id == planline.own_goal_id ? 'oe_bold' : ''}">