Gamification

gamification
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/19.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo S.A.
MAINTAINERS
MAINTAINERSOdoo S.A.
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Thibault Delavallée, Xavier Morel, Yannick Tivisse, Julien Castiaux, Sébastien Theys, Achraf (abz), Tiffany Chang (tic), Gorash, alsh-odoo, Victor Piryns (pivi), Dylan Kiss (dyki), omra-odoo, Serge Bayet (seba), Martin Trigaux (mat), mano-odoo, aamo-odoo, sben-odoo, Anton Romanova (roan), Krzysztof Magusiak (krma), defl, Giorgio Tocco (gito), Jérôme Belpaire, saurabh, chpa-odoo, panj-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:51:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (26)
XML IDNameModelTypeStatus
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge list New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line list New
challenge_list_view Challenges List gamification.challenge list New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.list gamification.karma.rank list New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.list gamification.karma.tracking list New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition list New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal list New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users xpath Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Html
    sanitize_attributes=False translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded these goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (8)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    string='Challenge' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
  • user_partner_id Many2one → res.partner
    related='user_id.partner_id' args: 'res.partner'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (26)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assignment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → discuss.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'discuss.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    index='btree_not_null' string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_count Integer
    compute='_compute_user_count' args: '# Users'
  • user_domain Char
    args: 'User domain'
  • user_ids Many2many → res.users
    string='Participants' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (10)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • action_view_users(self)
    Redirect to the participants (users) list.
  • create(self, vals_list)
    @api.model_create_multi
    Overwrite the create method to add the user of groups
  • default_get(self, fields)
    @api.model
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    index=True ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (21)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    args: 'Closed goal'
  • color Integer
    compute='_compute_color' args: 'Color Index'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Cancelled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    bypass_search_access=True index=True ondelete='cascade' required=True string='User' args: 'res.users'
  • user_partner_id Many2one → res.partner
    related='user_id.partner_id' args: 'res.partner'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals_list)
    @api.model_create_multi
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    ondelete='cascade' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank on your profile page' sanitize_attributes=False sanitize_overridable=True string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (9)
  • consolidated Boolean
    args: 'Consolidated'
  • gain Integer
    compute='_compute_gain' readonly=False args: 'Gain'
  • new_value Integer
    required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True args: 'Old Karma Value'
  • origin_ref Reference
    default=<expr> selection=<expr> string='Source'
  • origin_ref_model_name Selection
    compute='_compute_origin_ref_model_name' selection=<expr> store=True string='Source Type'
  • reason Text
    default=<expr> string='Description'
  • tracking_date Datetime
    default=fields.Datetime.now index=True readonly=True
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True args: 'res.users', 'User'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    compute='_compute_karma' readonly=False store=True args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    index='btree_not_null' args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • action_karma_report(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/18.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Xavier Morel, Aaron Bohy, qsm-odoo, Odoo Online, Aurélien Warnon, Brice bib Bartoletti, Tiffany Chang (tic), Gorash, Mathieu Duckerts-Antoine, Vincent Larcin, alsh-odoo, Gaetan Vanden Bergh (gavb), Louis Wicket (wil), Pierre-Yves Dufays, Dylan Kiss (dyki), Vivek Pathak, omra-odoo, Maryam Kia, Serge Bayet (seba), Louis (wil), mano-odoo, aamo-odoo, sben-odoo, kusi-odoo, Krzysztof Magusiak (krma), Jérôme Belpaire
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:25:56
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (26)
XML IDNameModelTypeStatus
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge list New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line list New
challenge_list_view Challenges List gamification.challenge list New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.list gamification.karma.rank list New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.list gamification.karma.tracking list New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition list New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal list New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users xpath Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Html
    sanitize_attributes=False translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded these goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    string='Challenge' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (26)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assignment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → discuss.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'discuss.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_count Integer
    compute='_compute_user_count' args: '# Users'
  • user_domain Char
    args: 'User domain'
  • user_ids Many2many → res.users
    string='Participants' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (10)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • action_view_users(self)
    Redirect to the participants (users) list.
  • create(self, vals_list)
    @api.model_create_multi
    Overwrite the create method to add the user of groups
  • default_get(self, fields_list)
    @api.model
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (20)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    args: 'Closed goal'
  • color Integer
    compute='_compute_color' args: 'Color Index'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Cancelled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals_list)
    @api.model_create_multi
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    ondelete='cascade' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank on your profile page' sanitize_attributes=False sanitize_overridable=True string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (9)
  • consolidated Boolean
    args: 'Consolidated'
  • gain Integer
    compute='_compute_gain' readonly=False args: 'Gain'
  • new_value Integer
    required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True args: 'Old Karma Value'
  • origin_ref Reference
    default=<expr> selection=<expr> string='Source'
  • origin_ref_model_name Selection
    compute='_compute_origin_ref_model_name' selection=<expr> store=True string='Source Type'
  • reason Text
    default=<expr> string='Description'
  • tracking_date Datetime
    default=fields.Datetime.now index=True readonly=True
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True args: 'res.users', 'User'
Public methods (1)
  • create(self, values_list)
    @api.model_create_multi

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    compute='_compute_karma' readonly=False store=True args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • action_karma_report(self)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, values)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/17.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Xavier Morel, Aaron Bohy, qsm-odoo, Odoo Online, Aurélien Warnon, Xavier-Do, Victor Feyens, Sébastien Theys, std-odoo, Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Pierre Paridans, Benoit Socias, Florian Charlier, Renaud Thiry, niyasraphy, alsh-odoo, Gaetan Vanden Bergh (gavb), Louis Wicket (wil), Pierre-Yves Dufays, Saurabh Choraria, Dylan Kiss (dyki), Bruno Boi, Brieuc-brd, Jordan D. (Joda), Serge Bayet (seba), Julien Carion (juca), Louis (wil), aamo-odoo, Elisabeth Dickinson, Julien, Jérôme Belpaire
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:02:07
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (26)
XML IDNameModelTypeStatus
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.tree gamification.karma.rank tree New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.tree gamification.karma.tracking tree New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users xpath Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Html
    sanitize_attributes=False translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded these goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    string='Challenge' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (26)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assignment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → discuss.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'discuss.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_count Integer
    compute='_compute_user_count' args: '# Users'
  • user_domain Char
    args: 'User domain'
  • user_ids Many2many → res.users
    string='Participants' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (10)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • action_view_users(self)
    Redirect to the participants (users) list.
  • create(self, vals_list)
    @api.model_create_multi
    Overwrite the create method to add the user of groups
  • default_get(self, fields_list)
    @api.model
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals_list)
    @api.model_create_multi
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    ondelete='cascade' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank on your profile page' sanitize_attributes=False sanitize_overridable=True string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (9)
  • consolidated Boolean
    args: 'Consolidated'
  • gain Integer
    compute='_compute_gain' readonly=False args: 'Gain'
  • new_value Integer
    required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True args: 'Old Karma Value'
  • origin_ref Reference
    default=<expr> selection=<expr> string='Source'
  • origin_ref_model_name Selection
    compute='_compute_origin_ref_model_name' selection=<expr> store=True string='Source Type'
  • reason Text
    default=<expr> string='Description'
  • tracking_date Datetime
    default=fields.Datetime.now index=True readonly=True
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True args: 'res.users', 'User'
Public methods (1)
  • create(self, values_list)
    @api.model_create_multi

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    compute='_compute_karma' readonly=False store=True args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • action_karma_report(self)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, values)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/16.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Géry Debongnie, Aaron Bohy, GitHub, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Victor Feyens, Tiffany Chang (tic), Mathieu Duckerts-Antoine, Benoit Socias, Florian Charlier, Fabio Barbero, niyasraphy, alsh-odoo, Louis Wicket (wil), Saurabh Choraria, Bruno Boi, Brieuc-brd, Jordan D. (Joda), Serge Bayet (seba), Karan Bosamia
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:49
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (26)
XML IDNameModelTypeStatus
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.tree gamification.karma.rank tree New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.tree gamification.karma.tracking tree New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users group Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Html
    sanitize_attributes=False translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded these goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    string='Challenge' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (26)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assignment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_count Integer
    compute='_compute_user_count' args: '# Users'
  • user_domain Char
    args: 'User domain'
  • user_ids Many2many → res.users
    string='Participants' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (10)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • action_view_users(self)
    Redirect to the participants (users) list.
  • create(self, vals_list)
    @api.model_create_multi
    Overwrite the create method to add the user of groups
  • default_get(self, fields_list)
    @api.model
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals_list)
    @api.model_create_multi
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    ondelete='cascade' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank on your profile page' sanitize_attributes=False sanitize_overridable=True string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (5)
  • consolidated Boolean
    args: 'Consolidated'
  • new_value Integer
    readonly=True required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True required=True args: 'Old Karma Value'
  • tracking_date Date
    default=fields.Date.context_today
  • user_id Many2one → res.users
    index=True ondelete='cascade' readonly=True required=True args: 'res.users', 'User'
