Browse Source

[NEW] track privacy activity

12.0-personal_privacy_activity
Nicolas JEUDY 3 years ago
parent
commit
29cc32b1e6
  1. 1
      privacy_personal_data/__init__.py
  2. 27
      privacy_personal_data/__manifest__.py
  3. 3
      privacy_personal_data/models/__init__.py
  4. 59
      privacy_personal_data/models/privacy_activity.py
  5. 74
      privacy_personal_data/models/privacy_personal_data.py
  6. 10
      privacy_personal_data/models/res_partner.py
  7. 2
      privacy_personal_data/readme/CONFIGURATION.rst
  8. 1
      privacy_personal_data/readme/CONTRIBUTORS.rst
  9. 1
      privacy_personal_data/readme/DESCRIPTION.rst
  10. 6
      privacy_personal_data/readme/USAGE.rst
  11. 11
      privacy_personal_data/security/ir.model.access.csv
  12. BIN
      privacy_personal_data/static/description/icon.png
  13. 115
      privacy_personal_data/static/description/icon.svg
  14. 45
      privacy_personal_data/views/privacy_activity_view.xml
  15. 40
      privacy_personal_data/views/privacy_objective_view.xml
  16. 91
      privacy_personal_data/views/privacy_personal_category_view.xml
  17. 105
      privacy_personal_data/views/privacy_personal_data_view.xml
  18. 19
      privacy_personal_data/views/res_partner_view.xml

1
privacy_personal_data/__init__.py

@ -0,0 +1 @@
from . import models

27
privacy_personal_data/__manifest__.py

@ -0,0 +1,27 @@
# Copyright 2019 Myceliandre - Nicolas JEUDY
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
{
'name': 'Private Personal Data details',
'version': '12.0.1.0.0',
'category': 'Data Protection',
'summary': 'Provides private data details on privacy activity ',
'author': "Nicolas JEUDY, "
"Odoo Community Association (OCA)",
'website': 'http://www.github.com/OCA/data-protection',
'license': 'AGPL-3',
'data': [
'security/ir.model.access.csv',
'views/privacy_activity_view.xml',
'views/privacy_personal_data_view.xml',
'views/privacy_personal_category_view.xml',
'views/privacy_objective_view.xml',
'views/res_partner_view.xml',
],
'demo': [
],
'depends': [
'mail', 'privacy',
],
'installable': True,
'application': False,
}

3
privacy_personal_data/models/__init__.py

@ -0,0 +1,3 @@
from . import privacy_personal_data
from . import privacy_activity
from . import res_partner

59
privacy_personal_data/models/privacy_activity.py

@ -0,0 +1,59 @@
# Copyright 2019 Myceliandre - Nicolas JEUDY
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class PersonalDataCategory(models.Model):
_name = "privacy.subject.category"
_description = "Subjects category"
name = fields.Char('Name', index=True, required=True, translate=True)
class PersonalDataLegal(models.Model):
_name = "privacy.legal"
_description = "Legal"
name = fields.Char('Name', index=True, required=True, translate=True)
class PrivacyActivity(models.Model):
_inherit = 'privacy.activity'
def _default_company(self):
return self.env['res.company']._company_default_get('privacy.activity')
@api.multi
def _compute_has_sensitive(self):
for record in self:
record.has_sensitive = 'sensitive' in record.personal_data_ids.mapped('type')
value = fields.Boolean(compute='_get_value')
personal_data_ids = fields.Many2many('privacy.personal.data')
subjects_categ_ids = fields.Many2many('privacy.subject.category')
has_sensitive = fields.Boolean(compute='_compute_has_sensitive')
legal_ids = fields.Many2many('privacy.legal')
controller_ids = fields.Many2many(
"res.partner",
"privacy_activity_res_partner_controler_ids",
string="Controllers",
)
define_objective = fields.Boolean(
"Define objective",
help="Add detailed objectif from a custom list.",
)
objective_ids = fields.Many2many('privacy.objective', string="Details")
company_id = fields.Many2one('res.company', 'Company', index=True, default=_default_company)
class PrivacyObjective(models.Model):
_name = "privacy.objective"
_description = "Objective database"
name = fields.Char('Name', index=True, required=True, translate=True)
description = fields.Html('Description')
active = fields.Boolean(
default=True,
index=True,
)

74
privacy_personal_data/models/privacy_personal_data.py

