diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/gamification/views | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/gamification/views')
| -rw-r--r-- | addons/gamification/views/badge.xml | 202 | ||||
| -rw-r--r-- | addons/gamification/views/challenge.xml | 230 | ||||
| -rw-r--r-- | addons/gamification/views/gamification.xml | 7 | ||||
| -rw-r--r-- | addons/gamification/views/gamification_karma_rank_views.xml | 94 | ||||
| -rw-r--r-- | addons/gamification/views/gamification_karma_tracking_views.xml | 63 | ||||
| -rw-r--r-- | addons/gamification/views/goal.xml | 300 | ||||
| -rw-r--r-- | addons/gamification/views/mail_templates.xml | 55 | ||||
| -rw-r--r-- | addons/gamification/views/res_users_views.xml | 17 |
8 files changed, 968 insertions, 0 deletions
diff --git a/addons/gamification/views/badge.xml b/addons/gamification/views/badge.xml new file mode 100644 index 00000000..522179c3 --- /dev/null +++ b/addons/gamification/views/badge.xml @@ -0,0 +1,202 @@ +<odoo> + <!-- Badge views --> + <record id="gamification_badge_view_search" model="ir.ui.view"> + <field name="name">gamification.badge.view.search</field> + <field name="model">gamification.badge</field> + <field name="arch" type="xml"> + <search string="Search Badge"> + <field name="name"/> + <separator/> + <filter string="Archived" name="inactive" domain="[('active', '=', False)]"/> + </search> + </field> + </record> + + <record id="badge_list_action" model="ir.actions.act_window"> + <field name="name">Badges</field> + <field name="res_model">gamification.badge</field> + <field name="view_mode">kanban,tree,form</field> + <field name="search_view_id" ref="gamification_badge_view_search"/> + <field name="help" type="html"> + <p class="o_view_nocontent_smiling_face"> + Create a new badge + </p><p> + A badge is a symbolic token granted to a user as a sign of reward. + It can be deserved automatically when some conditions are met or manually by users. + Some badges are harder than others to get with specific conditions. + </p> + </field> + </record> + + + <record id="badge_list_view" model="ir.ui.view"> + <field name="name">Badge List</field> + <field name="model">gamification.badge</field> + <field name="arch" type="xml"> + <tree string="Badge List"> + <field name="name"/> + <field name="granted_count"/> + <field name="stat_this_month"/> + <field name="stat_my"/> + <field name="rule_auth"/> + </tree> + </field> + </record> + + <record id="badge_form_view" model="ir.ui.view"> + <field name="name">Badge Form</field> + <field name="model">gamification.badge</field> + <field name="arch" type="xml"> + <form string="Badge"> + <header> + <button string="Grant this Badge" type="action" name="%(action_grant_wizard)d" class="oe_highlight" attrs="{'invisible': [('remaining_sending','=',0)]}" /> + </header> + <sheet> + <div class="oe_button_box" name="button_box"/> + <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/> + <field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/> + <div class="oe_title"> + <label for="name" class="oe_edit_only"/> + <h1> + <field name="name" placeholder="Badge Name"/> + </h1> + </div> + <group> + <field name="description" nolabel="1" placeholder="Badge Description"/> + </group> + <group string="Granting"> + <div class="oe_grey" colspan="2"> + Security rules to define who is allowed to manually grant badges. Not enforced for administrator. + </div> + <group> + <field name="active" invisible="1"/> + <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" /> + <field name="rule_max" attrs="{'invisible': [('rule_auth','=','nobody')]}" /> + <field name="rule_max_number" attrs="{'invisible': ['|',('rule_max','=',False),('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 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> + <group string="Rewards for challenges"> + <field name="challenge_ids" mode="kanban" widget="many2many" nolabel="1" context="{'default_reward_id': active_id}" /> + <field name="level"/> + </group> + <group id="badge_statistics" string="Statistics"> + <group> + <field name="granted_count"/> + <field name="stat_this_month"/> + <field name="granted_users_count"/> + </group> + <group> + <field name="stat_my"/> + <field name="stat_my_this_month"/> + </group> + </group> + </sheet> + </form> + </field> + </record> + + + <record id="badge_kanban_view" model="ir.ui.view" > + <field name="name">Badge Kanban View</field> + <field name="model">gamification.badge</field> + <field name="arch" type="xml"> + <kanban class="o_kanban_badge"> + <field name="id"/> + <field name="name"/> + <field name="description"/> + <field name="stat_my"/> + <field name="granted_count"/> + <field name="stat_this_month"/> + <field name="unique_owner_ids"/> + <field name="stat_my_monthly_sending"/> + <field name="remaining_sending" /> + <field name="rule_max_number" /> + <templates> + <t t-name="kanban-box"> + <div t-attf-class="o_kanban_gamification oe_kanban_global_click #{record.stat_my.raw_value ? 'oe_kanban_color_5' : 'oe_kanban_color_white'}"> + <div class="o_kanban_image"> + <img t-att-src="kanban_image('gamification.badge', 'image_1024', record.id.raw_value)" t-att-title="record.name.value" t-att-alt="record.name.value"/> + </div> + <div class="oe_kanban_details"> + <strong class="o_kanban_record_title"><field name="name"/></strong> + <span class="oe_grey"> + <t t-if="record.remaining_sending.value != -1"> + <t t-esc="record.stat_my_monthly_sending.value"/>/<t t-esc="record.rule_max_number.value"/> + </t> + <t t-if="record.remaining_sending.value == -1"> + <t t-esc="record.stat_my_monthly_sending.value"/>/∞ + </t> + </span> + <div t-if="record.remaining_sending.value == 0" class="oe_grey">Can not grant</div> + <div> + <strong><t t-esc="record.granted_count.raw_value"/></strong> granted, + <strong><t t-esc="record.stat_this_month.raw_value"/></strong> this month + </div> + <div t-if="record.description.value" class="o_kanban_badge_description"> + <em><field name="description"/></em> + <div> + <t t-foreach="record.unique_owner_ids.raw_value.slice(0,11)" t-as="owner"> + <img class="oe_kanban_avatar o_image_24_cover" t-att-src="kanban_image('res.users', 'image_128', owner)" t-att-data-member_id="owner" alt="Owner"/> + </t> + </div> + </div> + <div t-if="record.remaining_sending.value != 0 and !selection_mode" class="o_kanban_button"> + <button type="action" name="%(action_grant_wizard)d" class="oe_highlight btn btn-primary">Grant</button> + </div> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> + + + <!-- Badge user viewss --> + + <record id="badge_user_kanban_view" model="ir.ui.view" > + <field name="name">Badge User Kanban View</field> + <field name="model">gamification.badge.user</field> + <field name="arch" type="xml"> + <kanban class="oe_background_grey"> + <field name="badge_name"/> + <field name="badge_id"/> + <field name="user_id"/> + <field name="comment"/> + <field name="create_date"/> + <templates> + <t t-name="kanban-box"> + <div class="oe_kanban_card oe_kanban_global_click oe_kanban_badge oe_kanban_color_white o_kanban_gamification"> + <div class="o_kanban_content"> + <div class="o_kanban_image"> + <a type="open"><img t-att-src="kanban_image('gamification.badge', 'image_1024', record.badge_id.raw_value)" t-att-title="record.badge_name.value" t-att-alt="record.badge_name.value" /></a> + </div> + <div class="oe_kanban_details"> + <h4 class="mt0 mb0"> + <a class="o_kanban_record_title" type="open"><t t-esc="record.badge_name.raw_value" /></a> + </h4> + <t t-if="record.comment.raw_value"> + <p class="o_kanban_record_subtitle"><em><field name="comment"/></em></p> + </t> + <p>Granted by <a type="open"><field name="create_uid" /></a> the <t t-esc="moment(record.create_date.raw_value).format('L')" /></p> + </div> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> +</odoo> diff --git a/addons/gamification/views/challenge.xml b/addons/gamification/views/challenge.xml new file mode 100644 index 00000000..66a4b400 --- /dev/null +++ b/addons/gamification/views/challenge.xml @@ -0,0 +1,230 @@ +<odoo> + <record id="challenge_list_view" model="ir.ui.view"> + <field name="name">Challenges List</field> + <field name="model">gamification.challenge</field> + <field name="arch" type="xml"> + <tree string="Goal definitions" decoration-info="state == 'draft'" decoration-muted="state == 'done'"> + <field name="name"/> + <field name="period"/> + <field name="manager_id"/> + <field name="state"/> + </tree> + </field> + </record> + + <record id="goals_from_challenge_act" model="ir.actions.act_window"> + <field name="res_model">gamification.goal</field> + <field name="name">Related Goals</field> + <field name="view_mode">kanban,tree,form</field> + <field name="context">{'search_default_group_by_definition': True, 'search_default_inprogress': True, 'search_default_challenge_id': active_id, 'default_challenge_id': active_id}</field> + <field name="help" type="html"> + <p class="o_view_nocontent_empty_folder"> + No goal found + </p><p> + There is no goal associated to this challenge matching your search. + Make sure that your challenge is active and assigned to at least one user. + </p> + </field> + </record> + + <record id="challenge_form_view" model="ir.ui.view"> + <field name="name">Challenge Form</field> + <field name="model">gamification.challenge</field> + <field name="arch" type="xml"> + <form string="Goal definitions"> + <header> + <button string="Start Challenge" type="object" name="action_start" states="draft" class="oe_highlight"/> + <button string="Refresh Challenge" type="object" name="action_check" states="inprogress"/> + <button string="Send Report" type="object" name="action_report_progress" states="inprogress,done" groups="base.group_no_one"/> + <field name="state" widget="statusbar" options="{'clickable': '1'}"/> + </header> + <sheet> + <!-- action buttons --> + <div class="oe_button_box" name="button_box"> + <button type="action" + name="%(goals_from_challenge_act)d" + class="oe_stat_button" + icon="fa-gift" + attrs="{'invisible': [('state','=','draft')]}"> + <div class="o_field_widget o_stat_info"> + <span class="o_stat_text">Related</span> + <span class="o_stat_text">Goals</span> + </div> + </button> + </div> + + <div class="oe_title"> + <label for="name" class="oe_edit_only"/> + <h1> + <field name="name" placeholder="e.g. Monthly Sales Objectives"/> + </h1> + <label for="user_domain" class="oe_edit_only" string="Assign Challenge To"/> + <div> + <field name="user_domain" widget="domain" options="{'model': 'res.users'}" /> + <field name="user_ids" widget="many2many_tags" /> + </div> + </div> + + <group> + <group> + <field name="period" attrs="{'readonly':[('state','!=','draft')]}"/> + <field name="visibility_mode" widget="radio" colspan="1" /> + </group> + <group> + <field name="manager_id"/> + <field name="start_date" attrs="{'readonly':[('state','!=','draft')]}"/> + <field name="end_date" attrs="{'readonly':[('state','!=','draft')]}"/> + </group> + </group> + <notebook> + <page string="Goals" name="goals"> + <field name="line_ids" nolabel="1" colspan="4"> + <tree string="Line List" editable="bottom" > + <field name="sequence" widget="handle"/> + <field name="definition_id" /> + <field name="condition"/> + <field name="target_goal" string="Target"/> + <field name="definition_full_suffix"/> + </tree> + </field> + <field name="description" placeholder="Describe the challenge: what is does, who it targets, why it matters..."/> + </page> + <page string="Reward" name="reward"> + <group> + <field name="reward_id" attrs="{'required': [('reward_realtime','=', True)]}" /> + <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)]}" /> + <field name="reward_realtime" /> + </group> + <div class="oe_grey"> + <p>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.</p> + </div> + </page> + <page string="Advanced Options" name="advanced_options"> + <group string="Subscriptions"> + <field name="invited_user_ids" widget="many2many_tags" /> + </group> + <group string="Notification Messages"> + <div class="oe_grey" colspan="4"> + <p>Depending on the Display mode, reports will be individual or shared.</p> + </div> + <group colspan="4"> + <field name="report_message_frequency"/> + <field name="report_template_id" attrs="{'invisible': [('report_message_frequency','=','never')]}" /> + <field name="report_message_group_id" attrs="{'invisible': [('report_message_frequency','=','never')]}" /> + </group> + </group> + <group string="Reminders for Manual Goals"> + <label for="remind_update_delay" /> + <div> + <field name="remind_update_delay" class="oe_inline"/> days + </div> + </group> + <group string="Category" groups="base.group_no_one"> + <field name="challenge_category" widget="radio" /> + </group> + </page> + </notebook> + + </sheet> + <div class="oe_chatter"> + <field name="message_follower_ids"/> + <field name="message_ids"/> + </div> + </form> + </field> + </record> + + <record model="ir.ui.view" id="view_challenge_kanban"> + <field name="name">Challenge Kanban</field> + <field name="model">gamification.challenge</field> + <field name="arch" type="xml"> + <kanban string="Challenges" class="oe_background_grey"> + <field name="line_ids"/> + <field name="user_ids"/> + <templates> + <t t-name="kanban-box"> + <div t-attf-class="oe_kanban_card o_kanban_gamification oe_kanban_global_click"> + <div class="o_kanban_content"> + <strong> + <h4 class="o_kanban_record_title"><field name="name"/></h4> + <div class="oe_kanban_project_list o_kanban_record_subtitle"> + <a type="action" name="%(goals_from_challenge_act)d" style="margin-right: 10px" tabindex="-1"> + <span t-if="record.line_ids.raw_value.length gt 1"><t t-esc="record.line_ids.raw_value.length"/> Goals</span> + <span t-if="record.line_ids.raw_value.length lt 2"><t t-esc="record.line_ids.raw_value.length"/> Goal</span> + </a> + </div> + </strong> + <t t-foreach="record.user_ids.raw_value.slice(0,11)" t-as="member"> + <img class="o_kanban_badge_avatars" t-att-src="kanban_image('res.users', 'image_128', member)" t-att-data-member_id="member" alt="Member"/> + </t> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> + + <record id="challenge_list_action" model="ir.actions.act_window"> + <field name="name">Challenges</field> + <field name="res_model">gamification.challenge</field> + <field name="view_mode">kanban,tree</field> + <field name="context">{'search_default_inprogress':True, 'default_inprogress':True}</field> + <field name="help" type="html"> + <p class="o_view_nocontent_smiling_face"> + Create a new challenge + </p><p> + Assign a list of goals to chosen users to evaluate them. + The challenge can use a period (weekly, monthly...) for automatic creation of goals. + The goals are created for the specified users or member of the group. + </p> + </field> + </record> + <!-- Specify form view ID to avoid selecting view_challenge_wizard --> + <record id="challenge_list_action_view1" model="ir.actions.act_window.view"> + <field eval="1" name="sequence"/> + <field name="view_mode">kanban</field> + <field name="act_window_id" ref="challenge_list_action"/> + <field name="view_id" ref="view_challenge_kanban"/> + </record> + <record id="challenge_list_action_view2" model="ir.actions.act_window.view"> + <field eval="10" name="sequence"/> + <field name="view_mode">form</field> + <field name="act_window_id" ref="challenge_list_action"/> + <field name="view_id" ref="challenge_form_view"/> + </record> + + <!-- Line --> + <record id="challenge_line_list_view" model="ir.ui.view"> + <field name="name">Challenge line list</field> + <field name="model">gamification.challenge.line</field> + <field name="arch" type="xml"> + <tree string="Challenge Lines" > + <field name="definition_id"/> + <field name="target_goal" string="Target"/> + </tree> + </field> + </record> + + + <record id="challenge_search_view" model="ir.ui.view"> + <field name="name">Challenge Search</field> + <field name="model">gamification.challenge</field> + <field name="arch" type="xml"> + <search string="Search Challenges"> + <filter name="inprogress" string="Running Challenges" + domain="[('state', '=', 'inprogress')]"/> + <filter name="hr_challenges" string="HR Challenges" + domain="[('challenge_category', '=', 'hr')]"/> + <field name="name"/> + <group expand="0" string="Group By"> + <filter string="State" name="state" domain="[]" context="{'group_by':'state'}"/> + <filter string="Period" name="period" domain="[]" context="{'group_by':'period'}"/> + </group> + </search> + </field> + </record> +</odoo> diff --git a/addons/gamification/views/gamification.xml b/addons/gamification/views/gamification.xml new file mode 100644 index 00000000..08341ac8 --- /dev/null +++ b/addons/gamification/views/gamification.xml @@ -0,0 +1,7 @@ +<odoo> + <template id="assets_backend" name="gamification assets" inherit_id="web.assets_backend"> + <xpath expr="." position="inside"> + <link rel="stylesheet" type="text/scss" href="/gamification/static/src/scss/gamification.scss"/> + </xpath> + </template> +</odoo> diff --git a/addons/gamification/views/gamification_karma_rank_views.xml b/addons/gamification/views/gamification_karma_rank_views.xml new file mode 100644 index 00000000..bee0f28f --- /dev/null +++ b/addons/gamification/views/gamification_karma_rank_views.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data> + <!-- ACTIONS --> + <record id="action_current_rank_users" model="ir.actions.act_window"> + <field name="name">Users</field> + <field name="res_model">res.users</field> + <field name="view_mode">tree,form</field> + <field name="domain">[('rank_id', '=', active_id)]</field> + </record> + + <!-- Ranks views --> + <record id="gamification_karma_ranks_action" model="ir.actions.act_window"> + <field name="name">Ranks</field> + <field name="res_model">gamification.karma.rank</field> + <field name="view_mode">tree,form</field> + <field name="help" type="html"> + <p class="o_view_nocontent_smiling_face"> + Create a new rank + </p><p> + A rank correspond to a fixed karma level. The more you have karma, the more your rank is high. + This is used to quickly know which user is new or old or highly or not active. + </p> + </field> + </record> + + <record id="gamification_karma_ranks_view_search" model="ir.ui.view"> + <field name="name">gamification.karma.ranks.view.search</field> + <field name="model">gamification.karma.rank</field> + <field name="arch" type="xml"> + <search string="Search Ranks"> + <field name="name"/> + <field name="karma_min"/> + <field name="description"/> + <field name="user_ids"/> + </search> + </field> + </record> + + <record id="gamification_karma_ranks_view_tree" model="ir.ui.view"> + <field name="name">gamification.karma.ranks.view.tree</field> + <field name="model">gamification.karma.rank</field> + <field name="arch" type="xml"> + <tree string="Ranks List"> + <field name="name"/> + <field name="karma_min"/> + <field name="rank_users_count"/> + </tree> + </field> + </record> + + <record id="gamification_karma_rank_view_form" model="ir.ui.view"> + <field name="name">gamification.karma.rank.view.form</field> + <field name="model">gamification.karma.rank</field> + <field name="arch" type="xml"> + <form string="Rank"> + <sheet> + <div class="oe_button_box" name="button_box"> + <button type="action" class="oe_stat_button" icon="fa-users" name="%(action_current_rank_users)d"> + <div class="o_form_field o_stat_info"> + <span class="o_stat_value"> + <field name="rank_users_count" /> + </span> + <span class="o_stat_text">Users</span> + </div> + </button> + </div> + <field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/> + <div class="oe_title"> + <label for="name" class="oe_edit_only"/> + <h1> + <field name="name" placeholder="e.g. Master Chief"/> + </h1> + </div> + <group> + <field name="karma_min"/> + <field name="create_date" invisible="1"/> + </group> + <notebook> + <page string="Description" name="description"> + <field name="description" placeholder="e.g. A Master Chief knows quite everything on the forum! You cannot beat him!"/> + </page> + <page string="Motivational" name="motivational"> + <field name="description_motivational" placeholder="e.g. Reach this rank to gain a free mug !"/> + </page> + </notebook> + </sheet> + </form> + </field> + </record> + + <menuitem id="gamification_karma_ranks_menu" parent="gamification_menu" action="gamification_karma_ranks_action" sequence="40"/> + </data> +</odoo> diff --git a/addons/gamification/views/gamification_karma_tracking_views.xml b/addons/gamification/views/gamification_karma_tracking_views.xml new file mode 100644 index 00000000..998d0ff9 --- /dev/null +++ b/addons/gamification/views/gamification_karma_tracking_views.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo><data> + <record id="gamification_karma_tracking_view_search" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.search</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <search string="Search Trackings"> + <field name="user_id"/> + <field name="tracking_date"/> + <filter string="Consolidated" name="filter_consolidated" + domain="[('consolidated', '=', True)]"/> + <group string="Group By" expand="1"> + <filter string="User" name="group_by_user_id" + context="{'group_by': 'user_id'}"/> + </group> + </search> + </field> + </record> + + <record id="gamification_karma_tracking_view_tree" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.tree</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <tree string="Trackings"> + <field name="user_id"/> + <field name="tracking_date"/> + <field name="old_value"/> + <field name="new_value"/> + <field name="consolidated"/> + </tree> + </field> + </record> + + <record id="gamification_karma_tracking_view_form" model="ir.ui.view"> + <field name="name">gamification.karma.tracking.view.form</field> + <field name="model">gamification.karma.tracking</field> + <field name="arch" type="xml"> + <form string="Tracking"> + <sheet> + <group> + <field name="user_id"/> + <field name="tracking_date"/> + <field name="old_value"/> + <field name="new_value"/> + <field name="consolidated"/> + </group> + </sheet> + </form> + </field> + </record> + + <record id="gamification_karma_tracking_action" model="ir.actions.act_window"> + <field name="name">Trackings</field> + <field name="res_model">gamification.karma.tracking</field> + <field name="view_mode">tree,form</field> + </record> + + <menuitem id="gamification_karma_tracking_menu" + parent="gamification_menu" + action="gamification_karma_tracking_action" + sequence="50"/> + </data> +</odoo> diff --git a/addons/gamification/views/goal.xml b/addons/gamification/views/goal.xml new file mode 100644 index 00000000..bfba69b5 --- /dev/null +++ b/addons/gamification/views/goal.xml @@ -0,0 +1,300 @@ +<odoo> + <!-- Goal views --> + <record id="goal_list_action" model="ir.actions.act_window"> + <field name="name">Goals</field> + <field name="res_model">gamification.goal</field> + <field name="view_mode">tree,form,kanban</field> + <field name="context">{'search_default_group_by_user': True, 'search_default_group_by_definition': True}</field> + <field name="help" type="html"> + <p class="o_view_nocontent_smiling_face"> + Create a new goal + </p><p> + A goal is defined by a user and a goal definition. + Goals can be created automatically by using challenges. + </p> + </field> + </record> + + <record id="goal_list_view" model="ir.ui.view"> + <field name="name">Goal List</field> + <field name="model">gamification.goal</field> + <field name="arch" type="xml"> + <tree string="Goal List" decoration-danger="state == 'failed'" decoration-success="state == 'reached'" decoration-muted="state == 'canceled'" create="false"> + <field name="definition_id" invisible="1" /> + <field name="user_id" invisible="1" /> + <field name="start_date"/> + <field name="end_date"/> + <field name="current"/> + <field name="target_goal"/> + <field name="completeness" widget="progressbar"/> + <field name="state" invisible="1"/> + <field name="line_id" invisible="1"/> + </tree> + </field> + </record> + + <record id="goal_form_view" model="ir.ui.view"> + <field name="name">Goal Form</field> + <field name="model">gamification.goal</field> + <field name="arch" type="xml"> + <form string="Goal" create="false"> + <header> + <button string="Start goal" type="object" name="action_start" states="draft" class="oe_highlight"/> + + <button string="Goal Reached" type="object" name="action_reach" states="inprogress" /> + <button string="Goal Failed" type="object" name="action_fail" states="inprogress"/> + <button string="Reset Completion" type="object" name="action_cancel" states="failed,reached" groups="base.group_no_one" /> + <field name="state" widget="statusbar" statusbar_visible="draft,inprogress,reached" /> + </header> + <sheet> + <group> + <group string="Reference"> + <field name="definition_id" attrs="{'readonly':[('state','!=','draft')]}"/> + <field name="user_id" attrs="{'readonly':[('state','!=','draft')]}"/> + <field name="challenge_id" /> + </group> + <group string="Schedule"> + <field name="start_date" attrs="{'readonly':[('state','!=','draft')]}"/> + <field name="end_date" /> + <field name="computation_mode" invisible="1"/> + + <label for="remind_update_delay" attrs="{'invisible':[('computation_mode','!=', 'manually')]}"/> + <div attrs="{'invisible':[('computation_mode','!=', 'manually')]}"> + <field name="remind_update_delay" class="oe_inline"/> + days + </div> + <field name="last_update" groups="base.group_no_one"/> + </group> + <group string="Data" colspan="4"> + <label for="target_goal" /> + <div> + <field name="target_goal" attrs="{'readonly':[('state','!=','draft')]}" class="oe_inline"/> + <field name="definition_suffix" class="oe_inline"/> + </div> + <label for="current" /> + <div> + <field name="current" class="oe_inline"/> + <button string="refresh" type="object" name="update_goal" class="oe_link" attrs="{'invisible':['|',('computation_mode', '=', 'manually'),('state', '=', 'draft')]}" /> + <div class="oe_grey" attrs="{'invisible':[('definition_id', '=', False)]}"> + Reached when current value is <strong><field name="definition_condition" class="oe_inline"/></strong> than the target. + </div> + </div> + </group> + </group> + </sheet> + </form> + </field> + </record> + + <record id="goal_search_view" model="ir.ui.view"> + <field name="name">Goal Search</field> + <field name="model">gamification.goal</field> + <field name="arch" type="xml"> + <search string="Search Goals"> + <filter name="my" string="My Goals" domain="[('user_id', '=', uid)]"/> + <separator/> + <filter name="draft" string="Draft" domain="[('state', '=', 'draft')]"/> + <filter name="inprogress" string="Running" + domain="[ + '|', + ('state', '=', 'inprogress'), + '&', + ('state', 'in', ('done', 'failed')), + ('end_date', '>=', context_today().strftime('%%Y-%%m-%%d')) + ]"/> + <filter name="closed" string="Done" + domain="[ + ('state', 'in', ('reached', 'failed')), + '|', + ('end_date', '=', False), + ('end_date', '<', context_today().strftime('%%Y-%%m-%%d')) + ]"/> + <separator/> + + <field name="user_id"/> + <field name="definition_id"/> + <field name="challenge_id"/> + <group expand="0" string="Group By"> + <filter name="group_by_user" string="User" domain="[]" context="{'group_by':'user_id'}"/> + <filter name="group_by_definition" string="Goal Definition" domain="[]" context="{'group_by':'definition_id'}"/> + <filter string="State" name="state" domain="[]" context="{'group_by':'state'}"/> + <filter string="End Date" name="enddate" domain="[]" context="{'group_by':'end_date'}"/> + </group> + </search> + </field> + </record> + + <record id="goal_kanban_view" model="ir.ui.view" > + <field name="name">Goal Kanban View</field> + <field name="model">gamification.goal</field> + <field name="arch" type="xml"> + <kanban class="oe_background_grey" create="false"> + <field name="definition_id"/> + <field name="user_id"/> + <field name="current"/> + <field name="completeness"/> + <field name="state"/> + <field name="target_goal"/> + <field name="definition_description"/> + <field name="definition_condition"/> + <field name="definition_suffix"/> + <field name="definition_display"/> + <field name="start_date"/> + <field name="end_date"/> + <field name="last_update"/> + <templates> + <t t-name="kanban-tooltip"> + <ul class="oe_kanban_tooltip"> + <li><t t-esc="record.definition_description.value" /></li> + </ul> + </t> + <t t-name="kanban-box"> + <div t-attf-class="oe_kanban_card oe_kanban_global_click o_kanban_gamification #{record.end_date.raw_value < record.last_update.raw_value & record.state.raw_value == 'failed' ? 'oe_kanban_color_2' : ''} #{record.end_date.raw_value < record.last_update.raw_value & record.state.raw_value == 'reached' ? 'oe_kanban_color_5' : ''}"> + <div class="o_kanban_content"> + <p><strong><h4 class="oe_goal_name text-center" tooltip="kanban-tooltip"><field name="definition_id" /></h4></strong></p> + <div class="float-left"> + <img class="o_image_24_cover" t-att-src="kanban_image('res.users', 'image_128', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value"/> + </div> + <field name="user_id" /> + <div class="o_goal_state_block"> + <t t-if="record.definition_display.raw_value == 'boolean'"> + <div class="o_goal_state text-center"> + <t t-if="record.state.raw_value=='reached'"><i role="img" class="o_green fa fa-check fa-3x" title="Goal Reached" aria-label="Goal Reached"/></t> + <t t-if="record.state.raw_value=='inprogress'"><i role="img" class="fa fa-clock-o fa-3x" title="Goal in Progress" aria-label="Goal in Progress"/></t> + <t t-if="record.state.raw_value=='failed'"><i role="img" class="o_red fa fa-times fa-3x" title="Goal Failed" aria-label="Goal Failed"/></t> + </div> + </t> + <t t-if="record.definition_display.raw_value == 'progress'"> + <t t-if="record.definition_condition.raw_value =='higher'"> + <field name="current" widget="gauge" options="{'max_field': 'target_goal', 'label_field': 'definition_suffix', 'style': 'width:160px; height: 120px;'}" /> + </t> + <t t-if="record.definition_condition.raw_value != 'higher'"> + <div t-attf-class="o_goal_state #{record.current.raw_value == record.target_goal.raw_value+1 ? 'o_orange' : record.current.raw_value > record.target_goal.raw_value ? 'o_red' : 'o_green'}"> + <t t-esc="record.current.raw_value" /> + </div> + <em>Target: less than <t t-esc="record.target_goal.raw_value" /></em> + </t> + </t> + + </div> + <p class="text-center"> + <t t-if="record.start_date.value"> + From <t t-esc="record.start_date.value" /> + </t> + <t t-if="record.end_date.value"> + To <t t-esc="record.end_date.value" /> + </t> + </p> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> + + + <!-- Goal definitions view --> + + <record id="goal_definition_list_action" model="ir.actions.act_window"> + <field name="name">Goal Definitions</field> + <field name="res_model">gamification.goal.definition</field> + <field name="view_mode">tree,form</field> + <field name="help" type="html"> + <p class="o_view_nocontent_smiling_face"> + Create a new goal definition + </p><p> + A goal definition is a technical specification of a condition to reach. + The dates, values to reach or users are defined in goal instance. + </p> + </field> + </record> + + <record id="goal_definition_list_view" model="ir.ui.view"> + <field name="name">Goal Definitions List</field> + <field name="model">gamification.goal.definition</field> + <field name="arch" type="xml"> + <tree string="Goal Definitions"> + <field name="name"/> + <field name="computation_mode"/> + </tree> + </field> + </record> + + + <record id="goal_definition_form_view" model="ir.ui.view"> + <field name="name">Goal Definitions Form</field> + <field name="model">gamification.goal.definition</field> + <field name="arch" type="xml"> + <form string="Goal definitions"> + <sheet> + <label for="name" class="oe_edit_only"/> + <h1> + <field name="name"/> + </h1> + <label for="description" class="oe_edit_only"/> + <div> + <field name="description" class="oe_inline"/> + </div> + + <group string="How is the goal computed?" name="compute_details"> + + <field widget="radio" name="computation_mode"/> + + <!-- Hide the fields below if manually --> + <field name="model_id" class="oe_inline" + attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}"/> + <field name="model_inherited_ids" invisible="1"/> + <field name="field_id" class="oe_inline" + attrs="{'invisible':[('computation_mode','!=','sum')], 'required':[('computation_mode','=','sum')]}"/> + <field name="field_date_id" class="oe_inline" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))]}"/> + <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"/> + </group> + <group string="Optimisation" name="optimisation" attrs="{'invisible': [('computation_mode', 'not in', ('sum', 'count'))]}"> + <field name="batch_mode" /> + <div colspan="2">In batch mode, the domain is evaluated globally. If enabled, do not use keyword 'user' in above filter domain.</div> + <field name="batch_distinctive_field" attrs="{'invisible': [('batch_mode', '=', False)], 'required': [('batch_mode', '=', True)]}" + domain="[('model_id', '=', model_id)]" class="oe_inline" /> + <field name="batch_user_expression" attrs="{'invisible': [('batch_mode', '=', False)], 'required': [('batch_mode', '=', True)]}" class="oe_inline" + placeholder="e.g. user.partner_id.id"/> + </group> + <group string="Formatting Options" name="format_options"> + <field name="display_mode" widget="radio" /> + <field name="suffix" placeholder="e.g. days" class="oe_inline"/> + <field name="monetary"/> + </group> + <group string="Clickable Goals" name="clickable_goals" attrs="{'invisible': [('computation_mode', '=', 'manually')]}"> + <field name="action_id" class="oe_inline"/> + <field name="res_id_field" attrs="{'invisible': [('action_id', '=', False)]}" class="oe_inline"/> + </group> + + </sheet> + </form> + </field> + </record> + + <record id="goal_definition_search_view" model="ir.ui.view"> + <field name="name">Goal Definition Search</field> + <field name="model">gamification.goal.definition</field> + <field name="arch" type="xml"> + <search string="Search Goal Definitions"> + <field name="name"/> + <field name="model_id"/> + <field name="field_id"/> + <group expand="0" string="Group By"> + <filter string="Model" name="model" domain="[]" context="{'group_by':'model_id'}"/> + <filter string="Computation Mode" name="computationmode" domain="[]" context="{'group_by':'computation_mode'}"/> + </group> + </search> + </field> + </record> + + <!-- menus in settings - technical feature required --> + <menuitem id="gamification_menu" name="Gamification Tools" parent="base.menu_administration" groups="base.group_no_one" /> + <menuitem id="gamification_challenge_menu" parent="gamification_menu" action="challenge_list_action" sequence="0"/> + <menuitem id="gamification_goal_menu" parent="gamification_menu" action="goal_list_action" sequence="10"/> + <menuitem id="gamification_definition_menu" parent="gamification_menu" action="goal_definition_list_action" sequence="20"/> + <menuitem id="gamification_badge_menu" parent="gamification_menu" action="badge_list_action" sequence="30"/> +</odoo> diff --git a/addons/gamification/views/mail_templates.xml b/addons/gamification/views/mail_templates.xml new file mode 100644 index 00000000..e8a6a6a3 --- /dev/null +++ b/addons/gamification/views/mail_templates.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data> + <record id="mail_template_data_new_rank_reached" model="mail.template"> + <field name="name">User: New rank reached</field> + <field name="model_id" ref="base.model_res_users"/> + <field name="subject">New rank: ${object.rank_id.name}</field> + <field name="email_to"></field> + <field name="partner_to">${object.partner_id.id}</field> + <field name="body_html" type="html"> +<div style="background:#F0F0F0;color:#515166;padding:10px 0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;"> +<table style="width:600px;margin:0px auto;background:white;border:1px solid #e1e1e1;"> + <tbody> + <tr> + <td style="padding:15px 20px 10px 20px;"> + <p> + Congratulations + <span>${object.name or ''}</span>! + </p> + <p> + You just reached a new rank : <strong>${object.rank_id.name}</strong> + </p> + % if object.next_rank_id.name + <p>Continue your work to become a <strong>${object.next_rank_id.name}</strong> !</p> + % endif + <div style="margin: 16px 0px 16px 0px;"> + % set gamification_redirection_data = object.get_gamification_redirection_data() + % for data in gamification_redirection_data + % set url = data['url'] + % set label = data['label'] + <a href="${url}" style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">${label}</a> + % endfor + </div> + </td> + <td style="padding:15px 20px 10px 20px;"> + <p style="text-align: center;"> + <img src="/web/image/gamification.karma.rank/${object.rank_id.id}/image_128"/> + </p> + </td> + </tr> + % if user.signature + <tr> + <td style="padding:15px 20px 10px 20px;"> + ${user.signature | safe} + </td> + </tr> + % endif + </tbody> + </table> +</div></field> + <field name="lang">${object.lang}</field> + <field name="auto_delete" eval="True"/> + </record> + </data> +</odoo> diff --git a/addons/gamification/views/res_users_views.xml b/addons/gamification/views/res_users_views.xml new file mode 100644 index 00000000..c0c20cad --- /dev/null +++ b/addons/gamification/views/res_users_views.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> +<data> + + <record id="res_users_view_form" model="ir.ui.view"> + <field name="name">res.users.view.form.inherit.gamification</field> + <field name="model">res.users</field> + <field name="inherit_id" ref="base.view_users_form"/> + <field name="arch" type="xml"> + <group name="messaging" position="inside"> + <field name="karma"/> + </group> + </field> + </record> + +</data> +</odoo> |
