Browse Source

[ADD] gdpr_partner_report

pull/8/head
mreficent 7 years ago
committed by Daniel Reis
parent
commit
683729aa4f
  1. 36
      .gitignore
  2. 46
      .travis.yml
  3. 52
      data_protection_base/README.rst
  4. 1
      data_protection_base/__init__.py
  5. 18
      data_protection_base/__openerp__.py
  6. 25
      data_protection_base/security/data_protection.xml
  7. BIN
      data_protection_base/static/description/icon.png
  8. 54
      data_protection_base/views/data_protection_menu_view.xml
  9. 52
      gdpr_base/README.rst
  10. 1
      gdpr_base/__init__.py
  11. 18
      gdpr_base/__openerp__.py
  12. BIN
      gdpr_base/static/description/icon.png
  13. 15
      gdpr_base/views/gdpr_menu_view.xml
  14. 65
      gdpr_partner_report/README.rst
  15. 3
      gdpr_partner_report/__init__.py
  16. 21
      gdpr_partner_report/__openerp__.py
  17. 3
      gdpr_partner_report/report/__init__.py
  18. 26
      gdpr_partner_report/report/gdpr_partner.py
  19. 95
      gdpr_partner_report/report/gdpr_partner_xlsx.py
  20. BIN
      gdpr_partner_report/static/description/icon.png
  21. 16
      gdpr_partner_report/views/gdpr_menu_view.xml
  22. 22
      gdpr_partner_report/views/gdpr_report.xml
  23. 64
      gdpr_partner_report/views/report_partner.xml
  24. 2
      gdpr_partner_report/wizard/__init__.py
  25. 256
      gdpr_partner_report/wizard/gdpr_report_partner.py
  26. 55
      gdpr_partner_report/wizard/gdpr_report_partner_wizard.xml
  27. 15
      oca_dependencies.txt

36
.gitignore

@ -5,6 +5,24 @@ __pycache__/
# C extensions # C extensions
*.so *.so
# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
# Project specific
oca.cfg
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging # Distribution / packaging
.Python .Python
env/ env/
@ -21,6 +39,7 @@ var/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
*.egg *.egg
*.eggs
# Installer logs # Installer logs
pip-log.txt pip-log.txt
@ -36,10 +55,23 @@ coverage.xml
# Translations # Translations
*.mo *.mo
*.pot
# Pycharm # Pycharm
.idea .idea
# Eclipse
.settings
# Visual Studio cache/options directory
.vs/
# OSX Files
.DS_Store
# Django stuff:
*.log
# Mr Developer # Mr Developer
.mr.developer.cfg .mr.developer.cfg
.project .project
@ -55,5 +87,5 @@ docs/_build/
*~ *~
*.swp *.swp
# OSX Files
*.DS_Store
# OCA rules
!static/lib/

46
.travis.yml

@ -3,22 +3,62 @@ sudo: false
cache: pip cache: pip
python: python:
# For branches <= 10.0, put `- "2.7.13"`
- "3.5" - "3.5"
addons: addons:
# By default postgresql-9.1 is installed but there is issue related:
# https://github.com/OCA/maintainer-quality-tools/issues/432#issuecomment-281580935
# Better use higher PostgreSQL version
postgresql: "9.5" postgresql: "9.5"
apt: apt:
# sources:
# Search your sources alias here:
# https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
packages: packages:
- expect-dev # provides unbuffer utility - expect-dev # provides unbuffer utility
# Search your packages here:
# https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise
# For wkhtmltopdf, see the env section below
# Sometimes complicated website repos need Compass & SaSS:
#before_install:
# - rvm install ruby --latest
# - gem install bootstrap-sass
# - gem install compass --pre
env: env:
global: global:
- VERSION="11.0" TESTS="0" LINT_CHECK="0" TRANSIFEX="0"
- VERSION="10.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0"
# Set this variable to some version existing as linux-generic build on
# https://github.com/wkhtmltopdf/wkhtmltopdf/releases
# if you need to install wkhtmltopdf
# - WKHTMLTOPDF_VERSION="0.12.4"
# Set the above to install a `wkhtmltopdf` version that is not the one provided
# by the `pov-wkhtmltopdf` repo.
- PHANTOMJS_VERSION="latest"
# The above line controls the PhantomJS version that is used for JS testing.
# It is not necessary to include this value unless you are altering the default.
# Use `OS` to skip the PhantomJS upgrade & use the system version instead.
- WEBSITE_REPO="1"
# Use the above line to install dependencies that are required for website repos:
# * SASS & Bootstrap-SASS
# * Compass
matrix: matrix:
- LINT_CHECK="1" - LINT_CHECK="1"
- TESTS="1" ODOO_REPO="odoo/odoo"
- TESTS="1" ODOO_REPO="OCA/OCB" MAKEPOT="1"
# use this to install a standalone database to export .pot files
# - MAKEPOT="1"
# add MAKEPOT="1" to a TEST line to export .pot files from
# the test database after test success
- TESTS="1" ODOO_REPO="odoo/odoo" MAKEPOT="1"
- TESTS="1" ODOO_REPO="OCA/OCB"
# either use the two lines above or the two below. Don't change the default if
# it's not necessary (it is only necessary if modules in your repository can't
# be installed in the same database. And you get a huge speed penalty in your
# tests)
# - TESTS="1.0" ODOO_REPO="odoo/odoo" UNIT_TEST="1"
# - TESTS="1.0" ODOO_REPO="OCA/OCB" UNIT_TEST="1"
install: install:
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools

