Browse Source

[MIG] report_qweb_signer: Migration to 10.0

pull/145/head
Pedro M. Baeza 8 years ago
parent
commit
6340188703
  1. 26
      report_qweb_signer/README.rst
  2. 1
      report_qweb_signer/__init__.py
  3. 14
      report_qweb_signer/__manifest__.py
  4. 21
      report_qweb_signer/demo/report_certificate.xml
  5. 20
      report_qweb_signer/demo/report_certificate_demo.xml
  6. 46
      report_qweb_signer/demo/report_partner.xml
  7. 45
      report_qweb_signer/demo/report_partner_demo.xml
  8. 4
      report_qweb_signer/i18n/es.po
  9. 140
      report_qweb_signer/models/report.py
  10. 2
      report_qweb_signer/models/report_certificate.py
  11. 2
      report_qweb_signer/models/res_company.py
  12. 4
      report_qweb_signer/tests/__init__.py
  13. 27
      report_qweb_signer/tests/test_report_qweb_signer.py
  14. 9
      report_qweb_signer/views/report_certificate_view.xml
  15. 40
      report_qweb_signer/views/res_company_view.xml

26
report_qweb_signer/README.rst

@ -50,17 +50,15 @@ but signed PDF is automatically downloaded if this document model is configured
as indicated above. as indicated above.
If 'Save as attachment' is configured, signed PDF is saved as attachment and If 'Save as attachment' is configured, signed PDF is saved as attachment and
next time saved one is downloaded without signing again. This is appropiate when
signing date is important, for example, when signing customer invoices.
next time saved one is downloaded without signing again. This is appropiate
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".
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/143/8.0
For further information, please visit:
* https://www.odoo.com/forum/help-1
:target: https://runbot.odoo-community.org/runbot/143/10.0
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@ -69,6 +67,7 @@ Known issues / Roadmap
then 'Save as attachment' is not applied and signed result is not then 'Save as attachment' is not applied and signed result is not
saved as attachment. saved as attachment.
* To have a visible signature through an image embedded in the resulting PDF. * To have a visible signature through an image embedded in the resulting PDF.
* Add tests.
Bug Tracker Bug Tracker
@ -76,8 +75,8 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_. 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. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_qweb_signer%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
If you spotted it first, help us smashing it by providing a detailed and
welcomed feedback `here <https://github.com/OCA/reporting-engine/issues/new>`_.
Credits Credits
@ -98,8 +97,9 @@ Icon
Contributors Contributors
------------ ------------
* Rafael Blasco <rafabn@antiun.com>
* Antonio Espinosa <antonioea@antiun.com>
* Rafael Blasco <rafael.blasco@tecnativa.com>
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
Maintainer Maintainer
---------- ----------
@ -114,4 +114,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
To contribute to this module, please visit https://odoo-community.org.

1
report_qweb_signer/__init__.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# 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).
from . import models from . import models

14
report_qweb_signer/__openerp__.py → report_qweb_signer/__manifest__.py

@ -1,17 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# Copyright 2015 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Pedro M. Baeza
# 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": "Qweb PDF reports signer", "name": "Qweb PDF reports signer",
"summary": "Sign Qweb PDFs usign a PKCS#12 certificate", "summary": "Sign Qweb PDFs usign a PKCS#12 certificate",
"version": "8.0.1.0.0",
"version": "10.0.1.0.0",
"category": "Reporting", "category": "Reporting",
"website": "http://www.antiun.com",
"author": "Antiun Ingeniería S.L., "
"website": "https://www.tecnativa.com",
"author": "Tecnativa, "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
"license": "AGPL-3", "license": "AGPL-3",
"application": False,
"installable": True, "installable": True,
"depends": [ "depends": [
"report", "report",
@ -25,7 +25,7 @@
"views/res_company_view.xml", "views/res_company_view.xml",
], ],
"demo": [ "demo": [
"demo/report_partner.xml",
"demo/report_certificate.xml",
"demo/report_partner_demo.xml",
"demo/report_certificate_demo.xml",
], ],
} }

