Tower: upload at_accounting 18.0.1.7 (via marketplace)
This commit is contained in:
310
addons/at_accounting/wizard/account_report_send.py
Normal file
310
addons/at_accounting/wizard/account_report_send.py
Normal file
@@ -0,0 +1,310 @@
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.misc import get_lang
|
||||
|
||||
|
||||
class AccountReportSend(models.TransientModel):
|
||||
_name = 'account.report.send'
|
||||
_description = "Account Report Send"
|
||||
|
||||
partner_ids = fields.Many2many(
|
||||
comodel_name='res.partner',
|
||||
compute='_compute_partner_ids',
|
||||
)
|
||||
mode = fields.Selection(
|
||||
selection=[
|
||||
('single', "Single Recipient"),
|
||||
('multi', "Multiple Recipients"),
|
||||
],
|
||||
compute='_compute_mode',
|
||||
readonly=False,
|
||||
store=True,
|
||||
)
|
||||
|
||||
# == PRINT ==
|
||||
enable_download = fields.Boolean()
|
||||
checkbox_download = fields.Boolean(string="Download")
|
||||
|
||||
# == MAIL ==
|
||||
enable_send_mail = fields.Boolean(default=True)
|
||||
checkbox_send_mail = fields.Boolean(string="Email", default=True)
|
||||
|
||||
display_mail_composer = fields.Boolean(compute='_compute_send_mail_extra_fields')
|
||||
warnings = fields.Json(compute='_compute_warnings')
|
||||
send_mail_readonly = fields.Boolean(compute='_compute_send_mail_extra_fields')
|
||||
mail_template_id = fields.Many2one(
|
||||
comodel_name='mail.template',
|
||||
string="Email template",
|
||||
domain="[('model', '=', 'res.partner')]",
|
||||
)
|
||||
|
||||
account_report_id = fields.Many2one(
|
||||
comodel_name='account.report',
|
||||
string="Report",
|
||||
)
|
||||
report_options = fields.Json()
|
||||
|
||||
mail_lang = fields.Char(
|
||||
string="Lang",
|
||||
compute='_compute_mail_lang',
|
||||
)
|
||||
mail_partner_ids = fields.Many2many(
|
||||
comodel_name='res.partner',
|
||||
string="Recipients",
|
||||
compute='_compute_mail_partner_ids',
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
mail_subject = fields.Char(
|
||||
string="Subject",
|
||||
compute='_compute_mail_subject_body',
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
mail_body = fields.Html(
|
||||
string="Contents",
|
||||
sanitize_style=True,
|
||||
compute='_compute_mail_subject_body',
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
mail_attachments_widget = fields.Json(
|
||||
compute='_compute_mail_attachments_widget',
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
# EXTENDS 'base'
|
||||
results = super().default_get(fields_list)
|
||||
|
||||
context_options = self._context.get('default_report_options', {})
|
||||
if 'account_report_id' in fields_list and 'account_report_id' not in results:
|
||||
report_id = context_options.get('report_id', False)
|
||||
results['account_report_id'] = report_id
|
||||
results['report_options'] = context_options
|
||||
|
||||
return results
|
||||
|
||||
@api.model
|
||||
def _get_mail_field_value(self, partner, mail_template, mail_lang, field, **kwargs):
|
||||
if not mail_template:
|
||||
return
|
||||
return mail_template\
|
||||
.with_context(lang=mail_lang)\
|
||||
._render_field(field, partner.ids, **kwargs)[partner._origin.id]
|
||||
|
||||
def _get_default_mail_attachments_widget(self, partner, mail_template):
|
||||
return self._get_placeholder_mail_attachments_data(partner) \
|
||||
+ self._get_mail_template_attachments_data(mail_template)
|
||||
|
||||
def _get_wizard_values(self):
|
||||
self.ensure_one()
|
||||
options = self.report_options
|
||||
if not options.get('partner_ids', []):
|
||||
options['partner_ids'] = self.partner_ids.ids
|
||||
return {
|
||||
'mail_template_id': self.mail_template_id.id,
|
||||
'checkbox_download': self.checkbox_download,
|
||||
'checkbox_send_mail': self.checkbox_send_mail,
|
||||
'report_options': options,
|
||||
}
|
||||
|
||||
def _get_placeholder_mail_attachments_data(self, partner):
|
||||
""" Returns all the placeholder data.
|
||||
Should be extended to add placeholder based on the checkboxes.
|
||||
:param: partner: The partner for which this report is generated.
|
||||
:returns: A list of dictionary for each placeholder.
|
||||
* id: str: The (fake) id of the attachment, this is needed in rendering in t-key.
|
||||
* name: str: The name of the attachment.
|
||||
* mimetype: str: The mimetype of the attachment.
|
||||
* placeholder bool: Should be true to prevent download / deletion.
|
||||
"""
|
||||
self.ensure_one()
|
||||
filename = f"{partner.name} - {self.account_report_id.get_default_report_filename(self.report_options, 'pdf')}"
|
||||
return [{
|
||||
'id': f'placeholder_{filename}',
|
||||
'name': filename,
|
||||
'mimetype': 'application/pdf',
|
||||
'placeholder': True,
|
||||
}]
|
||||
|
||||
@api.model
|
||||
def _get_mail_template_attachments_data(self, mail_template):
|
||||
""" Returns all the placeholder data and mail template data
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'id': attachment.id,
|
||||
'name': attachment.name,
|
||||
'mimetype': attachment.mimetype,
|
||||
'placeholder': False,
|
||||
'mail_template_id': mail_template.id,
|
||||
}
|
||||
for attachment in mail_template.attachment_ids
|
||||
]
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# COMPUTE METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@api.depends('partner_ids')
|
||||
def _compute_mode(self):
|
||||
for wizard in self:
|
||||
wizard.mode = 'single' if len(wizard.partner_ids) == 1 else 'multi'
|
||||
|
||||
@api.depends('checkbox_send_mail')
|
||||
def _compute_send_mail_extra_fields(self):
|
||||
for wizard in self:
|
||||
wizard.display_mail_composer = wizard.mode == 'single'
|
||||
partners_without_mail_data = wizard.mail_partner_ids.filtered(lambda x: not x.email)
|
||||
wizard.send_mail_readonly = partners_without_mail_data == wizard.mail_partner_ids
|
||||
|
||||
@api.depends('mail_partner_ids', 'checkbox_send_mail', 'send_mail_readonly')
|
||||
def _compute_warnings(self):
|
||||
for wizard in self:
|
||||
warnings = {}
|
||||
|
||||
partners_without_mail = wizard.mail_partner_ids.filtered(lambda x: not x.email)
|
||||
if wizard.send_mail_readonly or (wizard.checkbox_send_mail and partners_without_mail):
|
||||
warnings['account_missing_email'] = {
|
||||
'message': _("Partner(s) should have an email address."),
|
||||
'action_text': _("View Partner(s)"),
|
||||
'action': partners_without_mail._get_records_action(name=_("Check Partner(s) Email(s)"))
|
||||
}
|
||||
|
||||
wizard.warnings = warnings
|
||||
|
||||
@api.depends('partner_ids')
|
||||
def _compute_mail_lang(self):
|
||||
for wizard in self:
|
||||
if wizard.mode == 'single':
|
||||
wizard.mail_lang = wizard.partner_ids.lang
|
||||
else:
|
||||
wizard.mail_lang = get_lang(self.env).code
|
||||
|
||||
@api.depends('account_report_id', 'report_options')
|
||||
def _compute_partner_ids(self):
|
||||
for wizard in self:
|
||||
wizard.partner_ids = wizard.account_report_id._get_report_send_recipients(wizard.report_options)
|
||||
|
||||
@api.depends('account_report_id', 'report_options')
|
||||
def _compute_mail_partner_ids(self):
|
||||
for wizard in self:
|
||||
wizard.mail_partner_ids = wizard.partner_ids
|
||||
|
||||
@api.depends('mail_template_id', 'mail_lang', 'mode')
|
||||
def _compute_mail_subject_body(self):
|
||||
for wizard in self:
|
||||
if wizard.mode == 'single' and wizard.mail_template_id:
|
||||
wizard.mail_subject = self._get_mail_field_value(wizard.mail_partner_ids, wizard.mail_template_id, wizard.mail_lang, 'subject')
|
||||
wizard.mail_body = self._get_mail_field_value(wizard.mail_partner_ids, wizard.mail_template_id, wizard.mail_lang, 'body_html', options={'post_process': True})
|
||||
else:
|
||||
wizard.mail_subject = wizard.mail_body = None
|
||||
|
||||
@api.depends('mail_template_id', 'mode')
|
||||
def _compute_mail_attachments_widget(self):
|
||||
for wizard in self:
|
||||
if wizard.mode == 'single':
|
||||
wizard.mail_attachments_widget = wizard._get_default_mail_attachments_widget(wizard.mail_partner_ids, wizard.mail_template_id)
|
||||
else:
|
||||
wizard.mail_attachments_widget = []
|
||||
|
||||
@api.model
|
||||
def _action_download(self, attachments):
|
||||
""" Download the PDF attachment, or a zip of attachments if there are more than one. """
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': f'/account_reports/download_attachments/{",".join(map(str, attachments.ids))}',
|
||||
'close': True,
|
||||
}
|
||||
|
||||
def _process_send_and_print(self, report, options, recipient_partner_ids=None, wizard=None):
|
||||
""" Generate a report for one partner based on the options (send_and_print_values stored on the report).
|
||||
:param options: dict of report options (should contain one partner id in options['partner_ids'])
|
||||
:param recipient_partner_ids: list of partner ids that will receive the mail message.
|
||||
:param wizard: account.report.send wizard if exists. Indicates if sending by cron.
|
||||
"""
|
||||
wizard_vals = report.send_and_print_values if not wizard else wizard._get_wizard_values()
|
||||
to_email = wizard_vals['checkbox_send_mail']
|
||||
to_download = wizard_vals['checkbox_download']
|
||||
|
||||
mail_template_id = self.env['mail.template'].browse(wizard_vals['mail_template_id'])
|
||||
if wizard:
|
||||
attachments_ids = [att['id'] for att in wizard.mail_attachments_widget or [] if not att['placeholder']]
|
||||
else:
|
||||
attachments_ids = mail_template_id.attachment_ids.ids
|
||||
|
||||
options['unfold_all'] = True
|
||||
|
||||
partner_ids = options.get('partner_ids', [])
|
||||
partners = self.env['res.partner'].browse(partner_ids)
|
||||
if not recipient_partner_ids:
|
||||
recipient_partner_ids = partners.filtered('email').ids
|
||||
|
||||
downloadable_attachments = self.env['ir.attachment']
|
||||
|
||||
for partner in partners:
|
||||
options['partner_ids'] = partner.ids
|
||||
report_attachment = partner._get_partner_account_report_attachment(report, options)
|
||||
|
||||
if to_email and recipient_partner_ids:
|
||||
if wizard and wizard.mode == 'single':
|
||||
subject = self.mail_subject
|
||||
body = self.mail_body
|
||||
else:
|
||||
subject = self._get_mail_field_value(partner, mail_template_id, partner.lang, 'subject')
|
||||
body = self._get_mail_field_value(partner, mail_template_id, partner.lang, 'body_html', options={'post_process': True})
|
||||
|
||||
partner.message_post(
|
||||
body=body,
|
||||
subject=subject,
|
||||
partner_ids=recipient_partner_ids,
|
||||
attachment_ids=attachments_ids + report_attachment.ids,
|
||||
)
|
||||
|
||||
if to_download:
|
||||
downloadable_attachments += report_attachment
|
||||
|
||||
if downloadable_attachments:
|
||||
return self._action_download(downloadable_attachments)
|
||||
|
||||
def action_send_and_print(self, force_synchronous=False):
|
||||
""" Create the documents and send them to the end customers.
|
||||
If we are sending multiple statements and not downloading them we will process the moves asynchronously.
|
||||
:param force_synchronous: Flag indicating if the method should be done synchronously.
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if self.mode == 'multi' and self.checkbox_send_mail and not self.mail_template_id:
|
||||
raise UserError(_('Please select a mail template to send multiple statements.'))
|
||||
|
||||
force_synchronous = force_synchronous or self.checkbox_download
|
||||
process_later = self.mode == 'multi' and not force_synchronous
|
||||
if process_later:
|
||||
# Set sending information on report
|
||||
if self.account_report_id.send_and_print_values:
|
||||
raise UserError(_('There are currently reports waiting to be sent, please try again later.'))
|
||||
self.account_report_id.send_and_print_values = self._get_wizard_values()
|
||||
self.env.ref('at_accounting.ir_cron_account_report_send')._trigger()
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'info',
|
||||
'title': _('Sending statements'),
|
||||
'message': _('Statements are being sent in the background.'),
|
||||
'next': {'type': 'ir.actions.act_window_close'},
|
||||
},
|
||||
}
|
||||
options = {
|
||||
**self.report_options,
|
||||
'partner_ids': self.partner_ids.ids,
|
||||
}
|
||||
return self._process_send_and_print(
|
||||
report=self.account_report_id,
|
||||
options=options,
|
||||
recipient_partner_ids=self.mail_partner_ids.ids,
|
||||
wizard=self,
|
||||
)
|
||||
Reference in New Issue
Block a user