52
data_protection_base/README.rst

@ -0,0 +1,52 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
====================
Data Protection Base
====================
This module provides security and menus for data protection modules.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/263/9.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/data-protection/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Miquel Raïch <miquel.raich@eficent.com>
Do not contact contributors directly about support or help with technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.

1
data_protection_base/__init__.py

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

18
data_protection_base/__openerp__.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
'name': 'Data Protection Base',
'version': '9.0.1.0.0',
'category': '??',
'summary': 'Provides security and menus for data protection modules.',
'author': "Eficent, "
"Odoo Community Association (OCA)",
'website': 'http://www.github.com/Eficent/gdpr,',
'license': 'AGPL-3',
'data': [
'security/data_protection.xml',
'views/data_protection_menu_view.xml',
],
'installable': True,
}

25
data_protection_base/security/data_protection.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data noupdate="0">
<record model="ir.module.category" id="module_category_data_protection">
<field name="name">Data Protection</field>
<field name="sequence">30</field>
</record>
<record id="group_data_protection_user" model="res.groups">
<field name="name">Data Protection User</field>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="category_id" ref="module_category_data_protection"/>
</record>
<record id="group_data_protection_manager" model="res.groups">
<field name="name">Data Protection Manager</field>
<field name="implied_ids" eval="[(4, ref('data_protection_base.group_data_protection_user'))]"/>
<field name="category_id" ref="module_category_data_protection"/>
</record>
</data>
</openerp>

BIN
data_protection_base/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

54
data_protection_base/views/data_protection_menu_view.xml

@ -0,0 +1,54 @@
<?xml version="1.0"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data>
<record id="action_data_protection_partner_form" model="ir.actions.act_window">
<field name="name">Partners</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
<field name="filter" eval="True"/>
</record>
<menuitem id="parent_menu_data_protection"
name="Data Protection"
groups="group_data_protection_user,group_data_protection_manager"
/>
<menuitem id="menu_data_protection_master_data"
name="Master Data"
parent="parent_menu_data_protection"
groups="group_data_protection_user,group_data_protection_manager"
sequence="2"
/>
<menuitem id="menu_data_protection_partner"
name="Partners"
parent="menu_data_protection_master_data"
action="action_data_protection_partner_form"
sequence="10"
/>
<menuitem id="menu_data_protection_transaction"
name="Transactions"
parent="parent_menu_data_protection"
groups="group_data_protection_user,group_data_protection_manager"
sequence="3"
/>
<menuitem id="menu_data_protection_report"
name="Reports"
parent="parent_menu_data_protection"
groups="group_data_protection_user,group_data_protection_manager"
sequence="4"
/>
<menuitem id="menu_data_protection_setting"
name="Settings"
parent="parent_menu_data_protection"
groups="group_data_protection_manager"
sequence="15"
/>
</data>
</openerp>

52
gdpr_base/README.rst

@ -0,0 +1,52 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
=========
GDPR Base
=========
This module provides a shared base for all GDPR modules.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/263/9.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/data-protection/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Miquel Raïch <miquel.raich@eficent.com>
Do not contact contributors directly about support or help with technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.

1
gdpr_base/__init__.py

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

18
gdpr_base/__openerp__.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
'name': 'GDPR Base',
'version': '9.0.1.0.0',
'category': 'GDPR',
'summary': 'Provides a shared base for all GDPR modules.',
'author': "Eficent, "
"Odoo Community Association (OCA)",
'website': 'http://www.github.com/Eficent/gdpr,',
'license': 'AGPL-3',
'depends': ['data_protection_base'],
'data': [
'views/gdpr_menu_view.xml',
],
'installable': True,
}

