diff --git a/oca_dependencies.txt b/oca_dependencies.txt
index 4b4edc6..6da85e0 100644
--- a/oca_dependencies.txt
+++ b/oca_dependencies.txt
@@ -1,2 +1 @@
reporting-engine
-
diff --git a/privacy_partner_report/__manifest__.py b/privacy_partner_report/__manifest__.py
index 0d4d092..a3d98fe 100644
--- a/privacy_partner_report/__manifest__.py
+++ b/privacy_partner_report/__manifest__.py
@@ -1,20 +1,19 @@
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
- 'name': 'Privacy Partner Report',
- 'version': '13.0.1.0.0',
- 'category': 'GDPR',
- 'summary': 'Show the transactions that a specific partner is involved in.',
- 'author': "Eficent, "
- "Odoo Community Association (OCA)",
- 'website': 'https://github.com/OCA/data-protection/',
- 'license': 'AGPL-3',
- 'depends': ['privacy', 'report_xlsx'],
- 'data': [
- 'wizard/privacy_report_partner_wizard.xml',
- 'views/privacy_report.xml',
- 'views/privacy_menu_view.xml',
+ "name": "Privacy Partner Report",
+ "version": "13.0.1.0.0",
+ "category": "GDPR",
+ "summary": "Show the transactions that a specific partner is involved in.",
+ "author": "Eficent, " "Odoo Community Association (OCA)",
+ "website": "https://github.com/OCA/data-protection/",
+ "license": "AGPL-3",
+ "depends": ["privacy", "report_xlsx"],
+ "data": [
+ "wizard/privacy_report_partner_wizard.xml",
+ "views/privacy_report.xml",
+ "views/privacy_menu_view.xml",
],
- 'installable': True,
- 'maintainers': ['mreficent'],
+ "installable": True,
+ "maintainers": ["mreficent"],
}
diff --git a/privacy_partner_report/report/privacy_partner_xlsx.py b/privacy_partner_report/report/privacy_partner_xlsx.py
index 48bdc8b..f7e788d 100644
--- a/privacy_partner_report/report/privacy_partner_xlsx.py
+++ b/privacy_partner_report/report/privacy_partner_xlsx.py
@@ -2,6 +2,7 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
import logging
+
from odoo import models
from odoo.tools.translate import _
@@ -9,8 +10,8 @@ _logger = logging.getLogger(__name__)
class ReportPartnerXlsx(models.AbstractModel):
- _name = 'report.privacy_partner_report.report_partner_xlsx'
- _inherit = 'report.report_xlsx.abstract'
+ _name = "report.privacy_partner_report.report_partner_xlsx"
+ _inherit = "report.report_xlsx.abstract"
def _search_longest_row(self, tables):
res = 0
@@ -24,26 +25,26 @@ class ReportPartnerXlsx(models.AbstractModel):
def generate_xlsx_report(self, workbook, data, objects):
for o in objects:
report_data = o.compute_data_for_report(data)
- partner = report_data['form'].get('partner_id', False)
- partner = self.env['res.partner'].sudo().browse(partner[0])
- workbook.set_properties({
- 'comments': 'Created with Python and XlsxWriter from Odoo'})
- sheet = workbook.add_worksheet(_('Partner Data'))
+ partner = report_data["form"].get("partner_id", False)
+ partner = self.env["res.partner"].sudo().browse(partner[0])
+ workbook.set_properties(
+ {"comments": "Created with Python and XlsxWriter from Odoo"}
+ )
+ 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(
- report_data['tables']), 25)
+ sheet.set_column(0, self._search_longest_row(report_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)
+ {"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(report_data['tables'].keys()):
- for model in sorted(report_data['tables'][table].keys()):
- rows = len(report_data['tables'][table][model])
+ first_row = i + 2
+ for table in sorted(report_data["tables"].keys()):
+ for model in sorted(report_data["tables"][table].keys()):
+ rows = len(report_data["tables"][table][model])
if rows:
style = workbook.add_format()
style.set_bold(True)
@@ -51,19 +52,18 @@ class ReportPartnerXlsx(models.AbstractModel):
sheet.write_row(i, 0, [model], style)
i += 1
j = 0
- for column in report_data['tables'][table][model][0]:
+ for column in report_data["tables"][table][model][0]:
style = workbook.add_format()
style.set_bold(True)
if j == 0:
style.set_left(1)
- if j == len(report_data['tables'][
- table][model][0]) - 1:
+ if j == len(report_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 report_data['tables'][table][model]:
+ for row in report_data["tables"][table][model]:
i += 1
j = 0
for column in row:
@@ -77,7 +77,7 @@ class ReportPartnerXlsx(models.AbstractModel):
if row[column]:
sheet.write_row(i, j, [row[column]], style)
else:
- sheet.write_row(i, j, [''], style)
+ sheet.write_row(i, j, [""], style)
j += 1
i += 2
- first_row = i+2
+ first_row = i + 2
diff --git a/privacy_partner_report/views/privacy_menu_view.xml b/privacy_partner_report/views/privacy_menu_view.xml
index 7f22a67..780adf8 100644
--- a/privacy_partner_report/views/privacy_menu_view.xml
+++ b/privacy_partner_report/views/privacy_menu_view.xml
@@ -1,13 +1,12 @@
-
-
-
diff --git a/privacy_partner_report/wizard/privacy_report_partner.py b/privacy_partner_report/wizard/privacy_report_partner.py
index df0d76b..534c092 100644
--- a/privacy_partner_report/wizard/privacy_report_partner.py
+++ b/privacy_partner_report/wizard/privacy_report_partner.py
@@ -1,77 +1,70 @@
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-from odoo import api, fields, models, _
-from odoo.exceptions import UserError
import ast
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError
+
class PrivacyPartnerReport(models.TransientModel):
_name = "privacy.partner.report"
_description = "Privacy Partner Report"
company_id = fields.Many2one(
- comodel_name='res.company',
- string='Company',
+ 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,
+ comodel_name="res.partner", string="Partner", required=True,
)
table_ids = fields.Many2many(
- comodel_name='privacy.partner.data',
- string='Models with related partner data',
+ comodel_name="privacy.partner.data", string="Models with related partner data",
)
- @api.onchange('partner_id')
+ @api.onchange("partner_id")
def _onchange_partner_id(self):
if self.partner_id:
data = self._get_tables_from_partner(self.partner_id)
names = self._get_table_names(data)
- tables = self.env['privacy.partner.data']
+ tables = self.env["privacy.partner.data"]
for name in sorted(names):
vals = self._get_default_table(
- name=name,
- data=[t for t in data if t[0] == name and not t[5]],
+ name=name, data=[t for t in data if t[0] == name and not t[5]],
)
if vals:
- tables |= self.env['privacy.partner.data'].create(vals)
+ tables |= self.env["privacy.partner.data"].create(vals)
self.table_ids = tables
else:
- self.table_ids = self.env['privacy.partner.data']
+ self.table_ids = self.env["privacy.partner.data"]
return {
- 'domain': {
- 'table_ids': [
- ('id', 'in', self.table_ids.ids)],
- },
+ "domain": {"table_ids": [("id", "in", self.table_ids.ids)]},
}
- @api.onchange('company_id')
+ @api.onchange("company_id")
def _onchange_company_id(self):
if not self.company_id:
self.company_id = self.env.user.company_id
return {
- 'domain': {
- 'partner_id': [
- ('company_id', 'in', [self.company_id.id, False])],
+ "domain": {
+ "partner_id": [("company_id", "in", [self.company_id.id, False])],
},
}
-
def button_export_xlsx(self):
self.ensure_one()
if not self.table_ids:
- raise UserError(_('No data for this partner.'))
+ raise UserError(_("No data for this partner."))
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
+ 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
@staticmethod
@@ -86,54 +79,55 @@ class PrivacyPartnerReport(models.TransientModel):
for key, value in row.items():
label = self.env[model]._fields[key].string or key
if self.env[model]._fields[key].store:
- if 'many2one' == self.env[model]._fields[key].type:
+ if "many2one" == self.env[model]._fields[key].type:
comodel = self.env[model]._fields[key].comodel_name
if value:
record = self.env[comodel].sudo().browse(value)
cleaned_rows[i][label] = record.display_name
else:
cleaned_rows[i][label] = rows[i][key]
- elif 'binary' == self.env[model]._fields[key].type:
+ elif "binary" == self.env[model]._fields[key].type:
binary = self._transform_binary(rows[i][key])
if binary:
cleaned_rows[i][label] = binary
- elif '2many' not in self.env[model]._fields[key].type:
+ elif "2many" not in self.env[model]._fields[key].type:
cleaned_rows[i][label] = rows[i][key]
return cleaned_rows
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]
+ 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']['id'] = str(data['form']['id'])
- data['form']['used_context'] = dict(
- used_context, lang=self.env.context.get('lang', 'en_US'))
+ data["form"]["id"] = str(data["form"]["id"])
+ 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)
def compute_data_for_report(self, data):
- if not data.get('form'):
+ if not data.get("form"):
raise UserError(
- _("Form content is missing, this report cannot be printed."))
- partner = data['form'].get('partner_id', False)
+ _("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'].sudo().browse(partner[0])
- tables = data['form'].get('table_ids', False)
+ raise UserError(_("No provided partner."))
+ partner = self.env["res.partner"].sudo().browse(partner[0])
+ tables = data["form"].get("table_ids", False)
if tables:
- tables = self.env['privacy.partner.data'].browse(tables)
+ tables = self.env["privacy.partner.data"].browse(tables)
tables = self._get_rows_from_tables(tables, partner)
- data.update({'tables': tables, })
+ data.update({"tables": tables})
return data
def _exclude_column(self, model, column):
# 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'):
+ if model in ("mail.compose.message", "survey.mail.compose.message"):
+ if column in ("needaction_partner_ids", "starred_partner_ids"):
return True
# feel free to add more specific cases meanwhile the issue is not fixed
@@ -147,12 +141,14 @@ class PrivacyPartnerReport(models.TransientModel):
res |= self.env[t[1]].sudo().browse(t[3])
if res:
values = {
- 'name': name,
- 'model_id': self.env['ir.model'].sudo().search(
- [('model', '=', res._name)]).id,
- 'count_rows': len(res.ids),
- 'field_type': field_type,
- 'res_ids': res.ids,
+ "name": name,
+ "model_id": self.env["ir.model"]
+ .sudo()
+ .search([("model", "=", res._name)])
+ .id,
+ "count_rows": len(res.ids),
+ "field_type": field_type,
+ "res_ids": res.ids,
}
return values
return {}
@@ -166,12 +162,15 @@ class PrivacyPartnerReport(models.TransientModel):
def _get_rows_from_model(self, model, partner):
lines = self.env[model.model]
- columns = [k for k, v in self.env[model.model]._fields.items()
- if v.comodel_name == 'res.partner' and
- v.store and not self._exclude_column(model.model, k)]
+ columns = [
+ k
+ for k, v in self.env[model.model]._fields.items()
+ if v.comodel_name == "res.partner"
+ and v.store
+ and not self._exclude_column(model.model, k)
+ ]
for column in columns:
- lines |= self.env[model.model].sudo().search(
- [(column, '=', partner.id)])
+ lines |= self.env[model.model].sudo().search([(column, "=", partner.id)])
rows = lines.sudo().read(load=False)
rows = self._clean_data(model.model, rows)
return rows
@@ -191,15 +190,30 @@ class PrivacyPartnerReport(models.TransientModel):
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
- v.store and not self._exclude_column(m, k)]
- for m in [x for x in self.env.registry.keys()]] if t]
+ 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 v.store
+ 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[4] == "many2many":
if t[3]:
relation = self.env[t[1]]._fields[t[2]].relation
if relation:
@@ -207,44 +221,38 @@ class PrivacyPartnerReport(models.TransientModel):
return tables
def _print_report(self, data, xlsx_report=False):
- records = self.env[data['model']].sudo().browse(data.get('ids', []))
+ records = self.env[data["model"]].sudo().browse(data.get("ids", []))
if xlsx_report:
- return self.env.ref('privacy_partner_report.report_partner_xlsx').\
- with_context(landscape=True).report_action(
- records, data=data)
+ return (
+ self.env.ref("privacy_partner_report.report_partner_xlsx")
+ .with_context(landscape=True)
+ .report_action(records, data=data)
+ )
class PrivacyPartnerData(models.TransientModel):
_name = "privacy.partner.data"
_description = "Privacy Partner Data"
- name = fields.Char(
- string='Database Table',
- )
+ name = fields.Char(string="Database Table",)
model_id = fields.Many2one(
- comodel_name='ir.model',
- ondelete='cascade',
- string='Models',
- )
- field_type = fields.Char(
- string="Type", oldname='type',
+ comodel_name="ir.model", ondelete="cascade", string="Models",
)
- count_rows = fields.Integer(
- default=0,
- string='Number of lines',
+ field_type = fields.Char(string="Type", oldname="type",)
+ count_rows = fields.Integer(default=0, string="Number of lines",)
+ res_ids = fields.Char(
+ "Related Document IDs", index=True, help="List of Related Document IDs"
)
- res_ids = fields.Char('Related Document IDs', index=True,
- help='List of Related Document IDs')
def action_view_records(self):
self.ensure_one()
response = {
- 'name': self.model_id.display_name,
- 'type': 'ir.actions.act_window',
- 'res_model': self.model_id.model,
- 'view_mode': 'tree,form',
- 'domain': [('id', 'in', ast.literal_eval(self.res_ids))],
- 'target': 'current',
- 'context': {'delete': True},
+ "name": self.model_id.display_name,
+ "type": "ir.actions.act_window",
+ "res_model": self.model_id.model,
+ "view_mode": "tree,form",
+ "domain": [("id", "in", ast.literal_eval(self.res_ids))],
+ "target": "current",
+ "context": {"delete": True},
}
return response
diff --git a/privacy_partner_report/wizard/privacy_report_partner_wizard.xml b/privacy_partner_report/wizard/privacy_report_partner_wizard.xml
index 215e3fe..c96863c 100644
--- a/privacy_partner_report/wizard/privacy_report_partner_wizard.xml
+++ b/privacy_partner_report/wizard/privacy_report_partner_wizard.xml
@@ -1,49 +1,75 @@
-
Partner Report
privacy.partner.report
-
+
-
-