@ -0,0 +1,74 @@
# Copyright 2019 Myceliandre - Nicolas JEUDY
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class PersonalDataCategory(models.Model):
_name = "privacy.personal.category"
_description = "Personal Data category"
_parent_name = "parent_id"
_parent_store = True
_rec_name = 'complete_name'
_order = 'complete_name'
name = fields.Char('Name', index=True, required=True, translate=True)
description = fields.Html(
translate=True,
help="Give more example, explanation of personal data"
)
complete_name = fields.Char(
'Complete Name', compute='_compute_complete_name',
store=True)
parent_id = fields.Many2one('privacy.personal.category', 'Parent Category', index=True, ondelete='cascade')
parent_path = fields.Char(index=True)
type = fields.Selection([
('common', 'Common'),
('risk', 'High Risk'),
('sensitive', 'Sensitive')],
string='Type',
default='common',
required=True,)
child_id = fields.One2many('privacy.personal.category', 'parent_id', 'Child Categories')
@api.depends('name', 'parent_id.complete_name')
def _compute_complete_name(self):
for category in self:
if category.parent_id:
category.complete_name = '%s / %s' % (category.parent_id.complete_name, category.name)
else:
category.complete_name = category.name
@api.constrains('parent_id')
def _check_category_recursion(self):
if not self._check_recursion():
raise ValidationError(_('You cannot create recursive categories.'))
return True
@api.model
def name_create(self, name):
return self.create({'name': name}).name_get()[0]
class PersonalData(models.Model):
_name = "privacy.personal.data"
_description = "Personal Data"
active = fields.Boolean(
default=True,
index=True,
)
name = fields.Char(
index=True,
required=True,
translate=True,
)
description = fields.Html(
translate=True,
help="Data list used in activity"
)
categ_id = fields.Many2one('privacy.personal.category',
string="Category",
domain=[('child_id', '=', False)])
type = fields.Selection(related="categ_id.type",)

10
privacy_personal_data/models/res_partner.py

@ -0,0 +1,10 @@
# Copyright 2019 Myceliandre - Nicolas JEUDY
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ResPartner(models.Model):
_inherit = "res.partner"
internal = fields.Boolean('Internal')

2
privacy_personal_data/readme/CONFIGURATION.rst

@ -0,0 +1,2 @@
In the "Privacy", open the "Settings" menu to find and enable
the personal data details feature.

1
privacy_personal_data/readme/CONTRIBUTORS.rst

@ -0,0 +1 @@
* Nicolas JEUDY <https://github.com/njeudy>

1
privacy_personal_data/readme/DESCRIPTION.rst

@ -0,0 +1 @@
This module provides personal data details in privacy activity.

6
privacy_personal_data/readme/USAGE.rst

@ -0,0 +1,6 @@
To define data processing activities:
#. Go to *Privacy > Master Data > Activities* and create one.
#. Define impacted personal data details
Consult your lawyer!

11
privacy_personal_data/security/ir.model.access.csv

@ -0,0 +1,11 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
read_all,Permission to read category,model_privacy_personal_category,privacy.group_data_protection_user,1,0,0,0
write_all,Permission to write category,model_privacy_personal_category,privacy.group_data_protection_manager,1,1,1,1
read,Permission to read personal data,model_privacy_personal_data,privacy.group_data_protection_user,1,0,0,0
write,Permission to write personal data,model_privacy_personal_data,privacy.group_data_protection_manager,1,1,1,1
read_objective,Permission to read objectives,model_privacy_objective,privacy.group_data_protection_user,1,0,0,0
write_objective,Permission to write objectives,model_privacy_objective,privacy.group_data_protection_manager,1,1,1,1
read_subject_category,Permission to read subject category,model_privacy_subject_category,privacy.group_data_protection_user,1,0,0,0
write_subject_category,Permission to write subject category,model_privacy_subject_category,privacy.group_data_protection_manager,1,1,1,1
read_legal,Permission to read legal,model_privacy_legal,privacy.group_data_protection_user,1,0,0,0
write_legal,Permission to write legal,model_privacy_legal,privacy.group_data_protection_manager,1,1,1,1

BIN
privacy_personal_data/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 2.1 KiB

