diff --git a/privacy_personal_data/__init__.py b/privacy_personal_data/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/privacy_personal_data/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/privacy_personal_data/__manifest__.py b/privacy_personal_data/__manifest__.py new file mode 100644 index 0000000..5c3ff88 --- /dev/null +++ b/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, +} diff --git a/privacy_personal_data/models/__init__.py b/privacy_personal_data/models/__init__.py new file mode 100644 index 0000000..08a9285 --- /dev/null +++ b/privacy_personal_data/models/__init__.py @@ -0,0 +1,3 @@ +from . import privacy_personal_data +from . import privacy_activity +from . import res_partner diff --git a/privacy_personal_data/models/privacy_activity.py b/privacy_personal_data/models/privacy_activity.py new file mode 100644 index 0000000..e20dc98 --- /dev/null +++ b/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, + ) diff --git a/privacy_personal_data/models/privacy_personal_data.py b/privacy_personal_data/models/privacy_personal_data.py new file mode 100644 index 0000000..5a18858 --- /dev/null +++ b/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",) diff --git a/privacy_personal_data/models/res_partner.py b/privacy_personal_data/models/res_partner.py new file mode 100644 index 0000000..c3726fa --- /dev/null +++ b/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') diff --git a/privacy_personal_data/readme/CONFIGURATION.rst b/privacy_personal_data/readme/CONFIGURATION.rst new file mode 100644 index 0000000..6c93652 --- /dev/null +++ b/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. diff --git a/privacy_personal_data/readme/CONTRIBUTORS.rst b/privacy_personal_data/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..c97a74f --- /dev/null +++ b/privacy_personal_data/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Nicolas JEUDY diff --git a/privacy_personal_data/readme/DESCRIPTION.rst b/privacy_personal_data/readme/DESCRIPTION.rst new file mode 100644 index 0000000..dce3893 --- /dev/null +++ b/privacy_personal_data/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module provides personal data details in privacy activity. diff --git a/privacy_personal_data/readme/USAGE.rst b/privacy_personal_data/readme/USAGE.rst new file mode 100644 index 0000000..fbf3d8f --- /dev/null +++ b/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! diff --git a/privacy_personal_data/security/ir.model.access.csv b/privacy_personal_data/security/ir.model.access.csv new file mode 100644 index 0000000..a63dd5a --- /dev/null +++ b/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 diff --git a/privacy_personal_data/static/description/icon.png b/privacy_personal_data/static/description/icon.png new file mode 100644 index 0000000..f36112b Binary files /dev/null and b/privacy_personal_data/static/description/icon.png differ diff --git a/privacy_personal_data/static/description/icon.svg b/privacy_personal_data/static/description/icon.svg new file mode 100644 index 0000000..90af7f3 --- /dev/null +++ b/privacy_personal_data/static/description/icon.svg @@ -0,0 +1,115 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/privacy_personal_data/views/privacy_activity_view.xml b/privacy_personal_data/views/privacy_activity_view.xml new file mode 100644 index 0000000..1b5f991 --- /dev/null +++ b/privacy_personal_data/views/privacy_activity_view.xml @@ -0,0 +1,45 @@ + + + + + Privacy Activity Form Personal Data + privacy.activity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/privacy_personal_data/views/privacy_objective_view.xml b/privacy_personal_data/views/privacy_objective_view.xml new file mode 100644 index 0000000..cd17a5e --- /dev/null +++ b/privacy_personal_data/views/privacy_objective_view.xml @@ -0,0 +1,40 @@ + + + + Privacy objective Form + privacy.objective + +
+ +
+ +
+
+
+ + + + + +
+
+
+
+ + Privacy Objective + privacy.objective + tree,form + +

+ Click to add a privacy objective. +

+
+
+ + + +
diff --git a/privacy_personal_data/views/privacy_personal_category_view.xml b/privacy_personal_data/views/privacy_personal_category_view.xml new file mode 100644 index 0000000..6f1e2cd --- /dev/null +++ b/privacy_personal_data/views/privacy_personal_category_view.xml @@ -0,0 +1,91 @@ + + + + + Privacy Personal Category Form + privacy.personal.category + +
+
+ +
+ +
+
+ + + + + + + + + + +
+
+
+
+ + + Privacy Personal Category Tree + privacy.personal.category + + + + + + + + + + + + Privacy Personal Category Search + privacy.personal.category + + + + + + + + + + + + + + + + + Personal Data Category + privacy.personal.category + tree,form + +

+ Click to add a personal data category. +

+
+
+ + + +
diff --git a/privacy_personal_data/views/privacy_personal_data_view.xml b/privacy_personal_data/views/privacy_personal_data_view.xml new file mode 100644 index 0000000..7ccf8f5 --- /dev/null +++ b/privacy_personal_data/views/privacy_personal_data_view.xml @@ -0,0 +1,105 @@ + + + + + Privacy Personal Data Form + privacy.personal.data + +
+
+ +
+ +
+ +
+
+
+ + + + + + + + + + +
+
+
+
+ + + Privacy Personal Data Tree + privacy.personal.data + + + + + + + + + + + + Privacy Personal Data Search + privacy.personal.data + + + + + + + + + + + + + + Personal Data + privacy.personal.data + tree,form + +

+ Click to add a personal data details. +

+
+
+ + + + +
diff --git a/privacy_personal_data/views/res_partner_view.xml b/privacy_personal_data/views/res_partner_view.xml new file mode 100644 index 0000000..4b5ce42 --- /dev/null +++ b/privacy_personal_data/views/res_partner_view.xml @@ -0,0 +1,19 @@ + + + + + Privacy Res partner form + res.partner + + + + + + + + + + + + +