21
report_qweb_signer/demo/report_certificate.xml

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp>
<data noupdate="1">
<record id="demo_certificate_test" model="report.certificate">
<field name="company_id" ref="base.main_company"/>
<field name="name">Test OCA certificate</field>
<field name="path">test.p12</field>
<field name="password_file">test.passwd</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain">[('customer', '=', True)]</field>
<field name="allow_only_one" eval="True"/>
<field name="attachment">'test_' + (object.name or '').replace(' ', '_').lower() + '.signed.pdf'</field>
</record>
</data>
</openerp>

20
report_qweb_signer/demo/report_certificate_demo.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Tecnativa - Antonio Espinosa
Copyright 2017 Tecnativa - Pedro M. Baeza
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<odoo noupdate="1">
<record id="demo_certificate_test" model="report.certificate">
<field name="company_id" ref="base.main_company"/>
<field name="name">Test OCA certificate</field>
<field name="path">test.p12</field>
<field name="password_file">test.passwd</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain">[('customer', '=', True)]</field>
<field name="allow_only_one" eval="True"/>
<field name="attachment">'test_' + (object.name or '').replace(' ', '_').lower() + '.signed.pdf'</field>
</record>
</odoo>

46
report_qweb_signer/demo/report_partner.xml

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp>
<data>
<template id="report_partner_demo_document">
<t t-call="report.external_layout">
<div class="page">
<div class="row">
<div class="col-md-12">
This is a sample report for testing PDF certificates
</div>
</div>
<div class="row">
<div class="col-md-12">
<strong>Partner:</strong> <span t-field="o.name"/>
</div>
</div>
</div>
</t>
</template>
<template id="report_partner_demo">
<t t-call="report.html_container">
<t t-foreach="doc_ids" t-as="doc_id">
<t t-raw="translate_doc(doc_id, doc_model, 'lang', 'report_qweb_signer.report_partner_demo_document')"/>
</t>
</t>
</template>
<report
id="partner_demo"
model="res.partner"
string="Test PDF certificate"
report_type="qweb-pdf"
name="report_qweb_signer.report_partner_demo"
file="report_qweb_signer.report_partner_demo"
attachment_use="True"
attachment="'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf'"
/>
</data>
</openerp>

45
report_qweb_signer/demo/report_partner_demo.xml

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Tecnativa - Antonio Espinosa
Copyright 2017 Tecnativa - Pedro M. Baeza
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<odoo>
<template id="report_partner_demo_document">
<t t-call="report.external_layout">
<div class="page">
<div class="row">
<div class="col-md-12">
<span>This is a sample report for testing PDF certificates.</span>
</div>
</div>
<div class="row">
<div class="col-md-12">
<strong>Partner:</strong> <span t-field="o.name"/>
</div>
</div>
</div>
</t>
</template>
<template id="report_partner_demo">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="report_qweb_signer.report_partner_demo_document" t-lang="o.lang"/>
</t>
</t>
</template>
<report
id="partner_demo_report"
model="res.partner"
string="Test PDF certificate"
report_type="qweb-pdf"
name="report_qweb_signer.report_partner_demo"
file="report_qweb_signer.report_partner_demo"
attachment_use="True"
attachment="'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf'"
/>
</odoo>

4
report_qweb_signer/i18n/es.po

@ -168,9 +168,9 @@ msgstr "Salvar como adjunto"
#: code:addons/report_qweb_signer/models/report.py:119 #: code:addons/report_qweb_signer/models/report.py:119
#, python-format #, python-format
msgid "" msgid ""
"Saving signed report (PDF): You do not have enought access rights to save "
"Saving signed report (PDF): You do not have enough access rights to save "
"attachments" "attachments"
msgstr "Guardar informe firmado (PDF): no tienes suficientes permisos de acceso para guardar adjuntos"
msgstr "Guardar informe firmado (PDF): no tiene suficientes permisos de acceso para guardar adjuntos"
#. module: report_qweb_signer #. module: report_qweb_signer
#: field:report.certificate,sequence:0 #: field:report.certificate,sequence:0

