import os import base64 from datetime import datetime from odoo import models, fields, api from weasyprint import HTML import calendar class ReportGenerator(models.Model): _name = "sos_report_generator" _description = "Monthly Report Generation" report_file = fields.Binary("Report File") report_filename = fields.Char("Report Filename") @api.model def generate_and_save_pdf(self): sales_group = self.env.ref("sos_inventory.sos_sales_user", raise_if_not_found=False) management_group = self.env.ref("sos_inventory.sos_management_user", raise_if_not_found=False) # Get users from both groups sales_users = self.env['res.users'].search([('groups_id', 'in', [sales_group.id])]) if sales_group else [] management_users = self.env['res.users'].search([('groups_id', 'in', [management_group.id])]) if management_group else [] # Get current month and year current_year = datetime.now().year current_month = datetime.now().month current_month_alpha = datetime.now().strftime("%B") from_date = f"01/{current_month:02d}/{current_year}" to_date = f"{calendar.monthrange(current_year, current_month)[1]}/{current_month:02d}/{current_year}" # Generate reports for sales users individually for sales_user in sales_users: title = f"SPENCO REPORT {current_month_alpha} {current_year}" filename = f"spenco_report_{current_month}_{current_year}_{sales_user.name}.pdf" domain = [('status', '=', 'open'), ('sales_person', '=', sales_user.id)] domain += [ ('line_ids.status_changed_on', '>=', from_date), ('line_ids.status_changed_on', '<=', to_date), ('spenco_status', '!=', 'Suspects'), ] email_cc='' self._generate_pdf_for_users(domain, filename,title,sales_user.login,email_cc) # Generate a single report for all management users if management_users: title = f"SPENCO REPORT {current_month_alpha} {current_year}" filename = f"spenco_report_{current_month}_{current_year}_top_management.pdf" domain = [('status', '=', 'open')] domain += [ ('line_ids.status_changed_on', '>=', from_date), ('line_ids.status_changed_on', '<=', to_date), ('spenco_status', '!=', 'Suspects'), ] email_to = 'ramachandran.r@sosaley.com' email_cc = 'sethuraman.n@sosaley.com,anitha.a@sosaley.com' self._generate_pdf_for_users(domain, filename,title,email_to,email_cc) return True def _generate_pdf_for_users(self, domain, filename,title,email_to,email_cc): """Common function to generate reports for given domain and filename.""" records = self.env['sos_case_diary'].search(domain) if not records: return case_diary_data = [] totals = { 'Prospects': 0, 'Engaged': 0, 'Negotiation': 0, 'Commercial Order': 0, 'Expected Order Value': 0, } for record in records: product_or_project = record.project_name if record.interested_in == "projects" else record.products latest_record = self.env['sos_case_diary_line'].search( [('ref_id', '=', record.id)], order="id desc", limit=1 ) current_state_value = round(latest_record.current_state_value, 2) spenco_status = latest_record.spenco_status # Update totals based on spenco_status if spenco_status == 'Prospects': totals['Prospects'] += current_state_value totals['Expected Order Value'] += round(current_state_value * 0.1, 2) elif spenco_status == 'Engaged': totals['Engaged'] += current_state_value totals['Expected Order Value'] += round(current_state_value * 0.3, 2) elif spenco_status == 'Negotiation': totals['Negotiation'] += current_state_value totals['Expected Order Value'] += round(current_state_value * 0.5, 2) elif spenco_status == 'Commercial Order': totals['Commercial Order'] += current_state_value totals['Expected Order Value'] += round(current_state_value, 2) case_diary_data.append({ 'customer_name': record.customer_name.customer_name, 'customer_city': record.customer_city, 'lead_generated_by': record.lead_generated_by, 'products': product_or_project, 'quantity': record.quantity, 'sales_person': record.sales_person.name, 'account_start_date': record.account_start_date, 'status_changed_on': latest_record.status_changed_on, 'spenco_status': latest_record.spenco_status, 'current_state_value': latest_record.current_state_value, 'status_values': { 'Prospects': current_state_value if spenco_status == 'Prospects' else '', 'Engaged': current_state_value if spenco_status == 'Engaged' else '', 'Negotiation': current_state_value if spenco_status == 'Negotiation' else '', 'Commercial Order': current_state_value if spenco_status == 'Commercial Order' else '', }, 'expected_order_value': round( current_state_value * ( 0.1 if spenco_status == 'Prospects' else 0.3 if spenco_status == 'Engaged' else 0.5 if spenco_status == 'Negotiation' else 1.0 if spenco_status == 'Commercial Order' else 0 ), 2 ), 'totals': totals, }) self.generate_html_report(case_diary_data, filename,title,email_to,email_cc) def generate_html_report(self, data,filename,title,email_to, email_cc): """Converts the given data list into an HTML table format and generates a PDF.""" # Define the table header html = f"""
| S.No | Customer | Sales Person | Status Changed On | Project/Product | Quantity | Order Booking (In Lakhs) | Expected Order Value (In Lakhs) | |||
|---|---|---|---|---|---|---|---|---|---|---|
| Prospects | Engaged | Negotiation | Commercial Order | |||||||
| {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} |
| Total | {} | {} | {} | {} | {} | |||||
This Month consolidated SPENCO REPORT is ready
""" body_html = f"""Hello User,
{message}Click the button below to Download:
|