234 lines
8.3 KiB
Python
234 lines
8.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2024-2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
|
|
from odoo import models, fields, api, _
|
|
from odoo.exceptions import UserError
|
|
import base64
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class OdspSubmitToOdspWizard(models.TransientModel):
|
|
_name = 'fusion_claims.submit.to.odsp.wizard'
|
|
_description = 'Submit Quotation & Authorizer Letter to ODSP'
|
|
|
|
sale_order_id = fields.Many2one('sale.order', required=True, readonly=True)
|
|
|
|
client_name = fields.Char(string='Client Name', readonly=True)
|
|
member_id = fields.Char(string='ODSP Member ID', readonly=True)
|
|
order_name = fields.Char(string='Order #', readonly=True)
|
|
|
|
odsp_office_id = fields.Many2one(
|
|
'res.partner',
|
|
string='ODSP Office',
|
|
domain="[('x_fc_contact_type', '=', 'odsp_office')]",
|
|
help='Override the ODSP office for this submission',
|
|
)
|
|
|
|
authorizer_letter = fields.Binary(
|
|
string='Authorizer Letter',
|
|
help='Upload the authorizer letter to include in the submission',
|
|
)
|
|
authorizer_letter_filename = fields.Char(string='Authorizer Letter Filename')
|
|
|
|
email_body_notes = fields.Text(
|
|
string='Email Body Notes',
|
|
help='Notes to include at the top of the email body (e.g. urgency, special instructions)',
|
|
)
|
|
|
|
@api.model
|
|
def default_get(self, fields_list):
|
|
res = super().default_get(fields_list)
|
|
order_id = self.env.context.get('active_id')
|
|
if order_id:
|
|
order = self.env['sale.order'].browse(order_id)
|
|
res.update({
|
|
'sale_order_id': order.id,
|
|
'client_name': order.partner_id.name or '',
|
|
'member_id': order.x_fc_odsp_member_id or '',
|
|
'order_name': order.name or '',
|
|
'odsp_office_id': order.x_fc_odsp_office_id.id if order.x_fc_odsp_office_id else False,
|
|
})
|
|
if order.x_fc_odsp_authorizer_letter:
|
|
res['authorizer_letter'] = order.x_fc_odsp_authorizer_letter
|
|
res['authorizer_letter_filename'] = order.x_fc_odsp_authorizer_letter_filename
|
|
return res
|
|
|
|
def _sync_odsp_office(self):
|
|
"""Sync the selected ODSP office back to the sale order."""
|
|
if self.odsp_office_id and self.odsp_office_id != self.sale_order_id.x_fc_odsp_office_id:
|
|
self.sale_order_id.x_fc_odsp_office_id = self.odsp_office_id
|
|
|
|
def _generate_attachments(self):
|
|
"""Generate quotation PDF and authorizer letter attachment, return list of ir.attachment IDs."""
|
|
order = self.sale_order_id
|
|
Attachment = self.env['ir.attachment'].sudo()
|
|
att_ids = []
|
|
|
|
report = self.env.ref('sale.action_report_saleorder')
|
|
quote_pdf, _ct = report._render_qweb_pdf(report.id, [order.id])
|
|
quote_filename = f'{order.name}.pdf'
|
|
quote_att = Attachment.create({
|
|
'name': quote_filename,
|
|
'type': 'binary',
|
|
'datas': base64.b64encode(quote_pdf),
|
|
'res_model': 'sale.order',
|
|
'res_id': order.id,
|
|
'mimetype': 'application/pdf',
|
|
})
|
|
att_ids.append(quote_att.id)
|
|
|
|
if self.authorizer_letter:
|
|
letter_filename = self.authorizer_letter_filename or 'Authorizer_Letter.pdf'
|
|
order.write({
|
|
'x_fc_odsp_authorizer_letter': self.authorizer_letter,
|
|
'x_fc_odsp_authorizer_letter_filename': letter_filename,
|
|
})
|
|
letter_att = Attachment.create({
|
|
'name': letter_filename,
|
|
'type': 'binary',
|
|
'datas': self.authorizer_letter,
|
|
'res_model': 'sale.order',
|
|
'res_id': order.id,
|
|
'mimetype': 'application/pdf',
|
|
})
|
|
att_ids.append(letter_att.id)
|
|
|
|
return att_ids
|
|
|
|
def _advance_status(self, order):
|
|
"""Advance status to submitted_to_odsp."""
|
|
current = order._get_odsp_status()
|
|
if current in ('quotation', 'documents_ready'):
|
|
order._odsp_advance_status('submitted_to_odsp',
|
|
"Quotation and authorizer letter submitted to ODSP.")
|
|
|
|
def action_send_email(self):
|
|
"""Generate quotation PDF, attach authorizer letter, and email to ODSP office."""
|
|
self.ensure_one()
|
|
self._sync_odsp_office()
|
|
order = self.sale_order_id
|
|
office = self.odsp_office_id or order.x_fc_odsp_office_id
|
|
|
|
if not office or not office.email:
|
|
raise UserError(_(
|
|
"No ODSP Office with an email address is set. "
|
|
"Please select an ODSP Office before sending."
|
|
))
|
|
|
|
att_ids = self._generate_attachments()
|
|
|
|
order._send_odsp_submission_email(
|
|
attachment_ids=att_ids,
|
|
email_body_notes=self.email_body_notes,
|
|
)
|
|
|
|
self._advance_status(order)
|
|
|
|
order.message_post(
|
|
body=_("Quotation and authorizer letter emailed to %s.") % office.name,
|
|
message_type='comment',
|
|
attachment_ids=att_ids,
|
|
)
|
|
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': _('Email Sent'),
|
|
'message': _('Documents emailed to %s.') % office.email,
|
|
'type': 'success',
|
|
'sticky': False,
|
|
'next': {'type': 'ir.actions.act_window_close'},
|
|
},
|
|
}
|
|
|
|
def action_send_fax(self):
|
|
"""Generate quotation PDF, attach authorizer letter, and open fax wizard."""
|
|
self.ensure_one()
|
|
self._sync_odsp_office()
|
|
order = self.sale_order_id
|
|
office = self.odsp_office_id or order.x_fc_odsp_office_id
|
|
|
|
att_ids = self._generate_attachments()
|
|
|
|
self._advance_status(order)
|
|
|
|
ctx = {
|
|
'default_sale_order_id': order.id,
|
|
'default_partner_id': office.id if office else False,
|
|
'default_generate_pdf': False,
|
|
'forward_attachment_ids': att_ids,
|
|
}
|
|
if office and hasattr(office, 'x_ff_fax_number') and office.x_ff_fax_number:
|
|
ctx['default_fax_number'] = office.x_ff_fax_number
|
|
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Send Fax - ODSP Submission'),
|
|
'res_model': 'fusion_faxes.send.fax.wizard',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': ctx,
|
|
}
|
|
|
|
def action_send_fax_and_email(self):
|
|
"""Generate documents, send email first, then open fax wizard."""
|
|
self.ensure_one()
|
|
self._sync_odsp_office()
|
|
order = self.sale_order_id
|
|
office = self.odsp_office_id or order.x_fc_odsp_office_id
|
|
|
|
if not office or not office.email:
|
|
raise UserError(_(
|
|
"No ODSP Office with an email address is set. "
|
|
"Please select an ODSP Office before sending."
|
|
))
|
|
|
|
att_ids = self._generate_attachments()
|
|
|
|
order._send_odsp_submission_email(
|
|
attachment_ids=att_ids,
|
|
email_body_notes=self.email_body_notes,
|
|
)
|
|
|
|
self._advance_status(order)
|
|
|
|
order.message_post(
|
|
body=_("Quotation and authorizer letter emailed to %s.") % office.name,
|
|
message_type='comment',
|
|
attachment_ids=att_ids,
|
|
)
|
|
|
|
ctx = {
|
|
'default_sale_order_id': order.id,
|
|
'default_partner_id': office.id,
|
|
'default_generate_pdf': False,
|
|
'forward_attachment_ids': att_ids,
|
|
}
|
|
if hasattr(office, 'x_ff_fax_number') and office.x_ff_fax_number:
|
|
ctx['default_fax_number'] = office.x_ff_fax_number
|
|
|
|
fax_action = {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Send Fax - ODSP Submission'),
|
|
'res_model': 'fusion_faxes.send.fax.wizard',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': ctx,
|
|
}
|
|
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': _('Email Sent'),
|
|
'message': _('Email sent to %s. Now proceeding to fax...') % office.email,
|
|
'type': 'success',
|
|
'sticky': False,
|
|
'next': fax_action,
|
|
},
|
|
}
|