diff --git a/.copier-answers.yml b/.copier-answers.yml index e29fc4145..85609caa8 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,7 +1,7 @@ # Do NOT update manually; changes here will be overwritten by Copier _commit: v1.6.1 _src_path: git+https://github.com/OCA/oca-addons-repo-template -ci: Travis +ci: GitHub dependency_installation_mode: PIP generate_requirements_txt: true include_wkhtmltopdf: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..e7364499e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,69 @@ +name: tests + +on: + pull_request: + branches: + - "13.0*" + push: + branches: + - "13.0" + - "13.0-ocabot-*" + +jobs: + unreleased-deps: + runs-on: ubuntu-latest + name: Detect unreleased dependencies + steps: + - uses: actions/checkout@v2 + - run: | + for reqfile in requirements.txt test-requirements.txt ; do + if [ -f ${reqfile} ] ; then + result=0 + # reject non-comment lines that contain a / (i.e. URLs, relative paths) + grep "^[^#].*/" ${reqfile} || result=$? + if [ $result -eq 0 ] ; then + echo "Unreleased dependencies found in ${reqfile}." + exit 1 + fi + fi + done + test: + runs-on: ubuntu-latest + container: ${{ matrix.container }} + name: ${{ matrix.name }} + strategy: + fail-fast: false + matrix: + include: + - container: ghcr.io/oca/oca-ci/py3.6-odoo13.0:latest + makepot: "true" + name: test with Odoo + - container: ghcr.io/oca/oca-ci/py3.6-ocb13.0:latest + name: test with OCB + services: + postgres: + image: postgres:9.6 + env: + POSTGRES_USER: odoo + POSTGRES_PASSWORD: odoo + POSTGRES_DB: odoo + ports: + - 5432:5432 + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + - name: Install addons and dependencies + run: oca_install_addons + - name: Check licenses + run: manifestoo -d . check-licenses + - name: Check development status + run: manifestoo -d . check-dev-status --default-dev-status=Beta + - name: Initialize test db + run: oca_init_test_database + - name: Run tests + run: oca_run_tests + - uses: codecov/codecov-action@v1 + - name: Update .pot files + run: oca_export_and_push_pot https://x-access-token:${{ secrets.GIT_PUSH_TOKEN }}@github.com/${{ github.repository }} + if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'OCA' }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 195fde565..000000000 --- a/.travis.yml +++ /dev/null @@ -1,45 +0,0 @@ -language: python -cache: - directories: - - $HOME/.cache/pip - - $HOME/.cache/pre-commit - -python: - - "3.6" - -addons: - postgresql: "9.6" - apt: - packages: - - expect-dev # provides unbuffer utility - - "swig" - - "libreoffice" - -stages: - - test - -jobs: - include: - - stage: test - env: - - TESTS=1 ODOO_REPO="odoo/odoo" MAKEPOT="1" - - stage: test - env: - - TESTS=1 ODOO_REPO="OCA/OCB" -env: - global: - - VERSION="13.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0" - - WKHTMLTOPDF_VERSION="0.12.5" - - MQT_DEP=PIP - -install: - - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git - ${HOME}/maintainer-quality-tools - - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - - travis_install_nightly - -script: - - travis_run_tests - -after_success: - - travis_after_tests_success diff --git a/README.md b/README.md index 814b4ebec..3884ac8d7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Runboat](https://img.shields.io/badge/runboat-Try%20me-875A7B.png)](https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=13.0) -[![Build Status](https://travis-ci.com/OCA/reporting-engine.svg?branch=13.0)](https://travis-ci.com/OCA/reporting-engine) +[![Pre-commit Status](https://github.com/OCA/reporting-engine/actions/workflows/pre-commit.yml/badge.svg?branch=13.0)](https://github.com/OCA/reporting-engine/actions/workflows/pre-commit.yml?query=branch%3A13.0) +[![Build Status](https://github.com/OCA/reporting-engine/actions/workflows/test.yml/badge.svg?branch=13.0)](https://github.com/OCA/reporting-engine/actions/workflows/test.yml?query=branch%3A13.0) [![codecov](https://codecov.io/gh/OCA/reporting-engine/branch/13.0/graph/badge.svg)](https://codecov.io/gh/OCA/reporting-engine) [![Translation Status](https://translation.odoo-community.org/widgets/reporting-engine-13-0/-/svg-badge.svg)](https://translation.odoo-community.org/engage/reporting-engine-13-0/?utm_source=widget) diff --git a/report_py3o/__manifest__.py b/report_py3o/__manifest__.py index a05fa0ad3..f75641ce0 100644 --- a/report_py3o/__manifest__.py +++ b/report_py3o/__manifest__.py @@ -10,7 +10,10 @@ "author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)", "website": "https://github.com/OCA/reporting-engine", "depends": ["web"], - "external_dependencies": {"python": ["py3o.template", "py3o.formats", "PyPDF2"]}, + "external_dependencies": { + "python": ["py3o.template", "py3o.formats", "PyPDF2"], + "deb": ["libreoffice"], + }, "data": [ "security/ir.model.access.csv", "views/menu.xml", diff --git a/report_py3o_fusion_server/__manifest__.py b/report_py3o_fusion_server/__manifest__.py index a6f3131e6..8cd6fe423 100644 --- a/report_py3o_fusion_server/__manifest__.py +++ b/report_py3o_fusion_server/__manifest__.py @@ -9,7 +9,10 @@ "author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)", "website": "https://github.com/OCA/reporting-engine", "depends": ["report_py3o"], - "external_dependencies": {"python": ["py3o.template", "py3o.formats"]}, + "external_dependencies": { + "python": ["py3o.template", "py3o.formats"], + "deb": ["libreoffice"], + }, "demo": ["demo/report_py3o.xml", "demo/py3o_pdf_options.xml"], "data": [ "views/ir_actions_report.xml", diff --git a/report_qweb_signer/__manifest__.py b/report_qweb_signer/__manifest__.py index 982f0163d..bf732ec0a 100644 --- a/report_qweb_signer/__manifest__.py +++ b/report_qweb_signer/__manifest__.py @@ -13,7 +13,10 @@ "license": "AGPL-3", "installable": True, "depends": ["web_editor"], - "external_dependencies": {"python": ["endesive", "cryptography"]}, + "external_dependencies": { + "python": ["endesive", "cryptography"], + "deb": ["default-jre-headless"], + }, "data": [ "data/defaults.xml", "security/ir.model.access.csv", diff --git a/report_qweb_signer/data/defaults.xml b/report_qweb_signer/data/defaults.xml index 9b0f92af8..959d37593 100644 --- a/report_qweb_signer/data/defaults.xml +++ b/report_qweb_signer/data/defaults.xml @@ -2,6 +2,10 @@ report_qweb_signer.java_parameters - -Xms4M -Xmx4M -XX:CompressedClassSpaceSize=256m + -Xms16M -Xmx16M -XX:CompressedClassSpaceSize=256m + + + report_qweb_signer.java_position_parameters + -llx 400 -lly 820 -urx 600 -ury 100 -fs 8 diff --git a/report_qweb_signer/demo/report_partner_demo.xml b/report_qweb_signer/demo/report_partner_demo.xml index 84bdc71a0..dea7a775d 100644 --- a/report_qweb_signer/demo/report_partner_demo.xml +++ b/report_qweb_signer/demo/report_partner_demo.xml @@ -33,14 +33,16 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + + Test PDF certificate + res.partner + qweb-pdf + report_qweb_signer.report_partner_demo + 'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf' + True + + report + diff --git a/report_qweb_signer/models/ir_actions_report.py b/report_qweb_signer/models/ir_actions_report.py index 4db4237c7..69566b38e 100644 --- a/report_qweb_signer/models/ir_actions_report.py +++ b/report_qweb_signer/models/ir_actions_report.py @@ -39,11 +39,13 @@ class IrActionsReport(models.Model): """Obtain the proper certificate for the report and the conditions.""" if self.report_type != "qweb-pdf": return False + company_id = self.env.company.id + if res_ids: + obj = self.env[self.model].browse(res_ids[0]) + if "company_id" in obj: + company_id = obj.company_id.id or company_id certificates = self.env["report.certificate"].search( - [ - ("company_id", "=", self.env.user.company_id.id), - ("model_id", "=", self.model), - ] + [("company_id", "=", company_id), ("model_id", "=", self.model)] ) if not certificates: return False @@ -122,8 +124,13 @@ class IrActionsReport(models.Model): irc_param = self.env["ir.config_parameter"].sudo() java_bin = "java -jar" java_param = irc_param.get_param("report_qweb_signer.java_parameters") - jar = "{}/../static/jar/jPdfSign.jar".format(me) - return "{} {} {} {}".format(java_bin, java_param, jar, opts) + java_position_param = irc_param.get_param( + "report_qweb_signer.java_position_parameters" + ) + jar = "{}/../static/jar/JSignPdf.jar".format(me) + return "{} {} {} {} {}".format( + java_bin, java_param, jar, opts, java_position_param + ) def _get_endesive_params(self, certificate): date = datetime.datetime.utcnow() - datetime.timedelta(hours=12) @@ -160,7 +167,7 @@ class IrActionsReport(models.Model): return pdfsigned def pdf_sign(self, pdf, certificate): - pdfsigned = pdf + ".signed.pdf" + pdfsigned = pdf[:-4] + "_signed.pdf" p12 = _normalize_filepath(certificate.path) passwd = _normalize_filepath(certificate.password_file) method_used = certificate.signing_method @@ -169,7 +176,10 @@ class IrActionsReport(models.Model): _("Signing report (PDF): " "Certificate or password file not found") ) if method_used == "java": - signer_opts = '"{}" "{}" "{}" "{}"'.format(p12, pdf, pdfsigned, passwd) + passwd_f = open(passwd, "tr") + passwd = passwd_f.read().strip() + passwd_f.close() + signer_opts = ' "{}" -ksf "{}" -ksp "{}" -d "/tmp"'.format(pdf, p12, passwd) signer = self._signer_bin(signer_opts) process = subprocess.Popen( signer, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True @@ -220,7 +230,7 @@ class IrActionsReport(models.Model): for fname in (pdf, signed): try: os.unlink(fname) - except (OSError, IOError): + except OSError: _logger.error("Error when trying to remove file %s", fname) if certificate.attachment: self._attach_signed_write(res_ids, certificate, content) diff --git a/report_qweb_signer/models/report_certificate.py b/report_qweb_signer/models/report_certificate.py index 6159fa176..4a1e62512 100644 --- a/report_qweb_signer/models/report_certificate.py +++ b/report_qweb_signer/models/report_certificate.py @@ -31,6 +31,7 @@ class ReportCertificate(models.Model): required=True, comodel_name="ir.model", help="Model where apply this certificate", + ondelete="cascade", ) domain = fields.Char( string="Domain", help="Domain for filtering if sign or not the document", diff --git a/report_qweb_signer/readme/CONTRIBUTORS.rst b/report_qweb_signer/readme/CONTRIBUTORS.rst index b8f0c6c7e..9b6a265ad 100644 --- a/report_qweb_signer/readme/CONTRIBUTORS.rst +++ b/report_qweb_signer/readme/CONTRIBUTORS.rst @@ -5,3 +5,5 @@ * Pedro M. Baeza * Jairo Llopis * David Vidal +* Santi Argüeso +* Omar Castiñeira diff --git a/report_qweb_signer/readme/CREDITS.rst b/report_qweb_signer/readme/CREDITS.rst index 14593eb9d..49127c54a 100644 --- a/report_qweb_signer/readme/CREDITS.rst +++ b/report_qweb_signer/readme/CREDITS.rst @@ -1,9 +1,7 @@ External utilities ++++++++++++++++++ -* iText v1.4.8: © 2000-2006, Paulo Soares, Bruno Lowagie and others - License `MPL `__ or `LGPL2 `__ - http://sourceforge.net/projects/itext -* jPdfSign: © 2006 Jan Peter Stotz - License `MPL `__ or `LGPL2 `__ (inherited from iText) - http://private.sit.fraunhofer.de/~stotz/software/jpdfsign -* Modified jPdfSign: © 2015 Antonio Espinosa - License `MPL `__ or `LGPL2 `__ (inherited from iText) - static/src/java/JPdfSign.java +* JSignPdf: © Josef Cacek - License `MPL `__ or `LGPL2 `__ - http://jsignpdf.sourceforge.net/ Icon ++++ diff --git a/report_qweb_signer/readme/INSTALL.rst b/report_qweb_signer/readme/INSTALL.rst index fe6dc712b..e6018cf41 100644 --- a/report_qweb_signer/readme/INSTALL.rst +++ b/report_qweb_signer/readme/INSTALL.rst @@ -1,3 +1,3 @@ To install this module, you need to install Java JDK Headlees, e.g.: - apt-get install openjdk-8-jre-headless + apt-get install default-jre-headless diff --git a/report_qweb_signer/readme/ROADMAP.rst b/report_qweb_signer/readme/ROADMAP.rst index db930cb21..f5bc87ca1 100644 --- a/report_qweb_signer/readme/ROADMAP.rst +++ b/report_qweb_signer/readme/ROADMAP.rst @@ -1,5 +1,4 @@ * When signing multiple documents (if 'Allow only one document' is disable) then 'Save as attachment' is not applied and signed result is not saved as attachment. -* To have a visible signature through an image embedded in the resulting PDF. * Add tests. diff --git a/report_qweb_signer/readme/USAGE.rst b/report_qweb_signer/readme/USAGE.rst index 068f66e92..641c84f81 100644 --- a/report_qweb_signer/readme/USAGE.rst +++ b/report_qweb_signer/readme/USAGE.rst @@ -8,3 +8,8 @@ when signing date is important, for example, when signing customer invoices. You can try the signing with the demo report that is included for customers called "Test PDF certificate". + +You can set extra parameters of JSignPdf library in the system parameter +named 'report_qweb_signer.java_position_parameters', for example '-V' to +visible signature into pdf. You can also set extra parameters for Java in the +system parameter named 'report_qweb_signer.java_parameters'. diff --git a/report_qweb_signer/static/jar/JSignPdf.jar b/report_qweb_signer/static/jar/JSignPdf.jar new file mode 100644 index 000000000..27de18c27 Binary files /dev/null and b/report_qweb_signer/static/jar/JSignPdf.jar differ diff --git a/report_qweb_signer/static/jar/itext-1.4.8.jar b/report_qweb_signer/static/jar/itext-1.4.8.jar deleted file mode 100644 index dbbd4280c..000000000 Binary files a/report_qweb_signer/static/jar/itext-1.4.8.jar and /dev/null differ diff --git a/report_qweb_signer/static/jar/jPdfSign.jar b/report_qweb_signer/static/jar/jPdfSign.jar deleted file mode 100644 index 784b11fc6..000000000 Binary files a/report_qweb_signer/static/jar/jPdfSign.jar and /dev/null differ diff --git a/requirements.txt b/requirements.txt index 298ff2a87..66dfb2dcb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ py3o.template py3o.formats genshi>=0.7 cryptography +endesive