# -*- coding: utf-8 -*- from odoo import api, fields, models from markupsafe import Markup import logging _logger = logging.getLogger(__name__) class ProjectKudos(models.Model): _name = 'project.kudos' _description = 'Employee Task Reward' _inherit = ['mail.thread', 'mail.activity.mixin'] _order = 'date_awarded desc' name = fields.Char(string="Reward Title", default="Task Completion Reward", tracking=True) employee_id = fields.Many2one('hr.employee', string="Employee", required=True, tracking=True) task_id = fields.Many2one('project.task', string="Task", required=True, tracking=True) project_id = fields.Many2one('project.project', related='task_id.project_id', store=True, tracking=True) completed_early_by = fields.Float(string="Hours Early", tracking=True) points_awarded = fields.Integer(string="Points", default=10, tracking=True) date_awarded = fields.Datetime(default=fields.Datetime.now, tracking=True) # βœ… New: show badges this employee currently has badge_ids = fields.Many2many( 'project.kudos.badge', string="Badges", compute='_compute_badges', store=False, readonly=True ) @api.depends('employee_id') def _compute_badges(self): """Compute badges linked to the selected employee.""" Badge = self.env['project.kudos.badge'] for rec in self: if rec.employee_id: rec.badge_ids = Badge.search([('employee_ids', 'in', rec.employee_id.id)]) else: rec.badge_ids = [(5, 0, 0)] # clear @api.onchange('employee_id') def _onchange_employee_id(self): """Show badges immediately when selecting employee.""" for rec in self: rec._compute_badges() @api.model_create_multi def create(self, vals_list): records = super(ProjectKudos, self).create(vals_list) template = self.env.ref('project_kudos_plus.mail_template_kudos_notify', raise_if_not_found=False) # Ensure Kudos Announcements channel exists channel = None if 'discuss.channel' in self.env.registry.models: channel = self.env['discuss.channel'].sudo().search( [('name', '=', 'Kudos Announcements')], limit=1 ) if not channel: channel = self.env['discuss.channel'].sudo().create({ 'name': 'Kudos Announcements', 'public': 'comment', }) else: _logger.warning("Discuss module not found, skipping channel announcement.") for rec in records: # Send appreciation email if template and rec.employee_id.work_email: template.email_to = rec.employee_id.work_email template.send_mail(rec.id, force_send=True) # βœ… Message content (HTML safe) message = Markup( "🌟 KUDOS ALERT! 🌟

" f"πŸ† Employee: {rec.employee_id.name}
" f"πŸ“Œ Task Completed: {rec.task_id.name}
" f"πŸ’Ž Kudos Points Earned: {rec.points_awarded}

" "πŸ‘ Outstanding performance! Your dedication and hard work made this happen.
" "Let's keep up the momentum! πŸ’ͺπŸ”₯

" "β€” Project Kudos+ Team" ) # Post to record’s chatter rec.message_post( body=message, subject=f"🌟 Kudos for {rec.employee_id.name}", message_type='comment', subtype_xmlid="mail.mt_comment" ) # Post to Kudos Announcements channel if channel: try: channel.message_post( body=message, subject=f"🌟 Kudos for {rec.employee_id.name}", message_type='comment', subtype_xmlid='mail.mt_comment' ) except Exception as e: _logger.error(f"Failed to post to Kudos Announcements channel: {e}") # βœ… FIXED: use rec.employee_id instead of undefined 'employee' total_points = sum( self.search([('employee_id', '=', rec.employee_id.id)]).mapped('points_awarded') ) badge = self.env['project.kudos.badge'].search( [('threshold', '<=', total_points)], order='threshold desc', limit=1 ) if badge and rec.employee_id not in badge.employee_ids: badge.employee_ids = [(4, rec.employee_id.id)] rec.employee_id.message_post( body=f"πŸ… Congratulations {rec.employee_id.name}! You earned the {badge.level.title()} Badge!" ) return records