run pre-commit
parent
2c8fa5a9e7
commit
5a07dc1b5e
|
@ -8,7 +8,7 @@
|
||||||
"category": "Reporting",
|
"category": "Reporting",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)",
|
"author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)",
|
||||||
"website": "http://odoo.consulting/",
|
"website": "https://github.com/OCA/reporting-engine",
|
||||||
"depends": ["web"],
|
"depends": ["web"],
|
||||||
"external_dependencies": {"python": ["py3o.template", "py3o.formats", "PyPDF2"]},
|
"external_dependencies": {"python": ["py3o.template", "py3o.formats", "PyPDF2"]},
|
||||||
"data": [
|
"data": [
|
||||||
|
|
|
@ -92,12 +92,11 @@ class Py3oParserContext(object):
|
||||||
self._env, value, lang_code=lang_code, date_format=date_format
|
self._env, value, lang_code=lang_code, date_format=date_format
|
||||||
)
|
)
|
||||||
|
|
||||||
def _format_datetime(self, value, tz=False, dt_format='medium', lang_code=False):
|
def _format_datetime(self, value, tz=False, dt_format="medium", lang_code=False):
|
||||||
return misc.format_datetime(
|
return misc.format_datetime(
|
||||||
self._env, value, tz=tz, dt_format=dt_format, lang_code=lang_code
|
self._env, value, tz=tz, dt_format=dt_format, lang_code=lang_code
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _old_format_lang(
|
def _old_format_lang(
|
||||||
self,
|
self,
|
||||||
value,
|
value,
|
||||||
|
|
|
@ -19,7 +19,7 @@ PY3O_CONVERSION_COMMAND_PARAMETER = "py3o.conversion_command"
|
||||||
|
|
||||||
|
|
||||||
class IrActionsReport(models.Model):
|
class IrActionsReport(models.Model):
|
||||||
""" Inherit from ir.actions.report to allow customizing the template
|
"""Inherit from ir.actions.report to allow customizing the template
|
||||||
file. The user cam chose a template from a list.
|
file. The user cam chose a template from a list.
|
||||||
The list is configurable in the configuration tab, see py3o_template.py
|
The list is configurable in the configuration tab, see py3o_template.py
|
||||||
"""
|
"""
|
||||||
|
@ -49,7 +49,7 @@ class IrActionsReport(models.Model):
|
||||||
report_type = fields.Selection(
|
report_type = fields.Selection(
|
||||||
selection_add=[("py3o", "py3o")],
|
selection_add=[("py3o", "py3o")],
|
||||||
ondelete={
|
ondelete={
|
||||||
'py3o': 'cascade',
|
"py3o": "cascade",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -173,8 +173,7 @@ class IrActionsReport(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def gen_report_download_filename(self, res_ids, data):
|
def gen_report_download_filename(self, res_ids, data):
|
||||||
"""Override this function to change the name of the downloaded report
|
"""Override this function to change the name of the downloaded report"""
|
||||||
"""
|
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
report = self.get_from_report_name(self.report_name, self.report_type)
|
report = self.get_from_report_name(self.report_name, self.report_type)
|
||||||
if report.print_report_name and not len(res_ids) > 1:
|
if report.print_report_name and not len(res_ids) > 1:
|
||||||
|
@ -183,8 +182,7 @@ class IrActionsReport(models.Model):
|
||||||
return "{}.{}".format(self.name, self.py3o_filetype)
|
return "{}.{}".format(self.name, self.py3o_filetype)
|
||||||
|
|
||||||
def _get_attachments(self, res_ids):
|
def _get_attachments(self, res_ids):
|
||||||
""" Return the report already generated for the given res_ids
|
"""Return the report already generated for the given res_ids"""
|
||||||
"""
|
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
save_in_attachment = {}
|
save_in_attachment = {}
|
||||||
if res_ids:
|
if res_ids:
|
||||||
|
|
|
@ -35,7 +35,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.debug("Cannot import py3o.formats")
|
logger.debug("Cannot import py3o.formats")
|
||||||
try:
|
try:
|
||||||
from PyPDF2 import PdfFileWriter, PdfFileReader
|
from PyPDF2 import PdfFileReader, PdfFileWriter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.debug("Cannot import PyPDF2")
|
logger.debug("Cannot import PyPDF2")
|
||||||
|
|
||||||
|
@ -83,8 +83,7 @@ class Py3oReport(models.TransientModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _is_valid_template_path(self, path):
|
def _is_valid_template_path(self, path):
|
||||||
""" Check if the path is a trusted path for py3o templates.
|
"""Check if the path is a trusted path for py3o templates."""
|
||||||
"""
|
|
||||||
real_path = os.path.realpath(path)
|
real_path = os.path.realpath(path)
|
||||||
root_path = tools.config.get_misc("report_py3o", "root_tmpl_path")
|
root_path = tools.config.get_misc("report_py3o", "root_tmpl_path")
|
||||||
if not root_path:
|
if not root_path:
|
||||||
|
@ -105,8 +104,7 @@ class Py3oReport(models.TransientModel):
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
def _is_valid_template_filename(self, filename):
|
def _is_valid_template_filename(self, filename):
|
||||||
""" Check if the filename can be used as py3o template
|
"""Check if the filename can be used as py3o template"""
|
||||||
"""
|
|
||||||
if filename and os.path.isfile(filename):
|
if filename and os.path.isfile(filename):
|
||||||
fname, ext = os.path.splitext(filename)
|
fname, ext = os.path.splitext(filename)
|
||||||
ext = ext.replace(".", "")
|
ext = ext.replace(".", "")
|
||||||
|
@ -120,7 +118,7 @@ class Py3oReport(models.TransientModel):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _get_template_from_path(self, tmpl_name):
|
def _get_template_from_path(self, tmpl_name):
|
||||||
""" Return the template from the path to root of the module if specied
|
"""Return the template from the path to root of the module if specied
|
||||||
or an absolute path on your server
|
or an absolute path on your server
|
||||||
"""
|
"""
|
||||||
if not tmpl_name:
|
if not tmpl_name:
|
||||||
|
@ -201,12 +199,13 @@ class Py3oReport(models.TransientModel):
|
||||||
# consumption...
|
# consumption...
|
||||||
# ... but odoo wants the whole data in memory anyways :)
|
# ... but odoo wants the whole data in memory anyways :)
|
||||||
buffer = BytesIO(f.read())
|
buffer = BytesIO(f.read())
|
||||||
self.ir_actions_report_id._postprocess_pdf_report(model_instance, buffer)
|
self.ir_actions_report_id._postprocess_pdf_report(
|
||||||
|
model_instance, buffer
|
||||||
|
)
|
||||||
return result_path
|
return result_path
|
||||||
|
|
||||||
def _create_single_report(self, model_instance, data):
|
def _create_single_report(self, model_instance, data):
|
||||||
""" This function to generate our py3o report
|
"""This function to generate our py3o report"""
|
||||||
"""
|
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
result_fd, result_path = tempfile.mkstemp(
|
result_fd, result_path = tempfile.mkstemp(
|
||||||
suffix=".ods", prefix="p3o.report.tmp."
|
suffix=".ods", prefix="p3o.report.tmp."
|
||||||
|
@ -306,7 +305,7 @@ class Py3oReport(models.TransientModel):
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _merge_pdf(self, reports_path):
|
def _merge_pdf(self, reports_path):
|
||||||
""" Merge PDF files into one.
|
"""Merge PDF files into one.
|
||||||
|
|
||||||
:param reports_path: list of path of pdf files
|
:param reports_path: list of path of pdf files
|
||||||
:returns: path of the merged pdf
|
:returns: path of the merged pdf
|
||||||
|
@ -344,8 +343,7 @@ class Py3oReport(models.TransientModel):
|
||||||
logger.error("Error when trying to remove file %s" % temporary_file)
|
logger.error("Error when trying to remove file %s" % temporary_file)
|
||||||
|
|
||||||
def create_report(self, res_ids, data):
|
def create_report(self, res_ids, data):
|
||||||
""" Override this function to handle our py3o report
|
"""Override this function to handle our py3o report"""
|
||||||
"""
|
|
||||||
model_instances = self.env[self.ir_actions_report_id.model].browse(res_ids)
|
model_instances = self.env[self.ir_actions_report_id.model].browse(res_ids)
|
||||||
reports_path = []
|
reports_path = []
|
||||||
if len(res_ids) > 1 and self.ir_actions_report_id.py3o_multi_in_one:
|
if len(res_ids) > 1 and self.ir_actions_report_id.py3o_multi_in_one:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/* Copyright 2017-2018 ACSONE SA/NV
|
/* Copyright 2017-2018 ACSONE SA/NV
|
||||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||||
odoo.define("report_py3o.report", function(require) {
|
odoo.define("report_py3o.report", function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ActionManager = require("web.ActionManager");
|
var ActionManager = require("web.ActionManager");
|
||||||
|
|
||||||
ActionManager.include({
|
ActionManager.include({
|
||||||
_executeReportAction: function(action, options) {
|
_executeReportAction: function (action, options) {
|
||||||
// Py3o reports
|
// Py3o reports
|
||||||
if ("report_type" in action && action.report_type === "py3o") {
|
if ("report_type" in action && action.report_type === "py3o") {
|
||||||
return this._triggerDownload(action, options, "py3o");
|
return this._triggerDownload(action, options, "py3o");
|
||||||
|
@ -14,7 +14,7 @@ odoo.define("report_py3o.report", function(require) {
|
||||||
return this._super.apply(this, arguments);
|
return this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
_makeReportUrls: function(action) {
|
_makeReportUrls: function (action) {
|
||||||
var reportUrls = this._super.apply(this, arguments);
|
var reportUrls = this._super.apply(this, arguments);
|
||||||
reportUrls.py3o = "/report/py3o/" + action.report_name;
|
reportUrls.py3o = "/report/py3o/" + action.report_name;
|
||||||
// We may have to build a query string with `action.data`. It's the place
|
// We may have to build a query string with `action.data`. It's the place
|
||||||
|
|
|
@ -8,8 +8,8 @@ import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
from PyPDF2 import PdfFileWriter
|
from PyPDF2 import PdfFileWriter
|
||||||
from PyPDF2.pdf import PageObject
|
from PyPDF2.pdf import PageObject
|
||||||
|
|
Loading…
Reference in New Issue