140
report_qweb_signer/models/report.py

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# Copyright 2015 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Pedro M. Baeza
# 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 base64 import base64
@ -9,9 +10,9 @@ import subprocess
import tempfile import tempfile
import time import time
from openerp import models, api, _
from openerp.exceptions import Warning, AccessError
from openerp.tools.safe_eval import safe_eval
from odoo import models, api, _
from odoo.exceptions import UserError, AccessError
from odoo.tools.safe_eval import safe_eval
import logging import logging
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -30,99 +31,80 @@ def _normalize_filepath(path):
class Report(models.Model): class Report(models.Model):
_inherit = 'report' _inherit = 'report'
def _certificate_get(self, cr, uid, ids, report, context=None):
def _certificate_get(self, report, docids):
"""Obtain the proper certificate for the report and the conditions."""
if report.report_type != 'qweb-pdf': if report.report_type != 'qweb-pdf':
_logger.info(
"Can only sign qweb-pdf reports, this one is '%s' type",
report.report_type)
return False return False
m_cert = self.pool['report.certificate']
company_id = self.pool['res.users']._get_company(cr, uid)
certificate_ids = m_cert.search(cr, uid, [
('company_id', '=', company_id),
('model_id', '=', report.model)], context=context)
if not certificate_ids:
_logger.info(
"No PDF certificate found for report '%s'",
report.report_name)
certificates = self.env['report.certificate'].search([
('company_id', '=', self.env.user.company_id.id),
('model_id', '=', report.model),
])
if not certificates:
return False return False
for cert in m_cert.browse(cr, uid, certificate_ids, context=context):
for cert in certificates:
# Check allow only one document # Check allow only one document
if cert.allow_only_one and len(ids) > 1:
_logger.info(
if cert.allow_only_one and len(self) > 1:
_logger.debug(
"Certificate '%s' allows only one document, " "Certificate '%s' allows only one document, "
"but printing %d documents", "but printing %d documents",
cert.name, len(ids))
cert.name, len(docids))
continue continue
# Check domain # Check domain
if cert.domain: if cert.domain:
m_model = self.pool[cert.model_id.model]
domain = [('id', 'in', tuple(ids))]
domain = [('id', 'in', tuple(docids))]
domain = domain + safe_eval(cert.domain) domain = domain + safe_eval(cert.domain)
doc_ids = m_model.search(cr, uid, domain, context=context)
if not doc_ids:
_logger.info(
docs = self.env[cert.model_id.model].search(domain)
if not docs:
_logger.debug(
"Certificate '%s' domain not satisfied", cert.name) "Certificate '%s' domain not satisfied", cert.name)
continue continue
# Certificate match! # Certificate match!
return cert return cert
return False return False
def _attach_filename_get(self, cr, uid, ids, certificate, context=None):
if len(ids) != 1:
def _attach_filename_get(self, docids, certificate):
if len(docids) != 1:
return False return False
obj = self.pool[certificate.model_id.model].browse(cr, uid, ids[0])
filename = safe_eval(certificate.attachment, {
'object': obj,
doc = self.env[certificate.model_id.model].browse(docids[0])
return safe_eval(certificate.attachment, {
'object': doc,
'time': time 'time': time
}) })
return filename
def _attach_signed_read(self, cr, uid, ids, certificate, context=None):
if len(ids) != 1:
def _attach_signed_read(self, docids, certificate):
if len(docids) != 1:
return False return False
filename = self._attach_filename_get(
cr, uid, ids, certificate, context=context)
filename = self._attach_filename_get(docids, certificate)
if not filename: if not filename:
return False return False
signed = False
m_attachment = self.pool['ir.attachment']
attach_ids = m_attachment.search(cr, uid, [
attachment = self.env['ir.attachment'].search([
('datas_fname', '=', filename), ('datas_fname', '=', filename),
('res_model', '=', certificate.model_id.model), ('res_model', '=', certificate.model_id.model),
('res_id', '=', ids[0])
])
if attach_ids:
signed = m_attachment.browse(cr, uid, attach_ids[0]).datas
signed = base64.decodestring(signed)
return signed
('res_id', '=', docids[0]),
], limit=1)
if attachment:
return base64.decodestring(attachment.datas)
return False
def _attach_signed_write(self, cr, uid, ids, certificate, signed,
context=None):
if len(ids) != 1:
def _attach_signed_write(self, docids, certificate, signed):
if len(docids) != 1:
return False return False
filename = self._attach_filename_get(
cr, uid, ids, certificate, context=context)
filename = self._attach_filename_get(docids, certificate)
if not filename: if not filename:
return False return False
m_attachment = self.pool['ir.attachment']
try: try:
attach_id = m_attachment.create(cr, uid, {
attachment = self.env['ir.attachment'].create({
'name': filename, 'name': filename,
'datas': base64.encodestring(signed), 'datas': base64.encodestring(signed),
'datas_fname': filename, 'datas_fname': filename,
'res_model': certificate.model_id.model, 'res_model': certificate.model_id.model,
'res_id': ids[0],
'res_id': docids[0],
}) })
except AccessError: except AccessError:
raise Warning(
raise UserError(
_('Saving signed report (PDF): ' _('Saving signed report (PDF): '
'You do not have enought access rights to save attachments'))
else:
_logger.info(
"The signed PDF document '%s' is now saved in the database",
filename)
return attach_id
'You do not have enough access rights to save attachments'))
return attachment
def _signer_bin(self, opts): def _signer_bin(self, opts):
me = os.path.dirname(__file__) me = os.path.dirname(__file__)
@ -135,7 +117,7 @@ class Report(models.Model):
p12 = _normalize_filepath(certificate.path) p12 = _normalize_filepath(certificate.path)
passwd = _normalize_filepath(certificate.password_file) passwd = _normalize_filepath(certificate.password_file)
if not (p12 and passwd): if not (p12 and passwd):
raise Warning(
raise UserError(
_('Signing report (PDF): ' _('Signing report (PDF): '
'Certificate or password file not found')) 'Certificate or password file not found'))
signer_opts = '"%s" "%s" "%s" "%s"' % (p12, pdf, pdfsigned, passwd) signer_opts = '"%s" "%s" "%s" "%s"' % (p12, pdf, pdfsigned, passwd)
@ -144,38 +126,37 @@ class Report(models.Model):
signer, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) signer, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out, err = process.communicate() out, err = process.communicate()
if process.returncode: if process.returncode:
raise Warning(
raise UserError(
_('Signing report (PDF): jPdfSign failed (error code: %s). ' _('Signing report (PDF): jPdfSign failed (error code: %s). '
'Message: %s. Output: %s') % 'Message: %s. Output: %s') %
(process.returncode, err, out)) (process.returncode, err, out))
return pdfsigned return pdfsigned
@api.v7
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None,
context=None):
signed_content = False
report = self._get_report_from_name(cr, uid, report_name)
certificate = self._certificate_get(
cr, uid, ids, report, context=context)
@api.model
def get_pdf(self, docids, report_name, html=None, data=None):
report = self._get_report_from_name(report_name)
certificate = self._certificate_get(report, docids)
if certificate and certificate.attachment: if certificate and certificate.attachment:
signed_content = self._attach_signed_read(
cr, uid, ids, certificate, context=context)
signed_content = self._attach_signed_read(docids, certificate)
if signed_content: if signed_content:
_logger.info("The signed PDF document '%s/%s' was loaded from "
"the database", report_name, ids)
_logger.debug(
"The signed PDF document '%s/%s' was loaded from the "
"database", report_name, docids,
)
return signed_content return signed_content
content = super(Report, self).get_pdf( content = super(Report, self).get_pdf(
cr, uid, ids, report_name, html=html, data=data,
context=context)
docids, report_name, html=html, data=data,
)
if certificate: if certificate:
# Creating temporary origin PDF # Creating temporary origin PDF
pdf_fd, pdf = tempfile.mkstemp( pdf_fd, pdf = tempfile.mkstemp(
suffix='.pdf', prefix='report.tmp.') suffix='.pdf', prefix='report.tmp.')
with closing(os.fdopen(pdf_fd, 'w')) as pf: with closing(os.fdopen(pdf_fd, 'w')) as pf:
pf.write(content) pf.write(content)
_logger.info(
"Signing PDF document '%s/%s' with certificate '%s'",
report_name, ids, certificate.name)
_logger.debug(
"Signing PDF document '%s' for IDs %s with certificate '%s'",
report_name, docids, certificate.name,
)
signed = self.pdf_sign(pdf, certificate) signed = self.pdf_sign(pdf, certificate)
# Read signed PDF # Read signed PDF
if os.path.exists(signed): if os.path.exists(signed):
@ -188,6 +169,5 @@ class Report(models.Model):
except (OSError, IOError): except (OSError, IOError):
_logger.error('Error when trying to remove file %s', fname) _logger.error('Error when trying to remove file %s', fname)
if certificate.attachment: if certificate.attachment:
self._attach_signed_write(
cr, uid, ids, certificate, content, context=context)
self._attach_signed_write(docids, certificate, content)
return content return content