BIN
gdpr_base/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

15
gdpr_base/views/gdpr_menu_view.xml

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data>
<menuitem id="menu_data_protection_report_gdpr"
name="GDPR"
parent="data_protection_base.menu_data_protection_report"
groups="data_protection_base.group_data_protection_user,data_protection_base.group_data_protection_manager"
sequence="15"
/>
</data>
</openerp>

65
gdpr_partner_report/README.rst

@ -0,0 +1,65 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
===================
GDPR Partner Report
===================
This module helps a company to identify all the transactions that a specific
partner is involved in, with the possibility to export the associated data.
Usage
=====
To use this module, you need to:
#. Go to menu of ``Data Protection > Reports > GDPR > Partner Report``
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/263/9.0
Known issues / Roadmap
======================
* This module works only if https://github.com/odoo/odoo/pull/24964 is merged.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/data-protection/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Miquel Raïch <miquel.raich@eficent.com>
Do not contact contributors directly about support or help with technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.

3
gdpr_partner_report/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import report
from . import wizard

21
gdpr_partner_report/__openerp__.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
'name': 'GDPR Partner Report',
'version': '9.0.1.0.0',
'category': 'GDPR',
'summary': 'Show the transactions that a specific partner is involved in.',
'author': "Eficent, "
"Odoo Community Association (OCA)",
'website': 'http://www.github.com/Eficent/gdpr,',
'license': 'AGPL-3',
'depends': ['gdpr_base', 'report_xlsx'],
'data': [
'wizard/gdpr_report_partner_wizard.xml',
'views/gdpr_report.xml',
'views/gdpr_menu_view.xml',
'views/report_partner.xml',
],
'installable': True,
}

3
gdpr_partner_report/report/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import gdpr_partner
from . import gdpr_partner_xlsx

26
gdpr_partner_report/report/gdpr_partner.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from openerp import api, fields, models
class ReportPartner(models.AbstractModel):
_name = 'report.gdpr.report_partner'
@api.multi
def render_html(self, data):
docs = self.env['gdpr.partner.report'].browse(
self.env.context.get('active_ids', []))
partner = data['form'].get('partner_id', False)
partner = self.env['res.partner'].browse(partner[0])
docargs = {
'doc_ids': self.ids,
'doc_model': 'gdpr.partner.report',
'data': data['form'],
'docs': docs,
'date': fields.date.today(),
'tables': data['tables'],
'partner': partner,
}
return self.env['report'].render(
'gdpr_partner_report.report_partner', values=docargs)

95
gdpr_partner_report/report/gdpr_partner_xlsx.py

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
import logging
from openerp.report import report_sxw
from openerp.tools.translate import _
_logger = logging.getLogger(__name__)
try:
from openerp.addons.report_xlsx.report.report_xlsx import ReportXlsx
except ImportError:
_logger.debug("report_xlsx not installed, Excel export non functional")
class ReportXlsx(object):
def __init__(self, *args, **kwargs):
pass
class ReportPartnerXlsx(ReportXlsx):
def _search_longest_row(self, tables):
res = 0
for table in tables:
for model in tables[table]:
if len(tables[table][model]) > 0:
if len(tables[table][model][0]) > res:
res = len(tables[table][model][0])
return res
def generate_xlsx_report(self, workbook, data, objects):
partner = data['form'].get('partner_id', False)
partner = self.env['res.partner'].browse(partner[0])
workbook.set_properties({
'comments': 'Created with Python and XlsxWriter from Odoo 9.0'})
sheet = workbook.add_worksheet(_('Partner Data'))
sheet.set_landscape()
sheet.fit_to_pages(1, 0)
sheet.set_zoom(75)
sheet.set_column(0, self._search_longest_row(data['tables']), 25)
title_style = workbook.add_format(
{'bold': True, 'bg_color': '#FFFFCC', 'border': 2})
sheet.set_row(0, None, None, {'collapsed': 1})
sheet.write_row(1, 0, ["Partner: " + partner.display_name],
title_style)
i = 3
first_row = i+2
for table in sorted(data['tables'].keys()):
for model in sorted(data['tables'][table].keys()):
rows = len(data['tables'][table][model])
if rows:
style = workbook.add_format()
style.set_bold(True)
style.set_border(2)
sheet.write_row(i, 0, [model], style)
sheet.write_row(i, 1, [table], style)
i += 1
j = 0
for column in data['tables'][table][model][0]:
style = workbook.add_format()
style.set_bold(True)
if j == 0:
style.set_left(1)
if j == len(data['tables'][table][model][0]) - 1:
style.set_right(1)
style.set_top(1)
style.set_bottom(1)
sheet.write_row(i, j, [column], style)
j += 1
for row in data['tables'][table][model]:
i += 1
j = 0
for column in row:
style = workbook.add_format()
if j == 0:
style.set_left(1)
if j == len(row) - 1:
style.set_right(1)
if i == rows + first_row - 1:
style.set_bottom(1)
if row[column]:
sheet.write_row(i, j, [row[column]], style)
else:
sheet.write_row(i, j, [''], style)
j += 1
i += 2
first_row = i+2
ReportPartnerXlsx(
'report.gdpr.report_partner_xlsx',
'gdpr.partner.report',
parser=report_sxw.rml_parse
)

