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