Newer
Older
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.safe_eval import safe_eval
from odoo.addons.redner.utils.formats import Formats
_logger = logging.getLogger(__name__)
class IrActionsReport(models.Model):
"""
Inherit from ir.action.report to allow customizing the template
file.
"""
_inherit = "ir.actions.report"
@api.constrains("redner_filetype", "report_type")
def _check_redner_filetype(self):
for report in self:
if report.report_type == "redner" and not report.redner_filetype:
raise ValidationError(
_("Field 'Output Format' is required for Redner report")
)
@api.model
def _get_redner_filetypes(self):
formats = Formats()
names = formats.get_known_format_names()
selections = []
for name in names:
description = name
if formats.get_format(name).native:
description = description + " " + _("(Native)")
selections.append((name, description))
return selections
report_type = fields.Selection(selection_add=[("redner", "redner")])
redner_multi_in_one = fields.Boolean(

adrien.bonamy
committed
string="Multiple Records in a Single Redner Report",
help="If you execute a report on several records, "
"by default Odoo will generate a ZIP file that contains as many "
"files as selected records. If you enable this option, Odoo will "
"generate instead a single report for the selected records.",
)
redner_filetype = fields.Selection(

adrien.bonamy
committed
selection="_get_redner_filetypes", string="Redner Output Format"
)
is_redner_native_format = fields.Boolean(
compute="_compute_is_redner_native_format"
)
redner_tmpl_id = fields.Many2one(
comodel_name="redner.template",
string="Redner template",
domain=[("active", "=", True)],
)
substitution_ids = fields.One2many(
comodel_name="redner.substitution",
inverse_name="ir_actions_report_id",
string="Substitution",
)
@api.depends("report_type", "redner_filetype")
def _compute_is_redner_native_format(self):
fmt = Formats()
for rec in self:
rec.is_redner_native_format = False
if not rec.report_type == "redner" or not rec.redner_filetype:
continue
filetype = rec.redner_filetype
rec.is_redner_native_format = fmt.get_format(filetype).native
@api.multi
def action_get_substitutions(self):

adrien.bonamy
committed
"""Call by: action button `Get Substitutions from Redner Report`"""
self.ensure_one()
if self.redner_tmpl_id:
keywords = self.redner_tmpl_id.get_keywords()
# Get current substitutions
subs = self.substitution_ids.mapped("keyword") or []
values = []
for key in keywords:
# check to avoid duplicate keys
if key not in subs:
values.append((0, 0, {"keyword": key}))
self.write({"substitution_ids": values})
# remove obsolete keywords in substitutions model
if len(self.substitution_ids) > len(keywords):
deprecated_keys = self.substitution_ids.filtered(
lambda s: s.keyword not in keywords
)
if len(deprecated_keys) > 0:
deprecated_keys.unlink()
def get_report_metadata(self):
self.ensure_one()
metadata_values = {}
pformat = self.paperformat_id
if not pformat:
return metadata_values
# Get print-paper-size values
if pformat.format and pformat.orientation:
metadata_values["print-paper-size"] = "%s %s" % (
pformat.format,
pformat.orientation,
)
elif pformat.format and not pformat.orientation:
metadata_values["print-paper-size"] = "%s" % pformat.format
# Get print-paper-margin values: top | right | bottom | left
metadata_values["print-paper-margin"] = "%s %s %s %s" % (
pformat.margin_top,
pformat.margin_right,
pformat.margin_bottom,
pformat.margin_left,
)
return metadata_values

adrien.bonamy
committed
@api.model
def get_from_report_name(self, report_name, report_type):
return self.search(
[
("report_name", "=", report_name),
("report_type", "=", report_type),
]
)
def render_redner(self, res_ids, data):
self.ensure_one()
if self.report_type != "redner":
raise RuntimeError(
"redner rendition is only available on redner report.\n"
"(current: '{}', expected 'redner'".format(self.report_type)
)
return (
self.env["redner.report"]
.create({"ir_actions_report_id": self.id})
.create_report(res_ids, data)
)
def gen_report_download_filename(self, res_ids, data):

adrien.bonamy
committed
"""Override this function to change the name of the downloaded
report"""
self.ensure_one()
report = self.get_from_report_name(self.report_name, self.report_type)
if report.print_report_name and not len(res_ids) > 1:
obj = self.env[self.model].browse(res_ids)
return safe_eval(
report.print_report_name, {"object": obj, "time": time}
)
return "{}.{}".format(self.name, self.redner_filetype)
def _get_attachments(self, res_ids):

adrien.bonamy
committed
"""Return the report already generated for the given res_ids"""
self.ensure_one()
save_in_attachment = {}
if res_ids:
# Dispatch the records by ones having an attachment
Model = self.env[self.model]
record_ids = Model.browse(res_ids)
if self.attachment:
for record_id in record_ids:
attachment_id = self.retrieve_attachment(record_id)
if attachment_id:
save_in_attachment[record_id.id] = attachment_id
return save_in_attachment