2
report_qweb_signer/models/report_certificate.py

@ -2,7 +2,7 @@
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa # © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# 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).
from openerp import api, fields, models
from odoo import api, fields, models
class ReportCertificate(models.Model): class ReportCertificate(models.Model):

2
report_qweb_signer/models/res_company.py

@ -2,7 +2,7 @@
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa # © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# 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).
from openerp import models, fields
from odoo import models, fields
class ResCompany(models.Model): class ResCompany(models.Model):

4
report_qweb_signer/tests/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_report_qweb_signer

27
report_qweb_signer/tests/test_report_qweb_signer.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests import common
@common.at_install(False)
@common.post_install(True)
class TestReportQwebSigner(common.SavepointCase):
@classmethod
def setUpClass(cls):
super(TestReportQwebSigner, cls).setUpClass()
cls.partner = cls.env['res.partner'].create({
'name': 'Test partner',
'customer': True,
})
cls.report = cls.env.ref('report_qweb_signer.partner_demo_report')
def test_report_qweb_signer(self):
self.env['report'].get_pdf(
self.partner.ids, self.report.report_name, data={},
)
# Reprint again for taking the PDF from attachment
self.env['report'].get_pdf(
self.partner.ids, self.report.report_name, data={},
)

9
report_qweb_signer/views/report_certificate_view.xml

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
© 2015 Antiun Ingenieria S.L. - Antonio Espinosa
Copyright 2015 Tecnativa - Antonio Espinosa
Copyright 2017 Tecnativa - Pedro M. Baeza
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).
--> -->
<openerp>
<data>
<odoo>
<record id="view_report_certificate_form" model="ir.ui.view"> <record id="view_report_certificate_form" model="ir.ui.view">
<field name="name">report.certificate.form</field> <field name="name">report.certificate.form</field>
@ -62,5 +62,4 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
parent="report.reporting_menuitem" parent="report.reporting_menuitem"
action="action_report_certificate"/> action="action_report_certificate"/>
</data>
</openerp>
</odoo>

