from odoo import models, api from odoo.exceptions import UserError from datetime import date, timedelta from calendar import month_name class WeekSummaryReport(models.AbstractModel): _name = 'report.sos_sales.report_action_plan_summary' _description = 'Action Plan Summary Report' def _compute_table(self, model_name, period_field, period_value, sales_person_id, action_column_map, columns, row_labels): domain = [(period_field, '=', period_value)] if sales_person_id: domain.append(('sales_executive', '=', sales_person_id)) records = self.env[model_name].search(domain) # Initialize empty table for known row labels only table = {row: {col: 0 for col in columns} | {'Total': 0} for row in row_labels} column_totals = {col: 0 for col in columns} column_totals['Total'] = 0 for rec in records: action_label = action_column_map.get((rec.action or '').strip()) action_type = (rec.action_type or '').strip() # Skip unknown actions or row labels if not action_label or action_label not in columns: continue if action_type not in row_labels: continue count = int(rec.count or 0) table[action_type][action_label] += count table[action_type]['Total'] += count column_totals[action_label] += count column_totals['Total'] += count return table, column_totals @api.model def _get_report_values(self, docids, data=None): if not data: raise UserError("No filter data provided for the report.") sales_person_id = data.get('sales_person_id') current_date = date.today() # Period values start_of_week = current_date - timedelta(days=current_date.weekday()) end_of_week = start_of_week + timedelta(days=5) #week_number = f"{start_of_week.strftime('%b %d')} - {end_of_week.strftime('%b %d')}" week_number = data.get('week_number') month_number = current_date.strftime('%B') month = current_date.month year = current_date.year quarter_number = ( "Q1" if 4 <= month <= 6 else "Q2" if 7 <= month <= 9 else "Q3" if 10 <= month <= 12 else "Q4" ) year_number = f"{year}-{year + 1}" if month >= 4 else f"{year - 1}-{year}" sales_person_name = self.env['res.users'].browse(sales_person_id).name if sales_person_id else 'All Sales Persons' # Mapping from DB value to report column name action_column_map = { 'Generate More Suspects': 'S', 'Suspect to Prospects': 'S to P', 'Prospect to Engaged': 'P to E', 'Engaged to Negotiation': 'E to N', 'Negotiation to Order': 'N to O', } columns = ['S', 'S to P', 'P to E', 'E to N', 'N to O'] row_labels = ['Meeting', 'Demo', 'Discussion', 'Visit', 'Negotiation', 'Validation', 'Proposal', 'Email/Call/Video Call'] # Build each table dynamically table_data_week, totals_week = self._compute_table( 'sos_action_plan_summary_week_wise', 'week_number', week_number, sales_person_id, action_column_map, columns, row_labels ) table_data_month, totals_month = self._compute_table( 'sos_action_plan_summary_month_wise', 'month_number', month_number, sales_person_id, action_column_map, columns, row_labels ) table_data_qtd, totals_qtd = self._compute_table( 'sos_action_plan_summary_quarter_wise', 'quarter_number', quarter_number, sales_person_id, action_column_map, columns, row_labels ) table_data_ytd, totals_ytd = self._compute_table( 'sos_action_plan_summary_year_wise', 'year', year_number, sales_person_id, action_column_map, columns, row_labels ) return { 'doc_ids': docids or [], 'doc_model': 'sos_action_plan_summary_week_wise', 'column_headers': columns, 'table_data_week': table_data_week, 'column_totals_week': totals_week, 'table_data_mtd': table_data_month, 'column_totals_mtd': totals_month, 'table_data_qtd': table_data_qtd, 'column_totals_qtd': totals_qtd, 'table_data_ytd': table_data_ytd, 'column_totals_ytd': totals_ytd, 'week_number': week_number, 'month_number':month_number, 'quarter_number':quarter_number, 'year_number':year_number, 'sales_person_name': sales_person_name, }