[ADD] report_qweb_pdf_cover

This commit is contained in:
LauraCForgeFlow
2024-08-27 10:22:02 +02:00
parent 7470393761
commit 9cfb437eb2
14 changed files with 1158 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
=====================
Report QWeb PDF Cover
=====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1287ee62d703ed048f33bb706f289cf01e5c99bead22b8b612d69e88071a4d67
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/16.0/report_qweb_pdf_cover
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-report_qweb_pdf_cover
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows for front and back covers to be added to the generated PDF
reports. They can be added as a separate page, at the beginning or the end of
the report, but they can also overlap the first and last page of the actual
report, respectively.
**Table of contents**
.. contents::
:local:
Usage
=====
To add a cover to a report, you need to access to the report's configuration,
more specifically to the `Advanced Properties` tab. There, you will find two
checkboxes, one for the front cover and another for the back cover.
They both work the same, so let's focus on the front cover with an example.
* You must check the `Use Front Cover` checkbox to enable the front cover. You
will see that a new checkbox and a PDF file widget appear.
* If you want the front cover to overlap with the first page of the PDF report,
you should also check the `Overlap Front Cover` checkbox. Leave it unchecked
if you don't want the front cover to overlap with the first page.
* The last step would be to upload the PDF file that will be used as the front
cover. You can do this by clicking on the PDF file widget and selecting the
file.
* Important! The file must be a PDF file, and it should have only one page. If
it has more pages, only the first one will be used.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_qweb_pdf_cover%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* ForgeFlow
Contributors
~~~~~~~~~~~~
* Laura Cazorla <laura.cazorla@forgeflow.com>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/16.0/report_qweb_pdf_cover>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,4 @@
# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com)
# Part of ForgeFlow. See LICENSE file for full copyright and licensing details.
from . import models

View File

@@ -0,0 +1,16 @@
# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com)
# Part of ForgeFlow. See LICENSE file for full copyright and licensing details.
{
"name": "Report QWeb PDF Cover",
"summary": "Add front and back covers to your QWeb PDF reports",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/reporting-engine",
"category": "Reporting",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"depends": ["web"],
"data": ["views/ir_actions_views.xml"],
"installable": True,
"application": False,
}

View File

@@ -0,0 +1,157 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * report_qweb_pdf_cover
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 08:09+0000\n"
"PO-Revision-Date: 2024-08-27 08:09+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__back_cover_pdf
msgid "Back Cover PDF"
msgstr "Contraportada PDF"
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Failed to load back cover: %s"
msgstr "Error al cargar la contraportada: %s"
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Failed to load front cover: %s"
msgstr "Error al cargar la portada: %s"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__front_cover_pdf
msgid "Front Cover PDF"
msgstr "Portada PDF"
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "No usable back cover found."
msgstr "No se encontró ninguna contraportada usable."
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "No usable front cover found."
msgstr "No se encontró ninguna portada usable."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__back_cover_overlap
msgid "Overlap Back Cover"
msgstr "Superponer Contraportada"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__front_cover_overlap
msgid "Overlap Front Cover"
msgstr "Superponer Portada"
#. module: report_qweb_pdf_cover
#: model:ir.model,name:report_qweb_pdf_cover.model_ir_actions_report
msgid "Report Action"
msgstr "Acción de Informe"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__back_cover_pdf
msgid "Upload an PDF file to use as a back cover on this report."
msgstr "Suba un archivo PDF para usar como contraportada en este informe."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__front_cover_pdf
msgid "Upload an PDF file to use as a front cover on this report."
msgstr "Suba un archivo PDF para usar como portada en este informe."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__use_back_cover
msgid "Use Back Cover"
msgstr "Usar Contraportada"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__use_front_cover
msgid "Use Front Cover"
msgstr "Usar Portada"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__use_back_cover
msgid "Use a back cover when rendering the PDF report."
msgstr "Usar una contraportada al renderizar el informe PDF."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__use_front_cover
msgid "Use a front cover when rendering the PDF report."
msgstr "Usar una portada al renderizar el informe PDF."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__back_cover_overlap
msgid ""
"When set, the back cover of the report will overlap with the contents of the"
" last page of the report. This is useful to include some information of the"
" report in the back cover."
msgstr ""
"Cuando se establece, la contraportada del informe se superpondrá con el "
"contenido de la última página del informe. Esto es útil para incluir alguna "
"información del informe en la contraportada."
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__front_cover_overlap
msgid ""
"When set, the front cover of the report will overlap with the contents of "
"the first page of the report. This is useful to include some information of "
"the report in the front cover."
msgstr ""
"Cuando se establece, la portada del informe se superpondrá con el contenido "
"de la primera página del informe. Esto es útil para incluir alguna "
"información del informe en la portada."
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid ""
"Your back cover PDF contains more than one page, all but the first one will "
"be ignored."
msgstr ""
"Su contraportada PDF contiene más de una página, todas menos la primera se "
"ignorarán."
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Your back cover PDF does not contain any pages."
msgstr "Su contraportada PDF no contiene ninguna página."
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid ""
"Your front cover PDF contains more than one page, all but the first one will"
" be ignored."
msgstr ""
"Su portada PDF contiene más de una página, todas menos la primera se "
"ignorarán."
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Your front cover PDF does not contain any pages."
msgstr "Su portada PDF no contiene ninguna página"