Public methods (0)

No public methods.

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    copy=False default=0 args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • add_karma(self, karma)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/15.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Jeremy Kersten, GitHub, Barad Mahendra, Nicolas Seinlet, Xavier-Do, Victor Feyens, Julien Mougenot, Tiffany Chang (tic), Kevin Baptiste, Benjamin Vray, Benoit Socias, Florian Charlier, Nicolas Bayet, Michael Mattiello (mcm), Fabio Barbero, niyasraphy, Leonardo Pavan Rocha, Jordan D. (Joda), Karan Bosamia
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:25:28
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (26)
XML IDNameModelTypeStatus
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.tree gamification.karma.rank tree New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.tree gamification.karma.tracking tree New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users group Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Html
    sanitize_attributes=False translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (25)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • create(self, vals_list)
    @api.model_create_multi
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    help='These goals will not be recomputed.' args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals_list)
    @api.model_create_multi
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> help='The field containing the value to evaluate' string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    help='The model object for the field to evaluate' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank' sanitize_attributes=False string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 help='Minimum karma needed to reach this rank' required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    help='Users having this rank' string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (5)
  • consolidated Boolean
    args: 'Consolidated'
  • new_value Integer
    readonly=True required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True required=True args: 'Old Karma Value'
  • tracking_date Date
    default=fields.Date.context_today
  • user_id Many2one → res.users
    index=True ondelete='cascade' readonly=True required=True args: 'res.users', 'User'
Public methods (0)

