# -*- coding: utf-8 -*- # Copyright 2024-2025 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) from odoo import models, fields, api, _ from odoo.exceptions import UserError from markupsafe import Markup import logging _logger = logging.getLogger(__name__) class AssessmentCompletedWizard(models.TransientModel): _name = 'fusion_claims.assessment.completed.wizard' _description = 'Assessment Completed Wizard' sale_order_id = fields.Many2one( 'sale.order', string='Sale Order', required=True, readonly=True, ) is_override = fields.Boolean( string='Scheduling Override', compute='_compute_is_override', store=False, ) assessment_start_date = fields.Date( string='Assessment Start Date', required=True, help='Date the assessment was conducted', ) completion_date = fields.Date( string='Assessment Completion Date', required=True, default=fields.Date.context_today, ) notes = fields.Text( string='Notes', help='Notes from the assessment', ) override_reason = fields.Text( string='Override Reason', help='Mandatory when skipping the scheduling step. Explain why the assessment was completed without scheduling through the system.', ) notify_authorizer = fields.Boolean( string='Notify Authorizer', default=True, help='Send email to the authorizer about assessment completion', ) @api.depends('sale_order_id') def _compute_is_override(self): for rec in self: rec.is_override = ( rec.sale_order_id and rec.sale_order_id.x_fc_adp_application_status == 'quotation' ) @api.model def default_get(self, fields_list): res = super().default_get(fields_list) active_id = self._context.get('active_id') if active_id: order = self.env['sale.order'].browse(active_id) res['sale_order_id'] = order.id if order.x_fc_assessment_start_date: res['assessment_start_date'] = order.x_fc_assessment_start_date else: res['assessment_start_date'] = fields.Date.context_today(self) return res def action_complete(self): """Mark assessment as completed.""" self.ensure_one() order = self.sale_order_id current_status = order.x_fc_adp_application_status is_override = current_status == 'quotation' if current_status not in ('quotation', 'assessment_scheduled'): raise UserError( _("Can only complete assessment from 'Quotation' or 'Assessment Scheduled' status.") ) if is_override and not (self.override_reason or '').strip(): raise UserError( _("Override Reason is mandatory when skipping the assessment scheduling step. " "Please explain why this assessment was completed without being scheduled through the system.") ) if self.completion_date < self.assessment_start_date: raise UserError( _("Completion date (%s) cannot be before assessment start date (%s).") % (self.completion_date, self.assessment_start_date) ) write_vals = { 'x_fc_adp_application_status': 'assessment_completed', 'x_fc_assessment_end_date': self.completion_date, } if is_override or not order.x_fc_assessment_start_date: write_vals['x_fc_assessment_start_date'] = self.assessment_start_date order.with_context(skip_status_validation=True).write(write_vals) if is_override: override_html = Markup( '
' '

' ' Assessment Scheduling Override

' '

Override by: %s

' '

Reason: %s

' '

Assessment Date: %s to %s

' '%s' '
' ) % ( self.env.user.name, self.override_reason.strip(), self.assessment_start_date.strftime("%B %d, %Y"), self.completion_date.strftime("%B %d, %Y"), Markup('

Notes: %s

') % self.notes if self.notes else Markup(''), ) order.message_post( body=override_html, message_type='notification', subtype_xmlid='mail.mt_note', ) else: notes_html = ( Markup('

Notes: %s

') % self.notes ) if self.notes else Markup('') order.message_post( body=Markup( '
' '

' ' Assessment Completed

' '

Completion Date: %s

' '%s' '
' ) % (self.completion_date.strftime("%B %d, %Y"), notes_html), message_type='notification', subtype_xmlid='mail.mt_note', ) if self.notify_authorizer: self._send_backend_completion_email(order, is_override) return {'type': 'ir.actions.act_window_close'} def _send_backend_completion_email(self, order, is_override): """Send assessment completion email when done from backend.""" self.ensure_one() if not order._email_is_enabled(): return authorizer = order.x_fc_authorizer_id if not authorizer or not authorizer.email: _logger.info("No authorizer email for %s, skipping notification", order.name) return to_email = authorizer.email cc_emails = [] if order.user_id and order.user_id.email: cc_emails.append(order.user_id.email) company = self.env.company office_partners = company.sudo().x_fc_office_notification_ids cc_emails.extend([p.email for p in office_partners if p.email]) client_name = order.partner_id.name or 'Client' override_note = '' if is_override: override_note = ( '
' 'Note: This assessment was completed without being scheduled ' 'through the system. ' f'Reason: {self.override_reason.strip()}' '
' ) sections = [ ('Assessment Details', [ ('Client', client_name), ('Case', order.name), ('Assessment Date', f"{self.assessment_start_date.strftime('%B %d, %Y')} to {self.completion_date.strftime('%B %d, %Y')}"), ('Completed by', self.env.user.name), ]), ] if self.notes: sections.append(('Notes', [('', self.notes)])) summary = ( f'The assessment for {client_name} ({order.name}) ' f'has been completed on {self.completion_date.strftime("%B %d, %Y")}.' ) if is_override: summary += f' {override_note}' email_body = order._email_build( title='Assessment Completed', summary=summary, email_type='success', sections=sections, note='Next step: Please submit the ADP application ' '(including pages 11-12 signed by the client) so we can proceed.', button_url=f'{order.get_base_url()}/web#id={order.id}&model=sale.order&view_type=form', button_text='View Case', sender_name=order.user_id.name if order.user_id else 'The Team', ) try: self.env['mail.mail'].sudo().create({ 'subject': f'Assessment Completed - {client_name} - {order.name}', 'body_html': email_body, 'email_to': to_email, 'email_cc': ', '.join(cc_emails) if cc_emails else False, 'model': 'sale.order', 'res_id': order.id, 'auto_delete': True, }).send() order.message_post( body=Markup( '' ) % (to_email, ', '.join(cc_emails) or 'None'), message_type='notification', subtype_xmlid='mail.mt_note', ) _logger.info("Sent backend assessment completed email for %s", order.name) except Exception as e: _logger.error("Failed to send assessment completed email for %s: %s", order.name, e)