'Generate the goals for each line and user.
If goals already exist for this line and user, the line is skipped. This
can be called after each change in the list of users or lines.
:param list(int) ids: the list of challenge concerned'

def _generate_goals_from_challenge(self):

    Goals = self.env['gamification.goal']
    for challenge in self:
        (start_date, end_date) = start_end_date_for_period(challenge.period, challenge.start_date, challenge.end_date)
        to_update = Goals.browse(())
        for line in challenge.line_ids:
            date_clause = ''
            query_params = [line.id]
            if start_date:
                date_clause += 'AND    g.start_date    =    %s'
                query_params.append(start_date)
            if end_date:
                date_clause += 'AND    g.end_date    =    %s'
                query_params.append(end_date)
            query = 'SELECT    u.id    AS    user_id\n                                                                                                                    FROM    res_users    u\n                                                                                                LEFT    JOIN    gamification_goal    g\n                                                                                                                            ON    (u.id    =    g.user_id)\n                                                                                                                WHERE    line_id    =    %s\n                                                                                                                        {date_clause}\n                                                                                                '.format(date_clause=date_clause)
            self.env.cr.execute(query, query_params)
            user_with_goal_ids = {it for [it] in self.env.cr._obj}
            participant_user_ids = set(challenge.user_ids.ids)
            user_squating_challenge_ids = (user_with_goal_ids - participant_user_ids)
            if user_squating_challenge_ids:
                Goals.search([('challenge_id', '=', challenge.id), ('user_id', 'in', list(user_squating_challenge_ids))]).unlink()
            values = {'definition_id': line.definition_id.id, 'line_id': line.id, 'target_goal': line.target_goal, 'state': 'inprogress'}
            if start_date:
                values['start_date'] = start_date
            if end_date:
                values['end_date'] = end_date
                if (line.condition == 'higher'):
                    values['current'] = (line.target_goal - 1)
                else:
                    values['current'] = (line.target_goal + 1)
            if challenge.remind_update_delay:
                values['remind_update_delay'] = challenge.remind_update_delay
            for user_id in (participant_user_ids - user_with_goal_ids):
                values['user_id'] = user_id
                to_update |= Goals.create(values)
        to_update.update_goal()
    return True