View File

@@ -0,0 +1,147 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * report_qweb_pdf_cover
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 08:08+0000\n"
"PO-Revision-Date: 2024-08-27 08:08+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__back_cover_pdf
msgid "Back Cover PDF"
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Failed to load back cover: %s"
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Failed to load front cover: %s"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__front_cover_pdf
msgid "Front Cover PDF"
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "No usable back cover found."
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "No usable front cover found."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__back_cover_overlap
msgid "Overlap Back Cover"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__front_cover_overlap
msgid "Overlap Front Cover"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model,name:report_qweb_pdf_cover.model_ir_actions_report
msgid "Report Action"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__back_cover_pdf
msgid "Upload an PDF file to use as a back cover on this report."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__front_cover_pdf
msgid "Upload an PDF file to use as a front cover on this report."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__use_back_cover
msgid "Use Back Cover"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,field_description:report_qweb_pdf_cover.field_ir_actions_report__use_front_cover
msgid "Use Front Cover"
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__use_back_cover
msgid "Use a back cover when rendering the PDF report."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__use_front_cover
msgid "Use a front cover when rendering the PDF report."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__back_cover_overlap
msgid ""
"When set, the back cover of the report will overlap with the contents of the"
" last page of the report. This is useful to include some information of the"
" report in the back cover."
msgstr ""
#. module: report_qweb_pdf_cover
#: model:ir.model.fields,help:report_qweb_pdf_cover.field_ir_actions_report__front_cover_overlap
msgid ""
"When set, the front cover of the report will overlap with the contents of "
"the first page of the report. This is useful to include some information of "
"the report in the front cover."
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid ""
"Your back cover PDF contains more than one page, all but the first one will "
"be ignored."
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Your back cover PDF does not contain any pages."
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid ""
"Your front cover PDF contains more than one page, all but the first one will"
" be ignored."
msgstr ""
#. module: report_qweb_pdf_cover
#. odoo-python
#: code:addons/report_qweb_pdf_cover/models/ir_actions_report.py:0
#, python-format
msgid "Your front cover PDF does not contain any pages."
msgstr ""

View File

@@ -0,0 +1,4 @@
# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com)
# Part of ForgeFlow. See LICENSE file for full copyright and licensing details.
from . import ir_actions_report

View File