No public methods.

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    copy=False default=0 args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • add_karma(self, karma)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/14.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Nicolas Martinelli, Jeremy Kersten, GitHub, Yannick Tivisse, Nicolas Seinlet, Aurélien Warnon, Xavier-Do, Victor Feyens, Sébastien Theys, fw-bot, David Beguin, Kevin Baptiste, Benjamin Vray, Florian Charlier, Patrick Hoste, Fabio Barbero, niyasraphy
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:14:29
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (27)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.tree gamification.karma.rank tree New
gamification_karma_tracking_view_form gamification.karma.tracking.view.form gamification.karma.tracking form New
gamification_karma_tracking_view_search gamification.karma.tracking.view.search gamification.karma.tracking search New
gamification_karma_tracking_view_tree gamification.karma.tracking.view.tree gamification.karma.tracking tree New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
res_users_view_form res.users.view.form.inherit.gamification res.users group Inherits base.view_users_form
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (11)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Text
    translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • granted_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • granted_users_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level'
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals)
    @api.model

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (25)
  • challenge_category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • create(self, vals)
    @api.model
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' string='Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' index=True readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    help='These goals will not be recomputed.' args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' string='Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' string='Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals)
    @api.model
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (19)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinguishes one user from the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Define how the goals will be computed. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    domain=<expr> help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    domain=<expr> help='The field containing the value to evaluate' string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    help='The model object for the field to evaluate' string='Model' args: 'ir.model'
  • model_inherited_ids Many2many → ir.model
    related='model_id.inherited_model_ids' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (6)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank' sanitize_attributes=False string='Motivational' translate=html_translate
  • karma_min Integer
    default=1 help='Minimum karma needed to reach this rank' required=True string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • rank_users_count Integer
    compute='_compute_rank_users_count' args: '# Users'
  • user_ids One2many → res.users
    help='Users having this rank' string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (5)
  • consolidated Boolean
    args: 'Consolidated'
  • new_value Integer
    readonly=True required=True args: 'New Karma Value'
  • old_value Integer
    readonly=True required=True args: 'Old Karma Value'
  • tracking_date Date
    default=fields.Date.context_today
  • user_id Many2one → res.users
    index=True ondelete='cascade' readonly=True required=True args: 'res.users', 'User'
Public methods (0)

No public methods.

New fields (8)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    copy=False default=0 args: 'Karma'
  • karma_tracking_ids One2many → gamification.karma.tracking
    groups='base.group_system' string='Karma Changes' args: 'gamification.karma.tracking', 'user_id'
  • next_rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • add_karma(self, karma)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/13.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Nicolas Martinelli, Jeremy Kersten, Yannick Tivisse, qsm-odoo, Odoo Online, Adrien Dieudonne, Jorge Pinna Puissant, Alexandre Kühn, Adrian Torres, Aurélien Warnon, Xavier-Do, Sébastien Theys, fw-bot, Rémy Baranx (bar), Achraf (abz), David Beguin, fja-odoo, Yenthe666
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:06:42
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (23)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
gamification_badge_view_search gamification.badge.view.search gamification.badge search New
gamification_karma_rank_view_form gamification.karma.rank.view.form gamification.karma.rank form New
gamification_karma_ranks_view_search gamification.karma.ranks.view.search gamification.karma.rank search New
gamification_karma_ranks_view_tree gamification.karma.ranks.view.tree gamification.karma.rank tree New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (10)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Text
    translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • level Selection
    default='bronze' string='Forum Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • stat_count_distinct Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (7)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • level Selection
    readonly=True related='badge_id.level' store=True string='Badge Level' args: [('bronze', 'Bronze'), ('silver', 'Silver'), ('gold', 'Gold')]
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals)
    @api.model

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    Wizard action for sending a badge to a chosen user

New fields (25)
  • category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
  • action_check(self)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    Start a challenge
  • create(self, vals)
    @api.model
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' args: 'Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    help='These goals will not be recomputed.' args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True tracking=True args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' args: 'Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' args: 'Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' tracking=True args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True tracking=True args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals)
    @api.model
  • get_action(self)
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (18)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinct one user form the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Defined how will be computed the goals. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    help='The field containing the value to evaluate' string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    help='The model object for the field to evaluate' string='Model' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, vals)

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    Wizard action for updating the current value

New fields (5)
  • description Html
    sanitize_attributes=False string='Description' translate=html_translate
  • description_motivational Html
    help='Motivational phrase to reach this rank' sanitize_attributes=False string='Motivational' translate=html_translate
  • karma_min Integer
    help='Minimum karma needed to reach this rank' string='Required Karma'
  • name Text
    required=True string='Rank Name' translate=True
  • user_ids One2many → res.users
    help='Users having this rank' string='Users' args: 'res.users', 'rank_id'
Public methods (2)
  • create(self, values_list)
    @api.model_create_multi
  • write(self, vals)

New fields (7)
  • badge_ids One2many → gamification.badge.user
    copy=False string='Badges' args: 'gamification.badge.user', 'user_id'
  • bronze_badge Integer
    compute='_get_user_badge_level' args: 'Bronze badges count'
  • gold_badge Integer
    compute='_get_user_badge_level' args: 'Gold badges count'
  • karma Integer
    default=0 args: 'Karma'
  • next_rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Next Rank'
  • rank_id Many2one → gamification.karma.rank
    index=False args: 'gamification.karma.rank', 'Rank'
  • silver_badge Integer
    compute='_get_user_badge_level' args: 'Silver badges count'