40
report_qweb_signer/views/res_company_view.xml

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
© 2015 Antiun Ingenieria S.L. - Antonio Espinosa
Copyright 2015 Tecnativa - Antonio Espinosa
Copyright 2017 Tecnativa - Pedro M. Baeza
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).
--> -->
<openerp>
<data>
<odoo>
<record id="view_company_form" model="ir.ui.view">
<field name="name">Add PDF report certificates list</field>
<field name="inherit_id" ref="base.view_company_form" />
<field name="model">res.company</field>
<field name="arch" type="xml">
<data>
<xpath expr="//page[@string='Report Configuration']/group[@string='Configuration']" position="after">
<group string="Certificates" col="2">
<field name="report_certificate_ids"
context="{'default_company_id': active_id}"/>
</group>
</xpath>
</data>
</field>
</record>
<record id="view_company_form" model="ir.ui.view">
<field name="name">Add PDF report certificates list</field>
<field name="inherit_id" ref="base.view_company_form" />
<field name="model">res.company</field>
<field name="arch" type="xml">
<data>
<notebook position="inside">
<page name="pdf_sign_certificate" string="Certificates (PDF signing)">
<field name="report_certificate_ids"
context="{'default_company_id': active_id}"
/>
</page>
</notebook>
</data>
</field>
</record>
</data>
</openerp>
</odoo>
Loading…
Cancel
Save