115
privacy_personal_data/static/description/icon.svg

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
width="60"
height="60"
viewBox="0 0 60 60"
sodipodi:docname="icon.svg"
inkscape:export-filename="icon.png"
inkscape:export-xdpi="204.8"
inkscape:export-ydpi="204.8">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1853"
inkscape:window-height="1018"
id="namedview4"
showgrid="false"
inkscape:zoom="5.6568542"
inkscape:cx="-13.498037"
inkscape:cy="27.319233"
inkscape:window-x="67"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
showguides="true"
inkscape:guide-bbox="true">
<sodipodi:guide
position="0,41.75"
orientation="1,0"
id="guide3360"
inkscape:locked="false" />
<sodipodi:guide
position="60,60.074219"
orientation="1,0"
id="guide3362"
inkscape:locked="false" />
<sodipodi:guide
position="0.17578125,60"
orientation="0,1"
id="guide3364"
inkscape:locked="false" />
<sodipodi:guide
position="58.71196,-0.0055242717"
orientation="0,1"
id="guide3366"
inkscape:locked="false" />
<sodipodi:guide
position="47.0625,10.9375"
orientation="-0.70710678,0.70710678"
id="guide3347"
inkscape:locked="false" />
<sodipodi:guide
position="21.743534,47.376154"
orientation="-0.70710678,0.70710678"
id="guide23"
inkscape:locked="false" />
</sodipodi:namedview>
<rect
style="opacity:1;fill:#0092d7;fill-opacity:1"
id="rect4147"
width="60"
height="60"
x="0"
y="0" />
<path
style="opacity:1;fill:#000000;fill-opacity:0.39215686"
d="M 0.0078125,34.359568 0,60 36.1162,60.0088 47.0625,49.0625 37.871757,16.233181 21.743534,12.623846 Z"
id="rect4171"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<g
id="g4169"
transform="matrix(0.3061173,0,0,0.3061173,-1.0360053,-1.0457906)"
style="fill:#ffffff;stroke:none" />
<g
aria-label=""
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.38242626px;line-height:0%;font-family:FontAwesome;-inkscape-font-specification:FontAwesome;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.78186888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text3352">
<path
d="m 44.064502,27.442816 c 1.038855,0 1.917886,0.399559 2.717006,1.118767 0.719207,0.799119 1.118767,1.67815 1.118767,2.717006 v 15.343092 c 0,1.118767 -0.39956,1.997799 -1.118767,2.717006 -0.79912,0.799119 -1.678151,1.118767 -2.717006,1.118767 H 15.935499 c -1.118767,0 -1.997799,-0.319648 -2.717006,-1.118767 -0.79912,-0.719207 -1.118767,-1.598239 -1.118767,-2.717006 V 31.278589 c 0,-1.038856 0.319647,-1.917887 1.118767,-2.717006 0.719207,-0.719208 1.598239,-1.118767 2.717006,-1.118767 h 1.917886 v -5.75366 c 0,-2.157622 0.479472,-4.155421 1.598239,-6.073308 1.118767,-1.837974 2.557182,-3.276389 4.475069,-4.395156 C 25.764667,10.101925 27.762466,9.542541 30,9.542541 c 2.157623,0 4.155421,0.559384 6.073308,1.678151 1.837974,1.118767 3.276389,2.557182 4.395156,4.395156 1.118768,1.917887 1.678151,3.915686 1.678151,6.073308 v 5.75366 z m -8.310842,0 v -5.75366 c 0,-1.598239 -0.559384,-2.956742 -1.678151,-4.075509 C 32.956742,16.49488 31.598239,15.935496 30,15.935496 c -1.598239,0 -2.956742,0.559384 -4.075509,1.678151 -1.118767,1.118767 -1.67815,2.47727 -1.67815,4.075509 v 5.75366 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.91491318px;line-height:1.25;font-family:'Font Awesome 5 Free';-inkscape-font-specification:'Font Awesome 5 Free';stroke-width:0.78186888px"
id="path25" />
</g>
</svg>

45
privacy_personal_data/views/privacy_activity_view.xml

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<data>
<record model="ir.ui.view" id="activity_form_inherit_personal_data">
<field name="name">Privacy Activity Form Personal Data</field>
<field name="model">privacy.activity</field>
<field name="inherit_id" ref="privacy.activity_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='subjects']" position="inside">
<field name="subjects_categ_ids" widget="many2many_tags" string="Category"/>
<field name="legal_ids" widget="many2many_tags" string="Legal"/>
<label for="personal_data_ids" string="Tracked data"/>
<field name="personal_data_ids" nolabel="1"/>
</xpath>
<xpath expr="//group[@name='basic']" position="after">
<group name="controller_details" colspan="4">
<field name="controller_ids"/>
</group>
<group name="objective_details" colspan="4">
<field name="define_objective" string="Define Objective(s)"/>
<field name="objective_ids" attrs='{"invisible": [("define_objective", "=", False)]}'>
<tree name="objective">
<field name="name"/>
<field name="description"/>
</tree>
</field>
</group>
</xpath>
<xpath expr="//group[@name='subjects']" position="after">
<field name="has_sensitive" invisible="1"/>
<group colspan="4" attrs='{"invisible": [("has_sensitive", "=", False)]}'>
<div class="alert alert-warning" role="alert" style="margin-bottom:0px;">
This activity has sensitive data.
</div>
</group>
</xpath>
<!--<xpath expr="//tree[@name='processors']/field[@name='country_id']" position="after">
<field name="internal"/>
</xpath>-->
</field>
</record>
</data>