Public methods (4)
  • add_karma(self, karma)
  • create(self, values_list)
    @api.model_create_multi
  • get_gamification_redirection_data(self)
    Hook for other modules to add redirect button(s) in new rank reached mail Must return a list of dictionnary including url and label. E.g. return [{'url': '/forum', label: 'Go to Forum'}]
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/12.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, GitHub, Yannick Tivisse, Alexandre Kühn, qsm-odoo, Martin Geubelle, RomainLibert, Christophe Monniez, Adrian Torres, XavierDo, Xavier-Do, fw-bot
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:57:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (8)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Text
    translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • image Binary
    attachment=True help='This field holds the image used for the badge, limited to 256x256' args: 'Image'
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • stat_count_distinct Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (6)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    readonly=False related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals)
    @api.model

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    @api.multi
    Wizard action for sending a badge to a chosen user

New fields (25)
  • category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' track_visibility='onchange' args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
    @api.multi
  • action_check(self)
    @api.multi
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    @api.multi
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    @api.multi
    Start a challenge
  • create(self, vals)
    @api.model
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    @api.multi
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)
    @api.multi

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' args: 'Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    readonly=False related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    help='These goals will not be recomputed.' args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    readonly=False related='definition_id.computation_mode'
  • current Float
    default=0 required=True track_visibility='always' args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' args: 'Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' args: 'Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' track_visibility='always' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True track_visibility='always' args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    @api.multi
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    @api.multi
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    @api.multi
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    @api.multi
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals)
    @api.model
  • get_action(self)
    @api.multi
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    @api.multi
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    @api.multi
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (18)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinct one user form the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Defined how will be computed the goals. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    help='The field containing the value to evaluate' string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    help='The model object for the field to evaluate' string='Model' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, vals)
    @api.multi

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    @api.multi
    Wizard action for updating the current value
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/11.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Joren Van Onder, Jérome Maes, qdp-odoo, Aaron Bohy, ged-odoo, GitHub, Lucas Perais (lpe), qsm-odoo, Martin Geubelle, Odoo Online, alt-odoo
WEBSITE
WEBSITEhttps://www.odoo.com/page/gamification
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:53:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (8)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Text
    translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • image Binary
    attachment=True help='This field holds the image used for the badge, limited to 256x256' args: 'Image'
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • stat_count_distinct Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (8)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • create_date Datetime
    readonly=True args: 'Created'
  • create_uid Many2one → res.users
    readonly=True string='Creator' args: 'res.users'
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals)
    @api.model

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    @api.multi
    Wizard action for sending a badge to a chosen user

New fields (25)
  • category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' track_visibility='onchange' args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
    @api.multi
  • action_check(self)
    @api.multi
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    @api.multi
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    @api.multi
    Start a challenge
  • create(self, vals)
    @api.model
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    @api.multi
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)
    @api.multi

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' args: 'Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (19)
  • challenge_id Many2one
    help='Challenge that generated the goal, assign challenge to users to generate goals with a value in this field.' readonly=True related='line_id.challenge_id' store=True
  • closed Boolean
    help='These goals will not be recomputed.' args: 'Closed goal'
  • completeness Float
    compute='_get_completion' args: 'Completeness'
  • computation_mode Selection
    related='definition_id.computation_mode'
  • current Float
    default=0 required=True track_visibility='always' args: 'Current Value'
  • definition_condition Selection
    readonly=True related='definition_id.condition' args: 'Definition Condition'
  • definition_description Text
    readonly=True related='definition_id.description' args: 'Definition Description'
  • definition_display Selection
    readonly=True related='definition_id.display_mode' args: 'Display Mode'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • end_date Date
    args: 'End Date'
  • last_update Date
    help='In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge.' args: 'Last Update'
  • line_id Many2one → gamification.challenge.line
    ondelete='cascade' string='Challenge Line' args: 'gamification.challenge.line'
  • remind_update_delay Integer
    help='The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified.' args: 'Remind delay'
  • start_date Date
    default=fields.Date.today args: 'Start Date'
  • state Selection
    default='draft' required=True string='State' track_visibility='always' args: [('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled')]
  • target_goal Float
    required=True track_visibility='always' args: 'To Reach'
  • to_update Boolean
    args: 'To update'
  • user_id Many2one → res.users
    auto_join=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (8)
  • action_cancel(self)
    @api.multi
    Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criteria match the conditions for a change of state, this will be applied at the next goal update.
  • action_fail(self)
    @api.multi
    Set the state of the goal to failed. A failed goal will be ignored in future checks.
  • action_reach(self)
    @api.multi
    Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.
  • action_start(self)
    @api.multi
    Mark a goal as started. This should only be used when creating goals manually (in draft state)
  • create(self, vals)
    @api.model
  • get_action(self)
    @api.multi
    Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionary
  • update_goal(self)
    @api.multi
    Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.
  • write(self, vals)
    @api.multi
    Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated

New fields (18)
  • action_id Many2one → ir.actions.act_window
    help='The action that will be called to update the goal value.' string='Action' args: 'ir.actions.act_window'
  • batch_distinctive_field Many2one → ir.model.fields
    help='In batch mode, this indicates which field distinct one user form the other, e.g. user_id, partner_id...' string='Distinctive field for batch user' args: 'ir.model.fields'
  • batch_mode Boolean
    help='Evaluate the expression in batch instead of once for each user' args: 'Batch Mode'
  • batch_user_expression Char
    help="The value to compare with the distinctive field. The expression can contain reference to 'user' which is a browse record of the current user, e.g. user.id, user.partner_id.id..." args: 'Evaluated expression for batch mode'
  • computation_mode Selection
    default='manually' help="Defined how will be computed the goals. The result of the operation will be stored in the field 'Current'." required=True string='Computation Mode' args: [('manually', 'Recorded manually'), ('count', 'Automatic: number of records'), ('sum', 'Automatic: sum on a field'), ('python', 'Automatic: execute a specific Python code')]
  • compute_code Text
    help="Python code to be executed for each user. 'result' should contains the new current value. Evaluated user can be access through object.user_id." args: 'Python Code'
  • condition Selection
    default='higher' help='A goal is considered as completed when the current value is compared to the value to reach' required=True string='Goal Performance' args: [('higher', 'The higher the better'), ('lower', 'The lower the better')]
  • description Text
    args: 'Goal Description'
  • display_mode Selection
    default='progress' required=True string='Displayed as' args: [('progress', 'Progressive (using numerical values)'), ('boolean', 'Exclusive (done or not-done)')]
  • domain Char
    default='[]' help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode." required=True args: 'Filter Domain'
  • field_date_id Many2one → ir.model.fields
    help='The date to use for the time period evaluated' string='Date Field' args: 'ir.model.fields'
  • field_id Many2one → ir.model.fields
    help='The field containing the value to evaluate' string='Field to Sum' args: 'ir.model.fields'
  • full_suffix Char
    compute='_compute_full_suffix' help='The currency and suffix field' args: 'Full Suffix'
  • model_id Many2one → ir.model
    help='The model object for the field to evaluate' string='Model' args: 'ir.model'
  • monetary Boolean
    default=False help='The target and current value are defined in the company currency.' args: 'Monetary Value'
  • name Char
    required=True translate=True args: 'Goal Definition'
  • res_id_field Char
    help='The field name on the user profile (res.users) containing the value for res_id for action.' args: 'ID Field of user'
  • suffix Char
    help='The unit of the target and current values' translate=True args: 'Suffix'
Public methods (2)
  • create(self, vals)
    @api.model
  • write(self, vals)
    @api.multi

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    @api.multi
    Wizard action for updating the current value
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/10.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Simon Lejeune, Nicolas Lempereur, Julien Legros, qdp-odoo, Jeremy Kersten, Yannick Tivisse
WEBSITE
WEBSITEhttps://www.odoo.com/page/gamification
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:50:48
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of Odoo.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover Odoo and configure their user profile.

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (6)

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • challenge_ids One2many → gamification.challenge
    string='Reward of Challenges' args: 'gamification.challenge', 'reward_id'
  • description Text
    translate=True args: 'Description'
  • goal_definition_ids Many2many → gamification.goal.definition
    help='The users that have succeeded theses goals will receive automatically the badge.' string='Rewarded by' args: 'gamification.goal.definition', 'badge_unlocked_definition_rel'
  • image Binary
    attachment=True help='This field holds the image used for the badge, limited to 256x256' args: 'Image'
  • name Char
    required=True translate=True args: 'Badge'
  • owner_ids One2many → gamification.badge.user
    help='The list of instances of this badge granted to users' string='Owners' args: 'gamification.badge.user', 'badge_id'
  • remaining_sending Integer
    compute='_remaining_sending_calc' help='If a maximum is set' args: 'Remaining Sending Allowed'
  • rule_auth Selection
    default='everyone' help='Who can grant this badge' required=True string='Allowance to Grant' args: [('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges')]
  • rule_auth_badge_ids Many2many → gamification.badge
    help='Only the people having these badges can give this badge' string='Required Badges' args: 'gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id'
  • rule_auth_user_ids Many2many → res.users
    help='Only these people can give this badge' string='Authorized Users' args: 'res.users', 'rel_badge_auth_users'
  • rule_max Boolean
    help='Check to set a monthly limit per person of sending this badge' args: 'Monthly Limited Sending'
  • rule_max_number Integer
    help='The maximum number of time this badge can be sent per month per person.' args: 'Limitation Number'
  • stat_count Integer
    compute='_get_owners_info' help='The number of time this badge has been received.' args: 'Total'
  • stat_count_distinct Integer
    compute='_get_owners_info' help='The number of time this badge has been received by unique users.' args: 'Number of users'
  • stat_my Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge.' args: 'My Total'
  • stat_my_monthly_sending Integer
    compute='_get_badge_user_stats' help='The number of time the current user has sent this badge this month.' args: 'My Monthly Sending Total'
  • stat_my_this_month Integer
    compute='_get_badge_user_stats' help='The number of time the current user has received this badge this month.' args: 'My Monthly Total'
  • stat_this_month Integer
    compute='_get_badge_user_stats' help='The number of time this badge has been received this month.' args: 'Monthly total'
  • unique_owner_ids Many2many → res.users
    compute='_get_owners_info' help='The list of unique users having received this badge.' string='Unique Owners' args: 'res.users'
Public methods (1)
  • check_granting(self)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID

New fields (8)
  • badge_id Many2one → gamification.badge
    index=True ondelete='cascade' required=True string='Badge' args: 'gamification.badge'
  • badge_name Char
    related='badge_id.name' string='Badge Name'
  • challenge_id Many2one → gamification.challenge
    help='If this badge was rewarded through a challenge' string='Challenge originating' args: 'gamification.challenge'
  • comment Text
    args: 'Comment'
  • create_date Datetime
    readonly=True args: 'Created'
  • create_uid Many2one → res.users
    readonly=True string='Creator' args: 'res.users'
  • sender_id Many2one → res.users
    help='The user who has send the badge' string='Sender' args: 'res.users'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=True string='User' args: 'res.users'
Public methods (1)
  • create(self, vals)
    @api.model

New fields (3)
  • badge_id Many2one → gamification.badge
    required=True string='Badge' args: 'gamification.badge'
  • comment Text
    args: 'Comment'
  • user_id Many2one → res.users
    required=True string='User' args: 'res.users'
Public methods (1)
  • action_grant_badge(self)
    @api.multi
    Wizard action for sending a badge to a chosen user

New fields (25)
  • category Selection
    default='hr' help='Define the visibility of the challenge through menus' required=True string='Appears in' args: [('hr', 'Human Resources / Engagement'), ('other', 'Settings / Gamification Tools')]
  • description Text
    translate=True args: 'Description'
  • end_date 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.' args: 'End Date'
  • invited_user_ids Many2many → res.users
    string='Suggest to users' args: 'res.users', 'gamification_invited_user_ids_rel'
  • last_report_date Date
    default=fields.Date.today args: 'Last Report Date'
  • line_ids One2many → gamification.challenge.line
    copy=True help='List of goals that will be set' required=True string='Lines' args: 'gamification.challenge.line', 'challenge_id'
  • manager_id Many2one → res.users
    default=<expr> help='The user responsible for the challenge.' string='Responsible' args: 'res.users'
  • name Char
    required=True translate=True args: 'Challenge Name'
  • next_report_date Date
    compute='_get_next_report_date' store=True args: 'Next Report Date'
  • period Selection
    default='once' help='Period of automatic goal assigment. If none is selected, should be launched manually.' required=True string='Periodicity' args: [('once', 'Non recurring'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • remind_update_delay Integer
    help='Never reminded if no value or zero is specified.' args: 'Non-updated manual goals will be reminded after'
  • report_message_frequency Selection
    default='never' required=True string='Report Frequency' args: [('never', 'Never'), ('onchange', 'On change'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly')]
  • report_message_group_id Many2one → mail.channel
    help='Group that will receive a copy of the report in addition to the user' string='Send a copy to' args: 'mail.channel'
  • report_template_id Many2one → mail.template
    default=<expr> required=True string='Report Template' args: 'mail.template'
  • reward_failure Boolean
    args: 'Reward Bests if not Succeeded?'
  • reward_first_id Many2one → gamification.badge
    string='For 1st user' args: 'gamification.badge'
  • reward_id Many2one → gamification.badge
    string='For Every Succeeding User' args: 'gamification.badge'
  • reward_realtime Boolean
    default=True help='With this option enabled, a user can receive a badge only once. The top 3 badges are still rewarded only at the end of the challenge.' args: 'Reward as soon as every goal is reached'
  • reward_second_id Many2one → gamification.badge
    string='For 2nd user' args: 'gamification.badge'
  • reward_third_id Many2one → gamification.badge
    string='For 3rd user' args: 'gamification.badge'
  • start_date 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.' args: 'Start Date'
  • state Selection
    copy=False default='draft' required=True string='State' track_visibility='onchange' args: [('draft', 'Draft'), ('inprogress', 'In Progress'), ('done', 'Done')]
  • user_domain Char
    help='Alternative to a list of users' args: 'User domain'
  • user_ids Many2many → res.users
    help='List of users participating to the challenge' string='Users' args: 'res.users', 'gamification_challenge_users_rel'
  • visibility_mode Selection
    default='personal' required=True string='Display Mode' args: [('personal', 'Individual Goals'), ('ranking', 'Leader Board (Group Ranking)')]
Public methods (8)
  • accept_challenge(self)
    @api.multi
  • action_check(self)
    @api.multi
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self)
    @api.multi
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self)
    @api.multi
    Start a challenge
  • create(self, vals)
    @api.model
    Overwrite the create method to add the user of groups
  • discard_challenge(self)
    @api.multi
    The user discard the suggested challenge
  • report_progress(self, users=(), subset_goals=False)
    Post report about the progress of the goals :param users: users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param subset_goals: goals to restrict the report
  • write(self, vals)
    @api.multi

New fields (9)
  • challenge_id Many2one → gamification.challenge
    ondelete='cascade' required=True string='Challenge' args: 'gamification.challenge'
  • condition Selection
    readonly=True related='definition_id.condition' args: 'Condition'
  • definition_full_suffix Char
    readonly=True related='definition_id.full_suffix' args: 'Suffix'
  • definition_id Many2one → gamification.goal.definition
    ondelete='cascade' required=True string='Goal Definition' args: 'gamification.goal.definition'
  • definition_monetary Boolean
    readonly=True related='definition_id.monetary' args: 'Monetary'
  • definition_suffix Char
    readonly=True related='definition_id.suffix' args: 'Unit'
  • name Char
    related='definition_id.name' args: 'Name'
  • sequence Integer
    default=1 help='Sequence number for ordering' args: 'Sequence'
  • target_goal Float
    required=True args: 'Target Value to Reach'
Public methods (0)

No public methods.

New fields (2)
  • current Float
    args: 'Current'
  • goal_id Many2one → gamification.goal
    required=True string='Goal' args: 'gamification.goal'
Public methods (1)
  • action_update_current(self)
    @api.multi
    Wizard action for updating the current value
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/9.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Denis Ledoux, Fabien Meghazi, Christophe Simonis, Nicolas Martinelli, Richard Mathot, Géry Debongnie, Aaron Bohy, Julien De Coster, Yannick Tivisse, qsm-odoo, Martin Geubelle
WEBSITE
WEBSITEhttps://www.odoo.com/page/gamification
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:48:30
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - bus
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of OpenERP.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover OpenERP and configure their user profile.

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_challenge_wizard Challenge Wizard gamification.challenge form New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (7)

New fields (0)

No new fields.

Public methods (2)
  • check_granting(self, cr, uid, badge_id, context=None)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID
  • check_progress(self, cr, uid, context=None)

New fields (0)

No new fields.

Public methods (1)
  • create(self, cr, uid, vals, context=None)

New fields (0)

No new fields.

Public methods (1)
  • action_grant_badge(self, cr, uid, ids, context=None)
    Wizard action for sending a badge to a chosen user

New fields (0)

No new fields.

Public methods (13)
  • accept_challenge(self, cr, uid, challenge_ids, context=None, user_id=None)
    The user accept the suggested challenge
  • action_check(self, cr, uid, ids, context=None)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self, cr, uid, ids, context=None)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self, cr, uid, ids, context=None)
    Start a challenge
  • check_challenge_reward(self, cr, uid, ids, force=False, context=None)
    Actions for the end of a challenge If a reward was selected, grant it to the correct users. Rewards granted at: - the end date for a challenge with no periodicity - the end of a period for challenge with periodicity - when a challenge is manually closed (if no end date, a running challenge is never rewarded)
  • create(self, cr, uid, vals, context=None)
    Overwrite the create method to add the user of groups
  • discard_challenge(self, cr, uid, challenge_ids, context=None, user_id=None)
    The user discard the suggested challenge
  • get_top3_users(self, cr, uid, challenge, context=None)
    Get the top 3 users for a defined challenge Ranking criterias: 1. succeed every goal of the challenge 2. total completeness of each goal (can be over 100) Top 3 is computed only for users succeeding every goal of the challenge, except if reward_failure is True, in which case every user is considered. :return: ('first', 'second', 'third'), tuple containing the res.users objects of the top 3 users. If no user meets the criterias for a rank, it is set to False. Nobody can receive a rank is noone receives the higher one (eg: if 'second' == False, 'third' will be False)
  • quick_update(self, cr, uid, challenge_id, context=None)
    Update all the goals of a specific challenge, no generation of new goals
  • reply_challenge_wizard(self, cr, uid, challenge_id, context=None)
  • report_progress(self, cr, uid, challenge, context=None, users=False, subset_goal_ids=False)
    Post report about the progress of the goals :param challenge: the challenge object that need to be reported :param users: the list(res.users) of users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param goal_ids: the list(int) of goal ids linked to the challenge for the report. If not specified, use the goals for the current challenge period. This parameter can be used to produce report for previous challenge periods. :param subset_goal_ids: a list(int) of goal ids to restrict the report
  • reward_user(self, cr, uid, user_id, badge_id, challenge_id=False, context=None)
    Create a badge user and send the badge to him :param user_id: the user to reward :param badge_id: the concerned badge
  • write(self, cr, uid, ids, vals, context=None)

