fix problem with fields of Html type
This commit is contained in:
parent
3209a208e6
commit
da4f636fde
@ -16,7 +16,7 @@
|
|||||||
"category": "Technical",
|
"category": "Technical",
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"depends": ["base", "web", "custom_report_field", "report_monetary_helpers"],
|
"depends": ["base", "web", "custom_report_field", "report_monetary_helpers"],
|
||||||
"external_dependencies": {"python": ["docxcompose", "docxtpl"]},
|
"external_dependencies": {"python": ["docxcompose", "docxtpl", "bs4"]},
|
||||||
"data": [
|
"data": [
|
||||||
"views/ir_actions_report_views.xml",
|
"views/ir_actions_report_views.xml",
|
||||||
],
|
],
|
||||||
|
@ -22,8 +22,7 @@ class DocxReportController(ReportController):
|
|||||||
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
|
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
|
||||||
context = dict(request.env.context)
|
context = dict(request.env.context)
|
||||||
_data = dict()
|
_data = dict()
|
||||||
if docids:
|
_docids = [int(i) for i in docids.split(",")] if docids else []
|
||||||
_docids = [int(i) for i in docids.split(",")]
|
|
||||||
if data.get("options"):
|
if data.get("options"):
|
||||||
_data.update(json_loads(data.pop("options")))
|
_data.update(json_loads(data.pop("options")))
|
||||||
if data.get("context"):
|
if data.get("context"):
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
@ -6,7 +7,6 @@ from logging import getLogger
|
|||||||
from docx import Document
|
from docx import Document
|
||||||
from docxcompose.composer import Composer
|
from docxcompose.composer import Composer
|
||||||
from docxtpl import DocxTemplate
|
from docxtpl import DocxTemplate
|
||||||
from jinja2 import Environment as Jinja2Environment
|
|
||||||
from requests import codes as codes_request, post as post_request
|
from requests import codes as codes_request, post as post_request
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ class IrActionsReport(models.Model):
|
|||||||
res_ids = docx_record_ids.ids
|
res_ids = docx_record_ids.ids
|
||||||
|
|
||||||
if save_in_attachment and not res_ids:
|
if save_in_attachment and not res_ids:
|
||||||
_logger.info("The PDF report has been generated from attachments.")
|
_logger.info("The PDF report has been generated from attachment.")
|
||||||
self._raise_on_unreadable_pdfs(save_in_attachment.values(), stream_record)
|
self._raise_on_unreadable_pdfs(save_in_attachment.values(), stream_record)
|
||||||
return self_sudo._post_pdf(save_in_attachment), "pdf"
|
return self_sudo._post_pdf(save_in_attachment), "pdf"
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ class IrActionsReport(models.Model):
|
|||||||
res_ids = docx_record_ids.ids
|
res_ids = docx_record_ids.ids
|
||||||
|
|
||||||
if save_in_attachment and not res_ids:
|
if save_in_attachment and not res_ids:
|
||||||
_logger.info("The DOCS report has been generated from attachments.")
|
_logger.info("The DOCS report has been generated from attachment.")
|
||||||
return self_sudo._post_docx(save_in_attachment), "docx"
|
return self_sudo._post_docx(save_in_attachment), "docx"
|
||||||
|
|
||||||
docx_content = self._render_docx(res_ids, data=data)
|
docx_content = self._render_docx(res_ids, data=data)
|
||||||
@ -262,7 +262,9 @@ class IrActionsReport(models.Model):
|
|||||||
result = self._merge_docx(streams)
|
result = self._merge_docx(streams)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.exception(e)
|
_logger.exception(e)
|
||||||
raise UserError(_("One of the documents, you try to merge is fallback"))
|
raise UserError(
|
||||||
|
_("One of the documents you try to merge caused failure.")
|
||||||
|
)
|
||||||
|
|
||||||
close_streams(streams)
|
close_streams(streams)
|
||||||
return result
|
return result
|
||||||
@ -294,9 +296,10 @@ class IrActionsReport(models.Model):
|
|||||||
)
|
)
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
def _merge_docx(self, streams):
|
@staticmethod
|
||||||
|
def _merge_docx(streams):
|
||||||
"""
|
"""
|
||||||
Объединяет несколько docx файлов в один
|
Joins several docx files into one.
|
||||||
"""
|
"""
|
||||||
if streams:
|
if streams:
|
||||||
writer = Document(streams[0])
|
writer = Document(streams[0])
|
||||||
@ -318,15 +321,13 @@ class IrActionsReport(models.Model):
|
|||||||
data = self._get_rendering_context(docids, data)
|
data = self._get_rendering_context(docids, data)
|
||||||
return self._render_docx_template(self.report_docx_template, values=data)
|
return self._render_docx_template(self.report_docx_template, values=data)
|
||||||
|
|
||||||
def _render_docx_template(self, template, values=None):
|
def _render_docx_template(self, template: bytes, values: dict = None):
|
||||||
"""
|
"""
|
||||||
Непосредственно рендеринг docx файла
|
Непосредственно рендеринг docx файла
|
||||||
"""
|
"""
|
||||||
if values is None:
|
if values is None:
|
||||||
values = {}
|
values = {}
|
||||||
|
|
||||||
context = dict(self.env.context, inherit_branding=False)
|
context = dict(self.env.context, inherit_branding=False)
|
||||||
|
|
||||||
# Browse the user instead of using the sudo self.env.user
|
# Browse the user instead of using the sudo self.env.user
|
||||||
user = self.env["res.users"].browse(self.env.uid)
|
user = self.env["res.users"].browse(self.env.uid)
|
||||||
website = None
|
website = None
|
||||||
@ -338,7 +339,6 @@ class IrActionsReport(models.Model):
|
|||||||
translatable=context.get("lang")
|
translatable=context.get("lang")
|
||||||
!= request.env["ir.http"]._get_default_lang().code,
|
!= request.env["ir.http"]._get_default_lang().code,
|
||||||
)
|
)
|
||||||
|
|
||||||
values.update(
|
values.update(
|
||||||
time=time,
|
time=time,
|
||||||
context_timestamp=lambda t: fields.Datetime.context_timestamp(
|
context_timestamp=lambda t: fields.Datetime.context_timestamp(
|
||||||
@ -352,23 +352,41 @@ class IrActionsReport(models.Model):
|
|||||||
.get_param("web.base.url", default=""),
|
.get_param("web.base.url", default=""),
|
||||||
)
|
)
|
||||||
|
|
||||||
data = {key: value for key, value in values.items() if not callable(value)}
|
record_to_render = values["docs"]
|
||||||
functions = {key: value for key, value in values.items() if callable(value)}
|
docs = {
|
||||||
|
key: record_to_render[key]
|
||||||
|
for key in record_to_render._fields.keys()
|
||||||
|
if not isinstance(record_to_render[key], fields.Markup)
|
||||||
|
}
|
||||||
|
docs.update(
|
||||||
|
{
|
||||||
|
key: self._parse_markup(record_to_render[key])
|
||||||
|
for key in record_to_render._fields.keys()
|
||||||
|
if isinstance(record_to_render[key], fields.Markup)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
values["docs"] = docs
|
||||||
|
|
||||||
docx_content = BytesIO()
|
docx_content = BytesIO()
|
||||||
jinja_env = Jinja2Environment()
|
|
||||||
jinja_env.globals.update(**functions)
|
|
||||||
|
|
||||||
with BytesIO(b64decode(template)) as template_file:
|
with BytesIO(b64decode(template)) as template_file:
|
||||||
doc = DocxTemplate(template_file)
|
doc = DocxTemplate(template_file)
|
||||||
doc.render(data, jinja_env)
|
doc.render(values)
|
||||||
doc.save(docx_content)
|
doc.save(docx_content)
|
||||||
|
|
||||||
docx_content.seek(0)
|
docx_content.seek(0)
|
||||||
|
|
||||||
return docx_content
|
return docx_content
|
||||||
|
|
||||||
def _get_pdf_from_office(self, content_stream):
|
@staticmethod
|
||||||
|
def _parse_markup(markup_data: fields.Markup):
|
||||||
|
"""
|
||||||
|
Extracts data from field of Html type and returns them in text format,
|
||||||
|
without html tags.
|
||||||
|
"""
|
||||||
|
soup = BeautifulSoup(markup_data.__str__())
|
||||||
|
data_arr = list(soup.strings)
|
||||||
|
return "\n".join(data_arr)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_pdf_from_office(content_stream):
|
||||||
"""
|
"""
|
||||||
Вызов конвертации docx в pdf с помощью gotenberg
|
Вызов конвертации docx в pdf с помощью gotenberg
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user