40
privacy_personal_data/views/privacy_objective_view.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<data>
<record model="ir.ui.view" id="privacy_objective_form">
<field name="name">Privacy objective Form</field>
<field name="model">privacy.objective</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" icon="fa-archive" name="toggle_active" type="object">
<field name="active" options='{"terminology": "archive"}' widget="boolean_button"/>
</button>
</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
</div>
<group>
<field name="description" nolabel="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="privacy_objective_action" model="ir.actions.act_window">
<field name="name">Privacy Objective</field>
<field name="res_model">privacy.objective</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a privacy objective.
</p>
</field>
</record>
<menuitem name="Objective" groups="privacy.group_data_protection_user" parent="privacy.menu_data_protection_setting" id="menu_privacy_objective" sequence="10"/>
<menuitem name="Objective" sequence="10" action="privacy_objective_action" groups="privacy.group_data_protection_user" parent="menu_privacy_objective" id="menu_privacy_objective_model"/>
</data>

91
privacy_personal_data/views/privacy_personal_category_view.xml

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<data>
<record model="ir.ui.view" id="personal_category_form">
<field name="name">Privacy Personal Category Form</field>
<field name="model">privacy.personal.category</field>
<field name="arch" type="xml">
<form>
<header>
<field name="type" widget="statusbar" options="{'clickable': '1'}"/>
</header>
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
</div>
<group name="basic">
<field name="parent_id"/>
</group>
<notebook string="Details" name="advanced">
<page string="Description" name="description">
<group>
<field name="description" nolabel="1"/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="personal_category_tree">
<field name="name">Privacy Personal Category Tree</field>
<field name="model">privacy.personal.category</field>
<field name="arch" type="xml">
<tree>
<field name="complete_name"/>
<field name="name" invisible="1"/>
<field name="type"/>
<field name="description"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="personal_category_search">
<field name="name">Privacy Personal Category Search</field>
<field name="model">privacy.personal.category</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="parent_id"/>
<field name="description"/>
<separator/>
<filter
string="Archived"
name="inactive"
domain="[('active', '=', False)]"
/>
<separator/>
<group string="Group By" name="groupby">
<filter
name="parent_id_groupby"
string="Parent"
context="{'group_by': 'parent_id'}"
/>
</group>
</search>
</field>
</record>
<record id="personal_category_action" model="ir.actions.act_window">
<field name="name">Personal Data Category</field>
<field name="res_model">privacy.personal.category</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a personal data category.
</p>
</field>
</record>
<menuitem
name="Category"
sequence="10"
action="personal_category_action"
groups="privacy.group_data_protection_manager"
parent="menu_privacy_personal_data"
id="menu_privacy_personal_category"
/>
</data>

105
privacy_personal_data/views/privacy_personal_data_view.xml

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<data>
<record model="ir.ui.view" id="personal_data_form">
<field name="name">Privacy Personal Data Form</field>
<field name="model">privacy.personal.data</field>
<field name="arch" type="xml">
<form>
<header>
<field name="type" widget="statusbar" options="{'clickable': '0'}"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button
class="oe_stat_button"
icon="fa-archive"
name="toggle_active"
type="object"
>
<field
name="active"
options='{"terminology": "archive"}'
widget="boolean_button"
/>
</button>
</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
</div>
<group name="basic">
<field name="categ_id"/>
</group>
<notebook string="Details" name="advanced">
<page string="Description" name="description">
<group name="Personal Data details">
<field name="description" nolabel="1"/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="personal_data_tree">
<field name="name">Privacy Personal Data Tree</field>
<field name="model">privacy.personal.data</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="categ_id"/>
<field name="type"/>
<field name="description"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="personal_data_search">
<field name="name">Privacy Personal Data Search</field>
<field name="model">privacy.personal.data</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="categ_id"/>
<field name="description"/>
<field name="type"/>
<separator/>
<filter
string="Archived"
name="inactive"
domain="[('active', '=', False)]"
/>
</search>
</field>
</record>
<record id="personal_data_action" model="ir.actions.act_window">
<field name="name">Personal Data</field>
<field name="res_model">privacy.personal.data</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a personal data details.
</p>
</field>
</record>
<menuitem
name="Personal Data"
groups="privacy.group_data_protection_user"
parent="privacy.menu_data_protection_setting"
id="menu_privacy_personal_data"
sequence="10"
/>
<menuitem
name="Personal Data"
sequence="10"
action="personal_data_action"
groups="privacy.group_data_protection_user"
parent="menu_privacy_personal_data"
id="menu_privacy_personal_data_model"
/>
</data>

19
privacy_personal_data/views/res_partner_view.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<data>
<record model="ir.ui.view" id="rgpd_form_inherit_view_partner_form">
<field name="name">Privacy Res partner form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<page name="sales_purchases" position="after">
<page string="Privacy" name="privacy">
<group>
<field name="internal"/>
</group>
</page>
</page>
</field>
</record>
</data>
Loading…
Cancel
Save