diff --git a/docx_report_generation/__manifest__.py b/docx_report_generation/__manifest__.py
index 0584174..8a9533a 100755
--- a/docx_report_generation/__manifest__.py
+++ b/docx_report_generation/__manifest__.py
@@ -11,20 +11,20 @@
This is the beta version, bugs may be present.
""",
- "author": "RYDLAB",
+ "author": "RYDLAB, Yaltik",
"website": "https://rydlab.ru",
"category": "Technical",
- "version": "16.0.2.0.0",
+ "version": "16.0.2.1.0",
"license": "LGPL-3",
"depends": ["base", "web", "custom_report_field", "report_monetary_helpers"],
- "external_dependencies": {"python": ["docxcompose", "docxtpl", "bs4"]},
+ "external_dependencies": {"python": ["docxcompose", "docxtpl", "beautifulsoup4"]},
"data": [
"views/ir_actions_report_views.xml",
],
"assets": {
"web.assets_backend": [
- "docx_report/static/src/css/mimetypes.css",
- "docx_report/static/src/js/action_manager_report.js",
+ "docx_report_generation/static/src/css/mimetypes.css",
+ "docx_report_generation/static/src/js/action_manager_report.js",
],
},
"images": ["static/description/banner.jpg"],
diff --git a/docx_report_generation/models/ir_actions_report.py b/docx_report_generation/models/ir_actions_report.py
index 8098c20..7cbee79 100644
--- a/docx_report_generation/models/ir_actions_report.py
+++ b/docx_report_generation/models/ir_actions_report.py
@@ -2,11 +2,20 @@ from base64 import b64decode
from bs4 import BeautifulSoup
from collections import OrderedDict
from io import BytesIO
+from functools import partial
+from re import findall
+from json import loads
from logging import getLogger
+from lxml import etree
+
from docx import Document
+from docx.oxml import OxmlElement
+from docx.oxml.ns import qn
+from docx.shared import RGBColor
from docxcompose.composer import Composer
from docxtpl import DocxTemplate
+import jinja2
from requests import codes as codes_request, post as post_request
from requests.exceptions import RequestException
@@ -14,6 +23,7 @@ from odoo import _, api, fields, models
from odoo.exceptions import AccessError, UserError
from odoo.http import request
from odoo.tools.safe_eval import safe_eval, time
+from odoo.tools.misc import format_date
try:
from odoo.addons.gotenberg.service.utils import (
@@ -419,24 +429,77 @@ class IrActionsReport(models.Model):
)
record_to_render = values["docs"]
+ # No more HTML / Markup stripping
docs = {
key: record_to_render[key]
for key in record_to_render._fields.keys()
- if not isinstance(record_to_render[key], fields.Markup)
+ # 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
+ def _html_generate(field, tpl):
+
+ def _create_list(paragraph, list_type):
+ p = paragraph._p #access to xml paragraph element
+ pPr = p.get_or_add_pPr() #access paragraph properties
+ numPr = OxmlElement('w:numPr') #create number properties element
+ numId = OxmlElement('w:numId') #create numId element - sets bullet type
+ numId.set(qn('w:val'), list_type) #set list type/indentation
+ numPr.append(numId) #add bullet type to number properties list
+ pPr.append(numPr) #add number properties to paragraph
+
+ if isinstance(field, fields.Markup):
+ html_field = str(field).replace('
', '').replace(' ', ' ')
+ xml_tree = etree.fromstring('%s' % html_field)
+ md = tpl.new_subdoc()
+ for child in xml_tree.iter():
+ if child.tag in ('p', 'strong', 'em', 's', 'u', 'ul',
+ 'ol', 'li', 'font', 'a'):
+ if child.tag == 'p':
+ p = md.add_paragraph(child.text)
+ elif child.tag == 'a':
+ p.add_run(child.text).style = 'Hyperlink'
+ elif child.tag == 'strong':
+ p.add_run(child.text).bold = True
+ p.add_run(' ')
+ elif child.tag == 'em':
+ p.add_run(child.text).italic = True
+ p.add_run(' ')
+ elif child.tag == 'u':
+ p.add_run(child.text).underline = True
+ p.add_run(' ')
+ elif child.tag == 's':
+ p.add_run(child.text).font.strike = True
+ p.add_run(' ')
+ elif child.tag == 'font' and 'style' in child.attrib:
+ if 'color' in child.get('style'):
+ rgb = [int(_v)
+ for _v in findall(r'\d+', child.get('style'))]
+ if len(rgb) == 3:
+ p.add_run(child.text).font.color.rgb = RGBColor(*rgb)
+ else:
+ p.add_run(child.text)
+ elif child.tag == 'ul':
+ list_type = '9' # 9/25/28 : •, 8 : -, 19 : v
+ elif child.tag == 'ol':
+ list_type = '30' # 27 : 1.2 sans indent, 30: 1.2
+ elif child.tag == 'li':
+ lp = md.add_paragraph(child.text, style='List Paragraph')
+ _create_list(lp, list_type)
+ elif child.tag == 'root':
+ continue
+ else: # Not handled, add text only
+ p.add_run(child.text)
+ return md
+
+ jinja_env = jinja2.Environment()
+
docx_content = BytesIO()
with BytesIO(b64decode(template)) as template_file:
doc = DocxTemplate(template_file)
- doc.render(values)
+ jinja_env.filters['htmlgen'] = partial(_html_generate, tpl=doc)
+ jinja_env.filters['datefmt'] = lambda dt: format_date(self.env, dt)
+ doc.render(values, jinja_env)
doc.save(docx_content)
docx_content.seek(0)
return docx_content
@@ -476,3 +539,11 @@ class IrActionsReport(models.Model):
_logger.exception(e)
finally:
return result
+
+ @api.model
+ def _get_rendering_context(self, report, docids, data):
+ data = super()._get_rendering_context(report, docids, data)
+ data.update({
+ 'jloads': loads,
+ })
+ return data