BIN
gdpr_partner_report/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

16
gdpr_partner_report/views/gdpr_menu_view.xml

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data>
<menuitem id="menu_data_protection_report_gdpr_report"
name="Partner Report"
parent="gdpr_base.menu_data_protection_report_gdpr"
groups="data_protection_base.group_data_protection_user,data_protection_base.group_data_protection_manager"
sequence="10"
action="gdpr_partner_report.action_gdpr_partner_menu"
/>
</data>
</openerp>

22
gdpr_partner_report/views/gdpr_report.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<report
id="action_report_partner_data"
model="gdpr.partner.report"
string="GDPR Partner Data"
report_type="qweb-pdf"
name="gdpr.report_partner"
file="gdpr.report_partner"
/>
<record id="action_report_partner_data_xlsx" model="ir.actions.report.xml">
<field name="name">GDPR Partner Data to Excel</field>
<field name="model">gdpr.partner.report</field>
<field name="type">ir.actions.report.xml</field>
<field name="report_name">gdpr.report_partner_xlsx</field>
<field name="report_type">xlsx</field>
<field name="auto" eval="False"/>
</record>
</data>
</openerp>

64
gdpr_partner_report/views/report_partner.xml

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data>
<template id="report_partner">
<t t-call="report.html_container">
<t t-call="report.internal_layout">
<t t-call="report.external_layout">
<div class="page">
<div class="row">
<h4 style="padding-left:15em;padding-top:1em">
Partner Data
</h4>
<p>
Date: <span t-esc="date"/><br/>
Partner: <span t-field="partner.display_name"/>
</p>
<br/><br/>
<t t-if="tables">
<t t-foreach="tables" t-as="models">
<t t-foreach="tables[models]" t-as="table">
<t t-if="tables[models][table]">
<table class="table table-condensed" style="border: 1px solid black; border-collapse: collapse;">
<thead>
<tr>
<th style="border-right: 1px solid black;"><span t-esc="table"/></th>
</tr>
<tr>
<th style="border-right: 1px solid black;" t-foreach="tables[models][table][0]" t-as="head">
<span t-esc="head"/>
</th>
</tr>
</thead>
<tr t-foreach="tables[models][table]" t-as="row">
<td style="border-right: 1px solid black;" t-foreach="row" t-as="field">
<span t-esc="row[field]"/>
</td>
</tr>
</table>
</t>
<br/>
</t>
</t>
</t>
<p t-if="not tables">
<strong>We have no data for this partner.</strong>
</p>
</div>
</div>
</t>
</t>
</t>
</template>
<!--<template id="report_partner">-->
<!--<t t-call="report.html_container">-->
<!--<t t-call="gdpr_partner_report.report_partner"/>-->
<!--</t>-->
<!--</template>-->
</data>
</openerp>

2
gdpr_partner_report/wizard/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import gdpr_report_partner

256
gdpr_partner_report/wizard/gdpr_report_partner.py

