[IMP] report_py3o, report_py3o_fusion_server: black, isort
parent
19961919e6
commit
b2735878e4
|
@ -1,31 +1,21 @@
|
||||||
# Copyright 2017 Therp BV <http://therp.nl>
|
# Copyright 2017 Therp BV <http://therp.nl>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
{
|
{
|
||||||
'name': 'Py3o Report Engine - Fusion server support',
|
"name": "Py3o Report Engine - Fusion server support",
|
||||||
'summary': 'Let the fusion server handle format conversion.',
|
"summary": "Let the fusion server handle format conversion.",
|
||||||
'version': '12.0.1.0.0',
|
"version": "12.0.1.0.0",
|
||||||
'category': 'Reporting',
|
"category": "Reporting",
|
||||||
'license': 'AGPL-3',
|
"license": "AGPL-3",
|
||||||
'author': 'XCG Consulting,'
|
"author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)",
|
||||||
'ACSONE SA/NV,'
|
"website": "https://github.com/OCA/reporting-engine",
|
||||||
'Odoo Community Association (OCA)',
|
"depends": ["report_py3o"],
|
||||||
'website': 'https://github.com/OCA/reporting-engine',
|
"external_dependencies": {"python": ["py3o.template", "py3o.formats"]},
|
||||||
'depends': ['report_py3o'],
|
"demo": ["demo/report_py3o.xml", "demo/py3o_pdf_options.xml"],
|
||||||
'external_dependencies': {
|
"data": [
|
||||||
'python': [
|
|
||||||
'py3o.template',
|
|
||||||
'py3o.formats',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'demo': [
|
|
||||||
"demo/report_py3o.xml",
|
|
||||||
"demo/py3o_pdf_options.xml",
|
|
||||||
],
|
|
||||||
'data': [
|
|
||||||
"views/ir_actions_report.xml",
|
"views/ir_actions_report.xml",
|
||||||
'security/ir.model.access.csv',
|
"security/ir.model.access.csv",
|
||||||
'views/py3o_server.xml',
|
"views/py3o_server.xml",
|
||||||
'views/py3o_pdf_options.xml',
|
"views/py3o_pdf_options.xml",
|
||||||
],
|
],
|
||||||
'installable': True,
|
"installable": True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
# © 2017 Therp BV <http://therp.nl>
|
# © 2017 Therp BV <http://therp.nl>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openerp import _, api, fields, models
|
from openerp import _, api, fields, models
|
||||||
|
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class IrActionsReport(models.Model):
|
class IrActionsReport(models.Model):
|
||||||
_inherit = 'ir.actions.report'
|
_inherit = "ir.actions.report"
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.constrains("py3o_is_local_fusion", "py3o_server_id")
|
@api.constrains("py3o_is_local_fusion", "py3o_server_id")
|
||||||
|
@ -17,40 +19,52 @@ class IrActionsReport(models.Model):
|
||||||
for report in self:
|
for report in self:
|
||||||
if report.report_type != "py3o":
|
if report.report_type != "py3o":
|
||||||
continue
|
continue
|
||||||
if (not report.py3o_is_local_fusion and not report.py3o_server_id):
|
if not report.py3o_is_local_fusion and not report.py3o_server_id:
|
||||||
raise ValidationError(_(
|
raise ValidationError(
|
||||||
|
_(
|
||||||
"You can not use remote fusion without Fusion server. "
|
"You can not use remote fusion without Fusion server. "
|
||||||
"Please specify a Fusion Server"))
|
"Please specify a Fusion Server"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
py3o_is_local_fusion = fields.Boolean(
|
py3o_is_local_fusion = fields.Boolean(
|
||||||
"Local Fusion",
|
"Local Fusion",
|
||||||
help="Native formats will be processed without a server. "
|
help="Native formats will be processed without a server. "
|
||||||
"You must use this mode if you call methods on your model into "
|
"You must use this mode if you call methods on your model into "
|
||||||
"the template.",
|
"the template.",
|
||||||
default=True)
|
default=True,
|
||||||
py3o_server_id = fields.Many2one(
|
)
|
||||||
"py3o.server",
|
py3o_server_id = fields.Many2one("py3o.server", "Fusion Server")
|
||||||
"Fusion Server")
|
|
||||||
pdf_options_id = fields.Many2one(
|
pdf_options_id = fields.Many2one(
|
||||||
'py3o.pdf.options', string='PDF Options', ondelete='restrict',
|
"py3o.pdf.options",
|
||||||
|
string="PDF Options",
|
||||||
|
ondelete="restrict",
|
||||||
help="PDF options can be set per report, but also per Py3o Server. "
|
help="PDF options can be set per report, but also per Py3o Server. "
|
||||||
"If both are defined, the options on the report are used.")
|
"If both are defined, the options on the report are used.",
|
||||||
|
)
|
||||||
|
|
||||||
@api.depends("lo_bin_path", "is_py3o_native_format", "report_type",
|
@api.depends(
|
||||||
"py3o_server_id")
|
"lo_bin_path", "is_py3o_native_format", "report_type", "py3o_server_id"
|
||||||
|
)
|
||||||
@api.multi
|
@api.multi
|
||||||
def _compute_py3o_report_not_available(self):
|
def _compute_py3o_report_not_available(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
if not rec.report_type == "py3o":
|
if not rec.report_type == "py3o":
|
||||||
continue
|
continue
|
||||||
if (not rec.is_py3o_native_format and
|
if (
|
||||||
not rec.lo_bin_path and not rec.py3o_server_id):
|
not rec.is_py3o_native_format
|
||||||
|
and not rec.lo_bin_path
|
||||||
|
and not rec.py3o_server_id
|
||||||
|
):
|
||||||
rec.is_py3o_report_not_available = True
|
rec.is_py3o_report_not_available = True
|
||||||
rec.msg_py3o_report_not_available = _(
|
rec.msg_py3o_report_not_available = (
|
||||||
|
_(
|
||||||
"A fusion server or a libreoffice runtime are required "
|
"A fusion server or a libreoffice runtime are required "
|
||||||
"to genereate the py3o report '%s'. If the libreoffice"
|
"to genereate the py3o report '%s'. If the libreoffice"
|
||||||
"runtime is already installed and is not found by "
|
"runtime is already installed and is not found by "
|
||||||
"Odoo, you can provide the full path to the runtime by "
|
"Odoo, you can provide the full path to the runtime by "
|
||||||
"setting the key 'py3o.conversion_command' into the "
|
"setting the key 'py3o.conversion_command' into the "
|
||||||
"configuration parameters."
|
"configuration parameters."
|
||||||
) % rec.name
|
)
|
||||||
|
% rec.name
|
||||||
|
)
|
||||||
|
|
|
@ -2,223 +2,283 @@
|
||||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, fields, models, _
|
|
||||||
from odoo.exceptions import ValidationError
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from odoo import _, api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Py3oPdfOptions(models.Model):
|
class Py3oPdfOptions(models.Model):
|
||||||
_name = 'py3o.pdf.options'
|
_name = "py3o.pdf.options"
|
||||||
_description = 'Define PDF export options for Libreoffice'
|
_description = "Define PDF export options for Libreoffice"
|
||||||
|
|
||||||
name = fields.Char(required=True)
|
name = fields.Char(required=True)
|
||||||
# GENERAL TAB
|
# GENERAL TAB
|
||||||
# UseLosslessCompression (bool)
|
# UseLosslessCompression (bool)
|
||||||
image_compression = fields.Selection([
|
image_compression = fields.Selection(
|
||||||
('lossless', 'Lossless Compression'),
|
[("lossless", "Lossless Compression"), ("jpeg", "JPEG Compression")],
|
||||||
('jpeg', 'JPEG Compression'),
|
string="Image Compression",
|
||||||
], string='Image Compression', default='jpeg')
|
default="jpeg",
|
||||||
|
)
|
||||||
# Quality (int)
|
# Quality (int)
|
||||||
image_jpeg_quality = fields.Integer(
|
image_jpeg_quality = fields.Integer(
|
||||||
string='Image JPEG Quality', default=90,
|
string="Image JPEG Quality",
|
||||||
help="Enter a percentage between 0 and 100.")
|
default=90,
|
||||||
|
help="Enter a percentage between 0 and 100.",
|
||||||
|
)
|
||||||
# ReduceImageResolution (bool) and MaxImageResolution (int)
|
# ReduceImageResolution (bool) and MaxImageResolution (int)
|
||||||
image_reduce_resolution = fields.Selection([
|
image_reduce_resolution = fields.Selection(
|
||||||
('none', 'Disable'),
|
[
|
||||||
('75', '75 DPI'),
|
("none", "Disable"),
|
||||||
('150', '150 DPI'),
|
("75", "75 DPI"),
|
||||||
('300', '300 DPI'),
|
("150", "150 DPI"),
|
||||||
('600', '600 DPI'),
|
("300", "300 DPI"),
|
||||||
('1200', '1200 DPI'),
|
("600", "600 DPI"),
|
||||||
], string='Reduce Image Resolution', default='300')
|
("1200", "1200 DPI"),
|
||||||
watermark = fields.Boolean('Sign With Watermark')
|
],
|
||||||
|
string="Reduce Image Resolution",
|
||||||
|
default="300",
|
||||||
|
)
|
||||||
|
watermark = fields.Boolean("Sign With Watermark")
|
||||||
# Watermark (string)
|
# Watermark (string)
|
||||||
watermark_text = fields.Char('WaterMark Text')
|
watermark_text = fields.Char("WaterMark Text")
|
||||||
# UseTaggedPDF (bool)
|
# UseTaggedPDF (bool)
|
||||||
tagged_pdf = fields.Boolean('Tagged PDF (add document structure)')
|
tagged_pdf = fields.Boolean("Tagged PDF (add document structure)")
|
||||||
# SelectPdfVersion (int)
|
# SelectPdfVersion (int)
|
||||||
# 0 = PDF 1.4 (default selection).
|
# 0 = PDF 1.4 (default selection).
|
||||||
# 1 = PDF/A-1 (ISO 19005-1:2005)
|
# 1 = PDF/A-1 (ISO 19005-1:2005)
|
||||||
pdfa = fields.Boolean(
|
pdfa = fields.Boolean(
|
||||||
'Archive PDF/A-1a (ISO 19005-1)',
|
"Archive PDF/A-1a (ISO 19005-1)",
|
||||||
help="If you enable this option, you will not be able to "
|
help="If you enable this option, you will not be able to "
|
||||||
"password-protect the document or apply other security settings.")
|
"password-protect the document or apply other security settings.",
|
||||||
|
)
|
||||||
# ExportFormFields (bool)
|
# ExportFormFields (bool)
|
||||||
pdf_form = fields.Boolean('Create PDF Form', default=True)
|
pdf_form = fields.Boolean("Create PDF Form", default=True)
|
||||||
# FormsType (int)
|
# FormsType (int)
|
||||||
pdf_form_format = fields.Selection([
|
pdf_form_format = fields.Selection(
|
||||||
('0', 'FDF'),
|
[("0", "FDF"), ("1", "PDF"), ("2", "HTML"), ("3", "XML")],
|
||||||
('1', 'PDF'),
|
string="Submit Format",
|
||||||
('2', 'HTML'),
|
default="0",
|
||||||
('3', 'XML'),
|
)
|
||||||
], string='Submit Format', default='0')
|
|
||||||
# AllowDuplicateFieldNames (bool)
|
# AllowDuplicateFieldNames (bool)
|
||||||
pdf_form_allow_duplicate = fields.Boolean('Allow Duplicate Field Names')
|
pdf_form_allow_duplicate = fields.Boolean("Allow Duplicate Field Names")
|
||||||
# ExportBookmarks (bool)
|
# ExportBookmarks (bool)
|
||||||
export_bookmarks = fields.Boolean('Export Bookmarks', default=True)
|
export_bookmarks = fields.Boolean("Export Bookmarks", default=True)
|
||||||
# ExportPlaceholders (bool)
|
# ExportPlaceholders (bool)
|
||||||
export_placeholders = fields.Boolean('Export Placeholders', default=True)
|
export_placeholders = fields.Boolean("Export Placeholders", default=True)
|
||||||
# ExportNotes (bool)
|
# ExportNotes (bool)
|
||||||
export_comments = fields.Boolean('Export Comments')
|
export_comments = fields.Boolean("Export Comments")
|
||||||
# ExportHiddenSlides (bool) ??
|
# ExportHiddenSlides (bool) ??
|
||||||
export_hidden_slides = fields.Boolean(
|
export_hidden_slides = fields.Boolean("Export Automatically Insered Blank Pages")
|
||||||
'Export Automatically Insered Blank Pages')
|
|
||||||
# Doesn't make sense to have the option "View PDF after export" ! :)
|
# Doesn't make sense to have the option "View PDF after export" ! :)
|
||||||
# INITIAL VIEW TAB
|
# INITIAL VIEW TAB
|
||||||
# InitialView (int)
|
# InitialView (int)
|
||||||
initial_view = fields.Selection([
|
initial_view = fields.Selection(
|
||||||
('0', 'Page Only'),
|
[("0", "Page Only"), ("1", "Bookmarks and Page"), ("2", "Thumbnails and Page")],
|
||||||
('1', 'Bookmarks and Page'),
|
string="Panes",
|
||||||
('2', 'Thumbnails and Page'),
|
default="0",
|
||||||
], string='Panes', default='0')
|
)
|
||||||
# InitialPage (int)
|
# InitialPage (int)
|
||||||
initial_page = fields.Integer(string='Initial Page', default=1)
|
initial_page = fields.Integer(string="Initial Page", default=1)
|
||||||
# Magnification (int)
|
# Magnification (int)
|
||||||
magnification = fields.Selection([
|
magnification = fields.Selection(
|
||||||
('0', 'Default'),
|
[
|
||||||
('1', 'Fit in Window'),
|
("0", "Default"),
|
||||||
('2', 'Fit Width'),
|
("1", "Fit in Window"),
|
||||||
('3', 'Fit Visible'),
|
("2", "Fit Width"),
|
||||||
('4', 'Zoom'),
|
("3", "Fit Visible"),
|
||||||
], string='Magnification', default='0')
|
("4", "Zoom"),
|
||||||
|
],
|
||||||
|
string="Magnification",
|
||||||
|
default="0",
|
||||||
|
)
|
||||||
# Zoom (int)
|
# Zoom (int)
|
||||||
zoom = fields.Integer(
|
zoom = fields.Integer(
|
||||||
string='Zoom Factor', default=100,
|
string="Zoom Factor", default=100, help="Possible values: from 50 to 1600"
|
||||||
help='Possible values: from 50 to 1600')
|
)
|
||||||
# PageLayout (int)
|
# PageLayout (int)
|
||||||
page_layout = fields.Selection([
|
page_layout = fields.Selection(
|
||||||
('0', 'Default'),
|
[
|
||||||
('1', 'Single Page'),
|
("0", "Default"),
|
||||||
('2', 'Continuous'),
|
("1", "Single Page"),
|
||||||
('3', 'Continuous Facing'),
|
("2", "Continuous"),
|
||||||
], string='Page Layout', default='0')
|
("3", "Continuous Facing"),
|
||||||
|
],
|
||||||
|
string="Page Layout",
|
||||||
|
default="0",
|
||||||
|
)
|
||||||
# USER INTERFACE TAB
|
# USER INTERFACE TAB
|
||||||
# ResizeWindowToInitialPage (bool)
|
# ResizeWindowToInitialPage (bool)
|
||||||
resize_windows_initial_page = fields.Boolean(
|
resize_windows_initial_page = fields.Boolean(
|
||||||
string='Resize Windows to Initial Page')
|
string="Resize Windows to Initial Page"
|
||||||
|
)
|
||||||
# CenterWindow (bool)
|
# CenterWindow (bool)
|
||||||
center_window = fields.Boolean(string='Center Window on Screen')
|
center_window = fields.Boolean(string="Center Window on Screen")
|
||||||
# OpenInFullScreenMode (bool)
|
# OpenInFullScreenMode (bool)
|
||||||
open_fullscreen = fields.Boolean(string='Open in Full Screen Mode')
|
open_fullscreen = fields.Boolean(string="Open in Full Screen Mode")
|
||||||
# DisplayPDFDocumentTitle (bool)
|
# DisplayPDFDocumentTitle (bool)
|
||||||
display_document_title = fields.Boolean(string='Display Document Title')
|
display_document_title = fields.Boolean(string="Display Document Title")
|
||||||
# HideViewerMenubar (bool)
|
# HideViewerMenubar (bool)
|
||||||
hide_menubar = fields.Boolean(string='Hide Menubar')
|
hide_menubar = fields.Boolean(string="Hide Menubar")
|
||||||
# HideViewerToolbar (bool)
|
# HideViewerToolbar (bool)
|
||||||
hide_toolbar = fields.Boolean(string='Hide Toolbar')
|
hide_toolbar = fields.Boolean(string="Hide Toolbar")
|
||||||
# HideViewerWindowControls (bool)
|
# HideViewerWindowControls (bool)
|
||||||
hide_window_controls = fields.Boolean(string='Hide Windows Controls')
|
hide_window_controls = fields.Boolean(string="Hide Windows Controls")
|
||||||
# OpenBookmarkLevels (int) -1 = all (default) from 1 to 10
|
# OpenBookmarkLevels (int) -1 = all (default) from 1 to 10
|
||||||
open_bookmark_levels = fields.Selection([
|
open_bookmark_levels = fields.Selection(
|
||||||
('-1', 'All Levels'),
|
[
|
||||||
('1', '1'),
|
("-1", "All Levels"),
|
||||||
('2', '2'),
|
("1", "1"),
|
||||||
('3', '3'),
|
("2", "2"),
|
||||||
('4', '4'),
|
("3", "3"),
|
||||||
('5', '5'),
|
("4", "4"),
|
||||||
('6', '6'),
|
("5", "5"),
|
||||||
('7', '7'),
|
("6", "6"),
|
||||||
('8', '8'),
|
("7", "7"),
|
||||||
('9', '9'),
|
("8", "8"),
|
||||||
('10', '10'),
|
("9", "9"),
|
||||||
], default='-1', string='Visible Bookmark Levels')
|
("10", "10"),
|
||||||
|
],
|
||||||
|
default="-1",
|
||||||
|
string="Visible Bookmark Levels",
|
||||||
|
)
|
||||||
# LINKS TAB
|
# LINKS TAB
|
||||||
# ExportBookmarksToPDFDestination (bool)
|
# ExportBookmarksToPDFDestination (bool)
|
||||||
export_bookmarks_named_dest = fields.Boolean(
|
export_bookmarks_named_dest = fields.Boolean(
|
||||||
string='Export Bookmarks as Named Destinations')
|
string="Export Bookmarks as Named Destinations"
|
||||||
|
)
|
||||||
# ConvertOOoTargetToPDFTarget (bool)
|
# ConvertOOoTargetToPDFTarget (bool)
|
||||||
convert_doc_ref_to_pdf_target = fields.Boolean(
|
convert_doc_ref_to_pdf_target = fields.Boolean(
|
||||||
string='Convert Document References to PDF Targets')
|
string="Convert Document References to PDF Targets"
|
||||||
|
)
|
||||||
# ExportLinksRelativeFsys (bool)
|
# ExportLinksRelativeFsys (bool)
|
||||||
export_filesystem_urls = fields.Boolean(
|
export_filesystem_urls = fields.Boolean(string="Export URLs Relative to Filesystem")
|
||||||
string='Export URLs Relative to Filesystem')
|
|
||||||
# PDFViewSelection -> mnDefaultLinkAction (int)
|
# PDFViewSelection -> mnDefaultLinkAction (int)
|
||||||
cross_doc_link_action = fields.Selection([
|
cross_doc_link_action = fields.Selection(
|
||||||
('0', 'Default'),
|
[
|
||||||
('1', 'Open with PDF Reader Application'),
|
("0", "Default"),
|
||||||
('2', 'Open with Internet Browser'),
|
("1", "Open with PDF Reader Application"),
|
||||||
], string='Cross-document Links', default='0')
|
("2", "Open with Internet Browser"),
|
||||||
|
],
|
||||||
|
string="Cross-document Links",
|
||||||
|
default="0",
|
||||||
|
)
|
||||||
# SECURITY TAB
|
# SECURITY TAB
|
||||||
# EncryptFile (bool)
|
# EncryptFile (bool)
|
||||||
encrypt = fields.Boolean('Encrypt')
|
encrypt = fields.Boolean("Encrypt")
|
||||||
# DocumentOpenPassword (char)
|
# DocumentOpenPassword (char)
|
||||||
document_password = fields.Char(string='Document Password')
|
document_password = fields.Char(string="Document Password")
|
||||||
# RestrictPermissions (bool)
|
# RestrictPermissions (bool)
|
||||||
restrict_permissions = fields.Boolean('Restrict Permissions')
|
restrict_permissions = fields.Boolean("Restrict Permissions")
|
||||||
# PermissionPassword (char)
|
# PermissionPassword (char)
|
||||||
permission_password = fields.Char(string='Permission Password')
|
permission_password = fields.Char(string="Permission Password")
|
||||||
# TODO PreparedPasswords + PreparedPermissionPassword
|
# TODO PreparedPasswords + PreparedPermissionPassword
|
||||||
# I don't see those fields in the LO interface !
|
# I don't see those fields in the LO interface !
|
||||||
# But they are used in the LO code...
|
# But they are used in the LO code...
|
||||||
# Printing (int)
|
# Printing (int)
|
||||||
printing = fields.Selection([
|
printing = fields.Selection(
|
||||||
('0', 'Not Permitted'),
|
[
|
||||||
('1', 'Low Resolution (150 dpi)'),
|
("0", "Not Permitted"),
|
||||||
('2', 'High Resolution'),
|
("1", "Low Resolution (150 dpi)"),
|
||||||
], string='Printing', default='2')
|
("2", "High Resolution"),
|
||||||
|
],
|
||||||
|
string="Printing",
|
||||||
|
default="2",
|
||||||
|
)
|
||||||
# Changes (int)
|
# Changes (int)
|
||||||
changes = fields.Selection([
|
changes = fields.Selection(
|
||||||
('0', 'Not Permitted'),
|
[
|
||||||
('1', 'Inserting, Deleting and Rotating Pages'),
|
("0", "Not Permitted"),
|
||||||
('2', 'Filling in Form Fields'),
|
("1", "Inserting, Deleting and Rotating Pages"),
|
||||||
('3', 'Commenting, Filling in Form Fields'),
|
("2", "Filling in Form Fields"),
|
||||||
('4', 'Any Except Extracting Pages'),
|
("3", "Commenting, Filling in Form Fields"),
|
||||||
], string='Changes', default='4')
|
("4", "Any Except Extracting Pages"),
|
||||||
|
],
|
||||||
|
string="Changes",
|
||||||
|
default="4",
|
||||||
|
)
|
||||||
# EnableCopyingOfContent (bool)
|
# EnableCopyingOfContent (bool)
|
||||||
content_copying_allowed = fields.Boolean(
|
content_copying_allowed = fields.Boolean(
|
||||||
string='Enable Copying of Content', default=True)
|
string="Enable Copying of Content", default=True
|
||||||
|
)
|
||||||
# EnableTextAccessForAccessibilityTools (bool)
|
# EnableTextAccessForAccessibilityTools (bool)
|
||||||
text_access_accessibility_tools_allowed = fields.Boolean(
|
text_access_accessibility_tools_allowed = fields.Boolean(
|
||||||
string='Enable Text Access for Accessibility Tools', default=True)
|
string="Enable Text Access for Accessibility Tools", default=True
|
||||||
# DIGITAL SIGNATURE TAB
|
)
|
||||||
# This will be possible but not easy
|
|
||||||
# Because the certificate parameter is a pointer to a certificate
|
"""
|
||||||
# already registered in LO
|
DIGITAL SIGNATURE TAB
|
||||||
# On Linux LO reuses the Mozilla certificate store (on Windows the
|
This will be possible but not easy
|
||||||
# one from Windows)
|
Because the certificate parameter is a pointer to a certificate
|
||||||
# But there seems to be some possibilities to send this certificate via API
|
already registered in LO
|
||||||
# It seems you can add temporary certificates during runtime:
|
On Linux LO reuses the Mozilla certificate store (on Windows the
|
||||||
# https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1security_1_1XCertificateContainer.html
|
one from Windows)
|
||||||
# Here is an API to retrieve the known certificates:
|
But there seems to be some possibilities to send this certificate via API
|
||||||
# https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1xml_1_1crypto_1_1XSecurityEnvironment.html
|
It seems you can add temporary certificates during runtime:
|
||||||
# Thanks to 'samuel_m' on libreoffice-dev IRC chan for pointing me to this
|
https://api.libreoffice.org/docs/idl/ref/
|
||||||
|
interfacecom_1_1sun_1_1star_1_1security_1_1XCertificateContainer.html
|
||||||
|
Here is an API to retrieve the known certificates:
|
||||||
|
https://api.libreoffice.org/docs/idl/ref/
|
||||||
|
interfacecom_1_1sun_1_1star_1_1xml_1_1crypto_1_1XSecurityEnvironment.html
|
||||||
|
Thanks to 'samuel_m' on libreoffice-dev IRC chan for pointing me to this
|
||||||
|
"""
|
||||||
|
|
||||||
@api.constrains(
|
@api.constrains(
|
||||||
'image_jpeg_quality', 'initial_page', 'pdfa',
|
"image_jpeg_quality",
|
||||||
'cross_doc_link_action', 'magnification', 'zoom')
|
"initial_page",
|
||||||
|
"pdfa",
|
||||||
|
"cross_doc_link_action",
|
||||||
|
"magnification",
|
||||||
|
"zoom",
|
||||||
|
)
|
||||||
def check_pdf_options(self):
|
def check_pdf_options(self):
|
||||||
for opt in self:
|
for opt in self:
|
||||||
if opt.image_jpeg_quality > 100 or opt.image_jpeg_quality < 1:
|
if opt.image_jpeg_quality > 100 or opt.image_jpeg_quality < 1:
|
||||||
raise ValidationError(_(
|
raise ValidationError(
|
||||||
|
_(
|
||||||
"The parameter Image JPEG Quality must be between 1 %%"
|
"The parameter Image JPEG Quality must be between 1 %%"
|
||||||
" and 100 %% (current value: %s %%)")
|
" and 100 %% (current value: %s %%)"
|
||||||
% opt.image_jpeg_quality)
|
)
|
||||||
|
% opt.image_jpeg_quality
|
||||||
|
)
|
||||||
if opt.initial_page < 1:
|
if opt.initial_page < 1:
|
||||||
raise ValidationError(_(
|
raise ValidationError(
|
||||||
|
_(
|
||||||
"The initial page parameter must be strictly positive "
|
"The initial page parameter must be strictly positive "
|
||||||
"(current value: %d)") % opt.initial_page)
|
"(current value: %d)"
|
||||||
if opt.pdfa and opt.cross_doc_link_action == '1':
|
)
|
||||||
raise ValidationError(_(
|
% opt.initial_page
|
||||||
|
)
|
||||||
|
if opt.pdfa and opt.cross_doc_link_action == "1":
|
||||||
|
raise ValidationError(
|
||||||
|
_(
|
||||||
"The PDF/A option is not compatible with "
|
"The PDF/A option is not compatible with "
|
||||||
"'Cross-document Links' = "
|
"'Cross-document Links' = "
|
||||||
"'Open with PDF Reader Application'."))
|
"'Open with PDF Reader Application'."
|
||||||
if opt.magnification == '4' and (opt.zoom < 50 or opt.zoom > 1600):
|
)
|
||||||
raise ValidationError(_(
|
)
|
||||||
|
if opt.magnification == "4" and (opt.zoom < 50 or opt.zoom > 1600):
|
||||||
|
raise ValidationError(
|
||||||
|
_(
|
||||||
"The value of the zoom factor must be between 50 and 1600 "
|
"The value of the zoom factor must be between 50 and 1600 "
|
||||||
"(current value: %d)") % opt.zoom)
|
"(current value: %d)"
|
||||||
|
)
|
||||||
|
% opt.zoom
|
||||||
|
)
|
||||||
|
|
||||||
@api.onchange('encrypt')
|
@api.onchange("encrypt")
|
||||||
def encrypt_change(self):
|
def encrypt_change(self):
|
||||||
if not self.encrypt:
|
if not self.encrypt:
|
||||||
self.document_password = False
|
self.document_password = False
|
||||||
|
|
||||||
@api.onchange('restrict_permissions')
|
@api.onchange("restrict_permissions")
|
||||||
def restrict_permissions_change(self):
|
def restrict_permissions_change(self):
|
||||||
if not self.restrict_permissions:
|
if not self.restrict_permissions:
|
||||||
self.permission_password = False
|
self.permission_password = False
|
||||||
|
|
||||||
@api.onchange('pdfa')
|
@api.onchange("pdfa")
|
||||||
def pdfa_change(self):
|
def pdfa_change(self):
|
||||||
if self.pdfa:
|
if self.pdfa:
|
||||||
self.pdf_form = False
|
self.pdf_form = False
|
||||||
|
@ -229,87 +289,97 @@ class Py3oPdfOptions(models.Model):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
options = {}
|
options = {}
|
||||||
# GENERAL TAB
|
# GENERAL TAB
|
||||||
if self.image_compression == 'lossless':
|
if self.image_compression == "lossless":
|
||||||
options['UseLosslessCompression'] = True
|
options["UseLosslessCompression"] = True
|
||||||
else:
|
else:
|
||||||
options['UseLosslessCompression'] = False
|
options["UseLosslessCompression"] = False
|
||||||
options['Quality'] = self.image_jpeg_quality
|
options["Quality"] = self.image_jpeg_quality
|
||||||
if self.image_reduce_resolution != 'none':
|
if self.image_reduce_resolution != "none":
|
||||||
options['ReduceImageResolution'] = True
|
options["ReduceImageResolution"] = True
|
||||||
options['MaxImageResolution'] = int(self.image_reduce_resolution)
|
options["MaxImageResolution"] = int(self.image_reduce_resolution)
|
||||||
else:
|
else:
|
||||||
options['ReduceImageResolution'] = False
|
options["ReduceImageResolution"] = False
|
||||||
if self.watermark and self.watermark_text:
|
if self.watermark and self.watermark_text:
|
||||||
options['Watermark'] = self.watermark_text
|
options["Watermark"] = self.watermark_text
|
||||||
if self.pdfa:
|
if self.pdfa:
|
||||||
options['SelectPdfVersion'] = 1
|
options["SelectPdfVersion"] = 1
|
||||||
options['UseTaggedPDF'] = self.tagged_pdf
|
options["UseTaggedPDF"] = self.tagged_pdf
|
||||||
else:
|
else:
|
||||||
options['SelectPdfVersion'] = 0
|
options["SelectPdfVersion"] = 0
|
||||||
if self.pdf_form and self.pdf_form_format and not self.pdfa:
|
if self.pdf_form and self.pdf_form_format and not self.pdfa:
|
||||||
options['ExportFormFields'] = True
|
options["ExportFormFields"] = True
|
||||||
options['FormsType'] = int(self.pdf_form_format)
|
options["FormsType"] = int(self.pdf_form_format)
|
||||||
options['AllowDuplicateFieldNames'] = self.pdf_form_allow_duplicate
|
options["AllowDuplicateFieldNames"] = self.pdf_form_allow_duplicate
|
||||||
else:
|
else:
|
||||||
options['ExportFormFields'] = False
|
options["ExportFormFields"] = False
|
||||||
|
|
||||||
options.update({
|
options.update(
|
||||||
'ExportBookmarks': self.export_bookmarks,
|
{
|
||||||
'ExportPlaceholders': self.export_placeholders,
|
"ExportBookmarks": self.export_bookmarks,
|
||||||
'ExportNotes': self.export_comments,
|
"ExportPlaceholders": self.export_placeholders,
|
||||||
'ExportHiddenSlides': self.export_hidden_slides,
|
"ExportNotes": self.export_comments,
|
||||||
})
|
"ExportHiddenSlides": self.export_hidden_slides,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# INITIAL VIEW TAB
|
# INITIAL VIEW TAB
|
||||||
options.update({
|
options.update(
|
||||||
'InitialView': int(self.initial_view),
|
{
|
||||||
'InitialPage': self.initial_page,
|
"InitialView": int(self.initial_view),
|
||||||
'Magnification': int(self.magnification),
|
"InitialPage": self.initial_page,
|
||||||
'PageLayout': int(self.page_layout),
|
"Magnification": int(self.magnification),
|
||||||
})
|
"PageLayout": int(self.page_layout),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if self.magnification == '4':
|
if self.magnification == "4":
|
||||||
options['Zoom'] = self.zoom
|
options["Zoom"] = self.zoom
|
||||||
|
|
||||||
# USER INTERFACE TAB
|
# USER INTERFACE TAB
|
||||||
options.update({
|
options.update(
|
||||||
'ResizeWindowToInitialPage': self.resize_windows_initial_page,
|
{
|
||||||
'CenterWindow': self.center_window,
|
"ResizeWindowToInitialPage": self.resize_windows_initial_page,
|
||||||
'OpenInFullScreenMode': self.open_fullscreen,
|
"CenterWindow": self.center_window,
|
||||||
'DisplayPDFDocumentTitle': self.display_document_title,
|
"OpenInFullScreenMode": self.open_fullscreen,
|
||||||
'HideViewerMenubar': self.hide_menubar,
|
"DisplayPDFDocumentTitle": self.display_document_title,
|
||||||
'HideViewerToolbar': self.hide_toolbar,
|
"HideViewerMenubar": self.hide_menubar,
|
||||||
'HideViewerWindowControls': self.hide_window_controls,
|
"HideViewerToolbar": self.hide_toolbar,
|
||||||
})
|
"HideViewerWindowControls": self.hide_window_controls,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if self.open_bookmark_levels:
|
if self.open_bookmark_levels:
|
||||||
options['OpenBookmarkLevels'] = int(self.open_bookmark_levels)
|
options["OpenBookmarkLevels"] = int(self.open_bookmark_levels)
|
||||||
|
|
||||||
# LINKS TAB
|
# LINKS TAB
|
||||||
options.update({
|
options.update(
|
||||||
'ExportBookmarksToPDFDestination':
|
{
|
||||||
self.export_bookmarks_named_dest,
|
"ExportBookmarksToPDFDestination": self.export_bookmarks_named_dest,
|
||||||
'ConvertOOoTargetToPDFTarget': self.convert_doc_ref_to_pdf_target,
|
"ConvertOOoTargetToPDFTarget": self.convert_doc_ref_to_pdf_target,
|
||||||
'ExportLinksRelativeFsys': self.export_filesystem_urls,
|
"ExportLinksRelativeFsys": self.export_filesystem_urls,
|
||||||
'PDFViewSelection': int(self.cross_doc_link_action),
|
"PDFViewSelection": int(self.cross_doc_link_action),
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# SECURITY TAB
|
# SECURITY TAB
|
||||||
if not self.pdfa:
|
if not self.pdfa:
|
||||||
if self.encrypt and self.document_password:
|
if self.encrypt and self.document_password:
|
||||||
options['EncryptFile'] = True
|
options["EncryptFile"] = True
|
||||||
options['DocumentOpenPassword'] = self.document_password
|
options["DocumentOpenPassword"] = self.document_password
|
||||||
if self.restrict_permissions and self.permission_password:
|
if self.restrict_permissions and self.permission_password:
|
||||||
options.update({
|
# fmt: off
|
||||||
'RestrictPermissions': True,
|
options.update(
|
||||||
'PermissionPassword': self.permission_password,
|
{
|
||||||
'Printing': int(self.printing),
|
"RestrictPermissions": True,
|
||||||
'Changes': int(self.changes),
|
"PermissionPassword": self.permission_password,
|
||||||
'EnableCopyingOfContent': self.content_copying_allowed,
|
"Printing": int(self.printing),
|
||||||
'EnableTextAccessForAccessibilityTools':
|
"Changes": int(self.changes),
|
||||||
|
"EnableCopyingOfContent": self.content_copying_allowed,
|
||||||
|
"EnableTextAccessForAccessibilityTools":
|
||||||
self.text_access_accessibility_tools_allowed,
|
self.text_access_accessibility_tools_allowed,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
logger.debug(
|
logger.debug("Py3o PDF options ID %s converted to %s", self.id, options)
|
||||||
'Py3o PDF options ID %s converted to %s', self.id, options)
|
|
||||||
return options
|
return options
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import requests
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from datetime import datetime
|
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
from datetime import datetime
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import requests
|
||||||
from openerp import _, api, models
|
from openerp import _, api, models
|
||||||
from openerp.exceptions import UserError
|
from openerp.exceptions import UserError
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -19,11 +20,11 @@ try:
|
||||||
from py3o.template import Template
|
from py3o.template import Template
|
||||||
from py3o.template.helpers import Py3oConvertor
|
from py3o.template.helpers import Py3oConvertor
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.debug('Cannot import py3o.template')
|
logger.debug("Cannot import py3o.template")
|
||||||
|
|
||||||
|
|
||||||
class Py3oReport(models.TransientModel):
|
class Py3oReport(models.TransientModel):
|
||||||
_inherit = 'py3o.report'
|
_inherit = "py3o.report"
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _create_single_report(self, model_instance, data):
|
def _create_single_report(self, model_instance, data):
|
||||||
|
@ -33,40 +34,32 @@ class Py3oReport(models.TransientModel):
|
||||||
report_xml = self.ir_actions_report_id
|
report_xml = self.ir_actions_report_id
|
||||||
filetype = report_xml.py3o_filetype
|
filetype = report_xml.py3o_filetype
|
||||||
if not report_xml.py3o_server_id:
|
if not report_xml.py3o_server_id:
|
||||||
return super(Py3oReport, self)._create_single_report(
|
return super(Py3oReport, self)._create_single_report(model_instance, data)
|
||||||
model_instance, data,
|
|
||||||
)
|
|
||||||
elif report_xml.py3o_is_local_fusion:
|
elif report_xml.py3o_is_local_fusion:
|
||||||
result_path = super(
|
result_path = super(
|
||||||
Py3oReport, self.with_context(
|
Py3oReport, self.with_context(report_py3o_skip_conversion=True)
|
||||||
report_py3o_skip_conversion=True,
|
)._create_single_report(model_instance, data)
|
||||||
)
|
with closing(open(result_path, "rb")) as out_stream:
|
||||||
)._create_single_report(
|
|
||||||
model_instance, data
|
|
||||||
)
|
|
||||||
with closing(open(result_path, 'rb')) as out_stream:
|
|
||||||
tmpl_data = out_stream.read()
|
tmpl_data = out_stream.read()
|
||||||
datadict = {}
|
datadict = {}
|
||||||
else:
|
else:
|
||||||
result_fd, result_path = tempfile.mkstemp(
|
result_fd, result_path = tempfile.mkstemp(
|
||||||
suffix='.' + filetype, prefix='p3o.report.tmp.')
|
suffix="." + filetype, prefix="p3o.report.tmp."
|
||||||
|
)
|
||||||
tmpl_data = self.get_template(model_instance)
|
tmpl_data = self.get_template(model_instance)
|
||||||
|
|
||||||
in_stream = BytesIO(tmpl_data)
|
in_stream = BytesIO(tmpl_data)
|
||||||
with closing(os.fdopen(result_fd, 'wb+')) as out_stream:
|
with closing(os.fdopen(result_fd, "wb+")) as out_stream:
|
||||||
template = Template(in_stream, out_stream, escape_false=True)
|
template = Template(in_stream, out_stream, escape_false=True)
|
||||||
localcontext = self._get_parser_context(model_instance, data)
|
localcontext = self._get_parser_context(model_instance, data)
|
||||||
expressions = template.get_all_user_python_expression()
|
expressions = template.get_all_user_python_expression()
|
||||||
py_expression = template.convert_py3o_to_python_ast(
|
py_expression = template.convert_py3o_to_python_ast(expressions)
|
||||||
expressions)
|
|
||||||
convertor = Py3oConvertor()
|
convertor = Py3oConvertor()
|
||||||
data_struct = convertor(py_expression)
|
data_struct = convertor(py_expression)
|
||||||
datadict = data_struct.render(localcontext)
|
datadict = data_struct.render(localcontext)
|
||||||
|
|
||||||
# Call py3o.server to render the template in the desired format
|
# Call py3o.server to render the template in the desired format
|
||||||
files = {
|
files = {"tmpl_file": tmpl_data}
|
||||||
'tmpl_file': tmpl_data,
|
|
||||||
}
|
|
||||||
fields = {
|
fields = {
|
||||||
"targetformat": filetype,
|
"targetformat": filetype,
|
||||||
"datadict": json.dumps(datadict),
|
"datadict": json.dumps(datadict),
|
||||||
|
@ -74,37 +67,41 @@ class Py3oReport(models.TransientModel):
|
||||||
"escape_false": "on",
|
"escape_false": "on",
|
||||||
}
|
}
|
||||||
if report_xml.py3o_is_local_fusion:
|
if report_xml.py3o_is_local_fusion:
|
||||||
fields['skipfusion'] = '1'
|
fields["skipfusion"] = "1"
|
||||||
url = report_xml.py3o_server_id.url
|
url = report_xml.py3o_server_id.url
|
||||||
logger.info(
|
logger.info(
|
||||||
'Connecting to %s to convert report %s to %s',
|
"Connecting to %s to convert report %s to %s",
|
||||||
url, report_xml.report_name, filetype)
|
url,
|
||||||
if filetype == 'pdf':
|
report_xml.report_name,
|
||||||
options = report_xml.pdf_options_id or\
|
filetype,
|
||||||
report_xml.py3o_server_id.pdf_options_id
|
)
|
||||||
|
if filetype == "pdf":
|
||||||
|
options = (
|
||||||
|
report_xml.pdf_options_id or report_xml.py3o_server_id.pdf_options_id
|
||||||
|
)
|
||||||
if options:
|
if options:
|
||||||
pdf_options_dict = options.odoo2libreoffice_options()
|
pdf_options_dict = options.odoo2libreoffice_options()
|
||||||
fields['pdf_options'] = json.dumps(pdf_options_dict)
|
fields["pdf_options"] = json.dumps(pdf_options_dict)
|
||||||
logger.debug('PDF Export options: %s', pdf_options_dict)
|
logger.debug("PDF Export options: %s", pdf_options_dict)
|
||||||
start_chrono = datetime.now()
|
start_chrono = datetime.now()
|
||||||
r = requests.post(url, data=fields, files=files)
|
r = requests.post(url, data=fields, files=files)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
# server says we have an issue... let's tell that to enduser
|
# server says we have an issue... let's tell that to enduser
|
||||||
logger.error('Py3o fusion server error: %s', r.text)
|
logger.error("Py3o fusion server error: %s", r.text)
|
||||||
raise UserError(
|
raise UserError(_("Fusion server error %s") % r.text)
|
||||||
_('Fusion server error %s') % r.text,
|
|
||||||
)
|
|
||||||
|
|
||||||
chunk_size = 1024
|
chunk_size = 1024
|
||||||
with open(result_path, 'w+b') as fd:
|
with open(result_path, "w+b") as fd:
|
||||||
for chunk in r.iter_content(chunk_size):
|
for chunk in r.iter_content(chunk_size):
|
||||||
fd.write(chunk)
|
fd.write(chunk)
|
||||||
end_chrono = datetime.now()
|
end_chrono = datetime.now()
|
||||||
convert_seconds = (end_chrono - start_chrono).total_seconds()
|
convert_seconds = (end_chrono - start_chrono).total_seconds()
|
||||||
logger.info(
|
logger.info(
|
||||||
'Report %s converted to %s in %s seconds',
|
"Report %s converted to %s in %s seconds",
|
||||||
report_xml.report_name, filetype, convert_seconds)
|
report_xml.report_name,
|
||||||
|
filetype,
|
||||||
|
convert_seconds,
|
||||||
|
)
|
||||||
if len(model_instance) == 1:
|
if len(model_instance) == 1:
|
||||||
self._postprocess_report(
|
self._postprocess_report(model_instance, result_path)
|
||||||
model_instance, result_path)
|
|
||||||
return result_path
|
return result_path
|
||||||
|
|
|
@ -4,16 +4,21 @@ from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
class Py3oServer(models.Model):
|
class Py3oServer(models.Model):
|
||||||
_name = 'py3o.server'
|
_name = "py3o.server"
|
||||||
_description = 'Py3o server'
|
_description = "Py3o server"
|
||||||
_rec_name = 'url'
|
_rec_name = "url"
|
||||||
|
|
||||||
url = fields.Char(
|
url = fields.Char(
|
||||||
"Py3o Fusion Server URL", required=True,
|
"Py3o Fusion Server URL",
|
||||||
|
required=True,
|
||||||
help="If your Py3o Fusion server is on the same machine and runs "
|
help="If your Py3o Fusion server is on the same machine and runs "
|
||||||
"on the default port, the URL is http://localhost:8765/form")
|
"on the default port, the URL is http://localhost:8765/form",
|
||||||
|
)
|
||||||
is_active = fields.Boolean("Active", default=True)
|
is_active = fields.Boolean("Active", default=True)
|
||||||
pdf_options_id = fields.Many2one(
|
pdf_options_id = fields.Many2one(
|
||||||
'py3o.pdf.options', string='PDF Options', ondelete='restrict',
|
"py3o.pdf.options",
|
||||||
|
string="PDF Options",
|
||||||
|
ondelete="restrict",
|
||||||
help="PDF options can be set per Py3o Server but also per report. "
|
help="PDF options can be set per Py3o Server but also per report. "
|
||||||
"If both are defined, the options on the report are used.")
|
"If both are defined, the options on the report are used.",
|
||||||
|
)
|
||||||
|
|
|
@ -1,62 +1,55 @@
|
||||||
# Copyright 2017 Therp BV <http://therp.nl>
|
# Copyright 2017 Therp BV <http://therp.nl>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError
|
||||||
from odoo.addons.report_py3o.models.ir_actions_report import \
|
|
||||||
PY3O_CONVERSION_COMMAND_PARAMETER
|
from odoo.addons.report_py3o.models.ir_actions_report import (
|
||||||
|
PY3O_CONVERSION_COMMAND_PARAMETER,
|
||||||
|
)
|
||||||
from odoo.addons.report_py3o.tests import test_report_py3o
|
from odoo.addons.report_py3o.tests import test_report_py3o
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'requests.post', mock.Mock(
|
"requests.post",
|
||||||
|
mock.Mock(
|
||||||
return_value=mock.Mock(
|
return_value=mock.Mock(
|
||||||
status_code=200,
|
status_code=200, iter_content=mock.Mock(return_value=[b"test_result"])
|
||||||
iter_content=mock.Mock(return_value=[b'test_result']),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o):
|
class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestReportPy3oFusionServer, self).setUp()
|
super(TestReportPy3oFusionServer, self).setUp()
|
||||||
py3o_server = self.env['py3o.server'].create({"url": "http://dummy"})
|
py3o_server = self.env["py3o.server"].create({"url": "http://dummy"})
|
||||||
# check the call to the fusion server
|
# check the call to the fusion server
|
||||||
self.report.write({
|
self.report.write({"py3o_server_id": py3o_server.id, "py3o_filetype": "pdf"})
|
||||||
"py3o_server_id": py3o_server.id,
|
|
||||||
"py3o_filetype": 'pdf',
|
|
||||||
})
|
|
||||||
self.py3o_server = py3o_server
|
self.py3o_server = py3o_server
|
||||||
|
|
||||||
def test_no_local_fusion_without_fusion_server(self):
|
def test_no_local_fusion_without_fusion_server(self):
|
||||||
self.assertTrue(self.report.py3o_is_local_fusion)
|
self.assertTrue(self.report.py3o_is_local_fusion)
|
||||||
# Fusion server is only required if not local...
|
# Fusion server is only required if not local...
|
||||||
self.report.write({
|
self.report.write({"py3o_server_id": None, "py3o_is_local_fusion": True})
|
||||||
"py3o_server_id": None,
|
self.report.write(
|
||||||
"py3o_is_local_fusion": True,
|
{"py3o_server_id": self.py3o_server.id, "py3o_is_local_fusion": True}
|
||||||
})
|
)
|
||||||
self.report.write({
|
self.report.write(
|
||||||
"py3o_server_id": self.py3o_server.id,
|
{"py3o_server_id": self.py3o_server.id, "py3o_is_local_fusion": False}
|
||||||
"py3o_is_local_fusion": True,
|
)
|
||||||
})
|
|
||||||
self.report.write({
|
|
||||||
"py3o_server_id": self.py3o_server.id,
|
|
||||||
"py3o_is_local_fusion": False,
|
|
||||||
})
|
|
||||||
with self.assertRaises(ValidationError) as e:
|
with self.assertRaises(ValidationError) as e:
|
||||||
self.report.write({
|
self.report.write({"py3o_server_id": None, "py3o_is_local_fusion": False})
|
||||||
"py3o_server_id": None,
|
|
||||||
"py3o_is_local_fusion": False,
|
|
||||||
})
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
e.exception.name,
|
e.exception.name,
|
||||||
"You can not use remote fusion without Fusion server. "
|
"You can not use remote fusion without Fusion server. "
|
||||||
"Please specify a Fusion Server")
|
"Please specify a Fusion Server",
|
||||||
|
)
|
||||||
|
|
||||||
def test_reports_no_local_fusion(self):
|
def test_reports_no_local_fusion(self):
|
||||||
self.report.py3o_is_local_fusion = False
|
self.report.py3o_is_local_fusion = False
|
||||||
self.test_reports()
|
self.test_reports()
|
||||||
|
|
||||||
def test_odoo2libreoffice_options(self):
|
def test_odoo2libreoffice_options(self):
|
||||||
for options in self.env['py3o.pdf.options'].search([]):
|
for options in self.env["py3o.pdf.options"].search([]):
|
||||||
options_dict = options.odoo2libreoffice_options()
|
options_dict = options.odoo2libreoffice_options()
|
||||||
self.assertIsInstance(options_dict, dict)
|
self.assertIsInstance(options_dict, dict)
|
||||||
|
|
||||||
|
@ -73,8 +66,9 @@ class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o):
|
||||||
self.assertFalse(self.report.msg_py3o_report_not_available)
|
self.assertFalse(self.report.msg_py3o_report_not_available)
|
||||||
|
|
||||||
# specify a wrong lo bin path and a non native format.
|
# specify a wrong lo bin path and a non native format.
|
||||||
self.env['ir.config_parameter'].set_param(
|
self.env["ir.config_parameter"].set_param(
|
||||||
PY3O_CONVERSION_COMMAND_PARAMETER, "/wrong_path")
|
PY3O_CONVERSION_COMMAND_PARAMETER, "/wrong_path"
|
||||||
|
)
|
||||||
self.report.py3o_filetype = "pdf"
|
self.report.py3o_filetype = "pdf"
|
||||||
self.report.refresh()
|
self.report.refresh()
|
||||||
# no native and no bin path, everything is still OK since a fusion
|
# no native and no bin path, everything is still OK since a fusion
|
||||||
|
@ -91,8 +85,9 @@ class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o):
|
||||||
self.assertTrue(self.report.msg_py3o_report_not_available)
|
self.assertTrue(self.report.msg_py3o_report_not_available)
|
||||||
|
|
||||||
# if we set a libreffice runtime, the report is available again
|
# if we set a libreffice runtime, the report is available again
|
||||||
self.env['ir.config_parameter'].set_param(
|
self.env["ir.config_parameter"].set_param(
|
||||||
PY3O_CONVERSION_COMMAND_PARAMETER, "libreoffice")
|
PY3O_CONVERSION_COMMAND_PARAMETER, "libreoffice"
|
||||||
|
)
|
||||||
self.report.refresh()
|
self.report.refresh()
|
||||||
self.assertTrue(self.report.lo_bin_path)
|
self.assertTrue(self.report.lo_bin_path)
|
||||||
self.assertFalse(self.report.is_py3o_report_not_available)
|
self.assertFalse(self.report.is_py3o_report_not_available)
|
||||||
|
|
Loading…
Reference in New Issue