@@ -0,0 +1,216 @@
# Copyright 2024 ForgeFlow S.L. (https://www.forgeflow.com)
# Part of ForgeFlow. See LICENSE file for full copyright and licensing details.
from base64 import b64decode
from io import BytesIO
from logging import getLogger
from PyPDF2 import PdfFileReader, PdfFileWriter
from odoo import _, api, fields, models
logger = getLogger(__name__)
class Report(models.Model):
_inherit = "ir.actions.report"
use_front_cover = fields.Boolean(
default=False, help="Use a front cover when rendering the PDF report."
)
use_back_cover = fields.Boolean(
default=False, help="Use a back cover when rendering the PDF report."
)
front_cover_overlap = fields.Boolean(
default=False,
string="Overlap Front Cover",
help="When set, the front cover of the report will overlap with the "
"contents of the first page of the report. This is useful to include "
"some information of the report in the front cover.",
)
back_cover_overlap = fields.Boolean(
default=False,
string="Overlap Back Cover",
help="When set, the back cover of the report will overlap with the "
"contents of the last page of the report. This is useful to include "
"some information of the report in the back cover.",
)
front_cover_pdf = fields.Binary(
string="Front Cover PDF",
help="Upload an PDF file to use as a front cover on this report.",
)
back_cover_pdf = fields.Binary(
string="Back Cover PDF",
help="Upload an PDF file to use as a back cover on this report.",
)
@api.model
def pdf_check_pages(self, num_pages, front=True):
if num_pages < 1:
if front:
logger.error(_("Your front cover PDF does not contain any pages."))
else:
logger.error(_("Your back cover PDF does not contain any pages."))
return False
elif num_pages > 1:
if front:
logger.info(
_(
"Your front cover PDF contains more than one page, "
"all but the first one will be ignored."
)
)
else:
logger.info(
_(
"Your back cover PDF contains more than one page, "
"all but the first one will be ignored."
)
)
return True
def load_covers(
self, report_sudo, front_cover, back_cover, use_front_cover, use_back_cover
):
if use_front_cover:
front_cover_pdf = self.front_cover_pdf or report_sudo.front_cover_pdf
if front_cover_pdf:
front_cover = b64decode(front_cover_pdf)
if use_back_cover:
back_cover_pdf = self.back_cover_pdf or report_sudo.back_cover_pdf
if back_cover_pdf:
back_cover = b64decode(back_cover_pdf)
return front_cover, back_cover
@api.model
def load_cover_pdfs(self, front_cover, back_cover, use_front_cover, use_back_cover):
pdf_front_cover = False
pdf_back_cover = False
if use_front_cover:
try:
pdf_front_cover = PdfFileReader(BytesIO(front_cover))
if not pdf_front_cover:
use_front_cover = False
logger.error(_("No usable front cover found."))
except Exception as e:
use_front_cover = False
logger.exception(_("Failed to load front cover: %s", e))
if use_back_cover:
try:
pdf_back_cover = PdfFileReader(BytesIO(back_cover))
if not pdf_back_cover:
use_back_cover = False
logger.error(_("No usable back cover found."))
except Exception as e:
use_back_cover = False
logger.exception(_("Failed to load back cover: %s", e))
return use_front_cover, pdf_front_cover, use_back_cover, pdf_back_cover
@api.model
def insert_cover_pages(
self,
pdf,
pages,
pdf_front_cover,
pdf_back_cover,
use_front_cover,
use_back_cover,
front_cover_overlap,
back_cover_overlap,
):
for index, page in enumerate(pages):
report_page = pdf.addBlankPage(
page.mediaBox.getWidth(), page.mediaBox.getHeight()
)
if index == 0 and use_front_cover:
if not front_cover_overlap:
front_cover_page = report_page
front_cover_page.mergePage(pdf_front_cover.getPage(0))
report_page = pdf.addBlankPage(
page.mediaBox.getWidth(), page.mediaBox.getHeight()
)
else:
report_page.mergePage(pdf_front_cover.getPage(0))
if index == len(pages) - 1 and use_back_cover:
if not back_cover_overlap:
back_cover_page = pdf.addBlankPage(
page.mediaBox.getWidth(), page.mediaBox.getHeight()
)
back_cover_page.mergePage(pdf_back_cover.getPage(0))
else:
report_page.mergePage(pdf_back_cover.getPage(0))
report_page.mergePage(page)
@api.model
def _run_wkhtmltopdf(
self,
bodies,
report_ref=False,
header=None,
footer=None,
landscape=False,
specific_paperformat_args=None,
set_viewport_size=False,
):
result = super()._run_wkhtmltopdf(
bodies,
report_ref=report_ref,
header=header,
footer=footer,
landscape=landscape,
specific_paperformat_args=specific_paperformat_args,
set_viewport_size=set_viewport_size,
)
report_sudo = self._get_report(report_ref)
front_cover = False
back_cover = False
use_front_cover = self.use_front_cover or report_sudo.use_front_cover
use_back_cover = self.use_back_cover or report_sudo.use_back_cover
front_cover_overlap = (
self.front_cover_overlap or report_sudo.front_cover_overlap
)
back_cover_overlap = self.back_cover_overlap or report_sudo.back_cover_overlap
if not use_front_cover and not use_back_cover:
return result
front_cover, back_cover = self.load_covers(
report_sudo, front_cover, back_cover, use_front_cover, use_back_cover
)
if not front_cover and not back_cover:
return result
pdf = PdfFileWriter()
(
use_front_cover,
pdf_front_cover,
use_back_cover,
pdf_back_cover,
) = self.load_cover_pdfs(
front_cover, back_cover, use_front_cover, use_back_cover
)
if use_front_cover and not self.pdf_check_pages(
pdf_front_cover.numPages, front=True
):
use_front_cover = False
if use_back_cover and not self.pdf_check_pages(
pdf_back_cover.numPages, front=False
):
use_back_cover = False
pages = PdfFileReader(BytesIO(result)).pages
self.insert_cover_pages(
pdf,
pages,
pdf_front_cover,
pdf_back_cover,
use_front_cover,
use_back_cover,
front_cover_overlap,
back_cover_overlap,
)
pdf_content = BytesIO()
pdf.write(pdf_content)
return pdf_content.getvalue()