@ -0,0 +1,256 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from openerp import api, fields, models, _
from openerp.osv import fields as old_fields
from openerp.exceptions import UserError
class GDPRPartnerReport(models.TransientModel):
_name = "gdpr.partner.report"
_description = "GDPR Partner Report"
company_id = fields.Many2one(
comodel_name='res.company',
string='Company',
required=True,
default=lambda self: self.env.user.company_id,
)
partner_id = fields.Many2one(
comodel_name='res.partner',
string='Partner',
required=True,
)
table_ids = fields.Many2many(
comodel_name='gdpr.partner.data',
string='Models with related partner data',
)
@api.multi
@api.onchange('partner_id')
def _onchange_table_ids(self):
self.ensure_one()
for report in self:
if report.partner_id:
data = self._get_tables_from_partner(self.partner_id)
names = self._get_table_names(data)
tables = self.env['gdpr.partner.data']
for name in sorted(names):
vals = report._get_default_table(
name=name,
data=[t for t in data if t[0] == name and not t[5]],
)
if vals:
tables |= self.env['gdpr.partner.data'].create(vals)
report.table_ids = tables
else:
report.table_ids = self.env['gdpr.partner.data']
return {
'domain': {
'table_ids': [
('id', 'in', report.table_ids.ids)],
},
}
@api.onchange('company_id')
def _onchange_company_id(self):
if self.company_id:
return {
'domain': {
'partner_id': [
('company_id', 'in', [self.company_id.id, False])],
},
}
else:
return {
'domain': {
'partner_id': [('company_id', '=', False)],
},
}
@api.multi
def button_export_pdf(self):
self.ensure_one()
return self.check_report()
@api.multi
def button_export_xlsx(self):
self.ensure_one()
return self.check_report(xlsx_report=True)
def _build_contexts(self, data):
result = {}
result['partner_id'] = data['form']['partner_id'][0] or False
result['company_id'] = data['form']['company_id'][0] or False
result['table_ids'] = 'table_ids' in data['form'] and \
data['form']['table_ids'] or False
return result
def _clean_data(self, model, rows):
cleaned_rows = []
for i, row in enumerate(rows):
cleaned_rows.append({})
for key, value in row.items():
label = self.env[model]._fields[key].string or key
if 'many2' in self.env[model]._fields[key].type:
comodel = self.env[model]._fields[key].comodel_name
if value:
record = self.env[comodel].browse(value)
cleaned_rows[i][label] = str(record.display_name)
else:
cleaned_rows[i][label] = rows[i][key]
else:
cleaned_rows[i][label] = rows[i][key]
return cleaned_rows
@api.multi
def check_report(self, xlsx_report=False):
self.ensure_one()
data = {}
data['ids'] = self.env.context.get('active_ids', [])
data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
data['form'] = self.read(['partner_id', 'company_id', 'table_ids'])[0]
used_context = self._build_contexts(data)
data['form']['used_context'] = dict(
used_context, lang=self.env.context.get('lang', 'en_US'))
return self._print_report(data=data, xlsx_report=xlsx_report)
@api.multi
def compute_data_for_report(self, data):
if not data.get('form'):
raise UserError(
_("Form content is missing, this report cannot be printed."))
partner = data['form'].get('partner_id', False)
if not partner:
raise UserError(
_("No provided partner."))
partner = self.env['res.partner'].browse(partner[0])
tables = data['form'].get('table_ids', False)
if tables:
tables = self.env['gdpr.partner.data'].browse(tables)
tables = self._get_rows_from_tables(tables, partner)
data.update({'tables': tables, })
return data
def _exclude_column(self, model, column):
# To remove in v10:
# (non-stored function fields should have _fnct_search)
column_info = self.env[model]._columns.get(column)
next_model = self.env[model]
while not column_info and column in next_model._inherit_fields:
next_model = self.env[next_model._inherit_fields[column][0]]
column_info = next_model._columns.get(column)
if isinstance(column_info, old_fields.function) \
and not column_info.store and not column_info._fnct_search:
return True
# https://github.com/odoo/odoo/issues/24927
if model in ('mail.compose.message', 'survey.mail.compose.message'):
if column in ('needaction_partner_ids', 'starred_partner_ids'):
return True
return False
def _get_default_table(self, name, data):
if data:
data_type = data[0][4]
res = self.env[data[0][1]]
for t in data:
res |= self.env[t[1]].browse(t[3])
if res:
values = {
'name': name,
'model_id': self.env['ir.model'].search(
[('model', '=', res._name)]).id,
'count_rows': len(res.ids),
'type': data_type,
}
return values
return {}
def _get_model_from_table(self, table, partner):
new_tables = {}
for model in table.model_id:
rows = self._get_rows_from_model(model, partner)
new_tables[str(model.display_name)] = rows
return new_tables
def _get_rows_from_model(self, model, partner):
cr = self.env.cr
lines = self.env[model.model]
columns = [k for k, v in self.env[model.model]._fields.items()
if v.comodel_name == 'res.partner' and
not self._exclude_column(model.model, k)]
for column in columns:
lines |= self.env[model.model].search([(column, '=', partner.id)])
line_ids = ', '.join([str(i) for i in lines.ids])
query = "SELECT * FROM %s WHERE id IN (%s)" % (
model.model.replace('.', '_'), line_ids)
cr.execute(query)
rows = cr.dictfetchall()
rows = self._clean_data(model.model, rows)
return rows
def _get_rows_from_tables(self, tables, partner):
new_tables = {}
for table in tables:
data_table = self._get_model_from_table(table, partner)
new_tables[str(table.name)] = data_table
return new_tables
def _get_table_names(self, data):
names = []
for t in data:
if t[3] and not t[5] and t[0] not in names:
names.append(t[0])
return names
def _get_tables_from_partner(self, partner):
tables = [t[0] for t in [
[[self.env[m]._table, m, k, self.env[m].sudo().search(
[(k, '=', partner.id)]).ids, v.type, self.env[m]._transient]
for k, v in self.env[m]._fields.items()
if v.comodel_name == 'res.partner' and self.env[m]._auto and
not self._exclude_column(m, k)]
for m in [x for x in self.env.registry.keys()]] if t]
for i, t in enumerate(tables):
if t[4] == 'many2many':
if t[3]:
relation = self.env[t[1]]._fields[t[2]].relation
if relation:
tables[i][0] = relation
return tables
def _print_report(self, data, xlsx_report=False):
records = self.env[data['model']].browse(data.get('ids', []))
processed_data = self.compute_data_for_report(data)
if xlsx_report:
kkk = self.env['report'].with_context(landscape=True).get_action(
records=records, report_name='gdpr.report_partner_xlsx',
data=processed_data)
return kkk
else:
return self.env['report'].with_context(landscape=True).get_action(
records=records, report_name='gdpr.report_partner',
data=processed_data)
class GDPRPartnerData(models.TransientModel):
_name = "gdpr.partner.data"
_description = "GDPR Partner Data"
name = fields.Char(
string='Database Table',
)
model_id = fields.Many2one(
comodel_name='ir.model',
ondelete='cascade',
string='Models',
)
type = fields.Char(
string="Type",
)
count_rows = fields.Integer(
default=0,
string='Number of lines',
)