New fields (0)

No new fields.

Public methods (1)
  • on_change_definition_id(self, cr, uid, ids, definition_id=False, context=None)

New fields (0)

No new fields.

Public methods (1)
  • action_update_current(self, cr, uid, ids, context=None)
    Wizard action for updating the current value

New fields (0)

No new fields.

Public methods (2)
  • get_challenge_suggestions(self, cr, uid, context=None)
    Return the list of challenges suggested to the user
  • get_serialised_gamification_summary(self, cr, uid, excluded_categories=None, context=None)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/8.0/gamification
VERSION
VERSION 1.0
CATEGORY
CATEGORYHuman Resources
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSStephane Wirtel, Odoo Translation Bot, Turkesh Patel (Open ERP), Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Quentin (OpenERP), Denis Ledoux, Fabien Meghazi, niv-openerp, Christophe Simonis, Xavier Morel, Goffin Simon, Richard Mathot, Géry Debongnie, ged-odoo, Gery Debongnie, Randhir Mayatra rma-openerp, Yogesh Parekh (OpenERP), Nick-OpusVL
WEBSITE
WEBSITEhttps://www.odoo.com/page/gamification
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:45:39
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - email_template
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Gamification process
====================
The Gamification module provides ways to evaluate and motivate the users of OpenERP.

The users can be evaluated using goals and numerical objectives to reach.
**Goals** are assigned through **challenges** to evaluate and compare members of a team with each others and through time.

