'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)'

def _check_challenge_reward(self, force=False):

    commit = (self.env.context.get('commit_gamification') and self.env.cr.commit)
    for challenge in self:
        (start_date, end_date) = start_end_date_for_period(challenge.period, challenge.start_date, challenge.end_date)
        yesterday = (date.today() - timedelta(days=1))
        rewarded_users = self.env['res.users']
        challenge_ended = (force or (end_date == fields.Date.to_string(yesterday)))
        if (challenge.reward_id and (challenge_ended or challenge.reward_realtime)):
            reached_goals = self.env['gamification.goal'].read_group([('challenge_id', '=', challenge.id), ('end_date', '=', end_date), ('state', '=', 'reached')], fields=['user_id'], groupby=['user_id'])
            for reach_goals_user in reached_goals:
                if (reach_goals_user['user_id_count'] == len(challenge.line_ids)):
                    user = self.env['res.users'].browse(reach_goals_user['user_id'][0])
                    if challenge.reward_realtime:
                        badges = self.env['gamification.badge.user'].search_count([('challenge_id', '=', challenge.id), ('badge_id', '=', challenge.reward_id.id), ('user_id', '=', user.id)])
                        if (badges > 0):
                            continue
                    challenge._reward_user(user, challenge.reward_id)
                    rewarded_users |= user
                    if commit:
                        commit()
        if challenge_ended:
            message_body = (_('The    challenge    %s    is    finished.') % challenge.name)
            if rewarded_users:
                user_names = rewarded_users.name_get()
                message_body += (_('<br/>Reward    (badge    %s)    for    every    succeeding    user    was    sent    to    %s.') % (challenge.reward_id.name, ',    '.join((name for (user_id, name) in user_names))))
            else:
                message_body += _('<br/>Nobody    has    succeeded    to    reach    every    goal,    no    badge    is    rewarded    for    this    challenge.')
            reward_message = _('<br/>    %(rank)d.    %(user_name)s    -    %(reward_name)s')
            if challenge.reward_first_id:
                (first_user, second_user, third_user) = challenge._get_topN_users(MAX_VISIBILITY_RANKING)
                if first_user:
                    challenge._reward_user(first_user, challenge.reward_first_id)
                    message_body += _('<br/>Special    rewards    were    sent    to    the    top    competing    users.    The    ranking    for    this    challenge    is    :')
                    message_body += (reward_message % {'rank': 1, 'user_name': first_user.name, 'reward_name': challenge.reward_first_id.name})
                else:
                    message_body += _('Nobody    reached    the    required    conditions    to    receive    special    badges.')
                if (second_user and challenge.reward_second_id):
                    challenge._reward_user(second_user, challenge.reward_second_id)
                    message_body += (reward_message % {'rank': 2, 'user_name': second_user.name, 'reward_name': challenge.reward_second_id.name})
                if (third_user and challenge.reward_third_id):
                    challenge._reward_user(third_user, challenge.reward_third_id)
                    message_body += (reward_message % {'rank': 3, 'user_name': third_user.name, 'reward_name': challenge.reward_third_id.name})
            challenge.message_post(partner_ids=[user.partner_id.id for user in challenge.user_ids], body=message_body)
            if commit:
                commit()
    return True