View File

@@ -0,0 +1 @@
* Laura Cazorla <laura.cazorla@forgeflow.com>

View File

@@ -0,0 +1,5 @@
This module allows for front and back covers to be added to the generated PDF
reports. They can be added as a separate page, at the beginning or the end of
the report, but they can also overlap the first and last page of the actual
report, respectively.

View File

@@ -0,0 +1,18 @@
To add a cover to a report, you need to access to the report's configuration,
more specifically to the `Advanced Properties` tab. There, you will find two
checkboxes, one for the front cover and another for the back cover.
They both work the same, so let's focus on the front cover with an example.
* You must check the `Use Front Cover` checkbox to enable the front cover. You
will see that a new checkbox and a PDF file widget appear.
* If you want the front cover to overlap with the first page of the PDF report,
you should also check the `Overlap Front Cover` checkbox. Leave it unchecked
if you don't want the front cover to overlap with the first page.
* The last step would be to upload the PDF file that will be used as the front
cover. You can do this by clicking on the PDF file widget and selecting the
file.
* Important! The file must be a PDF file, and it should have only one page. If
it has more pages, only the first one will be used.

View File

@@ -0,0 +1,443 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Report QWeb PDF Cover</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="report-qweb-pdf-cover">
<h1 class="title">Report QWeb PDF Cover</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1287ee62d703ed048f33bb706f289cf01e5c99bead22b8b612d69e88071a4d67
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/reporting-engine/tree/16.0/report_qweb_pdf_cover"><img alt="OCA/reporting-engine" src="https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-report_qweb_pdf_cover"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows for front and back covers to be added to the generated PDF
reports. They can be added as a separate page, at the beginning or the end of
the report, but they can also overlap the first and last page of the actual
report, respectively.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>To add a cover to a report, you need to access to the reports configuration,
more specifically to the <cite>Advanced Properties</cite> tab. There, you will find two
checkboxes, one for the front cover and another for the back cover.
They both work the same, so lets focus on the front cover with an example.</p>
<ul class="simple">
<li>You must check the <cite>Use Front Cover</cite> checkbox to enable the front cover. You
will see that a new checkbox and a PDF file widget appear.</li>
<li>If you want the front cover to overlap with the first page of the PDF report,
you should also check the <cite>Overlap Front Cover</cite> checkbox. Leave it unchecked
if you dont want the front cover to overlap with the first page.</li>
<li>The last step would be to upload the PDF file that will be used as the front
cover. You can do this by clicking on the PDF file widget and selecting the
file.</li>
<li>Important! The file must be a PDF file, and it should have only one page. If
it has more pages, only the first one will be used.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/reporting-engine/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_qweb_pdf_cover%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>ForgeFlow</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Laura Cazorla &lt;<a class="reference external" href="mailto:laura.cazorla&#64;forgeflow.com">laura.cazorla&#64;forgeflow.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/16.0/report_qweb_pdf_cover">OCA/reporting-engine</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="act_report_xml_view" model="ir.ui.view">
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_view" />
<field name="arch" type="xml">
<field name="attachment" position="after">
<field
name="use_front_cover"
attrs="{'invisible': [('report_type', '!=', 'qweb-pdf')]}"
/>
<field
name="front_cover_overlap"
attrs="{'invisible': ['|', ('report_type', '!=', 'qweb-pdf'),('use_front_cover', '=', False)]}"
/>
<field
name="front_cover_pdf"
attrs="{'invisible': ['|', ('report_type', '!=', 'qweb-pdf'),('use_front_cover', '=', False)]}"
widget="pdf_viewer"
/>
<field
name="use_back_cover"
attrs="{'invisible': [('report_type', '!=', 'qweb-pdf')]}"
/>
<field
name="back_cover_overlap"
attrs="{'invisible': ['|', ('report_type', '!=', 'qweb-pdf'),('use_back_cover', '=', False)]}"
/>
<field
name="back_cover_pdf"
attrs="{'invisible': ['|', ('report_type', '!=', 'qweb-pdf'),('use_back_cover', '=', False)]}"
widget="pdf_viewer"
/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
../../../../report_qweb_pdf_cover

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)