For non-numerical achievements, **badges** can be granted to users. From a simple "thank you" to an exceptional achievement, a badge is an easy way to exprimate gratitude to a user for their good work.

Both goals and badges are flexibles and can be adapted to a large range of modules and actions. When installed, this module creates easy goals to help new users to discover OpenERP and configure their user profile.

Code Analysis

Views touched (20)
XML IDNameModelTypeStatus
assets_backend gamification assets ir.ui.view qweb Inherits web.assets_backend
badge_form_view Badge Form gamification.badge form New
badge_kanban_view Badge Kanban View gamification.badge kanban New
badge_list_view Badge List gamification.badge tree New
badge_user_kanban_view Badge User Kanban View gamification.badge.user kanban New
challenge_form_view Challenge Form gamification.challenge form New
challenge_line_list_view Challenge line list gamification.challenge.line tree New
challenge_list_view Challenges List gamification.challenge tree New
challenge_search_view Challenge Search gamification.challenge search New
goal_definition_form_view Goal Definitions Form gamification.goal.definition form New
goal_definition_list_view Goal Definitions List gamification.goal.definition tree New
goal_definition_search_view Goal Definition Search gamification.goal.definition search New
goal_form_view Goal Form gamification.goal form New
goal_kanban_view Goal Kanban View gamification.goal kanban New
goal_list_view Goal List gamification.goal tree New
goal_search_view Goal Search gamification.goal search New
view_badge_wizard_grant Grant Badge User Form gamification.badge.user.wizard form New
view_challenge_kanban Challenge Kanban gamification.challenge kanban New
view_challenge_wizard Challenge Wizard gamification.challenge form New
view_goal_wizard_update_current Update the current value of the Goal gamification.goal.wizard form New
Models touched (7)

New fields (0)

No new fields.

Public methods (2)
  • check_granting(self, cr, uid, badge_id, context=None)
    Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID
  • check_progress(self, cr, uid, context=None)

New fields (0)

No new fields.

Public methods (1)
  • create(self, cr, uid, vals, context=None)

New fields (0)

No new fields.

Public methods (1)
  • action_grant_badge(self, cr, uid, ids, context=None)
    Wizard action for sending a badge to a chosen user

New fields (0)

No new fields.

Public methods (13)
  • accept_challenge(self, cr, uid, challenge_ids, context=None, user_id=None)
    The user accept the suggested challenge
  • action_check(self, cr, uid, ids, context=None)
    Check a challenge Create goals that haven't been created yet (eg: if added users) Recompute the current value for each goal related
  • action_report_progress(self, cr, uid, ids, context=None)
    Manual report of a goal, does not influence automatic report frequency
  • action_start(self, cr, uid, ids, context=None)
    Start a challenge
  • check_challenge_reward(self, cr, uid, ids, force=False, context=None)
    Actions for the end of a challenge If a reward was selected, grant it to the correct users. Rewards granted at: - the end date for a challenge with no periodicity - the end of a period for challenge with periodicity - when a challenge is manually closed (if no end date, a running challenge is never rewarded)
  • create(self, cr, uid, vals, context=None)
    Overwrite the create method to add the user of groups
  • discard_challenge(self, cr, uid, challenge_ids, context=None, user_id=None)
    The user discard the suggested challenge
  • get_top3_users(self, cr, uid, challenge, context=None)
    Get the top 3 users for a defined challenge Ranking criterias: 1. succeed every goal of the challenge 2. total completeness of each goal (can be over 100) Top 3 is computed only for users succeeding every goal of the challenge, except if reward_failure is True, in which case every user is considered. :return: ('first', 'second', 'third'), tuple containing the res.users objects of the top 3 users. If no user meets the criterias for a rank, it is set to False. Nobody can receive a rank is noone receives the higher one (eg: if 'second' == False, 'third' will be False)
  • quick_update(self, cr, uid, challenge_id, context=None)
    Update all the goals of a specific challenge, no generation of new goals
  • reply_challenge_wizard(self, cr, uid, challenge_id, context=None)
  • report_progress(self, cr, uid, challenge, context=None, users=False, subset_goal_ids=False)
    Post report about the progress of the goals :param challenge: the challenge object that need to be reported :param users: the list(res.users) of users that are concerned by the report. If False, will send the report to every user concerned (goal users and group that receive a copy). Only used for challenge with a visibility mode set to 'personal'. :param goal_ids: the list(int) of goal ids linked to the challenge for the report. If not specified, use the goals for the current challenge period. This parameter can be used to produce report for previous challenge periods. :param subset_goal_ids: a list(int) of goal ids to restrict the report
  • reward_user(self, cr, uid, user_id, badge_id, challenge_id=False, context=None)
    Create a badge user and send the badge to him :param user_id: the user to reward :param badge_id: the concerned badge
  • write(self, cr, uid, ids, vals, context=None)

New fields (0)

No new fields.

Public methods (1)
  • on_change_definition_id(self, cr, uid, ids, definition_id=False, context=None)

New fields (0)

No new fields.

Public methods (1)
  • action_update_current(self, cr, uid, ids, context=None)
    Wizard action for updating the current value

New fields (0)

No new fields.

Public methods (2)
  • get_challenge_suggestions(self, cr, uid, context=None)
    Return the list of challenges suggested to the user
  • get_serialised_gamification_summary(self, cr, uid, excluded_categories=None, context=None)