from odoo import models, api from odoo.exceptions import UserError from datetime import date, timedelta from calendar import month_name from collections import defaultdict class BRM_CrossReport(models.AbstractModel): _name = 'report.sos_brm.report_cross_dept_summary' _description = 'Cross Dept Summary Report' @api.model def _get_report_values(self, docids, data=None): if not data: raise UserError("No filter data provided for the report.") # Wizard inputs (expect raw IDs / strings, or falsy) assigned_from_dept = data.get('assigned_from_dept') assigned_to_dept = data.get('assigned_to_dept') assigned_by = data.get('assigned_by') status = data.get('status') or False # Cross-dept only domain = [('cross_dept_action', '=', 'cross_dept')] if assigned_from_dept not in (None, '', 0, '0'): try: domain.append(('assigned_from_dept', '=', int(assigned_from_dept))) except (TypeError, ValueError): pass if assigned_to_dept not in (None, '', 0, '0'): try: domain.append(('assigned_to_dept', '=', int(assigned_to_dept))) except (TypeError, ValueError): pass if assigned_by not in (None, '', 0, '0'): try: domain.append(('assigned_by', '=', int(assigned_by))) except (TypeError, ValueError): pass if status and status != 'all': domain.append(('status', '=', status)) Action = self.env['sos_brm_action'] ActionLine = self.env['sos_brm_action_lines'] # Main actions docs = Action.search(domain, order='target_date asc, id asc') # Prefetch child lines (open only) and group by parent lines_map = defaultdict(list) # ensure keys exist for all docs (lets us index lines_map[rec.id] in QWeb) for rec in docs: lines_map.setdefault(rec.id, []) if docs: all_lines = ActionLine.search( [('ref_id', 'in', docs.ids)], order='ref_id, start_date, id' ) for ln in all_lines: lines_map[ln.ref_id.id].append(ln) # Precompute for QWeb (avoid len()/dict() calls there) count_cross = len(docs) child_counts = {rid: len(lst) for rid, lst in lines_map.items()} return { 'doc_ids': docs.ids, 'doc_model': 'sos_brm_action', 'docs': docs, 'status': status or '', 'lines_map': lines_map, 'count_cross': count_cross, 'child_counts': child_counts, }