diff --git a/fusion_claims/models/dashboard.py b/fusion_claims/models/dashboard.py index fe020797..ee9e4361 100644 --- a/fusion_claims/models/dashboard.py +++ b/fusion_claims/models/dashboard.py @@ -4,159 +4,40 @@ from odoo import api, fields, models -CASE_TYPE_SELECTION = [ - ('adp', 'ADP'), - ('odsp', 'ODSP'), - ('march_of_dimes', 'March of Dimes'), - ('hardship', 'Hardship Funding'), - ('acsd', 'ACSD'), - ('muscular_dystrophy', 'Muscular Dystrophy'), - ('insurance', 'Insurance'), - ('wsib', 'WSIB'), -] - -TYPE_DOMAINS = { - 'adp': [('x_fc_sale_type', 'in', ['adp', 'adp_odsp'])], - 'odsp': [('x_fc_sale_type', 'in', ['odsp', 'adp_odsp'])], - 'march_of_dimes': [('x_fc_sale_type', '=', 'march_of_dimes')], - 'hardship': [('x_fc_sale_type', '=', 'hardship')], - 'acsd': [('x_fc_client_type', '=', 'ACS')], - 'muscular_dystrophy': [('x_fc_sale_type', '=', 'muscular_dystrophy')], - 'insurance': [('x_fc_sale_type', '=', 'insurance')], - 'wsib': [('x_fc_sale_type', '=', 'wsib')], -} - -TYPE_LABELS = dict(CASE_TYPE_SELECTION) - class FusionClaimsDashboard(models.TransientModel): _name = 'fusion.claims.dashboard' + _inherit = 'fusion_claims.adp.posting.schedule.mixin' _description = 'Fusion Claims Dashboard' _rec_name = 'name' name = fields.Char(default='Dashboard', readonly=True) - # Case counts by funding type - adp_count = fields.Integer(compute='_compute_stats') - odsp_count = fields.Integer(compute='_compute_stats') - march_of_dimes_count = fields.Integer(compute='_compute_stats') - hardship_count = fields.Integer(compute='_compute_stats') - acsd_count = fields.Integer(compute='_compute_stats') - muscular_dystrophy_count = fields.Integer(compute='_compute_stats') - insurance_count = fields.Integer(compute='_compute_stats') - wsib_count = fields.Integer(compute='_compute_stats') - total_profiles = fields.Integer(compute='_compute_stats') + # ========================================================================= + # Role-aware filter + # ========================================================================= + is_manager = fields.Boolean(compute='_compute_is_manager') - # Panel selectors (4 panels) - panel1_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 1', default='adp') - panel2_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 2', default='odsp') - panel3_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 3', default='march_of_dimes') - panel4_type = fields.Selection(CASE_TYPE_SELECTION, string='Window 4', default='hardship') - - # Panel HTML - panel1_html = fields.Html(compute='_compute_panels', sanitize=False) - panel2_html = fields.Html(compute='_compute_panels', sanitize=False) - panel3_html = fields.Html(compute='_compute_panels', sanitize=False) - panel4_html = fields.Html(compute='_compute_panels', sanitize=False) - panel1_title = fields.Char(compute='_compute_panels') - panel2_title = fields.Char(compute='_compute_panels') - panel3_title = fields.Char(compute='_compute_panels') - panel4_title = fields.Char(compute='_compute_panels') - - def _compute_stats(self): - SO = self.env['sale.order'].sudo() - Profile = self.env['fusion.client.profile'].sudo() + def _compute_is_manager(self): + manager_group = self.env.ref('fusion_claims.group_fusion_claims_manager', + raise_if_not_found=False) + sale_mgr_group = self.env.ref('sales_team.group_sale_manager', + raise_if_not_found=False) for rec in self: - rec.adp_count = SO.search_count(TYPE_DOMAINS['adp']) - rec.odsp_count = SO.search_count(TYPE_DOMAINS['odsp']) - rec.march_of_dimes_count = SO.search_count(TYPE_DOMAINS['march_of_dimes']) - rec.hardship_count = SO.search_count(TYPE_DOMAINS['hardship']) - rec.acsd_count = SO.search_count(TYPE_DOMAINS['acsd']) - rec.muscular_dystrophy_count = SO.search_count(TYPE_DOMAINS['muscular_dystrophy']) - rec.insurance_count = SO.search_count(TYPE_DOMAINS['insurance']) - rec.wsib_count = SO.search_count(TYPE_DOMAINS['wsib']) - rec.total_profiles = Profile.search_count([]) - - @api.depends('panel1_type', 'panel2_type', 'panel3_type', 'panel4_type') - def _compute_panels(self): - SO = self.env['sale.order'].sudo() - for rec in self: - for i in range(1, 5): - ptype = getattr(rec, f'panel{i}_type') or 'adp' - domain = TYPE_DOMAINS.get(ptype, []) - orders = SO.search(domain, order='create_date desc', limit=50) - count = SO.search_count(domain) - title = f'Window {i} - {TYPE_LABELS.get(ptype, ptype)} ({count} cases)' - html = rec._build_top_list(orders) - setattr(rec, f'panel{i}_title', title) - setattr(rec, f'panel{i}_html', html) - - def _build_top_list(self, orders): - if not orders: - return '

No cases found

' - rows = [] - for o in orders: - status = o.x_fc_adp_application_status or '' - status_label = dict(o._fields['x_fc_adp_application_status'].selection).get(status, status) - rows.append( - f'' - f'{o.name}' - f'{o.partner_id.name or ""}' - f'{status_label}' - f'${o.amount_total:,.2f}' - f'' + user = rec.env.user + rec.is_manager = bool( + (manager_group and user.has_group('fusion_claims.group_fusion_claims_manager')) + or (sale_mgr_group and user.has_group('sales_team.group_sale_manager')) ) - return ( - '' - '' - '' + ''.join(rows) + '
OrderClientStatusTotal
' - ) - def action_open_order(self, order_id): - """Open a specific sale order with breadcrumbs.""" - return { - 'type': 'ir.actions.act_window', - 'name': 'Sale Order', - 'res_model': 'sale.order', - 'view_mode': 'form', - 'res_id': order_id, - 'target': 'current', - } + def _role_filter_domain(self): + """Common domain prefix for SO-based counts. - def action_open_adp(self): - return self._open_type_action('adp') - - def action_open_odsp(self): - return self._open_type_action('odsp') - - def action_open_march(self): - return self._open_type_action('march_of_dimes') - - def action_open_hardship(self): - return self._open_type_action('hardship') - - def action_open_acsd(self): - return self._open_type_action('acsd') - - def action_open_muscular(self): - return self._open_type_action('muscular_dystrophy') - - def action_open_insurance(self): - return self._open_type_action('insurance') - - def action_open_wsib(self): - return self._open_type_action('wsib') - - def action_open_profiles(self): - return { - 'type': 'ir.actions.act_window', 'name': 'Client Profiles', - 'res_model': 'fusion.client.profile', 'view_mode': 'list,form', - } - - def _open_type_action(self, type_key): - return { - 'type': 'ir.actions.act_window', - 'name': f'{TYPE_LABELS.get(type_key, type_key)} Cases', - 'res_model': 'sale.order', 'view_mode': 'list,form', - 'domain': TYPE_DOMAINS.get(type_key, []), - } + Managers (fusion_claims.group_fusion_claims_manager or + sales_team.group_sale_manager) see everything. + Other users see only SOs where they are the salesperson. + """ + self.ensure_one() + if self.is_manager: + return [] + return [('user_id', '=', self.env.user.id)]