some docs added
This commit is contained in:
parent
c5f6f9c058
commit
2e80dac5dd
@ -1 +1,10 @@
|
|||||||
# DOCS report
|
# DOCS report
|
||||||
|
Adds docx reports printing from docx templates like standard Odoo reports
|
||||||
|
with qweb templates. Standard Odoo reports also available.
|
||||||
|
|
||||||
|
For generating pdf from docx external service the "gotenberg" is used.
|
||||||
|
It should work at the same server as Odoo app. If "gotenberg" absent, there
|
||||||
|
will be only reports in docx format.
|
||||||
|
|
||||||
|
To get and start "gotenberg" container use command:
|
||||||
|
docker run -h docx_to_pdf -e DEFAULT_LISTEN_PORT=8808 thecodingmachine/gotenberg
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "DOCX report",
|
"name": "DOCX report",
|
||||||
"summary": """
|
"summary": """Printing reports in docx format from docx templates.""",
|
||||||
Print docx report from docx template""",
|
"description": """
|
||||||
"description": """""",
|
Adds docx reports printing from docx templates like standard Odoo reports
|
||||||
|
with qweb templates. Standard Odoo reports also available.
|
||||||
|
For generating pdf from docx external service the "gotenberg" is used.
|
||||||
|
It should work at the same server as Odoo app. If "gotenberg" absent, there
|
||||||
|
will be only reports in docx format.
|
||||||
|
""",
|
||||||
"author": "RYDLAB",
|
"author": "RYDLAB",
|
||||||
"website": "http://rydlab.ru",
|
"website": "http://rydlab.ru",
|
||||||
"category": "Technical",
|
"category": "Technical",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"depends": ["base", "web"],
|
"depends": ["base", "web", "custom_report_field", "report_monetary_helpers"],
|
||||||
"external_dependencies": {"python": ["docxcompose", "docxtpl"]},
|
"external_dependencies": {"python": ["docxcompose", "docxtpl"]},
|
||||||
"data": [
|
"data": [
|
||||||
"views/assets.xml",
|
"views/assets.xml",
|
||||||
|
@ -20,6 +20,9 @@ _logger = getLogger(__name__)
|
|||||||
class DocxReportController(ReportController):
|
class DocxReportController(ReportController):
|
||||||
@route()
|
@route()
|
||||||
def report_routes(self, reportname, docids=None, converter=None, **data):
|
def report_routes(self, reportname, docids=None, converter=None, **data):
|
||||||
|
"""
|
||||||
|
Запускает генерацию файла отчета и возвращает его
|
||||||
|
"""
|
||||||
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()
|
||||||
@ -61,6 +64,9 @@ class DocxReportController(ReportController):
|
|||||||
|
|
||||||
@route()
|
@route()
|
||||||
def report_download(self, data, token, context=None):
|
def report_download(self, data, token, context=None):
|
||||||
|
"""
|
||||||
|
Обрабатывает запрос на скачивание файла отчета
|
||||||
|
"""
|
||||||
requestcontent = json_loads(data)
|
requestcontent = json_loads(data)
|
||||||
url, type = requestcontent[0], requestcontent[1]
|
url, type = requestcontent[0], requestcontent[1]
|
||||||
try:
|
try:
|
||||||
|
@ -51,6 +51,12 @@ class IrActionsReport(models.Model):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def retrieve_attachment(self, record):
|
def retrieve_attachment(self, record):
|
||||||
|
"""
|
||||||
|
Поиск существующего файла отчета во вложениях записи по:
|
||||||
|
1. name
|
||||||
|
2. res_model
|
||||||
|
3. res_id
|
||||||
|
"""
|
||||||
result = super().retrieve_attachment(record)
|
result = super().retrieve_attachment(record)
|
||||||
if result:
|
if result:
|
||||||
if self.report_type == "docx-docx":
|
if self.report_type == "docx-docx":
|
||||||
@ -69,6 +75,10 @@ class IrActionsReport(models.Model):
|
|||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _render_docx_pdf(self, res_ids=None, data=None):
|
def _render_docx_pdf(self, res_ids=None, data=None):
|
||||||
|
"""
|
||||||
|
Подготавливает данные для рендера файла отчета, вызывает метод рендера
|
||||||
|
И обрабатывает результат рендера
|
||||||
|
"""
|
||||||
if not data:
|
if not data:
|
||||||
data = {}
|
data = {}
|
||||||
data.setdefault("report_type", "pdf")
|
data.setdefault("report_type", "pdf")
|
||||||
@ -127,6 +137,10 @@ class IrActionsReport(models.Model):
|
|||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _render_docx_docx(self, res_ids=None, data=None):
|
def _render_docx_docx(self, res_ids=None, data=None):
|
||||||
|
"""
|
||||||
|
Подготавливает данные для рендера файла отчета, вызывает метод рендера
|
||||||
|
И обрабатывает результат рендера
|
||||||
|
"""
|
||||||
if not data:
|
if not data:
|
||||||
data = {}
|
data = {}
|
||||||
data.setdefault("report_type", "docx")
|
data.setdefault("report_type", "docx")
|
||||||
@ -174,6 +188,10 @@ class IrActionsReport(models.Model):
|
|||||||
return docx_content, "docx"
|
return docx_content, "docx"
|
||||||
|
|
||||||
def _post_docx(self, save_in_attachment, docx_content=None, res_ids=None):
|
def _post_docx(self, save_in_attachment, docx_content=None, res_ids=None):
|
||||||
|
"""
|
||||||
|
Добавляет сгенерированный файл в аттачменты
|
||||||
|
"""
|
||||||
|
|
||||||
def close_streams(streams):
|
def close_streams(streams):
|
||||||
for stream in streams:
|
for stream in streams:
|
||||||
try:
|
try:
|
||||||
@ -233,6 +251,9 @@ class IrActionsReport(models.Model):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _postprocess_docx_report(self, record, buffer):
|
def _postprocess_docx_report(self, record, buffer):
|
||||||
|
"""
|
||||||
|
Непосредственно создает запись в ir.attachment
|
||||||
|
"""
|
||||||
attachment_name = safe_eval(self.attachment, {"object": record, "time": time})
|
attachment_name = safe_eval(self.attachment, {"object": record, "time": time})
|
||||||
if not attachment_name:
|
if not attachment_name:
|
||||||
return None
|
return None
|
||||||
@ -257,6 +278,9 @@ class IrActionsReport(models.Model):
|
|||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
def _merge_docx(self, streams):
|
def _merge_docx(self, streams):
|
||||||
|
"""
|
||||||
|
Объединяет несколько docx файлов в один
|
||||||
|
"""
|
||||||
if streams:
|
if streams:
|
||||||
writer = Document(streams[0])
|
writer = Document(streams[0])
|
||||||
composer = Composer(writer)
|
composer = Composer(writer)
|
||||||
@ -268,6 +292,9 @@ class IrActionsReport(models.Model):
|
|||||||
return streams
|
return streams
|
||||||
|
|
||||||
def _render_docx(self, docids, data=None):
|
def _render_docx(self, docids, data=None):
|
||||||
|
"""
|
||||||
|
Получает данные для рендеринга и вызывает его.
|
||||||
|
"""
|
||||||
if not data:
|
if not data:
|
||||||
data = {}
|
data = {}
|
||||||
data.setdefault("report_type", "docx")
|
data.setdefault("report_type", "docx")
|
||||||
@ -275,6 +302,9 @@ class IrActionsReport(models.Model):
|
|||||||
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, values=None):
|
||||||
|
"""
|
||||||
|
Непосредственно рендеринг docx файла
|
||||||
|
"""
|
||||||
if values is None:
|
if values is None:
|
||||||
values = {}
|
values = {}
|
||||||
|
|
||||||
@ -322,6 +352,9 @@ class IrActionsReport(models.Model):
|
|||||||
return docx_content
|
return docx_content
|
||||||
|
|
||||||
def _get_pdf_from_office(self, content_stream):
|
def _get_pdf_from_office(self, content_stream):
|
||||||
|
"""
|
||||||
|
Вызов конвертации docx в pdf с помощью gotenberg
|
||||||
|
"""
|
||||||
result = None
|
result = None
|
||||||
try:
|
try:
|
||||||
response = post_request(
|
response = post_request(
|
||||||
|
@ -6,6 +6,9 @@ odoo.define("docx_report.ReportActionManager", function (require) {
|
|||||||
var session = require("web.session");
|
var session = require("web.session");
|
||||||
|
|
||||||
ActionManager.include({
|
ActionManager.include({
|
||||||
|
/**
|
||||||
|
* Запрос на скачивание сгенерированного файла отчета
|
||||||
|
*/
|
||||||
_downloadReport: function (url, action) {
|
_downloadReport: function (url, action) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var template_type = (action.report_type && action.report_type.split("-")[0]) || "qweb";
|
var template_type = (action.report_type && action.report_type.split("-")[0]) || "qweb";
|
||||||
@ -36,6 +39,13 @@ odoo.define("docx_report.ReportActionManager", function (require) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Этот метод вызывается при нажатии на пункт меню для печати отчета.
|
||||||
|
*
|
||||||
|
* Вызывает _triggerDownload с различными аргументами.
|
||||||
|
* Расширяется новыми вариантами.
|
||||||
|
* В оригинальном методе есть и другой функционал.
|
||||||
|
*/
|
||||||
_executeReportAction: function (action, options) {
|
_executeReportAction: function (action, options) {
|
||||||
if (action.report_type === "docx-docx") {
|
if (action.report_type === "docx-docx") {
|
||||||
return this._triggerDownload(action, options, "docx");
|
return this._triggerDownload(action, options, "docx");
|
||||||
@ -45,6 +55,10 @@ odoo.define("docx_report.ReportActionManager", function (require) {
|
|||||||
return this._super.apply(this, arguments);
|
return this._super.apply(this, arguments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запускает скачивание файла отчета
|
||||||
|
*/
|
||||||
_triggerDownload: function (action, options, type){
|
_triggerDownload: function (action, options, type){
|
||||||
var self = this;
|
var self = this;
|
||||||
var reportUrls = this._makeReportUrls(action);
|
var reportUrls = this._makeReportUrls(action);
|
||||||
@ -57,6 +71,9 @@ odoo.define("docx_report.ReportActionManager", function (require) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Генерирует URL для запроса отчета
|
||||||
|
*/
|
||||||
_makeReportUrls: function (action) {
|
_makeReportUrls: function (action) {
|
||||||
var reportUrls = this._super.apply(this, arguments);
|
var reportUrls = this._super.apply(this, arguments);
|
||||||
reportUrls.docx = "/report/docx/" + action.report_name;
|
reportUrls.docx = "/report/docx/" + action.report_name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user