from odoo import models, fields, api import xlsxwriter import base64 import io class SosCaseDiaryReportWizard(models.TransientModel): _name = 'sos_case_diary_report_wizard' _description = 'Case Diary Report Wizard' from_date = fields.Date( string="From Date", default=fields.Date.today # Default to today's date ) to_date = fields.Date( string="To Date", default=fields.Date.today # Default to today's date ) sales_person_id = fields.Many2one( 'res.users', string='Sales Executive', default=lambda self: self.env.user, domain=lambda self: [('groups_id', 'in', self.env.ref('sos_inventory.sos_sales_user').ids + self.env.ref('sos_inventory.sos_ce_head').ids)] ) customer = fields.Many2one('sos_customers',string="Customer Name") def generate_report(self): return self.env['sos_case_diary_report'].action_generate_report(self.from_date,self.to_date,self.sales_person_id.id,self.customer) def action_export(self): try: domain = [] if self.customer: domain.append(('ref_id.customer_name', '=', self.customer_name.customer_name)) # Use id for Many2one if self.from_date: domain.append(('status_changed_on', '>=', self.from_date)) if self.to_date: domain.append(('status_changed_on', '<=', self.to_date)) if self.sales_person_id: domain.append(('ref_id.sales_person', '=', self.sales_person_id.id)) if not domain: all_lines = self.env['sos_case_diary_line'].search([], order='id desc') else: all_lines = self.env['sos_case_diary_line'].search(domain, order='id desc') ref_ids = all_lines.mapped('ref_id').ids last_lines = self.env['sos_case_diary_line'] for ref_id in ref_ids: lines = all_lines.filtered(lambda l: l.ref_id.id == ref_id) if lines: last_line = lines.sorted('id', reverse=True)[:1] last_lines |= last_line if last_lines: output = io.BytesIO() workbook = xlsxwriter.Workbook(output, {'in_memory': True}) worksheet = workbook.add_worksheet('Case Diary Reports') headers = { 'customer': 'Customer', 'location': 'Location', 'product': 'Product', 'action_plan_date': 'Action Plan Date', 'spenco_status': 'SPENCO Status', 'status_changed_on': 'Status Changed On', 'current_state_value': 'Value (In Lakhs)', 'sales_executive': 'Sales Executive' } for col, header in enumerate(headers.values()): worksheet.write(0, col, header) for row, line in enumerate(last_lines, start=1): ref = line.ref_id data = { 'customer': ref.customer_name.customer_name if ref.customer_name else '', 'product': ref.products or '', 'location':ref.customer_name.customer_city if ref.customer_name else '', 'action_plan_date': line.action_plan_date.strftime('%Y-%m-%d') if line.action_plan_date else '', 'spenco_status': line.spenco_status or '', 'status_changed_on': line.status_changed_on.strftime('%Y-%m-%d') if line.status_changed_on else '', 'current_state_value': float(line.current_state_value) if line.current_state_value else 0.0, 'sales_executive': ref.sales_person.name if ref.sales_person else '', } for col, field in enumerate(headers.keys()): value = data[field] if isinstance(value, str) and value in ('', 'False', 'None'): worksheet.write(row, col, '') elif isinstance(value, (fields.Date, fields.Datetime)): worksheet.write(row, col, value.strftime('%Y-%m-%d') if value else '') else: worksheet.write(row, col, value) workbook.close() output.seek(0) # Verify file content file_content = output.read() if not file_content: raise ValueError("Empty file generated") attachment = self.env['ir.attachment'].create({ 'name': f'{self.from_date or "start"}_{self.to_date or "end"}_CaseDiary_Report.xlsx', 'type': 'binary', 'datas': base64.b64encode(file_content), 'res_model': self._name, 'res_id': self.id, 'mimetype': 'application/vnd.ms-excel' }) return { 'type': 'ir.actions.act_url', 'url': f'/web/content/{attachment.id}?download=true&mimetype=application/vnd.ms-excel', 'target': 'self', } else: return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': "No Records Found", 'type': 'danger', 'sticky': False } } except ValueError as e: print(f"Failed to find report action: {e}") return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': f"Error: {str(e)}", 'type': 'danger', 'sticky': False } } except Exception as e: print(f"Error generating export: {e}") return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': f"Error: {str(e)}", 'type': 'danger', 'sticky': False } }