55
gdpr_partner_report/wizard/gdpr_report_partner_wizard.xml

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<openerp>
<data>
<record id="gdpr_partner_report_wizard" model="ir.ui.view">
<field name="name">Partner Report</field>
<field name="model">gdpr.partner.report</field>
<field name="arch" type="xml">
<form string="Report Options">
<group groups="base.group_multi_company">
<group>
<span >Select a company</span><br/>
<field name="company_id" options="{'no_create': True}" nolabel="1" />
</group>
</group>
<group>
<group>
<span>Select a partner</span><br/>
<field name="partner_id" options="{'no_create': True}" nolabel="1" domain="[('company_id', 'in', [False, company_id])]"/>
</group>
</group>
<group attrs="{'invisible': [('partner_id', '=', False)]}" col="1">
<field name="table_ids" options="{'no_create': True}" editable="bottom">
<tree>
<field name="model_id"/>
<field name="count_rows" text-align="right"/>
</tree>
</field>
</group>
<footer>
<button name="button_export_xlsx" string="Export XLSX" type="object" default_focus="1" class="oe_highlight"/>
or
<button name="button_export_pdf" string="Print PDF" type="object"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_gdpr_partner_menu" model="ir.actions.act_window">
<field name="name">Partner Report</field>
<field name="res_model">gdpr.partner.report</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="gdpr_partner_report_wizard"/>
<field name="context">{}</field>
<field name="target">new</field>
</record>
</data>
</openerp>

15
oca_dependencies.txt

@ -1,15 +1,6 @@
# List the OCA project dependencies, one per line # List the OCA project dependencies, one per line
# Add a repository url and branch if you need a forked version # Add a repository url and branch if you need a forked version
# #
# Examples
# ========
#
# To depend on the standard version of sale-workflow, use:
# sale-workflow
#
# To explicitely give the URL of a fork, and still use the version specified in
# .travis.yml, use:
# sale-workflow https://github.com/OCA/sale-workflow
#
# To provide both the URL and a branch, use:
# sale-workflow https://github.com/OCA/sale-workflow branchname
reporting-engine
# https://github.com/OCA/OCB/pull/753
odoo https://github.com/Eficent/odoo 9.0-fix-web_controller_report_datas2data
Loading…
Cancel
Save