From aa4bcfb3245b5b62ebb80ebcec628e7a8a9f7dbe Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 8 Aug 2018 15:15:57 +0100 Subject: [PATCH 01/30] privacy_consent: Privacy explicit consent tracking tools (#11) --- privacy_consent/README.rst | 1 + privacy_consent/__init__.py | 3 + privacy_consent/__manifest__.py | 29 + privacy_consent/controllers/__init__.py | 1 + privacy_consent/controllers/main.py | 47 ++ privacy_consent/data/ir_actions_server.xml | 23 + privacy_consent/data/ir_cron.xml | 16 + privacy_consent/data/mail.xml | 155 ++++ privacy_consent/i18n/es.po | 663 ++++++++++++++++++ privacy_consent/models/__init__.py | 5 + privacy_consent/models/mail_mail.py | 54 ++ privacy_consent/models/mail_template.py | 33 + privacy_consent/models/privacy_activity.py | 144 ++++ privacy_consent/models/privacy_consent.py | 201 ++++++ privacy_consent/models/res_partner.py | 32 + privacy_consent/readme/CONTRIBUTORS.rst | 3 + privacy_consent/readme/DESCRIPTION.rst | 7 + privacy_consent/readme/INSTALL.rst | 15 + privacy_consent/readme/USAGE.rst | 69 ++ privacy_consent/security/ir.model.access.csv | 3 + privacy_consent/static/description/icon.png | Bin 0 -> 9455 bytes privacy_consent/templates/form.xml | 63 ++ privacy_consent/tests/__init__.py | 1 + privacy_consent/tests/test_consent.py | 247 +++++++ privacy_consent/views/privacy_activity.xml | 89 +++ privacy_consent/views/privacy_consent.xml | 113 +++ privacy_consent/views/res_partner.xml | 35 + privacy_consent/wizards/__init__.py | 1 + .../wizards/mail_compose_message.py | 16 + 29 files changed, 2069 insertions(+) create mode 100644 privacy_consent/README.rst create mode 100644 privacy_consent/__init__.py create mode 100644 privacy_consent/__manifest__.py create mode 100644 privacy_consent/controllers/__init__.py create mode 100644 privacy_consent/controllers/main.py create mode 100644 privacy_consent/data/ir_actions_server.xml create mode 100644 privacy_consent/data/ir_cron.xml create mode 100644 privacy_consent/data/mail.xml create mode 100644 privacy_consent/i18n/es.po create mode 100644 privacy_consent/models/__init__.py create mode 100644 privacy_consent/models/mail_mail.py create mode 100644 privacy_consent/models/mail_template.py create mode 100644 privacy_consent/models/privacy_activity.py create mode 100644 privacy_consent/models/privacy_consent.py create mode 100644 privacy_consent/models/res_partner.py create mode 100644 privacy_consent/readme/CONTRIBUTORS.rst create mode 100644 privacy_consent/readme/DESCRIPTION.rst create mode 100644 privacy_consent/readme/INSTALL.rst create mode 100644 privacy_consent/readme/USAGE.rst create mode 100644 privacy_consent/security/ir.model.access.csv create mode 100644 privacy_consent/static/description/icon.png create mode 100644 privacy_consent/templates/form.xml create mode 100644 privacy_consent/tests/__init__.py create mode 100644 privacy_consent/tests/test_consent.py create mode 100644 privacy_consent/views/privacy_activity.xml create mode 100644 privacy_consent/views/privacy_consent.xml create mode 100644 privacy_consent/views/res_partner.xml create mode 100644 privacy_consent/wizards/__init__.py create mode 100644 privacy_consent/wizards/mail_compose_message.py diff --git a/privacy_consent/README.rst b/privacy_consent/README.rst new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/privacy_consent/README.rst @@ -0,0 +1 @@ + diff --git a/privacy_consent/__init__.py b/privacy_consent/__init__.py new file mode 100644 index 0000000..ada0b87 --- /dev/null +++ b/privacy_consent/__init__.py @@ -0,0 +1,3 @@ +from . import controllers +from . import models +from . import wizards diff --git a/privacy_consent/__manifest__.py b/privacy_consent/__manifest__.py new file mode 100644 index 0000000..ee84254 --- /dev/null +++ b/privacy_consent/__manifest__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Privacy - Consent", + "summary": "Allow people to explicitly accept or reject inclusion " + "in some activity, GDPR compliant", + "version": "10.0.1.0.0", + "development_status": "Production/Stable", + "category": "Privacy", + "website": "https://github.com/OCA/management-activity", + "author": "Tecnativa, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "privacy", + ], + "data": [ + "security/ir.model.access.csv", + "data/ir_actions_server.xml", + "data/ir_cron.xml", + "data/mail.xml", + "templates/form.xml", + "views/privacy_consent.xml", + "views/privacy_activity.xml", + "views/res_partner.xml", + ], +} diff --git a/privacy_consent/controllers/__init__.py b/privacy_consent/controllers/__init__.py new file mode 100644 index 0000000..12a7e52 --- /dev/null +++ b/privacy_consent/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/privacy_consent/controllers/main.py b/privacy_consent/controllers/main.py new file mode 100644 index 0000000..8f243d0 --- /dev/null +++ b/privacy_consent/controllers/main.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import datetime + +from werkzeug.exceptions import NotFound + +from odoo.http import Controller, request, route + +from odoo.addons.web.controllers.main import ensure_db + + +class ConsentController(Controller): + @route("/privacy/consent//" + "/", + type="http", auth="none", website=True) + def consent(self, choice, consent_id, token, *args, **kwargs): + """Process user's consent acceptance or rejection.""" + ensure_db() + try: + # If there's a website, we need a user to render the template + request.uid = request.website.user_id.id + except AttributeError: + # If there's no website, the default is OK + pass + consent = request.env["privacy.consent"] \ + .with_context(subject_answering=True) \ + .sudo().browse(consent_id) + if not (consent.exists() and consent._token() == token): + raise NotFound + if consent.partner_id.lang: + consent = consent.with_context(lang=consent.partner_id.lang) + request.context = consent.env.context + consent.action_answer(choice == "accept", self._metadata()) + return request.render("privacy_consent.form", { + "consent": consent, + }) + + def _metadata(self): + return (u"User agent: {}\n" + u"Remote IP: {}\n" + u"Date and time: {:%Y-%m-%d %H:%M:%S}").format( + request.httprequest.environ.get("HTTP_USER_AGENT"), + request.httprequest.environ.get("REMOTE_ADDRESS"), + datetime.now(), + ) diff --git a/privacy_consent/data/ir_actions_server.xml b/privacy_consent/data/ir_actions_server.xml new file mode 100644 index 0000000..58788e6 --- /dev/null +++ b/privacy_consent/data/ir_actions_server.xml @@ -0,0 +1,23 @@ + + + + + + + Update partner's opt out + + + object_write + expression + record.partner_id + + + + + + equation + not record.accepted + + + diff --git a/privacy_consent/data/ir_cron.xml b/privacy_consent/data/ir_cron.xml new file mode 100644 index 0000000..cc4bb38 --- /dev/null +++ b/privacy_consent/data/ir_cron.xml @@ -0,0 +1,16 @@ + + + + + + + Request automatic data processing consents + privacy.activity + _cron_new_consents + 1 + work_days + -1 + + + diff --git a/privacy_consent/data/mail.xml b/privacy_consent/data/mail.xml new file mode 100644 index 0000000..c288e93 --- /dev/null +++ b/privacy_consent/data/mail.xml @@ -0,0 +1,155 @@ + + + + + + + + Personal data processing consent request + Data processing consent request for ${object.activity_id.display_name|safe} + + + +
+ + + + + + +
+ + ${object.activity_id.controller_id.display_name|safe} + +
+ + + + + + + + + + + + + +
+

+ Hello, ${object.partner_id.name|safe} +

+

+ We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called + ${object.activity_id.display_name|safe}, property of + ${object.activity_id.controller_id.display_name|safe} +

+ ${object.description or ""} +

+ % if object.state == "answered": + The last time you answered, you + % elif object.state == "sent": + If you do nothing, we will assume you have + % endif + + % if object.accepted: + accepted + % else: + rejected + % endif + such data processing. +

+

+ You can update your preferences below: +

+
+ + Accept + + + + Reject + +
+

+ If you need further information, please respond to this email and we will attend your request as soon as possible. +

+

+ Thank you! +

+
+ + + + + + +
+

+ Sent by + ${object.activity_id.controller_id.display_name|safe}. +

+
+
+
+
+ + + + New Consent + Privacy consent request created + privacy.consent + + + + + + Acceptance Changed by Subject + Acceptance status updated by subject + privacy.consent + + + + + + State Changed + Privacy consent request state changed + privacy.consent + + + + + + + New Consent + Privacy consent request created + privacy.activity + + + + + activity_id + + + Acceptance Changed + Privacy consent request acceptance status changed + privacy.activity + + + + + activity_id + + + State Changed + Privacy consent request state changed + privacy.activity + + + + + activity_id + + +
diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po new file mode 100644 index 0000000..b830d8e --- /dev/null +++ b/privacy_consent/i18n/es.po @@ -0,0 +1,663 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_consent +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-07-11 08:38+0000\n" +"PO-Revision-Date: 2018-07-11 11:07+0200\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.8\n" +"Last-Translator: Jairo Llopis \n" +"Language: es_ES\n" + +#. module: privacy_consent +#: model:mail.template,body_html:privacy_consent.template_consent +msgid "" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object."\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hello, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" We contacted you to ask you to give us " +"your explicit consent to include your data in a data processing activity " +"called\n" +" ${object.activity_id.display_name|" +"safe}, property of\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" The last time you answered, you\n" +" % elif object.state == \"sent\":\n" +" If you do nothing, we will assume " +"you have\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" accepted\n" +" % else:\n" +" rejected\n" +" % endif\n" +" such data processing.\n" +"

\n" +"

\n" +" You can update your preferences below:\n" +"

\n" +"
\n" +" \n" +" Accept\n" +" \n" +" \n" +" \n" +" Reject\n" +" \n" +"
\n" +"

\n" +" If you need further information, please " +"respond to this email and we will attend your request as soon as possible.\n" +"

\n" +"

\n" +" Thank you!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Sent by\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object."\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hola, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" Le hemos contactado para pedirle su " +"consentimiento explícito para incluir sus datos en una actividad de " +"tratamiento llamada\n" +" ${object.activity_id.display_name|" +"safe}, propiedad de\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" Según su última respuesta,\n" +" % elif object.state == \"sent\":\n" +" Si no recibimos respuesta, " +"asumiremos que\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" ha aceptado\n" +" % else:\n" +" ha rechazado\n" +" % endif\n" +" dicho procesamiento de datos.\n" +"

\n" +"

\n" +" Puede cambiar sus preferencias aquí " +"abajo:\n" +"

\n" +"
\n" +" \n" +" Aceptar\n" +" \n" +" \n" +" \n" +" Rechazar\n" +" \n" +"
\n" +"

\n" +" Si necesita más información, por favor " +"responda a este correo electrónico y atenderemos su solicitud a la mayor " +"brevedad posible.\n" +"

\n" +"

\n" +" ¡Gracias!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Enviado por\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed +msgid "Acceptance Changed" +msgstr "Aceptación cambiada" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance Changed by Subject" +msgstr "Aceptación cambiada por el interesado" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance status updated by subject" +msgstr "Estado de aceptación modificado por el interesado" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Accepted" +msgstr "Aceptado" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent +msgid "Accepted by default" +msgstr "Aceptado por defecto" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active +msgid "Active" +msgstr "Activo" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Activity" +msgstr "Actividad" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Answered" +msgstr "Respondido" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Archived" +msgstr "Archivado" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_form +msgid "Ask for consent" +msgstr "Solicitar consentimiento" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required +msgid "Ask subjects for consent" +msgstr "Solicitar consentimiento a los interesados" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Automatically" +msgstr "Automáticamente" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Awaiting response" +msgstr "Esperando respuesta" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Consent" +msgstr "Consentimiento" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_consent +msgid "Consent of data processing" +msgstr "Consentimiento para tratamiento de datos" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html +msgid "Consent template default body html" +msgstr "HTML por defecto para el cuerpo de la plantilla de consentimiento" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject +msgid "Consent template default subject" +msgstr "HTML por defecto para el asunto de la plantilla de consentimiento" + +#. module: privacy_consent +#: model:ir.actions.act_window,name:privacy_consent.consent_action +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count +#: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent +msgid "Consents" +msgstr "Consents" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date +msgid "Created on" +msgstr "Creado el" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_activity +msgid "Data processing activities" +msgstr "Actividades de tratamiento de datos" + +#. module: privacy_consent +#: model:mail.template,subject:privacy_consent.template_consent +msgid "" +"Data processing consent request for ${object.activity_id.display_name|safe}" +msgstr "" +"Solicitud de consentimiento para el tratamiento de datos personales para " +"${object.activity_id.display_name|safe}" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Draft" +msgstr "Borrador" + +#. module: privacy_consent +#: sql_constraint:privacy.consent:0 +msgid "Duplicated partner in this data processing activity" +msgstr "Contacto duplicado en esta actividad de tratamiento" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_template +msgid "Email Templates" +msgstr "Plantillas de correo electrónico" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Asistente de redacción de correo electrónico" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email template" +msgstr "Plantilla de correo electrónico" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id +msgid "" +"Email to be sent to subjects to ask for consent. A good template should " +"include details about the current consent request status, how to change it, " +"and where to get more information." +msgstr "" +"Correo electrónico a enviar a los interesados para solicitarles el " +"consentimiento. Una buena plantilla debería incluir detalles sobre el estado " +"actual del consentimiento, cómo cambiarlo, y dónde obtener más información." + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required +msgid "" +"Enable if you need to track any kind of consent from the affected subjects" +msgstr "" +"Actívelo si necesita registrar cualquier tipo de consentimiento de los " +"interesados." + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate and send missing consent requests" +msgstr "Generar y enviar solicitudes de consentimiento faltantes" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate missing draft consent requests" +msgstr "Generar borradores de las solicitudes de consentimiento faltantes" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:140 +#, python-format +msgid "Generated consents" +msgstr "Consentimientos generados" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Group By" +msgstr "Agrupar por" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Hello," +msgstr "Hola," + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I accept this processing of my data" +msgstr "Acepto este tratamiento de mis datos" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I reject this processing of my data" +msgstr "Rechazo este tratamiento de mis datos" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id +msgid "ID" +msgstr "ID" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "If it was a mistake, you can undo it here:" +msgstr "Si ha sido un error, puede deshacerlo aquí:" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted +msgid "" +"Indicates current acceptance status, which can come from subject's last " +"answer, or from the default specified in the related data processing " +"activity." +msgstr "" +"Indica el estado actual de la aceptación, el cual puede venir de la última " +"respuesta del interesado, o del estado por defecto especificado en la " +"actividad de tratamiento relacionada." + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata +msgid "Last metadata" +msgstr "Últimos metadatos" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Manually" +msgstr "Manualmente" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata +msgid "Metadata from the last acceptance or rejection by the subject" +msgstr "" +"Metadatos de la última aceptación o denegación por parte del interesado" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/mail_template.py:25 +#, python-format +msgid "" +"Missing privacy consent link placeholders. You need at least these two " +"links:\n" +"Accept\n" +"Reject" +msgstr "" +"Faltan los marcadores de posición de los enlaces para el consentimiento. " +"Necesita al menos estos dos enlaces:\n" +"Aceptar\n" +"Rechazar" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new +msgid "New Consent" +msgstr "Nuevo consentimiento" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_mail +msgid "Outgoing Mails" +msgstr "Correos electrónicos salientes" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_res_partner +msgid "Partner" +msgstr "Contacto" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed +msgid "Privacy consent request acceptance status changed" +msgstr "" +"El estado de aceptación de la solicitud de consentimiento para el " +"tratamiento de datos ha cambiado" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new +msgid "Privacy consent request created" +msgstr "" +"La solicitud de consentimiento para el tratamiento de datos ha sido creada" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed +msgid "Privacy consent request state changed" +msgstr "" +"El estado de la solicitud de consentimiento para el tratamiento de datos ha " +"cambiado" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count +msgid "Privacy consent requests amount" +msgstr "Cantidad de solicitudes de consentimiento para el tratamiento de datos" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids +msgid "Privacy consents" +msgstr "Consentimientos para el tratamiento de datos" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:100 +#, python-format +msgid "Require consent is available only for subjects in current database." +msgstr "" +"La opción de exigir consentimiento solo está disponible para interesados que " +"se encuentren en esta misma base de datos." + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id +msgid "" +"Run this action when a new consent request is created or its acceptance " +"status is updated." +msgstr "" +"Ejecutar esta acción cuando se cree una nueva solicitud de consentimiento, o " +"cuando su estado de aceptación cambie." + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id +msgid "Server action" +msgstr "Acción de servidor" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent +msgid "Should we assume the subject has accepted if we receive no response?" +msgstr "" +"¿Hay que asumir que el interesado ha aceptado si no recibimos respuesta?" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Sincerely,
" +msgstr "Atentamente,
" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:92 +#, python-format +msgid "Specify a mail template to ask automated consent." +msgstr "" +"Especifique una plantilla de correo electrónico para solicitar " +"automáticamente el consentimiento." + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "State" +msgstr "Estado" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed +msgid "State Changed" +msgstr "El estado ha cambiado" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id +msgid "Subject" +msgstr "Interesado" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id +msgid "Subject asked for consent." +msgstr "Interesado a quien se le pide el consentimiento." + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thank you!" +msgstr "¡Gracias!" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thanks for your response." +msgstr "Gracias por su respuesta." + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "This could send many consent emails, are you sure to proceed?" +msgstr "" +"Esto podría enviar muchos correos electrónicos solicitando consentimiento " +"para el tratamiento de datos, ¿seguro que quiere continuar?" + +#. module: privacy_consent +#: model:ir.actions.server,name:privacy_consent.update_opt_out +msgid "Update partner's opt out" +msgstr "Sincronizar la opción del contacto para recibir o no envíos masivos" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "" +"We asked you to authorize us to process your data in this data processing " +"activity:" +msgstr "" +"Le hemos solicitado que nos autorice para procesar sus datos personales en " +"esta actividad de tratamiento:" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We have recorded this action on your side." +msgstr "Hemos registrado esta acción por su parte." + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have rejected such processing." +msgstr "Ha rechazado dicho tratamiento." + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have accepted such processing." +msgstr "Ha aceptado dicho tratamiento." diff --git a/privacy_consent/models/__init__.py b/privacy_consent/models/__init__.py new file mode 100644 index 0000000..e776de3 --- /dev/null +++ b/privacy_consent/models/__init__.py @@ -0,0 +1,5 @@ +from . import mail_mail +from . import mail_template +from . import privacy_activity +from . import privacy_consent +from . import res_partner diff --git a/privacy_consent/models/mail_mail.py b/privacy_consent/models/mail_mail.py new file mode 100644 index 0000000..e53e7fc --- /dev/null +++ b/privacy_consent/models/mail_mail.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class MailMail(models.Model): + _inherit = "mail.mail" + + def _postprocess_sent_message(self, mail_sent=True): + """Write consent status after sending message.""" + if mail_sent and self.env.context.get('mark_consent_sent'): + # Get all mails sent to consents + consent_mails = self.filtered( + lambda one: one.mail_message_id.model == "privacy.consent" + ) + # Get related draft consents + consents = self.env["privacy.consent"].browse( + consent_mails.mapped("mail_message_id.res_id"), + self._prefetch + ).filtered(lambda one: one.state == "draft") + # Set as sent + consents.write({ + "state": "sent", + }) + return super(MailMail, self)._postprocess_sent_message(mail_sent) + + def send_get_mail_body(self, partner=None): + """Replace privacy consent magic links. + + This replacement is done here instead of directly writing it into + the ``mail.template`` to avoid writing the tokeinzed URL + in the mail thread for the ``privacy.consent`` record, + which would enable any reader of such thread to impersonate the + subject and choose in its behalf. + """ + result = super(MailMail, self).send_get_mail_body(partner=partner) + # Avoid polluting other model mails + if self.env.context.get("active_model") != "privacy.consent": + return result + # Tokenize consent links + consent = self.env["privacy.consent"] \ + .browse(self.mail_message_id.res_id) \ + .with_prefetch(self._prefetch) + result = result.replace( + "/privacy/consent/accept/", + consent._url(True), + ) + result = result.replace( + "/privacy/consent/reject/", + consent._url(False), + ) + return result diff --git a/privacy_consent/models/mail_template.py b/privacy_consent/models/mail_template.py new file mode 100644 index 0000000..a5fcec2 --- /dev/null +++ b/privacy_consent/models/mail_template.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from lxml import html + +from odoo import _, api, models +from odoo.exceptions import ValidationError + + +class MailTemplate(models.Model): + _inherit = "mail.template" + + @api.constrains("body_html", "model") + def _check_consent_links_in_body_html(self): + """Body for ``privacy.consent`` templates needs placeholder links.""" + links = [u"//a[@href='/privacy/consent/{}/']".format(action) + for action in ("accept", "reject")] + for one in self: + if one.model != "privacy.consent": + continue + doc = html.document_fromstring(one.body_html) + for link in links: + if not doc.xpath(link): + raise ValidationError(_( + "Missing privacy consent link placeholders. " + "You need at least these two links:\n" + 'Accept\n' + 'Reject' + ) % ( + "/privacy/consent/accept/", + "/privacy/consent/reject/", + )) diff --git a/privacy_consent/models/privacy_activity.py b/privacy_consent/models/privacy_activity.py new file mode 100644 index 0000000..c7d20c9 --- /dev/null +++ b/privacy_consent/models/privacy_activity.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools.safe_eval import safe_eval + + +class PrivacyActivity(models.Model): + _inherit = 'privacy.activity' + + server_action_id = fields.Many2one( + "ir.actions.server", + "Server action", + domain=[ + ("model_id.model", "=", "privacy.consent"), + ], + help="Run this action when a new consent request is created or its " + "acceptance status is updated.", + ) + consent_ids = fields.One2many( + "privacy.consent", + "activity_id", + "Consents", + ) + consent_count = fields.Integer( + "Consents", + compute="_compute_consent_count", + ) + consent_required = fields.Selection( + [("auto", "Automatically"), ("manual", "Manually")], + "Ask subjects for consent", + help="Enable if you need to track any kind of consent " + "from the affected subjects", + ) + consent_template_id = fields.Many2one( + "mail.template", + "Email template", + default=lambda self: self._default_consent_template_id(), + domain=[ + ("model", "=", "privacy.consent"), + ], + help="Email to be sent to subjects to ask for consent. " + "A good template should include details about the current " + "consent request status, how to change it, and where to " + "get more information.", + ) + default_consent = fields.Boolean( + "Accepted by default", + help="Should we assume the subject has accepted if we receive no " + "response?", + ) + + # Hidden helpers help user design new templates + consent_template_default_body_html = fields.Text( + compute="_compute_consent_template_defaults", + ) + consent_template_default_subject = fields.Char( + compute="_compute_consent_template_defaults", + ) + + @api.model + def _default_consent_template_id(self): + return self.env.ref("privacy_consent.template_consent", False) + + @api.depends("consent_ids") + def _compute_consent_count(self): + groups = self.env["privacy.consent"].read_group( + [("activity_id", "in", self.ids)], + ["activity_id"], + ["activity_id"], + ) + for group in groups: + self.browse(group["activity_id"][0], self._prefetch) \ + .consent_count = group["activity_id_count"] + + def _compute_consent_template_defaults(self): + """Used in context values, to help users design new templates.""" + template = self._default_consent_template_id() + if template: + self.update({ + "consent_template_default_body_html": template.body_html, + "consent_template_default_subject": template.subject, + }) + + @api.constrains("consent_required", "consent_template_id") + def _check_auto_consent_has_template(self): + """Require a mail template to automate consent requests.""" + for one in self: + if one.consent_required == "auto" and not one.consent_template_id: + raise ValidationError(_( + "Specify a mail template to ask automated consent." + )) + + @api.constrains("consent_required", "subject_find") + def _check_consent_required_subject_find(self): + for one in self: + if one.consent_required and not one.subject_find: + raise ValidationError(_( + "Require consent is available only for subjects " + "in current database." + )) + + @api.model + def _cron_new_consents(self): + """Ask all missing automatic consent requests.""" + automatic = self.search([("consent_required", "=", "auto")]) + automatic.action_new_consents() + + @api.onchange("consent_required") + def _onchange_consent_required_subject_find(self): + """Find subjects automatically if we require their consent.""" + if self.consent_required: + self.subject_find = True + + def action_new_consents(self): + """Generate new consent requests.""" + consents = self.env["privacy.consent"] + # Skip activitys where consent is not required + for one in self.with_context(active_test=False) \ + .filtered("consent_required"): + domain = safe_eval(one.subject_domain) + domain += [ + ("id", "not in", one.mapped("consent_ids.partner_id").ids), + ("email", "!=", False), + ] + # Create missing consent requests + for missing in self.env["res.partner"].search(domain): + consents |= consents.create({ + "partner_id": missing.id, + "accepted": one.default_consent, + "activity_id": one.id, + }) + # Send consent request emails for automatic activitys + consents.action_auto_ask() + # Redirect user to new consent requests generated + return { + "domain": [("id", "in", consents.ids)], + "name": _("Generated consents"), + "res_model": consents._name, + "type": "ir.actions.act_window", + "view_mode": "tree,form", + } diff --git a/privacy_consent/models/privacy_consent.py b/privacy_consent/models/privacy_consent.py new file mode 100644 index 0000000..6dacd97 --- /dev/null +++ b/privacy_consent/models/privacy_consent.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import hashlib +import hmac + +from odoo import api, fields, models + + +class PrivacyConsent(models.Model): + _name = 'privacy.consent' + _description = "Consent of data processing" + _inherit = "mail.thread" + _rec_name = "partner_id" + _sql_constraints = [ + ("unique_partner_activity", "UNIQUE(partner_id, activity_id)", + "Duplicated partner in this data processing activity"), + ] + + active = fields.Boolean( + default=True, + index=True, + ) + accepted = fields.Boolean( + track_visibility="onchange", + help="Indicates current acceptance status, which can come from " + "subject's last answer, or from the default specified in the " + "related data processing activity.", + ) + last_metadata = fields.Text( + readonly=True, + track_visibility="onchange", + help="Metadata from the last acceptance or rejection by the subject", + ) + partner_id = fields.Many2one( + "res.partner", + "Subject", + required=True, + readonly=True, + track_visibility="onchange", + help="Subject asked for consent.", + ) + activity_id = fields.Many2one( + "privacy.activity", + "Activity", + readonly=True, + required=True, + track_visibility="onchange", + ) + state = fields.Selection( + selection=[ + ("draft", "Draft"), + ("sent", "Awaiting response"), + ("answered", "Answered"), + ], + default="draft", + readonly=True, + required=True, + track_visibility="onchange", + ) + + def _track_subtype(self, init_values): + """Return specific subtypes.""" + if self.env.context.get("subject_answering"): + return "privacy_consent.mt_consent_acceptance_changed" + if "activity_id" in init_values or "partner_id" in init_values: + return "privacy_consent.mt_consent_consent_new" + if "state" in init_values: + return "privacy_consent.mt_consent_state_changed" + return super(PrivacyConsent, self)._track_subtype(init_values) + + def _token(self): + """Secret token to publicly authenticate this record.""" + secret = self.env["ir.config_parameter"].sudo().get_param( + "database.secret") + params = "{}-{}-{}-{}".format( + self.env.cr.dbname, + self.id, + self.partner_id.id, + self.activity_id.id, + ) + return hmac.new( + secret.encode('utf-8'), + params.encode('utf-8'), + hashlib.sha512, + ).hexdigest() + + def _url(self, accept): + """Tokenized URL to let subject decide consent. + + :param bool accept: + Indicates if you want the acceptance URL, or the rejection one. + """ + return "/privacy/consent/{}/{}/{}?db={}".format( + "accept" if accept else "reject", + self.id, + self._token(), + self.env.cr.dbname, + ) + + def _send_consent_notification(self): + """Send email notification to subject.""" + consents_by_template = {} + for one in self.with_context(tpl_force_default_to=True, + mail_notify_user_signature=False, + mail_auto_subscribe_no_notify=True, + mark_consent_sent=True): + # Group consents by template, to send in batch where possible + template_id = one.activity_id.consent_template_id.id + consents_by_template.setdefault(template_id, one) + consents_by_template[template_id] |= one + # Send emails + for template_id, consents in consents_by_template.items(): + consents.message_post_with_template( + template_id, + # This mode always sends email, regardless of partner's + # notification preferences; we use it here because it's very + # likely that we are asking authorisation to send emails + composition_mode="mass_mail", + ) + + def _run_action(self): + """Execute server action defined in data processing activity.""" + for one in self: + # Always skip draft consents + if one.state == "draft": + continue + action = one.activity_id.server_action_id.with_context( + active_id=one.id, + active_ids=one.ids, + active_model=one._name, + ) + action.run() + + @api.model + def create(self, vals): + """Run server action on create.""" + result = super(PrivacyConsent, self).create(vals) + # Sync the default acceptance status + result.sudo()._run_action() + return result + + def write(self, vals): + """Run server action on update.""" + result = super(PrivacyConsent, self).write(vals) + self._run_action() + return result + + def message_get_suggested_recipients(self): + result = super(PrivacyConsent, self) \ + .message_get_suggested_recipients() + reason = self._fields["partner_id"].string + for one in self: + one._message_add_suggested_recipient( + result, + partner=one.partner_id, + reason=reason, + ) + return result + + def action_manual_ask(self): + """Let user manually ask for consent.""" + return { + "context": { + "default_composition_mode": "mass_mail", + "default_model": self._name, + "default_res_id": self.id, + "default_template_id": self.activity_id.consent_template_id.id, + "default_use_template": True, + "mark_consent_sent": True, + "tpl_force_default_to": True, + }, + "force_email": True, + "res_model": "mail.compose.message", + "target": "new", + "type": "ir.actions.act_window", + "view_mode": "form", + } + + def action_auto_ask(self): + """Automatically ask for consent.""" + templated = self.filtered("activity_id.consent_template_id") + automated = templated.filtered( + lambda one: one.activity_id.consent_required == "auto") + automated._send_consent_notification() + + def action_answer(self, answer, metadata=False): + """Process answer. + + :param bool answer: + Did the subject accept? + + :param str metadata: + Metadata from last user acceptance or rejection request. + """ + self.write({ + "state": "answered", + "accepted": answer, + "last_metadata": metadata, + }) diff --git a/privacy_consent/models/res_partner.py b/privacy_consent/models/res_partner.py new file mode 100644 index 0000000..b97eab5 --- /dev/null +++ b/privacy_consent/models/res_partner.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# 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" + + privacy_consent_ids = fields.One2many( + "privacy.consent", + "partner_id", + "Privacy consents", + ) + privacy_consent_count = fields.Integer( + "Consents", + compute="_compute_privacy_consent_count", + help="Privacy consent requests amount", + ) + + @api.depends("privacy_consent_ids") + def _compute_privacy_consent_count(self): + """Count consent requests.""" + groups = self.env["privacy.consent"].read_group( + [("partner_id", "in", self.ids)], + ["partner_id"], + ["partner_id"], + ) + for group in groups: + self.browse(group["partner_id"][0], self._prefetch) \ + .privacy_consent_count = group["partner_id_count"] diff --git a/privacy_consent/readme/CONTRIBUTORS.rst b/privacy_consent/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..8c4d968 --- /dev/null +++ b/privacy_consent/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Tecnativa `_: + + * Jairo Llopis diff --git a/privacy_consent/readme/DESCRIPTION.rst b/privacy_consent/readme/DESCRIPTION.rst new file mode 100644 index 0000000..dfce06f --- /dev/null +++ b/privacy_consent/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +This module allows the user to define a set of subjects (partners) +affected by any data processing activity, and establish +a process to ask them for consent to include them in that activity. + +For those that need explicit consent as a lawfulness base for personal data +processing, as required by GDPR (article 6.1.a), this module provides the +needed tools to automate it. diff --git a/privacy_consent/readme/INSTALL.rst b/privacy_consent/readme/INSTALL.rst new file mode 100644 index 0000000..dabd03d --- /dev/null +++ b/privacy_consent/readme/INSTALL.rst @@ -0,0 +1,15 @@ +You may want to install, along with this module, one of OCA's +``mail_tracking`` module collection, such as ``mail_tracking_mailgun``, so +you can provide more undeniable proof that some consent request was sent, and +to whom. + +However, the most important proof to provide is the answer itself (more than +the question), and this addon provides enough tooling for that. + +Multi-database instances +~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable multi-database support, you must load this addon as a server-wide +addon. Example command to boot Odoo:: + + odoo-bin --load=web,privacy_consent diff --git a/privacy_consent/readme/USAGE.rst b/privacy_consent/readme/USAGE.rst new file mode 100644 index 0000000..68d4aec --- /dev/null +++ b/privacy_consent/readme/USAGE.rst @@ -0,0 +1,69 @@ +New options for data processing activities: + +#. Go to *Privacy > Master Data > Activities* and create one. + +#. Give it a name, such as *Sending mass mailings to customers*. + +#. Go to tab *Consent* and choose one option in *Ask subjects for consent*: + + * *Manual* tells the activity that you will want to create and send the + consent requests manually, and only provides some helpers for you to + be able to batch-generate them. + + * *Automatic* enables this module's full power: send all consent requests + to selected partners automatically, every day and under your demand. + +#. When you do this, all the consent-related options appear. Configure them: + + * A smart button tells you how many consents have been generated, and lets you + access them. + + * Choose one *Email template* to send to subjects. This email itself is what + asks for consent, and it gets recorded, to serve as a proof that it was sent. + The module provides a default template that should be good for most usage + cases; and if you create one directly from that field, some good defaults + are provided for your comfortability. + + * *Subjects filter* defines what partners will be elegible for inclusion in + this data processing activity. + + * You can enable *Accepted by default* if you want to assume subjects + accepted their data processing. You should possibly consult your + lawyer to use this. + + * You can choose a *Server action* (developer mode only) that will + be executed whenever a new non-draft consent request is created, + or when its acceptance status changes. + + This module supplies a server action by default, called + *Update partner's opt out*, that syncs the acceptance status with the + partner's *Elegible for mass mailings* option. + +#. Click on *Generate consent requests* link to create new consent requests. + + * If you chose *Manual* mode, all missing consent request are created as + drafts, and nothing else is done now. + + * If you chose *Automatic* mode, also those requests are sent to subjects + and set as *Sent*. + +#. You will be presented with the list of just-created consent requests. + See below. + +New options for consent requests: + +#. Access the consent requests by either: + + * Generating new consent requests from a data processing activity. + + * Pressing the *Consents* smart button in a data processing activity. + + * Going to *Privacy > Privacy > Consents*. + +#. A consent will include the partner, the activity, the acceptance status, + and the request state. + +#. You can manually ask for consent by pressing the button labeled as + *Ask for consent*. + +#. All consent requests and responses are recorded in the mail thread below. diff --git a/privacy_consent/security/ir.model.access.csv b/privacy_consent/security/ir.model.access.csv new file mode 100644 index 0000000..28285e4 --- /dev/null +++ b/privacy_consent/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +privacy_consent_read,Permission to read consents,model_privacy_consent,privacy.group_data_protection_user,1,0,0,0 +privacy_consent_write,Permission to write consents,model_privacy_consent,privacy.group_data_protection_manager,1,1,1,1 diff --git a/privacy_consent/static/description/icon.png b/privacy_consent/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/privacy_consent/templates/form.xml b/privacy_consent/templates/form.xml new file mode 100644 index 0000000..b0e260b --- /dev/null +++ b/privacy_consent/templates/form.xml @@ -0,0 +1,63 @@ + + + + + + + + diff --git a/privacy_consent/tests/__init__.py b/privacy_consent/tests/__init__.py new file mode 100644 index 0000000..42ba786 --- /dev/null +++ b/privacy_consent/tests/__init__.py @@ -0,0 +1 @@ +from . import test_consent diff --git a/privacy_consent/tests/test_consent.py b/privacy_consent/tests/test_consent.py new file mode 100644 index 0000000..7af0a90 --- /dev/null +++ b/privacy_consent/tests/test_consent.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from contextlib import contextmanager + +from odoo.exceptions import ValidationError +from odoo.tests.common import at_install, post_install, HttpCase + + +@at_install(False) +@post_install(True) +class ActivityCase(HttpCase): + def setUp(self): + super(ActivityCase, self).setUp() + # HACK https://github.com/odoo/odoo/issues/12237 + # TODO Remove hack in v12 + self._oldenv = self.env + self.env = self._oldenv(self.cursor()) + # HACK end + self.cron = self.env.ref("privacy_consent.cron_auto_consent") + self.update_opt_out = self.env.ref("privacy_consent.update_opt_out") + self.mt_consent_consent_new = self.env.ref( + "privacy_consent.mt_consent_consent_new") + self.mt_consent_acceptance_changed = self.env.ref( + "privacy_consent.mt_consent_acceptance_changed") + self.mt_consent_state_changed = self.env.ref( + "privacy_consent.mt_consent_state_changed") + # Some partners to ask for consent + self.partners = self.env["res.partner"] + self.partners += self.partners.create({ + "name": "consent-partner-0", + "email": "partner0@example.com", + "notify_email": "none", + "opt_out": False, + }) + self.partners += self.partners.create({ + "name": "consent-partner-1", + "email": "partner1@example.com", + "notify_email": "always", + "opt_out": True, + }) + self.partners += self.partners.create({ + "name": "consent-partner-2", + "email": "partner2@example.com", + "opt_out": False, + }) + # Partner without email, on purpose + self.partners += self.partners.create({ + "name": "consent-partner-3", + "opt_out": True, + }) + # Activity without consent + self.activity_noconsent = self.env["privacy.activity"].create({ + "name": "activity_noconsent", + "description": "I'm activity 1", + }) + # Activity with auto consent, for all partners + self.activity_auto = self.env["privacy.activity"].create({ + "name": "activity_auto", + "description": "I'm activity auto", + "subject_find": True, + "subject_domain": repr([("id", "in", self.partners.ids)]), + "consent_required": "auto", + "default_consent": True, + "server_action_id": self.update_opt_out.id, + }) + # Activity with manual consent, skipping partner 0 + self.activity_manual = self.env["privacy.activity"].create({ + "name": "activity_manual", + "description": "I'm activity 3", + "subject_find": True, + "subject_domain": repr([("id", "in", self.partners[1:].ids)]), + "consent_required": "manual", + "default_consent": False, + "server_action_id": self.update_opt_out.id, + }) + + # HACK https://github.com/odoo/odoo/issues/12237 + # TODO Remove hack in v12 + def tearDown(self): + self.env = self._oldenv + super(ActivityCase, self).tearDown() + + # HACK https://github.com/odoo/odoo/issues/12237 + # TODO Remove hack in v12 + @contextmanager + def release_cr(self): + self.env.cr.release() + yield + self.env.cr.acquire() + + def check_activity_auto_properly_sent(self): + """Check emails sent by ``self.activity_auto``.""" + consents = self.env["privacy.consent"].search([ + ("activity_id", "=", self.activity_auto.id), + ]) + # Check sent mails + for consent in consents: + self.assertEqual(consent.state, "sent") + messages = consent.mapped("message_ids") + self.assertEqual(len(messages), 4) + # 2nd message notifies creation + self.assertEqual( + messages[2].subtype_id, + self.mt_consent_consent_new, + ) + # 3rd message notifies subject + # Placeholder links should be logged + self.assertTrue("/privacy/consent/accept/" in messages[1].body) + self.assertTrue("/privacy/consent/reject/" in messages[1].body) + # Tokenized links shouldn't be logged + self.assertFalse(consent._url(True) in messages[1].body) + self.assertFalse(consent._url(False) in messages[1].body) + # 4th message contains the state change + self.assertEqual( + messages[0].subtype_id, + self.mt_consent_state_changed, + ) + # Partner's opt_out should be synced with default consent + self.assertFalse(consent.partner_id.opt_out) + + def test_default_template(self): + """We have a good mail template by default.""" + good = self.env.ref("privacy_consent.template_consent") + self.assertEqual( + self.activity_noconsent.consent_template_id, + good, + ) + self.assertEqual( + self.activity_noconsent.consent_template_default_body_html, + good.body_html, + ) + self.assertEqual( + self.activity_noconsent.consent_template_default_subject, + good.subject, + ) + + def test_find_subject_if_consent_required(self): + """If user wants to require consent, it needs subjects.""" + # Test the onchange helper + onchange_activity1 = self.env["privacy.activity"].new( + self.activity_noconsent.copy_data()[0]) + self.assertFalse(onchange_activity1.subject_find) + onchange_activity1.consent_required = "auto" + onchange_activity1._onchange_consent_required_subject_find() + self.assertTrue(onchange_activity1.subject_find) + # Test very dumb user that forces an error + with self.assertRaises(ValidationError): + self.activity_noconsent.consent_required = "manual" + + def test_template_required_auto(self): + """Automatic consent activities need a template.""" + self.activity_noconsent.subject_find = True + self.activity_noconsent.consent_template_id = False + self.activity_noconsent.consent_required = "manual" + with self.assertRaises(ValidationError): + self.activity_noconsent.consent_required = "auto" + + def test_generate_manually(self): + """Manually-generated consents work as expected.""" + self.partners.write({"opt_out": False}) + result = self.activity_manual.action_new_consents() + self.assertEqual(result["res_model"], "privacy.consent") + consents = self.env[result["res_model"]].search(result["domain"]) + self.assertEqual(consents.mapped("state"), ["draft"] * 2) + self.assertEqual(consents.mapped("partner_id.opt_out"), [False] * 2) + self.assertEqual(consents.mapped("accepted"), [False] * 2) + self.assertEqual(consents.mapped("last_metadata"), [False] * 2) + # Check sent mails + messages = consents.mapped("message_ids") + self.assertEqual(len(messages), 4) + subtypes = messages.mapped("subtype_id") + self.assertTrue(subtypes & self.mt_consent_consent_new) + self.assertFalse(subtypes & self.mt_consent_acceptance_changed) + self.assertFalse(subtypes & self.mt_consent_state_changed) + # Send one manual request + action = consents[0].action_manual_ask() + self.assertEqual(action["res_model"], "mail.compose.message") + composer = self.env[action["res_model"]] \ + .with_context(active_ids=consents[0].ids, + active_model=consents._name, + **action["context"]).create({}) + composer.onchange_template_id_wrapper() + composer.send_mail() + messages = consents.mapped("message_ids") - messages + self.assertEqual(len(messages), 2) + self.assertEqual(messages[0].subtype_id, self.mt_consent_state_changed) + self.assertEqual(consents.mapped("state"), ["sent", "draft"]) + self.assertEqual(consents.mapped("partner_id.opt_out"), [True, False]) + # Placeholder links should be logged + self.assertTrue("/privacy/consent/accept/" in messages[1].body) + self.assertTrue("/privacy/consent/reject/" in messages[1].body) + # Tokenized links shouldn't be logged + accept_url = consents[0]._url(True) + reject_url = consents[0]._url(False) + self.assertNotIn(accept_url, messages[1].body) + self.assertNotIn(reject_url, messages[1].body) + # Visit tokenized accept URL + with self.release_cr(): + result = self.url_open(accept_url).read() + self.assertIn("accepted", result) + self.assertIn(reject_url, result) + self.assertIn(self.activity_manual.name, result) + self.assertIn(self.activity_manual.description, result) + consents.invalidate_cache() + self.assertEqual(consents.mapped("accepted"), [True, False]) + self.assertTrue(consents[0].last_metadata) + self.assertFalse(consents[0].partner_id.opt_out) + self.assertEqual(consents.mapped("state"), ["answered", "draft"]) + self.assertEqual( + consents[0].message_ids[0].subtype_id, + self.mt_consent_acceptance_changed, + ) + # Visit tokenized reject URL + with self.release_cr(): + result = self.url_open(reject_url).read() + self.assertIn("rejected", result) + self.assertIn(accept_url, result) + self.assertIn(self.activity_manual.name, result) + self.assertIn(self.activity_manual.description, result) + consents.invalidate_cache() + self.assertEqual(consents.mapped("accepted"), [False, False]) + self.assertTrue(consents[0].last_metadata) + self.assertTrue(consents[0].partner_id.opt_out) + self.assertEqual(consents.mapped("state"), ["answered", "draft"]) + self.assertEqual( + consents[0].message_ids[0].subtype_id, + self.mt_consent_acceptance_changed, + ) + self.assertFalse(consents[1].last_metadata) + + def test_generate_automatically(self): + """Automatically-generated consents work as expected.""" + result = self.activity_auto.action_new_consents() + self.assertEqual(result["res_model"], "privacy.consent") + self.check_activity_auto_properly_sent() + + def test_generate_cron(self): + """Cron-generated consents work as expected.""" + self.cron.method_direct_trigger() + self.check_activity_auto_properly_sent() + + def test_mail_template_without_links(self): + """Cannot create mail template without needed links.""" + with self.assertRaises(ValidationError): + self.activity_manual.consent_template_id.body_html = "No links :(" diff --git a/privacy_consent/views/privacy_activity.xml b/privacy_consent/views/privacy_activity.xml new file mode 100644 index 0000000..35c9e5f --- /dev/null +++ b/privacy_consent/views/privacy_activity.xml @@ -0,0 +1,89 @@ + + + + + + + Add consent fields + privacy.activity + + +
+ + +
+ + + + + + + + + + + + + + + + + + +
+
+ +
diff --git a/privacy_consent/views/privacy_consent.xml b/privacy_consent/views/privacy_consent.xml new file mode 100644 index 0000000..5526a03 --- /dev/null +++ b/privacy_consent/views/privacy_consent.xml @@ -0,0 +1,113 @@ + + + + + + + Privacy Consent Form + privacy.consent + +
+
+
+ +
+ +
+ + + + + + +
+
+ + +
+
+
+
+ + + Privacy Consent Tree + privacy.consent + + + + + + + + + + + + Privacy Consent Search + privacy.consent + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/privacy_consent/views/res_partner.xml b/privacy_consent/views/res_partner.xml new file mode 100644 index 0000000..d1173d9 --- /dev/null +++ b/privacy_consent/views/res_partner.xml @@ -0,0 +1,35 @@ + + + + + + + Add consent smart button + res.partner + + + +
+ + +
+
+
+ +
diff --git a/privacy_consent/wizards/__init__.py b/privacy_consent/wizards/__init__.py new file mode 100644 index 0000000..b528d99 --- /dev/null +++ b/privacy_consent/wizards/__init__.py @@ -0,0 +1 @@ +from . import mail_compose_message diff --git a/privacy_consent/wizards/mail_compose_message.py b/privacy_consent/wizards/mail_compose_message.py new file mode 100644 index 0000000..a63ecc1 --- /dev/null +++ b/privacy_consent/wizards/mail_compose_message.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Jairo Llopis +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class MailComposeMessage(models.TransientModel): + _inherit = "mail.compose.message" + + @api.multi + def send_mail(self, auto_commit=False): + """Force auto commit when sending consent emails.""" + if self.env.context.get('mark_consent_sent'): + auto_commit = True + return super(MailComposeMessage, self).send_mail(auto_commit) From e5a2c97f69cf721088d2fec7562a64cbfe94af4c Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 8 Aug 2018 16:00:43 +0000 Subject: [PATCH 02/30] Update privacy_consent.pot --- privacy_consent/i18n/es.po | 4 +- privacy_consent/i18n/privacy_consent.pot | 487 +++++++++++++++++++++++ 2 files changed, 489 insertions(+), 2 deletions(-) create mode 100644 privacy_consent/i18n/privacy_consent.pot diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index b830d8e..1285c92 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -8,14 +8,14 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-07-11 08:38+0000\n" "PO-Revision-Date: 2018-07-11 11:07+0200\n" +"Last-Translator: Jairo Llopis \n" "Language-Team: \n" +"Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.0.8\n" -"Last-Translator: Jairo Llopis \n" -"Language: es_ES\n" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot new file mode 100644 index 0000000..51f7871 --- /dev/null +++ b/privacy_consent/i18n/privacy_consent.pot @@ -0,0 +1,487 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_consent +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: privacy_consent +#: model:mail.template,body_html:privacy_consent.template_consent +msgid "\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hello, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" +" ${object.activity_id.display_name|safe}, property of\n" +" ${object.activity_id.controller_id.display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" The last time you answered, you\n" +" % elif object.state == \"sent\":\n" +" If you do nothing, we will assume you have\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" accepted\n" +" % else:\n" +" rejected\n" +" % endif\n" +" such data processing.\n" +"

\n" +"

\n" +" You can update your preferences below:\n" +"

\n" +"
\n" +" \n" +" Accept\n" +" \n" +" \n" +" \n" +" Reject\n" +" \n" +"
\n" +"

\n" +" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +"

\n" +"

\n" +" Thank you!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Sent by\n" +" ${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed +msgid "Acceptance Changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance Changed by Subject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance status updated by subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Accepted" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent +msgid "Accepted by default" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active +msgid "Active" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Activity" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Answered" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Archived" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_form +msgid "Ask for consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required +msgid "Ask subjects for consent" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Automatically" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Awaiting response" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_consent +msgid "Consent of data processing" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html +msgid "Consent template default body html" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject +msgid "Consent template default subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.act_window,name:privacy_consent.consent_action +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count +#: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent +msgid "Consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid +msgid "Created by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date +msgid "Created on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_activity +msgid "Data processing activities" +msgstr "" + +#. module: privacy_consent +#: model:mail.template,subject:privacy_consent.template_consent +msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name +msgid "Display Name" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Draft" +msgstr "" + +#. module: privacy_consent +#: sql_constraint:privacy.consent:0 +msgid "Duplicated partner in this data processing activity" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email template" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required +msgid "Enable if you need to track any kind of consent from the affected subjects" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate and send missing consent requests" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate missing draft consent requests" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:140 +#, python-format +msgid "Generated consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Group By" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Hello," +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I accept this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I reject this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id +msgid "ID" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "If it was a mistake, you can undo it here:" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted +msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update +msgid "Last Modified on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date +msgid "Last Updated on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata +msgid "Last metadata" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Manually" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata +msgid "Metadata from the last acceptance or rejection by the subject" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/mail_template.py:25 +#, python-format +msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +"Accept\n" +"Reject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new +msgid "New Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_res_partner +msgid "Partner" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed +msgid "Privacy consent request acceptance status changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new +msgid "Privacy consent request created" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed +msgid "Privacy consent request state changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count +msgid "Privacy consent requests amount" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids +msgid "Privacy consents" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:100 +#, python-format +msgid "Require consent is available only for subjects in current database." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id +msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id +msgid "Server action" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent +msgid "Should we assume the subject has accepted if we receive no response?" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Sincerely,
" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:92 +#, python-format +msgid "Specify a mail template to ask automated consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "State" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed +msgid "State Changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id +msgid "Subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id +msgid "Subject asked for consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thank you!" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thanks for your response." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "This could send many consent emails, are you sure to proceed?" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.server,name:privacy_consent.update_opt_out +msgid "Update partner's opt out" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We asked you to authorize us to process your data in this data processing activity:" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We have recorded this action on your side." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have rejected such processing." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have accepted such processing." +msgstr "" + From ca8e76c2402941cea2c4b4992668b1a6a1546b53 Mon Sep 17 00:00:00 2001 From: OCA Git Bot Date: Thu, 9 Aug 2018 04:46:46 +0200 Subject: [PATCH 03/30] README.rst --- privacy_consent/README.rst | 172 +++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/privacy_consent/README.rst b/privacy_consent/README.rst index 8b13789..4f92832 100644 --- a/privacy_consent/README.rst +++ b/privacy_consent/README.rst @@ -1 +1,173 @@ +================= +Privacy - Consent +================= +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fdata--protection-lightgray.png?logo=github + :target: https://github.com/OCA/data-protection/tree/10.0/privacy_consent + :alt: OCA/data-protection +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/263/10.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows the user to define a set of subjects (partners) +affected by any data processing activity, and establish +a process to ask them for consent to include them in that activity. + +For those that need explicit consent as a lawfulness base for personal data +processing, as required by GDPR (article 6.1.a), this module provides the +needed tools to automate it. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +You may want to install, along with this module, one of OCA's +``mail_tracking`` module collection, such as ``mail_tracking_mailgun``, so +you can provide more undeniable proof that some consent request was sent, and +to whom. + +However, the most important proof to provide is the answer itself (more than +the question), and this addon provides enough tooling for that. + +Multi-database instances +~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable multi-database support, you must load this addon as a server-wide +addon. Example command to boot Odoo:: + + odoo-bin --load=web,privacy_consent + +Usage +===== + +New options for data processing activities: + +#. Go to *Privacy > Master Data > Activities* and create one. + +#. Give it a name, such as *Sending mass mailings to customers*. + +#. Go to tab *Consent* and choose one option in *Ask subjects for consent*: + + * *Manual* tells the activity that you will want to create and send the + consent requests manually, and only provides some helpers for you to + be able to batch-generate them. + + * *Automatic* enables this module's full power: send all consent requests + to selected partners automatically, every day and under your demand. + +#. When you do this, all the consent-related options appear. Configure them: + + * A smart button tells you how many consents have been generated, and lets you + access them. + + * Choose one *Email template* to send to subjects. This email itself is what + asks for consent, and it gets recorded, to serve as a proof that it was sent. + The module provides a default template that should be good for most usage + cases; and if you create one directly from that field, some good defaults + are provided for your comfortability. + + * *Subjects filter* defines what partners will be elegible for inclusion in + this data processing activity. + + * You can enable *Accepted by default* if you want to assume subjects + accepted their data processing. You should possibly consult your + lawyer to use this. + + * You can choose a *Server action* (developer mode only) that will + be executed whenever a new non-draft consent request is created, + or when its acceptance status changes. + + This module supplies a server action by default, called + *Update partner's opt out*, that syncs the acceptance status with the + partner's *Elegible for mass mailings* option. + +#. Click on *Generate consent requests* link to create new consent requests. + + * If you chose *Manual* mode, all missing consent request are created as + drafts, and nothing else is done now. + + * If you chose *Automatic* mode, also those requests are sent to subjects + and set as *Sent*. + +#. You will be presented with the list of just-created consent requests. + See below. + +New options for consent requests: + +#. Access the consent requests by either: + + * Generating new consent requests from a data processing activity. + + * Pressing the *Consents* smart button in a data processing activity. + + * Going to *Privacy > Privacy > Consents*. + +#. A consent will include the partner, the activity, the acceptance status, + and the request state. + +#. You can manually ask for consent by pressing the button labeled as + *Ask for consent*. + +#. All consent requests and responses are recorded in the mail thread below. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * Jairo Llopis + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +This module is part of the `OCA/data-protection `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. From 295e63a75373dc781e866daabd6ebb8985d661e7 Mon Sep 17 00:00:00 2001 From: OCA Git Bot Date: Fri, 24 Aug 2018 04:47:52 +0200 Subject: [PATCH 04/30] README.rst --- privacy_consent/static/description/index.html | 520 ++++++++++++++++++ 1 file changed, 520 insertions(+) create mode 100644 privacy_consent/static/description/index.html diff --git a/privacy_consent/static/description/index.html b/privacy_consent/static/description/index.html new file mode 100644 index 0000000..58af3e3 --- /dev/null +++ b/privacy_consent/static/description/index.html @@ -0,0 +1,520 @@ + + + + + + +Privacy - Consent + + + + + + From f543b9ea17309fcfb1ca4392a3e78ba1fe425fb9 Mon Sep 17 00:00:00 2001 From: Pedro Castro Silva Date: Thu, 20 Sep 2018 15:34:04 +0000 Subject: [PATCH 05/30] Added translation using Weblate (Portuguese) --- privacy_consent/i18n/pt.po | 487 +++++++++++++++++++++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 privacy_consent/i18n/pt.po diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po new file mode 100644 index 0000000..09d2ca6 --- /dev/null +++ b/privacy_consent/i18n/pt.po @@ -0,0 +1,487 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_consent +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: privacy_consent +#: model:mail.template,body_html:privacy_consent.template_consent +msgid "\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hello, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" +" ${object.activity_id.display_name|safe}, property of\n" +" ${object.activity_id.controller_id.display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" The last time you answered, you\n" +" % elif object.state == \"sent\":\n" +" If you do nothing, we will assume you have\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" accepted\n" +" % else:\n" +" rejected\n" +" % endif\n" +" such data processing.\n" +"

\n" +"

\n" +" You can update your preferences below:\n" +"

\n" +"
\n" +" \n" +" Accept\n" +" \n" +" \n" +" \n" +" Reject\n" +" \n" +"
\n" +"

\n" +" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +"

\n" +"

\n" +" Thank you!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Sent by\n" +" ${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed +msgid "Acceptance Changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance Changed by Subject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance status updated by subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Accepted" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent +msgid "Accepted by default" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active +msgid "Active" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Activity" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Answered" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Archived" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_form +msgid "Ask for consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required +msgid "Ask subjects for consent" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Automatically" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Awaiting response" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_consent +msgid "Consent of data processing" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html +msgid "Consent template default body html" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject +msgid "Consent template default subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.act_window,name:privacy_consent.consent_action +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count +#: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent +msgid "Consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid +msgid "Created by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date +msgid "Created on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_activity +msgid "Data processing activities" +msgstr "" + +#. module: privacy_consent +#: model:mail.template,subject:privacy_consent.template_consent +msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name +msgid "Display Name" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Draft" +msgstr "" + +#. module: privacy_consent +#: sql_constraint:privacy.consent:0 +msgid "Duplicated partner in this data processing activity" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email template" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required +msgid "Enable if you need to track any kind of consent from the affected subjects" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate and send missing consent requests" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate missing draft consent requests" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:140 +#, python-format +msgid "Generated consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Group By" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Hello," +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I accept this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I reject this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id +msgid "ID" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "If it was a mistake, you can undo it here:" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted +msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update +msgid "Last Modified on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date +msgid "Last Updated on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata +msgid "Last metadata" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Manually" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata +msgid "Metadata from the last acceptance or rejection by the subject" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/mail_template.py:25 +#, python-format +msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +"Accept\n" +"Reject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new +msgid "New Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_res_partner +msgid "Partner" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed +msgid "Privacy consent request acceptance status changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new +msgid "Privacy consent request created" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed +msgid "Privacy consent request state changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count +msgid "Privacy consent requests amount" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids +msgid "Privacy consents" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:100 +#, python-format +msgid "Require consent is available only for subjects in current database." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id +msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id +msgid "Server action" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent +msgid "Should we assume the subject has accepted if we receive no response?" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Sincerely,
" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:92 +#, python-format +msgid "Specify a mail template to ask automated consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "State" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed +msgid "State Changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id +msgid "Subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id +msgid "Subject asked for consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thank you!" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thanks for your response." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "This could send many consent emails, are you sure to proceed?" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.server,name:privacy_consent.update_opt_out +msgid "Update partner's opt out" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We asked you to authorize us to process your data in this data processing activity:" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We have recorded this action on your side." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have rejected such processing." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have accepted such processing." +msgstr "" From 7c8d30d6986ee099f95d56f4b8f8255af3b250a1 Mon Sep 17 00:00:00 2001 From: Pedro Castro Silva Date: Fri, 21 Sep 2018 09:15:05 +0000 Subject: [PATCH 06/30] Translated using Weblate (Portuguese) Currently translated at 100,0% (74 of 74 strings) Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/pt/ --- privacy_consent/i18n/pt.po | 268 +++++++++++++++++++++++++++---------- 1 file changed, 198 insertions(+), 70 deletions(-) diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 09d2ca6..6c52a2f 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -1,18 +1,17 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * privacy_consent -# msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Portuguese (data-protection-10.0)\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2018-09-21 09:15+0000\n" +"Last-Translator: Pedro Castro Silva \n" +"Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.1.1\n" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent @@ -100,93 +99,199 @@ msgid "\n" " \n" " " msgstr "" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \""\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Olá, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" Contactámos, para solicitar o seu " +"consentimento explícito, à inclusão dos seus dados numa atividade de " +"processamento de dados, chamada\n" +" " +"${object.activity_id.display_name|safe}, propriedade de\n" +" " +"${object.activity_id.controller_id.display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" A última vez que nos respondeu, " +"você\n" +" % elif object.state == \"sent\":\n" +" Se nada fizer, assumimos que você\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" aceitou\n" +" % else:\n" +" rejeitou\n" +" % endif\n" +" esse processamento de dados.\n" +"

\n" +"

\n" +" Pode atualizar as suas preferências " +"abaixo:\n" +"

\n" +"
\n" +" \n" +" Aceito\n" +" \n" +" \n" +" \n" +" Rejeito\n" +" \n" +"
\n" +"

\n" +" Se necessitar de mais informação, por " +"favor responda a este email e nós trataremos de esclarecer assim que " +"possível.\n" +"

\n" +"

\n" +" Obrigado!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
" +"\n" +"

\n" +" Enviado por\n" +" ${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed msgid "Acceptance Changed" -msgstr "" +msgstr "Aceitação alterada" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed msgid "Acceptance Changed by Subject" -msgstr "" +msgstr "Aceitação alterada por Titular" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed msgid "Acceptance status updated by subject" -msgstr "" +msgstr "Estado da aceitação atualizado por titular" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Accepted" -msgstr "" +msgstr "Aceite" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent msgid "Accepted by default" -msgstr "" +msgstr "Aceite por defeito" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active msgid "Active" -msgstr "" +msgstr "Ativo" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Activity" -msgstr "" +msgstr "Atividade" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Answered" -msgstr "" +msgstr "Respondido" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Archived" -msgstr "" +msgstr "Arquivado" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_form msgid "Ask for consent" -msgstr "" +msgstr "Pedir consentimento" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required msgid "Ask subjects for consent" -msgstr "" +msgstr "Questionar titulares sobre o consentimento" #. module: privacy_consent #: selection:privacy.activity,consent_required:0 msgid "Automatically" -msgstr "" +msgstr "Automaticamente" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Awaiting response" -msgstr "" +msgstr "Esperando Resposta" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Consent" -msgstr "" +msgstr "Consentimento" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_privacy_consent msgid "Consent of data processing" -msgstr "" +msgstr "Consentimento de processamento de dados" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html msgid "Consent template default body html" -msgstr "" +msgstr "Corpo predefinido HTML do modelo de consentimento" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject msgid "Consent template default subject" -msgstr "" +msgstr "Modelo pré-definido de consentimento do titular" #. module: privacy_consent #: model:ir.actions.act_window,name:privacy_consent.consent_action @@ -196,148 +301,158 @@ msgstr "" #: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count #: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent msgid "Consents" -msgstr "" +msgstr "Consentimentos" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid msgid "Created by" -msgstr "" +msgstr "Criado por" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date msgid "Created on" -msgstr "" +msgstr "Criado em" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_privacy_activity msgid "Data processing activities" -msgstr "" +msgstr "Atividades de processamento de dados" #. module: privacy_consent #: model:mail.template,subject:privacy_consent.template_consent msgid "Data processing consent request for ${object.activity_id.display_name|safe}" msgstr "" +"Processamento de dados de pedidos de consentimento para " +"${object.activity_id.display_name|safe}" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name msgid "Display Name" -msgstr "" +msgstr "Nome a Exibir" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Draft" -msgstr "" +msgstr "Rascunho" #. module: privacy_consent #: sql_constraint:privacy.consent:0 msgid "Duplicated partner in this data processing activity" -msgstr "" +msgstr "Parceiro duplicado nesta atividade de processamento de dados" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_template msgid "Email Templates" -msgstr "" +msgstr "Modelos de E-mail" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_compose_message msgid "Email composition wizard" -msgstr "" +msgstr "Assistente de criação de email" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" -msgstr "" +msgstr "Modelo de Email" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." msgstr "" +"Email a ser enviado para os titulares a pedir o consentimento. Um bom modelo " +"deve incluir detalhes sobre o estado atual do pedido de consentimento, como " +"alterá-lo, e onde obter ais informação." #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required msgid "Enable if you need to track any kind of consent from the affected subjects" msgstr "" +"Ativar se necessita seguir qualquer espécie de consentimento dos titulares " +"afetados" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Generate and send missing consent requests" -msgstr "" +msgstr "Gerar e enviar pedidos de consentimento em falta" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Generate missing draft consent requests" -msgstr "" +msgstr "Gerar pedidos de consentimento em rascunho em falta" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:140 #, python-format msgid "Generated consents" -msgstr "" +msgstr "Consentimentos gerados" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Group By" -msgstr "" +msgstr "Agrupar Por" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Hello," -msgstr "" +msgstr "Olá" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "I accept this processing of my data" -msgstr "" +msgstr "Eu aceito este processamento dos meus dados" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "I reject this processing of my data" -msgstr "" +msgstr "Eu rejeitto este processamento dos meus dados" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id msgid "ID" -msgstr "" +msgstr "ID" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "If it was a mistake, you can undo it here:" -msgstr "" +msgstr "Se foi um lapso, pode revertê-lo aqui:" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." msgstr "" +"Indica o estado atual da aceitação, que pode derivar da última resposta do " +"titular, ou estar pré-definida nos dados relacionados contidos na atividade " +"em processamento." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update msgid "Last Modified on" -msgstr "" +msgstr "Última Modificação em" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid msgid "Last Updated by" -msgstr "" +msgstr "Última Atualização por" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date msgid "Last Updated on" -msgstr "" +msgstr "Última Atualização em" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata msgid "Last metadata" -msgstr "" +msgstr "Últimos Metadados" #. module: privacy_consent #: selection:privacy.activity,consent_required:0 msgid "Manually" -msgstr "" +msgstr "Manualmente" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata msgid "Metadata from the last acceptance or rejection by the subject" -msgstr "" +msgstr "Metadados da última aceitação ou rejeição pelo titular" #. module: privacy_consent #: code:addons/privacy_consent/models/mail_template.py:25 @@ -346,142 +461,155 @@ msgid "Missing privacy consent link placeholders. You need at least these two li "Accept\n" "Reject" msgstr "" +"Espaços reservados aos links de consentimento de privacidade em falta. " +"Necessita pelo menos destes dois links:\n" +"Aceito\n" +"Rejeito" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new #: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new msgid "New Consent" -msgstr "" +msgstr "Novo Consentimento" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_mail msgid "Outgoing Mails" -msgstr "" +msgstr "Mensagens a sair" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_res_partner msgid "Partner" -msgstr "" +msgstr "Parceiro" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed msgid "Privacy consent request acceptance status changed" -msgstr "" +msgstr "Estado de aceitação do pedido de consentimento de privacidade alterado" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new #: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new msgid "Privacy consent request created" -msgstr "" +msgstr "Pedido de consentimento de privacidade criado" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed #: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed msgid "Privacy consent request state changed" -msgstr "" +msgstr "Estado do pedido de consentimento de privacidade alterado" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count #: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count msgid "Privacy consent requests amount" -msgstr "" +msgstr "Número de pedidos de consentimento de privacidade" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids #: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids msgid "Privacy consents" -msgstr "" +msgstr "Consentimentos de privacidade" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:100 #, python-format msgid "Require consent is available only for subjects in current database." msgstr "" +"Requerer consentimento, só está disponível para titulares da base de dados " +"atual." #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id msgid "Run this action when a new consent request is created or its acceptance status is updated." msgstr "" +"Execute esta ação quando um novo pedido de consentimento for criado ou seu " +"estado de aceitação for atualizado." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id msgid "Server action" -msgstr "" +msgstr "Ação do servidor" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent msgid "Should we assume the subject has accepted if we receive no response?" msgstr "" +"Devemos assumir que o titular dos dados aceitou, se não houver resposta?" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Sincerely,
" -msgstr "" +msgstr "Cumprimentos,
" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:92 #, python-format msgid "Specify a mail template to ask automated consent." -msgstr "" +msgstr "Especifique um modelo de email para pedido automático de consentimento." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "State" -msgstr "" +msgstr "Estado" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed #: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed msgid "State Changed" -msgstr "" +msgstr "Estado alterado" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id msgid "Subject" -msgstr "" +msgstr "Titular dos dados" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id msgid "Subject asked for consent." -msgstr "" +msgstr "Foi pedido consentimento ao titular." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Thank you!" -msgstr "" +msgstr "Obrigado!" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Thanks for your response." -msgstr "" +msgstr "Obrigado pela sua resposta." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "This could send many consent emails, are you sure to proceed?" msgstr "" +"Atenção, esta operação pode enviar múltiplo emails de consentimento pretende " +"prosseguir?" #. module: privacy_consent #: model:ir.actions.server,name:privacy_consent.update_opt_out msgid "Update partner's opt out" -msgstr "" +msgstr "Atualizar a Auto Exclusão do parceiro" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "We asked you to authorize us to process your data in this data processing activity:" msgstr "" +"Pedimos-lhe que nos desse autorização para processarmos os seus dados nesta " +"atividade de processamento:" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "We have recorded this action on your side." -msgstr "" +msgstr "Registámos esta ação com seu conhecimento." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have rejected such processing." -msgstr "" +msgstr "Você rejeitou este processamento." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." -msgstr "" +msgstr "Você aceitou este processamento." From b05307a4dd32c01f78cd65c3d4c0de19d38713e0 Mon Sep 17 00:00:00 2001 From: Pedro Castro Silva Date: Fri, 21 Sep 2018 09:16:12 +0000 Subject: [PATCH 07/30] Translated using Weblate (Portuguese) Currently translated at 98.6% (73 of 74 strings) Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/pt/ --- privacy_consent/i18n/pt.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 6c52a2f..4889212 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Portuguese (data-protection-10.0)\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2018-09-21 09:15+0000\n" +"PO-Revision-Date: 2018-09-22 09:44+0000\n" "Last-Translator: Pedro Castro Silva \n" "Language-Team: Portuguese \n" @@ -209,12 +209,12 @@ msgstr "" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed msgid "Acceptance Changed" -msgstr "Aceitação alterada" +msgstr "Aceitação Alterada" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed msgid "Acceptance Changed by Subject" -msgstr "Aceitação alterada por Titular" +msgstr "Aceitação Alterada por Titular" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed @@ -261,7 +261,7 @@ msgstr "Pedir consentimento" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required msgid "Ask subjects for consent" -msgstr "Questionar titulares sobre o consentimento" +msgstr "Solicitar consentimento aos titulares" #. module: privacy_consent #: selection:privacy.activity,consent_required:0 @@ -271,7 +271,7 @@ msgstr "Automaticamente" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Awaiting response" -msgstr "Esperando Resposta" +msgstr "À espera de resposta" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form @@ -291,7 +291,7 @@ msgstr "Corpo predefinido HTML do modelo de consentimento" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject msgid "Consent template default subject" -msgstr "Modelo pré-definido de consentimento do titular" +msgstr "Modelo predefinido de consentimento do titular" #. module: privacy_consent #: model:ir.actions.act_window,name:privacy_consent.consent_action @@ -404,12 +404,12 @@ msgstr "Eu aceito este processamento dos meus dados" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "I reject this processing of my data" -msgstr "Eu rejeitto este processamento dos meus dados" +msgstr "Eu rejeito este processamento dos meus dados" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id msgid "ID" -msgstr "ID" +msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form @@ -421,7 +421,7 @@ msgstr "Se foi um lapso, pode revertê-lo aqui:" msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." msgstr "" "Indica o estado atual da aceitação, que pode derivar da última resposta do " -"titular, ou estar pré-definida nos dados relacionados contidos na atividade " +"titular, ou estar predefinida nos dados relacionados contidos na atividade " "em processamento." #. module: privacy_consent @@ -475,7 +475,7 @@ msgstr "Novo Consentimento" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_mail msgid "Outgoing Mails" -msgstr "Mensagens a sair" +msgstr "Mensagens a Enviar" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_res_partner @@ -558,7 +558,7 @@ msgstr "Estado" #: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed #: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed msgid "State Changed" -msgstr "Estado alterado" +msgstr "Estado Alterado" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id From bbae9f3402238f6184fc52bb862bf56774cff8b7 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Tue, 11 Dec 2018 19:51:44 +0000 Subject: [PATCH 08/30] Added translation using Weblate (French) --- privacy_consent/i18n/fr.po | 487 +++++++++++++++++++++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 privacy_consent/i18n/fr.po diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po new file mode 100644 index 0000000..3a0067b --- /dev/null +++ b/privacy_consent/i18n/fr.po @@ -0,0 +1,487 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_consent +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: privacy_consent +#: model:mail.template,body_html:privacy_consent.template_consent +msgid "\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hello, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" +" ${object.activity_id.display_name|safe}, property of\n" +" ${object.activity_id.controller_id.display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" The last time you answered, you\n" +" % elif object.state == \"sent\":\n" +" If you do nothing, we will assume you have\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" accepted\n" +" % else:\n" +" rejected\n" +" % endif\n" +" such data processing.\n" +"

\n" +"

\n" +" You can update your preferences below:\n" +"

\n" +"
\n" +" \n" +" Accept\n" +" \n" +" \n" +" \n" +" Reject\n" +" \n" +"
\n" +"

\n" +" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +"

\n" +"

\n" +" Thank you!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Sent by\n" +" ${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed +msgid "Acceptance Changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance Changed by Subject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance status updated by subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Accepted" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent +msgid "Accepted by default" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active +msgid "Active" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Activity" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Answered" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Archived" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_form +msgid "Ask for consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required +msgid "Ask subjects for consent" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Automatically" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Awaiting response" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_consent +msgid "Consent of data processing" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html +msgid "Consent template default body html" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject +msgid "Consent template default subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.act_window,name:privacy_consent.consent_action +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count +#: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent +msgid "Consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid +msgid "Created by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date +msgid "Created on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_activity +msgid "Data processing activities" +msgstr "" + +#. module: privacy_consent +#: model:mail.template,subject:privacy_consent.template_consent +msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name +msgid "Display Name" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Draft" +msgstr "" + +#. module: privacy_consent +#: sql_constraint:privacy.consent:0 +msgid "Duplicated partner in this data processing activity" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email template" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required +msgid "Enable if you need to track any kind of consent from the affected subjects" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate and send missing consent requests" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate missing draft consent requests" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:140 +#, python-format +msgid "Generated consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Group By" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Hello," +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I accept this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I reject this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id +msgid "ID" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "If it was a mistake, you can undo it here:" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted +msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update +msgid "Last Modified on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date +msgid "Last Updated on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata +msgid "Last metadata" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Manually" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata +msgid "Metadata from the last acceptance or rejection by the subject" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/mail_template.py:25 +#, python-format +msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +"Accept\n" +"Reject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new +msgid "New Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_res_partner +msgid "Partner" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed +msgid "Privacy consent request acceptance status changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new +msgid "Privacy consent request created" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed +msgid "Privacy consent request state changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count +msgid "Privacy consent requests amount" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids +msgid "Privacy consents" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:100 +#, python-format +msgid "Require consent is available only for subjects in current database." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id +msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id +msgid "Server action" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent +msgid "Should we assume the subject has accepted if we receive no response?" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Sincerely,
" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:92 +#, python-format +msgid "Specify a mail template to ask automated consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "State" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed +msgid "State Changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id +msgid "Subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id +msgid "Subject asked for consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thank you!" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thanks for your response." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "This could send many consent emails, are you sure to proceed?" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.server,name:privacy_consent.update_opt_out +msgid "Update partner's opt out" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We asked you to authorize us to process your data in this data processing activity:" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We have recorded this action on your side." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have rejected such processing." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have accepted such processing." +msgstr "" From 528beb99807fe3a2c2e9ef70b71b8499fdf479a6 Mon Sep 17 00:00:00 2001 From: alvarorib Date: Fri, 14 Dec 2018 21:38:32 +0000 Subject: [PATCH 09/30] Translated using Weblate (Portuguese) Currently translated at 100.0% (74 of 74 strings) Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/pt/ --- privacy_consent/i18n/pt.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 4889212..c087e3e 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: Portuguese (data-protection-10.0)\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2018-09-22 09:44+0000\n" -"Last-Translator: Pedro Castro Silva \n" +"PO-Revision-Date: 2018-12-15 21:58+0000\n" +"Last-Translator: alvarorib \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 3.1.1\n" +"X-Generator: Weblate 3.3\n" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent @@ -409,7 +409,7 @@ msgstr "Eu rejeito este processamento dos meus dados" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id msgid "ID" -msgstr "" +msgstr "ID" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form From d805a53ddfafc18c4cf5a480e2c45d299d948506 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 21 Jan 2019 12:24:23 +0000 Subject: [PATCH 10/30] privacy_consent: Test at install The purpose of this `@post_install` no longer exists, and by removing these decorators, we avoid test failures in case some custom addon customizes the welcome message. --- privacy_consent/tests/test_consent.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/privacy_consent/tests/test_consent.py b/privacy_consent/tests/test_consent.py index 7af0a90..6a68e4f 100644 --- a/privacy_consent/tests/test_consent.py +++ b/privacy_consent/tests/test_consent.py @@ -5,11 +5,9 @@ from contextlib import contextmanager from odoo.exceptions import ValidationError -from odoo.tests.common import at_install, post_install, HttpCase +from odoo.tests.common import HttpCase -@at_install(False) -@post_install(True) class ActivityCase(HttpCase): def setUp(self): super(ActivityCase, self).setUp() From f85ffcfed3c1c1b17354dd9a481555628b3f40bf Mon Sep 17 00:00:00 2001 From: Cristina Martin Date: Fri, 1 Mar 2019 16:20:20 +0100 Subject: [PATCH 11/30] privacy_consent: set partner lang on mail template --- privacy_consent/data/mail.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/privacy_consent/data/mail.xml b/privacy_consent/data/mail.xml index c288e93..d7dad6c 100644 --- a/privacy_consent/data/mail.xml +++ b/privacy_consent/data/mail.xml @@ -1,5 +1,6 @@ @@ -10,6 +11,7 @@ Data processing consent request for ${object.activity_id.display_name|safe} + ${object.partner_id.lang}
From 79a449e021252494671d422bfeeef3cb3cb93cfa Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 6 Mar 2019 11:11:28 +0000 Subject: [PATCH 12/30] privacy_consent: Avoid race condition with mail queue cron Before this patch, all privacy consent emails were forced to be sent under a context with `mark_consent_sent=True` to track the state change and trigger the attached server action. When using the automatic mode, if a separate cron job started running the mail queue, it could happen that mails were being sent from that another worker, losing the context key and, as such, being sent without token and without being marked as sent nor executing the attached server action (if any). To avoid this problem, now the context dependency is removed. After all, the `mail.mail` object is only created when sending in `mass_mail` model, so other kind of notifications or messages are not affected. When a mail of type `mass_mail` is sent, we can assume that it is asking for consent and we can move draft consent requests to sent. --- privacy_consent/__init__.py | 1 - privacy_consent/models/mail_mail.py | 4 ++-- privacy_consent/models/privacy_activity.py | 5 ++--- privacy_consent/models/privacy_consent.py | 4 +--- privacy_consent/wizards/__init__.py | 1 - privacy_consent/wizards/mail_compose_message.py | 16 ---------------- 6 files changed, 5 insertions(+), 26 deletions(-) delete mode 100644 privacy_consent/wizards/__init__.py delete mode 100644 privacy_consent/wizards/mail_compose_message.py diff --git a/privacy_consent/__init__.py b/privacy_consent/__init__.py index ada0b87..91c5580 100644 --- a/privacy_consent/__init__.py +++ b/privacy_consent/__init__.py @@ -1,3 +1,2 @@ from . import controllers from . import models -from . import wizards diff --git a/privacy_consent/models/mail_mail.py b/privacy_consent/models/mail_mail.py index e53e7fc..25462e7 100644 --- a/privacy_consent/models/mail_mail.py +++ b/privacy_consent/models/mail_mail.py @@ -10,7 +10,7 @@ class MailMail(models.Model): def _postprocess_sent_message(self, mail_sent=True): """Write consent status after sending message.""" - if mail_sent and self.env.context.get('mark_consent_sent'): + if mail_sent: # Get all mails sent to consents consent_mails = self.filtered( lambda one: one.mail_message_id.model == "privacy.consent" @@ -37,7 +37,7 @@ class MailMail(models.Model): """ result = super(MailMail, self).send_get_mail_body(partner=partner) # Avoid polluting other model mails - if self.env.context.get("active_model") != "privacy.consent": + if self.model != "privacy.consent": return result # Tokenize consent links consent = self.env["privacy.consent"] \ diff --git a/privacy_consent/models/privacy_activity.py b/privacy_consent/models/privacy_activity.py index c7d20c9..578f2a7 100644 --- a/privacy_consent/models/privacy_activity.py +++ b/privacy_consent/models/privacy_activity.py @@ -120,11 +120,10 @@ class PrivacyActivity(models.Model): # Skip activitys where consent is not required for one in self.with_context(active_test=False) \ .filtered("consent_required"): - domain = safe_eval(one.subject_domain) - domain += [ + domain = [ ("id", "not in", one.mapped("consent_ids.partner_id").ids), ("email", "!=", False), - ] + ] + safe_eval(one.subject_domain) # Create missing consent requests for missing in self.env["res.partner"].search(domain): consents |= consents.create({ diff --git a/privacy_consent/models/privacy_consent.py b/privacy_consent/models/privacy_consent.py index 6dacd97..fd90678 100644 --- a/privacy_consent/models/privacy_consent.py +++ b/privacy_consent/models/privacy_consent.py @@ -104,8 +104,7 @@ class PrivacyConsent(models.Model): consents_by_template = {} for one in self.with_context(tpl_force_default_to=True, mail_notify_user_signature=False, - mail_auto_subscribe_no_notify=True, - mark_consent_sent=True): + mail_auto_subscribe_no_notify=True): # Group consents by template, to send in batch where possible template_id = one.activity_id.consent_template_id.id consents_by_template.setdefault(template_id, one) @@ -168,7 +167,6 @@ class PrivacyConsent(models.Model): "default_res_id": self.id, "default_template_id": self.activity_id.consent_template_id.id, "default_use_template": True, - "mark_consent_sent": True, "tpl_force_default_to": True, }, "force_email": True, diff --git a/privacy_consent/wizards/__init__.py b/privacy_consent/wizards/__init__.py deleted file mode 100644 index b528d99..0000000 --- a/privacy_consent/wizards/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import mail_compose_message diff --git a/privacy_consent/wizards/mail_compose_message.py b/privacy_consent/wizards/mail_compose_message.py deleted file mode 100644 index a63ecc1..0000000 --- a/privacy_consent/wizards/mail_compose_message.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2018 Tecnativa - Jairo Llopis -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import api, models - - -class MailComposeMessage(models.TransientModel): - _inherit = "mail.compose.message" - - @api.multi - def send_mail(self, auto_commit=False): - """Force auto commit when sending consent emails.""" - if self.env.context.get('mark_consent_sent'): - auto_commit = True - return super(MailComposeMessage, self).send_mail(auto_commit) From 40ff65a666d6d0c926684cd0bf850a71083dfd6d Mon Sep 17 00:00:00 2001 From: oca-travis Date: Sun, 10 Mar 2019 15:59:49 +0000 Subject: [PATCH 13/30] Update privacy_consent.pot --- privacy_consent/i18n/privacy_consent.pot | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot index 51f7871..a82c662 100644 --- a/privacy_consent/i18n/privacy_consent.pot +++ b/privacy_consent/i18n/privacy_consent.pot @@ -237,11 +237,6 @@ msgstr "" msgid "Email Templates" msgstr "" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -268,7 +263,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:140 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "" From 47b1b1fa7f4748d1ea6574464c25a03f64c64db1 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sun, 10 Mar 2019 15:59:54 +0000 Subject: [PATCH 14/30] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/ --- privacy_consent/i18n/es.po | 10 ++- privacy_consent/i18n/fr.po | 95 ++++++++++++++++--------- privacy_consent/i18n/pt.po | 141 +++++++++++++++++++++++-------------- 3 files changed, 155 insertions(+), 91 deletions(-) diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index 1285c92..17832bd 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -372,11 +372,6 @@ msgstr "Contacto duplicado en esta actividad de tratamiento" msgid "Email Templates" msgstr "Plantillas de correo electrónico" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "Asistente de redacción de correo electrónico" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -412,7 +407,7 @@ msgid "Generate missing draft consent requests" msgstr "Generar borradores de las solicitudes de consentimiento faltantes" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:140 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "Consentimientos generados" @@ -661,3 +656,6 @@ msgstr "Ha rechazado dicho tratamiento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Ha aceptado dicho tratamiento." + +#~ msgid "Email composition wizard" +#~ msgstr "Asistente de redacción de correo electrónico" diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po index 3a0067b..31c82d9 100644 --- a/privacy_consent/i18n/fr.po +++ b/privacy_consent/i18n/fr.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * privacy_consent +# * privacy_consent # msgid "" msgstr "" @@ -16,37 +16,48 @@ msgstr "" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent -msgid "\n" -"
\n" +msgid "" +"\n" +"
\n" "
\n" " \n" " \n" " \n" " \n" " \n" "
\n" " \n" -" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \"${object."\n" " \n" "
\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" " \n" -" \n" -" \n" " \n" " \n" -" \n" " \n" "
\n" +" \n" "

\n" " Hello, ${object.partner_id.name|safe}\n" "

\n" "

\n" -" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" -" ${object.activity_id.display_name|safe}, property of\n" -" ${object.activity_id.controller_id.display_name|safe}\n" +" We contacted you to ask you to give us " +"your explicit consent to include your data in a data processing activity " +"called\n" +" ${object.activity_id.display_name|" +"safe}, property of\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" "

\n" " ${object.description or \"\"}\n" "

\n" " % if object.state == \"answered\":\n" " The last time you answered, you\n" " % elif object.state == \"sent\":\n" -" If you do nothing, we will assume you have\n" +" If you do nothing, we will assume " +"you have\n" " % endif\n" "\n" " % if object.accepted:\n" @@ -62,21 +73,29 @@ msgid "\n" "

\n" -" \n" +" \n" +" \n" " Accept\n" " \n" " \n" -" \n" +" \n" +" \n" " Reject\n" " \n" "
\n" +" \n" "

\n" -" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +" If you need further information, please " +"respond to this email and we will attend your request as soon as possible.\n" "

\n" "

\n" " Thank you!\n" @@ -85,13 +104,16 @@ msgid "\n" "

\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" @@ -215,7 +237,8 @@ msgstr "" #. module: privacy_consent #: model:mail.template,subject:privacy_consent.template_consent -msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgid "" +"Data processing consent request for ${object.activity_id.display_name|safe}" msgstr "" #. module: privacy_consent @@ -238,11 +261,6 @@ msgstr "" msgid "Email Templates" msgstr "" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -250,12 +268,16 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id -msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgid "" +"Email to be sent to subjects to ask for consent. A good template should " +"include details about the current consent request status, how to change it, " +"and where to get more information." msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required -msgid "Enable if you need to track any kind of consent from the affected subjects" +msgid "" +"Enable if you need to track any kind of consent from the affected subjects" msgstr "" #. module: privacy_consent @@ -269,7 +291,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:140 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "" @@ -306,7 +328,10 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted -msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgid "" +"Indicates current acceptance status, which can come from subject's last " +"answer, or from the default specified in the related data processing " +"activity." msgstr "" #. module: privacy_consent @@ -342,7 +367,9 @@ msgstr "" #. module: privacy_consent #: code:addons/privacy_consent/models/mail_template.py:25 #, python-format -msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +msgid "" +"Missing privacy consent link placeholders. You need at least these two " +"links:\n" "Accept\n" "Reject" msgstr "" @@ -400,7 +427,9 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id -msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgid "" +"Run this action when a new consent request is created or its acceptance " +"status is updated." msgstr "" #. module: privacy_consent @@ -468,7 +497,9 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form -msgid "We asked you to authorize us to process your data in this data processing activity:" +msgid "" +"We asked you to authorize us to process your data in this data processing " +"activity:" msgstr "" #. module: privacy_consent diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index c087e3e..83bdd04 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -15,37 +15,48 @@ msgstr "" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent -msgid "\n" -"
\n" +msgid "" +"\n" +"
\n" "
\n" +" \n" "

\n" " Sent by\n" -" ${object.activity_id.controller_id.display_name|safe}.\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" "

\n" "
\n" " \n" " \n" " \n" " \n" " \n" "
\n" " \n" -" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \"${object."\n" " \n" "
\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" " \n" -" \n" -" \n" " \n" " \n" -" \n" " \n" "
\n" +" \n" "

\n" " Hello, ${object.partner_id.name|safe}\n" "

\n" "

\n" -" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" -" ${object.activity_id.display_name|safe}, property of\n" -" ${object.activity_id.controller_id.display_name|safe}\n" +" We contacted you to ask you to give us " +"your explicit consent to include your data in a data processing activity " +"called\n" +" ${object.activity_id.display_name|" +"safe}, property of\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" "

\n" " ${object.description or \"\"}\n" "

\n" " % if object.state == \"answered\":\n" " The last time you answered, you\n" " % elif object.state == \"sent\":\n" -" If you do nothing, we will assume you have\n" +" If you do nothing, we will assume " +"you have\n" " % endif\n" "\n" " % if object.accepted:\n" @@ -61,21 +72,29 @@ msgid "\n" "

\n" -" \n" +" \n" +" \n" " Accept\n" " \n" " \n" -" \n" +" \n" +" \n" " Reject\n" " \n" "
\n" +" \n" "

\n" -" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +" If you need further information, please " +"respond to this email and we will attend your request as soon as possible.\n" "

\n" "

\n" " Thank you!\n" @@ -84,13 +103,16 @@ msgid "\n" "

\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" @@ -100,23 +122,23 @@ msgid "\n" " " msgstr "" "\n" -"
\n" +"
\n" "
\n" +" \n" "

\n" " Sent by\n" -" ${object.activity_id.controller_id.display_name|safe}.\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" "

\n" "
\n" " \n" " \n" " \n" " \n" " \n" "
\n" " \n" -" \""\n" +" \"${object."\n" " \n" "
\n" -" \n" +"
\n" " \n" " \n" " \n" " \n" " \n" " \n" -" \n" " \n" @@ -320,10 +342,11 @@ msgstr "Atividades de processamento de dados" #. module: privacy_consent #: model:mail.template,subject:privacy_consent.template_consent -msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgid "" +"Data processing consent request for ${object.activity_id.display_name|safe}" msgstr "" -"Processamento de dados de pedidos de consentimento para " -"${object.activity_id.display_name|safe}" +"Processamento de dados de pedidos de consentimento para ${object.activity_id." +"display_name|safe}" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name @@ -345,11 +368,6 @@ msgstr "Parceiro duplicado nesta atividade de processamento de dados" msgid "Email Templates" msgstr "Modelos de E-mail" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "Assistente de criação de email" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -357,7 +375,10 @@ msgstr "Modelo de Email" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id -msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgid "" +"Email to be sent to subjects to ask for consent. A good template should " +"include details about the current consent request status, how to change it, " +"and where to get more information." msgstr "" "Email a ser enviado para os titulares a pedir o consentimento. Um bom modelo " "deve incluir detalhes sobre o estado atual do pedido de consentimento, como " @@ -365,7 +386,8 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required -msgid "Enable if you need to track any kind of consent from the affected subjects" +msgid "" +"Enable if you need to track any kind of consent from the affected subjects" msgstr "" "Ativar se necessita seguir qualquer espécie de consentimento dos titulares " "afetados" @@ -381,7 +403,7 @@ msgid "Generate missing draft consent requests" msgstr "Gerar pedidos de consentimento em rascunho em falta" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:140 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "Consentimentos gerados" @@ -418,7 +440,10 @@ msgstr "Se foi um lapso, pode revertê-lo aqui:" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted -msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgid "" +"Indicates current acceptance status, which can come from subject's last " +"answer, or from the default specified in the related data processing " +"activity." msgstr "" "Indica o estado atual da aceitação, que pode derivar da última resposta do " "titular, ou estar predefinida nos dados relacionados contidos na atividade " @@ -457,7 +482,9 @@ msgstr "Metadados da última aceitação ou rejeição pelo titular" #. module: privacy_consent #: code:addons/privacy_consent/models/mail_template.py:25 #, python-format -msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +msgid "" +"Missing privacy consent link placeholders. You need at least these two " +"links:\n" "Accept\n" "Reject" msgstr "" @@ -521,7 +548,9 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id -msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgid "" +"Run this action when a new consent request is created or its acceptance " +"status is updated." msgstr "" "Execute esta ação quando um novo pedido de consentimento for criado ou seu " "estado de aceitação for atualizado." @@ -546,7 +575,8 @@ msgstr "Cumprimentos,
" #: code:addons/privacy_consent/models/privacy_activity.py:92 #, python-format msgid "Specify a mail template to ask automated consent." -msgstr "Especifique um modelo de email para pedido automático de consentimento." +msgstr "" +"Especifique um modelo de email para pedido automático de consentimento." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state @@ -594,7 +624,9 @@ msgstr "Atualizar a Auto Exclusão do parceiro" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form -msgid "We asked you to authorize us to process your data in this data processing activity:" +msgid "" +"We asked you to authorize us to process your data in this data processing " +"activity:" msgstr "" "Pedimos-lhe que nos desse autorização para processarmos os seus dados nesta " "atividade de processamento:" @@ -613,3 +645,6 @@ msgstr "Você rejeitou este processamento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Você aceitou este processamento." + +#~ msgid "Email composition wizard" +#~ msgstr "Assistente de criação de email" From 786e421ab918d6e9d886d0f8aa3f11947ec8b0b6 Mon Sep 17 00:00:00 2001 From: Malin Kienke Date: Wed, 20 Mar 2019 14:11:00 +0000 Subject: [PATCH 15/30] Added translation using Weblate (German) --- privacy_consent/i18n/de.po | 482 +++++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 privacy_consent/i18n/de.po diff --git a/privacy_consent/i18n/de.po b/privacy_consent/i18n/de.po new file mode 100644 index 0000000..d42a41e --- /dev/null +++ b/privacy_consent/i18n/de.po @@ -0,0 +1,482 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_consent +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: privacy_consent +#: model:mail.template,body_html:privacy_consent.template_consent +msgid "\n" +"
\n" +"
${object.activity_id.display_name|safe}, propriedade de\n" -" " -"${object.activity_id.controller_id.display_name|safe}\n" +" ${object.activity_id.display_name|" +"safe}, propriedade de\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" "

\n" " ${object.description or \"\"}\n" "

\n" @@ -158,16 +180,16 @@ msgstr "" "

\n" -" \n" " Aceito\n" " \n" " \n" -" \n" " Rejeito\n" " \n" @@ -192,12 +214,12 @@ msgstr "" "\">\n" "
" -"\n" +" \n" "

\n" " Enviado por\n" -" ${object.activity_id.controller_id.display_name|safe}.\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" "

\n" "
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Hello, ${object.partner_id.name|safe}\n" +"

\n" +"

\n" +" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" +" ${object.activity_id.display_name|safe}, property of\n" +" ${object.activity_id.controller_id.display_name|safe}\n" +"

\n" +" ${object.description or \"\"}\n" +"

\n" +" % if object.state == \"answered\":\n" +" The last time you answered, you\n" +" % elif object.state == \"sent\":\n" +" If you do nothing, we will assume you have\n" +" % endif\n" +"\n" +" % if object.accepted:\n" +" accepted\n" +" % else:\n" +" rejected\n" +" % endif\n" +" such data processing.\n" +"

\n" +"

\n" +" You can update your preferences below:\n" +"

\n" +"
\n" +" \n" +" Accept\n" +" \n" +" \n" +" \n" +" Reject\n" +" \n" +"
\n" +"

\n" +" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +"

\n" +"

\n" +" Thank you!\n" +"

\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +" Sent by\n" +" ${object.activity_id.controller_id.display_name|safe}.\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_acceptance_changed +msgid "Acceptance Changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance Changed by Subject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed +msgid "Acceptance status updated by subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Accepted" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent +msgid "Accepted by default" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active +msgid "Active" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Activity" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Answered" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Archived" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_form +msgid "Ask for consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required +msgid "Ask subjects for consent" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Automatically" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Awaiting response" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_consent +msgid "Consent of data processing" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html +msgid "Consent template default body html" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject +msgid "Consent template default subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.act_window,name:privacy_consent.consent_action +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count +#: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent +msgid "Consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid +msgid "Created by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date +msgid "Created on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_privacy_activity +msgid "Data processing activities" +msgstr "" + +#. module: privacy_consent +#: model:mail.template,subject:privacy_consent.template_consent +msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name +msgid "Display Name" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.consent,state:0 +msgid "Draft" +msgstr "" + +#. module: privacy_consent +#: sql_constraint:privacy.consent:0 +msgid "Duplicated partner in this data processing activity" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email template" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id +msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required +msgid "Enable if you need to track any kind of consent from the affected subjects" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate and send missing consent requests" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "Generate missing draft consent requests" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:139 +#, python-format +msgid "Generated consents" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "Group By" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Hello," +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I accept this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "I reject this processing of my data" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id +msgid "ID" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "If it was a mistake, you can undo it here:" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted +msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update +msgid "Last Modified on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date +msgid "Last Updated on" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata +msgid "Last metadata" +msgstr "" + +#. module: privacy_consent +#: selection:privacy.activity,consent_required:0 +msgid "Manually" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata +msgid "Metadata from the last acceptance or rejection by the subject" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/mail_template.py:25 +#, python-format +msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +"Accept\n" +"Reject" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new +msgid "New Consent" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_res_partner +msgid "Partner" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed +msgid "Privacy consent request acceptance status changed" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new +#: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new +msgid "Privacy consent request created" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed +msgid "Privacy consent request state changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count +#: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count +msgid "Privacy consent requests amount" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids +#: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids +msgid "Privacy consents" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:100 +#, python-format +msgid "Require consent is available only for subjects in current database." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id +msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id +msgid "Server action" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent +msgid "Should we assume the subject has accepted if we receive no response?" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Sincerely,
" +msgstr "" + +#. module: privacy_consent +#: code:addons/privacy_consent/models/privacy_activity.py:92 +#, python-format +msgid "Specify a mail template to ask automated consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state +#: model:ir.ui.view,arch_db:privacy_consent.consent_search +msgid "State" +msgstr "" + +#. module: privacy_consent +#: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed +#: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed +msgid "State Changed" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id +msgid "Subject" +msgstr "" + +#. module: privacy_consent +#: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id +msgid "Subject asked for consent." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thank you!" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "Thanks for your response." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.activity_form +msgid "This could send many consent emails, are you sure to proceed?" +msgstr "" + +#. module: privacy_consent +#: model:ir.actions.server,name:privacy_consent.update_opt_out +msgid "Update partner's opt out" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We asked you to authorize us to process your data in this data processing activity:" +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "We have recorded this action on your side." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have rejected such processing." +msgstr "" + +#. module: privacy_consent +#: model:ir.ui.view,arch_db:privacy_consent.form +msgid "You have accepted such processing." +msgstr "" From 701370a37d7568746a2fc01ffe70eda7445ad96b Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 7 May 2019 13:04:52 +0100 Subject: [PATCH 16/30] privacy_consent: Avoid race condition when sending emails It could happen that, while Odoo is still sending emails, a subject receives it and clicks on accept/reject links. In such case, he'd get a 404 error because the record wouldn't exist yet in the database. That's because the DB commit was made only after processing all the sent emails. We need to commit in advance to make sure that doesn't happen. --- privacy_consent/models/privacy_activity.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/privacy_consent/models/privacy_activity.py b/privacy_consent/models/privacy_activity.py index 578f2a7..6a37e53 100644 --- a/privacy_consent/models/privacy_activity.py +++ b/privacy_consent/models/privacy_activity.py @@ -131,6 +131,9 @@ class PrivacyActivity(models.Model): "accepted": one.default_consent, "activity_id": one.id, }) + # Avoid race condition where a user could click on accept/reject link + # in his email before its consent record is saved to the database + consents.env.cr.commit() # Send consent request emails for automatic activitys consents.action_auto_ask() # Redirect user to new consent requests generated From 5d31591620041fa0497304e79c44f76ce518f933 Mon Sep 17 00:00:00 2001 From: dw3gn3r Date: Thu, 11 Apr 2019 07:20:13 +0000 Subject: [PATCH 17/30] Translated using Weblate (German) Currently translated at 79.5% (58 of 73 strings) Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/de/ --- privacy_consent/i18n/de.po | 122 +++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/privacy_consent/i18n/de.po b/privacy_consent/i18n/de.po index d42a41e..d2ee5f9 100644 --- a/privacy_consent/i18n/de.po +++ b/privacy_consent/i18n/de.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2019-04-11 11:16+0000\n" +"Last-Translator: dw3gn3r \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.5\n" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent @@ -109,7 +111,7 @@ msgstr "" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_consent_acceptance_changed msgid "Acceptance Changed by Subject" -msgstr "" +msgstr "Zustimmung durch den Betroffenen geändert" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_consent_acceptance_changed @@ -120,7 +122,7 @@ msgstr "" #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_accepted #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Accepted" -msgstr "" +msgstr "Akzeptiert" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_default_consent @@ -130,63 +132,63 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_active msgid "Active" -msgstr "" +msgstr "Aktiv" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_activity_id #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Activity" -msgstr "" +msgstr "Aktivität" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Answered" -msgstr "" +msgstr "Beantwortet" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Archived" -msgstr "" +msgstr "Archiviert" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_form msgid "Ask for consent" -msgstr "" +msgstr "Einwilligung einholen" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_required msgid "Ask subjects for consent" -msgstr "" +msgstr "Einwilligung beim Betroffenen einholen" #. module: privacy_consent #: selection:privacy.activity,consent_required:0 msgid "Automatically" -msgstr "" +msgstr "Automatisch" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Awaiting response" -msgstr "" +msgstr "Warten auf Antwort" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Consent" -msgstr "" +msgstr "Einwilligung" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_privacy_consent msgid "Consent of data processing" -msgstr "" +msgstr "Einwilligung in die Datenverarbeitung" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_body_html msgid "Consent template default body html" -msgstr "" +msgstr "Einverständniserklärung Standardtext html" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_default_subject msgid "Consent template default subject" -msgstr "" +msgstr "Standardmäßige Einverständniserklärung Betroffener" #. module: privacy_consent #: model:ir.actions.act_window,name:privacy_consent.consent_action @@ -196,47 +198,47 @@ msgstr "" #: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_count #: model:ir.ui.menu,name:privacy_consent.menu_privacy_consent msgid "Consents" -msgstr "" +msgstr "Einwilligungen" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_uid msgid "Created by" -msgstr "" +msgstr "Erstellt von" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_create_date msgid "Created on" -msgstr "" +msgstr "Erstellt am" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_privacy_activity msgid "Data processing activities" -msgstr "" +msgstr "Verarbeitungstätigkeiten" #. module: privacy_consent #: model:mail.template,subject:privacy_consent.template_consent msgid "Data processing consent request for ${object.activity_id.display_name|safe}" -msgstr "" +msgstr "Bitte um Erteilung der Einwilligung zur Datenverarbeitung:" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_display_name msgid "Display Name" -msgstr "" +msgstr "Anzeigename" #. module: privacy_consent #: selection:privacy.consent,state:0 msgid "Draft" -msgstr "" +msgstr "Entwurf" #. module: privacy_consent #: sql_constraint:privacy.consent:0 msgid "Duplicated partner in this data processing activity" -msgstr "" +msgstr "Doppelter Partner in dieser Verarbeitungsaktivität" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_template msgid "Email Templates" -msgstr "" +msgstr "E-Mail-Vorlagen" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id @@ -247,6 +249,10 @@ msgstr "" #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." msgstr "" +"E-Mail, die an die Betroffenen geschickt werden soll, um die Einwilligung " +"einzuholen. Eine gute Vorlage sollte Details über den aktuellen Status der " +"Einwilligungsanfrage enthalten, sowie Hinweise darüber, wie man den Status " +"der Einwilligung ändern kann und wo man weitere Informationen erhält." #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required @@ -256,12 +262,12 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Generate and send missing consent requests" -msgstr "" +msgstr "Erstellung und Versand fehlender Einwilligungsanfragen" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "Generate missing draft consent requests" -msgstr "" +msgstr "Fehlende Entwürfe von Einwilligungsanfragen erstellen" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:139 @@ -272,67 +278,70 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "Group By" -msgstr "" +msgstr "Gruppieren nach" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Hello," -msgstr "" +msgstr "Hallo" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "I accept this processing of my data" -msgstr "" +msgstr "Ich akzeptiere die Verarbeitung meiner Daten" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "I reject this processing of my data" -msgstr "" +msgstr "Ich lehne die Verarbeitung meiner Daten ab" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_id msgid "ID" -msgstr "" +msgstr "Ausweis" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "If it was a mistake, you can undo it here:" -msgstr "" +msgstr "Wenn es ein Fehler war, können Sie diesen hier rückgängig machen:" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." msgstr "" +"Zeigt den aktuellen Akzeptanzstatus an, der sich aus der letzten Antwort des " +"Betreffenden oder aus dem in der zugehörigen Datenverarbeitungsaktivität " +"angegebenen Standard ergeben kann." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent___last_update msgid "Last Modified on" -msgstr "" +msgstr "Letzte Änderung am" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_uid msgid "Last Updated by" -msgstr "" +msgstr "Zuletzt aktualisiert von" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_write_date msgid "Last Updated on" -msgstr "" +msgstr "Zuletzt aktualisiert am" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_last_metadata msgid "Last metadata" -msgstr "" +msgstr "Letzte Metadaten" #. module: privacy_consent #: selection:privacy.activity,consent_required:0 msgid "Manually" -msgstr "" +msgstr "Manuell" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_last_metadata msgid "Metadata from the last acceptance or rejection by the subject" -msgstr "" +msgstr "Metadaten aus der letzten Annahme oder Ablehnung durch den Betroffenen" #. module: privacy_consent #: code:addons/privacy_consent/models/mail_template.py:25 @@ -346,46 +355,48 @@ msgstr "" #: model:mail.message.subtype,name:privacy_consent.mt_activity_consent_new #: model:mail.message.subtype,name:privacy_consent.mt_consent_consent_new msgid "New Consent" -msgstr "" +msgstr "Neue Einwilligung" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_mail_mail msgid "Outgoing Mails" -msgstr "" +msgstr "Ausgehende Mails" #. module: privacy_consent #: model:ir.model,name:privacy_consent.model_res_partner msgid "Partner" -msgstr "" +msgstr "Partner" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_acceptance_changed msgid "Privacy consent request acceptance status changed" msgstr "" +"Der Akzeptanzstatus der Anfrage 'Einwilligung zum Datenschutz' wurde " +"geändert." #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_consent_new #: model:mail.message.subtype,description:privacy_consent.mt_consent_consent_new msgid "Privacy consent request created" -msgstr "" +msgstr "Anfrage zur Einwilligung erstellt" #. module: privacy_consent #: model:mail.message.subtype,description:privacy_consent.mt_activity_state_changed #: model:mail.message.subtype,description:privacy_consent.mt_consent_state_changed msgid "Privacy consent request state changed" -msgstr "" +msgstr "Status der Anfrage zur Einwilligung geändert" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_res_partner_privacy_consent_count #: model:ir.model.fields,help:privacy_consent.field_res_users_privacy_consent_count msgid "Privacy consent requests amount" -msgstr "" +msgstr "Anzahl der Anfragen zur Einwilligung" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_res_partner_privacy_consent_ids #: model:ir.model.fields,field_description:privacy_consent.field_res_users_privacy_consent_ids msgid "Privacy consents" -msgstr "" +msgstr "Einwilligung zum Datenschutz" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:100 @@ -401,7 +412,7 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_server_action_id msgid "Server action" -msgstr "" +msgstr "Server-Aktion" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_default_consent @@ -411,30 +422,32 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Sincerely,
" -msgstr "" +msgstr "Mit freundlichen Grüßen
" #. module: privacy_consent #: code:addons/privacy_consent/models/privacy_activity.py:92 #, python-format msgid "Specify a mail template to ask automated consent." msgstr "" +"Wählen Sie eine E-Mail-Vorlage aus, um eine automatische Einwilligung " +"einzuholen." #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_state #: model:ir.ui.view,arch_db:privacy_consent.consent_search msgid "State" -msgstr "" +msgstr "Status" #. module: privacy_consent #: model:mail.message.subtype,name:privacy_consent.mt_activity_state_changed #: model:mail.message.subtype,name:privacy_consent.mt_consent_state_changed msgid "State Changed" -msgstr "" +msgstr "Status geändert" #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_consent_partner_id msgid "Subject" -msgstr "" +msgstr "Betroffener" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_partner_id @@ -444,17 +457,19 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Thank you!" -msgstr "" +msgstr "Vielen Dank." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "Thanks for your response." -msgstr "" +msgstr "Vielen Dank für Ihre Antwort." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form msgid "This could send many consent emails, are you sure to proceed?" msgstr "" +"Hiermit könnten viele Einwilligungs-E-Mails verschickt werden. Sind Sie " +"sicher, dass Sie fortfahren wollen?" #. module: privacy_consent #: model:ir.actions.server,name:privacy_consent.update_opt_out @@ -475,8 +490,11 @@ msgstr "" #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have rejected such processing." msgstr "" +"Du hast diese Verarbeitungstätigkeit abgelehnt." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "" +"Du hast dieser Verarbeitungstätigkeit zugestimmt." From 39a7634bdffeccc0a2071592dee651f29188fb9b Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 8 May 2019 18:21:38 +0000 Subject: [PATCH 18/30] Update privacy_consent.pot --- privacy_consent/i18n/privacy_consent.pot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot index a82c662..275b3d2 100644 --- a/privacy_consent/i18n/privacy_consent.pot +++ b/privacy_consent/i18n/privacy_consent.pot @@ -263,7 +263,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:139 +#: code:addons/privacy_consent/models/privacy_activity.py:142 #, python-format msgid "Generated consents" msgstr "" From dc1e2b6dbeb63f8a1de87ae07b946214f98da486 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Wed, 8 May 2019 18:21:44 +0000 Subject: [PATCH 19/30] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/ --- privacy_consent/i18n/de.po | 94 ++++++++++++++++++++++++++------------ privacy_consent/i18n/es.po | 2 +- privacy_consent/i18n/fr.po | 2 +- privacy_consent/i18n/pt.po | 2 +- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/privacy_consent/i18n/de.po b/privacy_consent/i18n/de.po index d2ee5f9..620ee4b 100644 --- a/privacy_consent/i18n/de.po +++ b/privacy_consent/i18n/de.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * privacy_consent +# * privacy_consent # msgid "" msgstr "" @@ -18,37 +18,48 @@ msgstr "" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent -msgid "\n" -"
\n" +msgid "" +"\n" +"
\n" " \n" " \n" " \n" " \n" " \n" " \n" "
\n" " \n" -" \"${object.activity_id.controller_id.display_name|safe}\"\n" +" \"${object."\n" " \n" "
\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" " \n" -" \n" -" \n" " \n" " \n" -" \n" " \n" "
\n" +" \n" "

\n" " Hello, ${object.partner_id.name|safe}\n" "

\n" "

\n" -" We contacted you to ask you to give us your explicit consent to include your data in a data processing activity called\n" -" ${object.activity_id.display_name|safe}, property of\n" -" ${object.activity_id.controller_id.display_name|safe}\n" +" We contacted you to ask you to give us " +"your explicit consent to include your data in a data processing activity " +"called\n" +" ${object.activity_id.display_name|" +"safe}, property of\n" +" ${object.activity_id.controller_id." +"display_name|safe}\n" "

\n" " ${object.description or \"\"}\n" "

\n" " % if object.state == \"answered\":\n" " The last time you answered, you\n" " % elif object.state == \"sent\":\n" -" If you do nothing, we will assume you have\n" +" If you do nothing, we will assume " +"you have\n" " % endif\n" "\n" " % if object.accepted:\n" @@ -64,21 +75,29 @@ msgid "\n" "

\n" -" \n" +" \n" +" \n" " Accept\n" " \n" " \n" -" \n" +" \n" +" \n" " Reject\n" " \n" "
\n" +" \n" "

\n" -" If you need further information, please respond to this email and we will attend your request as soon as possible.\n" +" If you need further information, please " +"respond to this email and we will attend your request as soon as possible.\n" "

\n" "

\n" " Thank you!\n" @@ -87,13 +106,16 @@ msgid "\n" "

\n" -" \n" +"
\n" " \n" " \n" -" \n" " \n" @@ -217,7 +239,8 @@ msgstr "Verarbeitungstätigkeiten" #. module: privacy_consent #: model:mail.template,subject:privacy_consent.template_consent -msgid "Data processing consent request for ${object.activity_id.display_name|safe}" +msgid "" +"Data processing consent request for ${object.activity_id.display_name|safe}" msgstr "Bitte um Erteilung der Einwilligung zur Datenverarbeitung:" #. module: privacy_consent @@ -247,7 +270,10 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_template_id -msgid "Email to be sent to subjects to ask for consent. A good template should include details about the current consent request status, how to change it, and where to get more information." +msgid "" +"Email to be sent to subjects to ask for consent. A good template should " +"include details about the current consent request status, how to change it, " +"and where to get more information." msgstr "" "E-Mail, die an die Betroffenen geschickt werden soll, um die Einwilligung " "einzuholen. Eine gute Vorlage sollte Details über den aktuellen Status der " @@ -256,7 +282,8 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_consent_required -msgid "Enable if you need to track any kind of consent from the affected subjects" +msgid "" +"Enable if you need to track any kind of consent from the affected subjects" msgstr "" #. module: privacy_consent @@ -270,7 +297,7 @@ msgid "Generate missing draft consent requests" msgstr "Fehlende Entwürfe von Einwilligungsanfragen erstellen" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:139 +#: code:addons/privacy_consent/models/privacy_activity.py:142 #, python-format msgid "Generated consents" msgstr "" @@ -307,7 +334,10 @@ msgstr "Wenn es ein Fehler war, können Sie diesen hier rückgängig machen:" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_consent_accepted -msgid "Indicates current acceptance status, which can come from subject's last answer, or from the default specified in the related data processing activity." +msgid "" +"Indicates current acceptance status, which can come from subject's last " +"answer, or from the default specified in the related data processing " +"activity." msgstr "" "Zeigt den aktuellen Akzeptanzstatus an, der sich aus der letzten Antwort des " "Betreffenden oder aus dem in der zugehörigen Datenverarbeitungsaktivität " @@ -346,7 +376,9 @@ msgstr "Metadaten aus der letzten Annahme oder Ablehnung durch den Betroffenen" #. module: privacy_consent #: code:addons/privacy_consent/models/mail_template.py:25 #, python-format -msgid "Missing privacy consent link placeholders. You need at least these two links:\n" +msgid "" +"Missing privacy consent link placeholders. You need at least these two " +"links:\n" "Accept\n" "Reject" msgstr "" @@ -406,7 +438,9 @@ msgstr "" #. module: privacy_consent #: model:ir.model.fields,help:privacy_consent.field_privacy_activity_server_action_id -msgid "Run this action when a new consent request is created or its acceptance status is updated." +msgid "" +"Run this action when a new consent request is created or its acceptance " +"status is updated." msgstr "" #. module: privacy_consent @@ -478,7 +512,9 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.form -msgid "We asked you to authorize us to process your data in this data processing activity:" +msgid "" +"We asked you to authorize us to process your data in this data processing " +"activity:" msgstr "" #. module: privacy_consent @@ -496,5 +532,5 @@ msgstr "" #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "" -"Du hast dieser Verarbeitungstätigkeit zugestimmt." +"Du hast dieser Verarbeitungstätigkeit zugestimmt." diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index 17832bd..6bc168a 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -407,7 +407,7 @@ msgid "Generate missing draft consent requests" msgstr "Generar borradores de las solicitudes de consentimiento faltantes" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:139 +#: code:addons/privacy_consent/models/privacy_activity.py:142 #, python-format msgid "Generated consents" msgstr "Consentimientos generados" diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po index 31c82d9..54d87d1 100644 --- a/privacy_consent/i18n/fr.po +++ b/privacy_consent/i18n/fr.po @@ -291,7 +291,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:139 +#: code:addons/privacy_consent/models/privacy_activity.py:142 #, python-format msgid "Generated consents" msgstr "" diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 83bdd04..f8d513d 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -403,7 +403,7 @@ msgid "Generate missing draft consent requests" msgstr "Gerar pedidos de consentimento em rascunho em falta" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:139 +#: code:addons/privacy_consent/models/privacy_activity.py:142 #, python-format msgid "Generated consents" msgstr "Consentimentos gerados" From e3948fb8ab47e3aaa427d133a95d53cb29f1b443 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 13 May 2019 18:13:10 +0100 Subject: [PATCH 20/30] privacy_consent: Separate automated emails send process Before https://github.com/OCA/data-protection/pull/29 there was a race condition where an email could be sent while the same transaction that created the `privacy.consent` record still wasn't committed, producing a 404 error if the user clicked on "Accept" or "Reject" before all mails were sent. To avoid that, a raw `cr.commit()` was issued, but this produced another situation where the user had to wait until the full email queue is cleared to get his page loaded. It wasn't an error, but a long queue meant several minutes waiting, and it's ulikely that an average human is so patient. So, here's the final fix (I hope!). The main problem was that I was looking in the wrong place to send the email. It turns out that the `self.post_message_with_template()` method is absolutely helpless in the case at hand, where these criteria must be met: * E-mail must be enqueued, no matter if there are less or more than 50 consents to send. * The template must be processed per record. * In an ideal world, a `cr.commit()` must be issued after each sent mail. The metod that was being used: * Didn't allow to use `auto_commit` mode. * Only allowed to render the template per record if called with `composition_mode="mass_mail"`. * Only allowed to enqueue emails if called with `composition_mode="mass_post"`. Obviously, I cannot set 2 different values for `composition_mode`, so a different strategy had to be used. I discovered that the `mail.template` model has a helpful method called `send_mail()` that, by default: * Renders the template per record * Enqueues the email * The email queue is cleared in `auto_commit=True` mode. So, from now on, problems are gone: * The user click, or the cron run, will just generate the missing `privacy.consent` records and enqueue mails for them. * The mail queue manager will send them later, in `auto_commit` mode. * After sending the e-mail, this module will set the `privacy.consent` record as `sent`. * Thanks to *not* sending the email, the process the user faces when he hits the "generate" button is faster. * Instructions in the README and text in the "generate" button are updated to reflect this new behavior. * Thanks to the `auto_commit` feature, if Odoo is rebooted in the middle of a mail queue clearance, the records that were sent remain properly marked as sent, and the missing mails will be sent after the next boot. * No hardcoded commits. * No locked transactions. * BTW I discovered that 2 different emails were created when creating a new consent. I started using `mail_create_nolog=True` to avoid that problem and only log a single creation message. Note to self: never use again `post_message_with_template()`. --- privacy_consent/README.rst | 4 +-- privacy_consent/data/mail.xml | 1 + privacy_consent/i18n/es.po | 30 +++++++++++-------- privacy_consent/i18n/privacy_consent.pot | 13 ++++++-- privacy_consent/models/privacy_activity.py | 3 -- privacy_consent/models/privacy_consent.py | 18 ++--------- privacy_consent/readme/USAGE.rst | 4 +-- privacy_consent/static/description/index.html | 4 +-- privacy_consent/tests/test_consent.py | 14 +++++++-- privacy_consent/views/privacy_activity.xml | 4 +-- 10 files changed, 50 insertions(+), 45 deletions(-) diff --git a/privacy_consent/README.rst b/privacy_consent/README.rst index 4f92832..c15174b 100644 --- a/privacy_consent/README.rst +++ b/privacy_consent/README.rst @@ -106,8 +106,8 @@ New options for data processing activities: * If you chose *Manual* mode, all missing consent request are created as drafts, and nothing else is done now. - * If you chose *Automatic* mode, also those requests are sent to subjects - and set as *Sent*. + * If you chose *Automatic* mode, also those request e-mails are enqueued + and, when the mail queue is cleared, they will be set as *Sent*. #. You will be presented with the list of just-created consent requests. See below. diff --git a/privacy_consent/data/mail.xml b/privacy_consent/data/mail.xml index d7dad6c..f4ab84e 100644 --- a/privacy_consent/data/mail.xml +++ b/privacy_consent/data/mail.xml @@ -7,6 +7,7 @@ + Personal data processing consent request Data processing consent request for ${object.activity_id.display_name|safe} diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index 6bc168a..5c47d5f 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-07-11 08:38+0000\n" -"PO-Revision-Date: 2018-07-11 11:07+0200\n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" +"PO-Revision-Date: 2019-05-13 18:08+0100\n" "Last-Translator: Jairo Llopis \n" "Language-Team: \n" "Language: es_ES\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.8\n" +"X-Generator: Poedit 2.2.1\n" #. module: privacy_consent #: model:mail.template,body_html:privacy_consent.template_consent @@ -372,6 +372,11 @@ msgstr "Contacto duplicado en esta actividad de tratamiento" msgid "Email Templates" msgstr "Plantillas de correo electrónico" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Asistente de redacción de correo electrónico" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -394,12 +399,14 @@ msgid "" "Enable if you need to track any kind of consent from the affected subjects" msgstr "" "Actívelo si necesita registrar cualquier tipo de consentimiento de los " -"interesados." +"interesados" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "Generate and send missing consent requests" -msgstr "Generar y enviar solicitudes de consentimiento faltantes" +msgid "Generate and enqueue missing consent requests" +msgstr "" +"Generar y colocar en la bandeja de salida las solicitudes de consentimiento " +"que falten" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form @@ -407,7 +414,7 @@ msgid "Generate missing draft consent requests" msgstr "Generar borradores de las solicitudes de consentimiento faltantes" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:142 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "Consentimientos generados" @@ -623,10 +630,10 @@ msgstr "Gracias por su respuesta." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "This could send many consent emails, are you sure to proceed?" +msgid "This could enqueue many consent emails, are you sure to proceed?" msgstr "" -"Esto podría enviar muchos correos electrónicos solicitando consentimiento " -"para el tratamiento de datos, ¿seguro que quiere continuar?" +"Esto podría poner en la cola muchos correos electrónicos solicitando " +"consentimiento para el tratamiento de datos, ¿seguro que quiere continuar?" #. module: privacy_consent #: model:ir.actions.server,name:privacy_consent.update_opt_out @@ -656,6 +663,3 @@ msgstr "Ha rechazado dicho tratamiento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Ha aceptado dicho tratamiento." - -#~ msgid "Email composition wizard" -#~ msgstr "Asistente de redacción de correo electrónico" diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot index 275b3d2..cf3cd1a 100644 --- a/privacy_consent/i18n/privacy_consent.pot +++ b/privacy_consent/i18n/privacy_consent.pot @@ -6,6 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" +"PO-Revision-Date: 2019-05-13 17:04+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -237,6 +239,11 @@ msgstr "" msgid "Email Templates" msgstr "" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -254,7 +261,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "Generate and send missing consent requests" +msgid "Generate and enqueue missing consent requests" msgstr "" #. module: privacy_consent @@ -263,7 +270,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:142 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "" @@ -452,7 +459,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "This could send many consent emails, are you sure to proceed?" +msgid "This could enqueue many consent emails, are you sure to proceed?" msgstr "" #. module: privacy_consent diff --git a/privacy_consent/models/privacy_activity.py b/privacy_consent/models/privacy_activity.py index 6a37e53..578f2a7 100644 --- a/privacy_consent/models/privacy_activity.py +++ b/privacy_consent/models/privacy_activity.py @@ -131,9 +131,6 @@ class PrivacyActivity(models.Model): "accepted": one.default_consent, "activity_id": one.id, }) - # Avoid race condition where a user could click on accept/reject link - # in his email before its consent record is saved to the database - consents.env.cr.commit() # Send consent request emails for automatic activitys consents.action_auto_ask() # Redirect user to new consent requests generated diff --git a/privacy_consent/models/privacy_consent.py b/privacy_consent/models/privacy_consent.py index fd90678..866d4fb 100644 --- a/privacy_consent/models/privacy_consent.py +++ b/privacy_consent/models/privacy_consent.py @@ -101,23 +101,10 @@ class PrivacyConsent(models.Model): def _send_consent_notification(self): """Send email notification to subject.""" - consents_by_template = {} for one in self.with_context(tpl_force_default_to=True, mail_notify_user_signature=False, mail_auto_subscribe_no_notify=True): - # Group consents by template, to send in batch where possible - template_id = one.activity_id.consent_template_id.id - consents_by_template.setdefault(template_id, one) - consents_by_template[template_id] |= one - # Send emails - for template_id, consents in consents_by_template.items(): - consents.message_post_with_template( - template_id, - # This mode always sends email, regardless of partner's - # notification preferences; we use it here because it's very - # likely that we are asking authorisation to send emails - composition_mode="mass_mail", - ) + one.activity_id.consent_template_id.send_mail(one.id) def _run_action(self): """Execute server action defined in data processing activity.""" @@ -135,7 +122,8 @@ class PrivacyConsent(models.Model): @api.model def create(self, vals): """Run server action on create.""" - result = super(PrivacyConsent, self).create(vals) + result = super(PrivacyConsent, + self.with_context(mail_create_nolog=True)).create(vals) # Sync the default acceptance status result.sudo()._run_action() return result diff --git a/privacy_consent/readme/USAGE.rst b/privacy_consent/readme/USAGE.rst index 68d4aec..e621578 100644 --- a/privacy_consent/readme/USAGE.rst +++ b/privacy_consent/readme/USAGE.rst @@ -44,8 +44,8 @@ New options for data processing activities: * If you chose *Manual* mode, all missing consent request are created as drafts, and nothing else is done now. - * If you chose *Automatic* mode, also those requests are sent to subjects - and set as *Sent*. + * If you chose *Automatic* mode, also those request e-mails are enqueued + and, when the mail queue is cleared, they will be set as *Sent*. #. You will be presented with the list of just-created consent requests. See below. diff --git a/privacy_consent/static/description/index.html b/privacy_consent/static/description/index.html index 58af3e3..058144a 100644 --- a/privacy_consent/static/description/index.html +++ b/privacy_consent/static/description/index.html @@ -456,8 +456,8 @@ partner’s Elegible for mass mailings option.

  • If you chose Manual mode, all missing consent request are created as drafts, and nothing else is done now.
  • -
  • If you chose Automatic mode, also those requests are sent to subjects -and set as Sent.
  • +
  • If you chose Automatic mode, also those request e-mails are enqueued +and, when the mail queue is cleared, they will be set as Sent.
  • You will be presented with the list of just-created consent requests. diff --git a/privacy_consent/tests/test_consent.py b/privacy_consent/tests/test_consent.py index 6a68e4f..4c6f11c 100644 --- a/privacy_consent/tests/test_consent.py +++ b/privacy_consent/tests/test_consent.py @@ -17,6 +17,8 @@ class ActivityCase(HttpCase): self.env = self._oldenv(self.cursor()) # HACK end self.cron = self.env.ref("privacy_consent.cron_auto_consent") + self.cron_mail_queue = self.env.ref( + "mail.ir_cron_mail_scheduler_action") self.update_opt_out = self.env.ref("privacy_consent.update_opt_out") self.mt_consent_consent_new = self.env.ref( "privacy_consent.mt_consent_consent_new") @@ -93,11 +95,17 @@ class ActivityCase(HttpCase): consents = self.env["privacy.consent"].search([ ("activity_id", "=", self.activity_auto.id), ]) + # Check pending mails + for consent in consents: + self.assertEqual(consent.state, "draft") + messages = consent.message_ids + self.assertEqual(len(messages), 2) # Check sent mails + self.cron_mail_queue.method_direct_trigger() for consent in consents: self.assertEqual(consent.state, "sent") - messages = consent.mapped("message_ids") - self.assertEqual(len(messages), 4) + messages = consent.message_ids + self.assertEqual(len(messages), 3) # 2nd message notifies creation self.assertEqual( messages[2].subtype_id, @@ -167,7 +175,7 @@ class ActivityCase(HttpCase): self.assertEqual(consents.mapped("last_metadata"), [False] * 2) # Check sent mails messages = consents.mapped("message_ids") - self.assertEqual(len(messages), 4) + self.assertEqual(len(messages), 2) subtypes = messages.mapped("subtype_id") self.assertTrue(subtypes & self.mt_consent_consent_new) self.assertFalse(subtypes & self.mt_consent_acceptance_changed) diff --git a/privacy_consent/views/privacy_activity.xml b/privacy_consent/views/privacy_activity.xml index 35c9e5f..b13bce2 100644 --- a/privacy_consent/views/privacy_activity.xml +++ b/privacy_consent/views/privacy_activity.xml @@ -46,8 +46,8 @@ icon="fa-user-plus" name="action_new_consents" type="object" - string="Generate and send missing consent requests" - confirm="This could send many consent emails, are you sure to proceed?" + string="Generate and enqueue missing consent requests" + confirm="This could enqueue many consent emails, are you sure to proceed?" /> From a9716cabf2715e63f221eb42bd953039f31991c7 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Wed, 15 May 2019 07:08:56 +0000 Subject: [PATCH 21/30] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/ --- privacy_consent/i18n/de.po | 16 +++++++++++++--- privacy_consent/i18n/fr.po | 12 +++++++++--- privacy_consent/i18n/pt.po | 19 +++++++++++++------ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/privacy_consent/i18n/de.po b/privacy_consent/i18n/de.po index 620ee4b..81d5db9 100644 --- a/privacy_consent/i18n/de.po +++ b/privacy_consent/i18n/de.po @@ -6,6 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" "PO-Revision-Date: 2019-04-11 11:16+0000\n" "Last-Translator: dw3gn3r \n" "Language-Team: none\n" @@ -263,6 +264,11 @@ msgstr "Doppelter Partner in dieser Verarbeitungsaktivität" msgid "Email Templates" msgstr "E-Mail-Vorlagen" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -288,7 +294,9 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "Generate and send missing consent requests" +#, fuzzy +#| msgid "Generate and send missing consent requests" +msgid "Generate and enqueue missing consent requests" msgstr "Erstellung und Versand fehlender Einwilligungsanfragen" #. module: privacy_consent @@ -297,7 +305,7 @@ msgid "Generate missing draft consent requests" msgstr "Fehlende Entwürfe von Einwilligungsanfragen erstellen" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:142 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "" @@ -500,7 +508,9 @@ msgstr "Vielen Dank für Ihre Antwort." #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "This could send many consent emails, are you sure to proceed?" +#, fuzzy +#| msgid "This could send many consent emails, are you sure to proceed?" +msgid "This could enqueue many consent emails, are you sure to proceed?" msgstr "" "Hiermit könnten viele Einwilligungs-E-Mails verschickt werden. Sind Sie " "sicher, dass Sie fortfahren wollen?" diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po index 54d87d1..58c2729 100644 --- a/privacy_consent/i18n/fr.po +++ b/privacy_consent/i18n/fr.po @@ -6,6 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: fr\n" @@ -261,6 +262,11 @@ msgstr "" msgid "Email Templates" msgstr "" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -282,7 +288,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "Generate and send missing consent requests" +msgid "Generate and enqueue missing consent requests" msgstr "" #. module: privacy_consent @@ -291,7 +297,7 @@ msgid "Generate missing draft consent requests" msgstr "" #. module: privacy_consent -#: code:addons/privacy_consent/models/privacy_activity.py:142 +#: code:addons/privacy_consent/models/privacy_activity.py:139 #, python-format msgid "Generated consents" msgstr "" @@ -487,7 +493,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "This could send many consent emails, are you sure to proceed?" +msgid "This could enqueue many consent emails, are you sure to proceed?" msgstr "" #. module: privacy_consent diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index f8d513d..658d871 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -2,6 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Portuguese (data-protection-10.0)\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" "PO-Revision-Date: 2018-12-15 21:58+0000\n" "Last-Translator: alvarorib \n" "Language-Team: Portuguese rejeitou este processamento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Você aceitou este processamento." - -#~ msgid "Email composition wizard" -#~ msgstr "Assistente de criação de email" From 01467805ddd54673ff919bbff7a527169a734fa7 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 15 May 2019 07:16:47 +0000 Subject: [PATCH 22/30] Update privacy_consent.pot --- privacy_consent/i18n/privacy_consent.pot | 7 ------- 1 file changed, 7 deletions(-) diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot index cf3cd1a..8e0642f 100644 --- a/privacy_consent/i18n/privacy_consent.pot +++ b/privacy_consent/i18n/privacy_consent.pot @@ -6,8 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:04+0000\n" -"PO-Revision-Date: 2019-05-13 17:04+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -239,11 +237,6 @@ msgstr "" msgid "Email Templates" msgstr "" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" From a4adbad798ee0708c3b86697eed62a78e9996fa4 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Wed, 15 May 2019 07:16:53 +0000 Subject: [PATCH 23/30] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: data-protection-10.0/data-protection-10.0-privacy_consent Translate-URL: https://translation.odoo-community.org/projects/data-protection-10-0/data-protection-10-0-privacy_consent/ --- privacy_consent/i18n/de.po | 5 ----- privacy_consent/i18n/es.po | 8 +++----- privacy_consent/i18n/fr.po | 5 ----- privacy_consent/i18n/pt.po | 8 +++----- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/privacy_consent/i18n/de.po b/privacy_consent/i18n/de.po index 81d5db9..463d79d 100644 --- a/privacy_consent/i18n/de.po +++ b/privacy_consent/i18n/de.po @@ -264,11 +264,6 @@ msgstr "Doppelter Partner in dieser Verarbeitungsaktivität" msgid "Email Templates" msgstr "E-Mail-Vorlagen" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index 5c47d5f..d7e0b9c 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -372,11 +372,6 @@ msgstr "Contacto duplicado en esta actividad de tratamiento" msgid "Email Templates" msgstr "Plantillas de correo electrónico" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "Asistente de redacción de correo electrónico" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -663,3 +658,6 @@ msgstr "Ha rechazado dicho tratamiento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Ha aceptado dicho tratamiento." + +#~ msgid "Email composition wizard" +#~ msgstr "Asistente de redacción de correo electrónico" diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po index 58c2729..d32c4e6 100644 --- a/privacy_consent/i18n/fr.po +++ b/privacy_consent/i18n/fr.po @@ -262,11 +262,6 @@ msgstr "" msgid "Email Templates" msgstr "" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 658d871..5928e40 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -369,11 +369,6 @@ msgstr "Parceiro duplicado nesta atividade de processamento de dados" msgid "Email Templates" msgstr "Modelos de E-mail" -#. module: privacy_consent -#: model:ir.model,name:privacy_consent.model_mail_compose_message -msgid "Email composition wizard" -msgstr "Assistente de criação de email" - #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -655,3 +650,6 @@ msgstr "Você rejeitou este processamento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Você aceitou este processamento." + +#~ msgid "Email composition wizard" +#~ msgstr "Assistente de criação de email" From b97c991f02f51c2f5da803f326b54329be6cd8ef Mon Sep 17 00:00:00 2001 From: fkantelberg Date: Thu, 4 Jul 2019 14:44:17 +0200 Subject: [PATCH 24/30] Migrate privacy_consent to v11 --- privacy_consent/__manifest__.py | 5 ++--- privacy_consent/controllers/main.py | 1 - privacy_consent/data/ir_actions_server.xml | 13 +++---------- privacy_consent/data/ir_cron.xml | 8 +++++--- privacy_consent/i18n/es.po | 8 +++++--- privacy_consent/i18n/fr.po | 5 ++--- privacy_consent/i18n/privacy_consent.pot | 7 +++++++ privacy_consent/i18n/pt.po | 9 ++------- privacy_consent/models/mail_mail.py | 1 - privacy_consent/models/mail_template.py | 1 - privacy_consent/models/privacy_activity.py | 1 - privacy_consent/models/privacy_consent.py | 1 - privacy_consent/models/res_partner.py | 1 - privacy_consent/readme/CONTRIBUTORS.rst | 4 ++++ privacy_consent/tests/test_consent.py | 5 ++--- 15 files changed, 32 insertions(+), 38 deletions(-) diff --git a/privacy_consent/__manifest__.py b/privacy_consent/__manifest__.py index ee84254..a9d388b 100644 --- a/privacy_consent/__manifest__.py +++ b/privacy_consent/__manifest__.py @@ -1,15 +1,14 @@ -# -*- coding: utf-8 -*- # Copyright 2018 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Privacy - Consent", "summary": "Allow people to explicitly accept or reject inclusion " "in some activity, GDPR compliant", - "version": "10.0.1.0.0", + "version": "11.0.1.0.0", "development_status": "Production/Stable", "category": "Privacy", "website": "https://github.com/OCA/management-activity", - "author": "Tecnativa, Odoo Community Association (OCA)", + "author": "Tecnativa, initOS GmbH, Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, diff --git a/privacy_consent/controllers/main.py b/privacy_consent/controllers/main.py index 8f243d0..dddb20b 100644 --- a/privacy_consent/controllers/main.py +++ b/privacy_consent/controllers/main.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2018 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/privacy_consent/data/ir_actions_server.xml b/privacy_consent/data/ir_actions_server.xml index 58788e6..4e7bc4d 100644 --- a/privacy_consent/data/ir_actions_server.xml +++ b/privacy_consent/data/ir_actions_server.xml @@ -1,5 +1,6 @@ @@ -8,16 +9,8 @@ Update partner's opt out - object_write - expression - record.partner_id - - - - - - equation - not record.accepted + code + records.mapped('partner_id').write({'opt_out': not record.accepted}) diff --git a/privacy_consent/data/ir_cron.xml b/privacy_consent/data/ir_cron.xml index cc4bb38..72acc37 100644 --- a/privacy_consent/data/ir_cron.xml +++ b/privacy_consent/data/ir_cron.xml @@ -1,15 +1,17 @@ Request automatic data processing consents - privacy.activity - _cron_new_consents + + code + model._cron_new_consents() 1 - work_days + days -1 diff --git a/privacy_consent/i18n/es.po b/privacy_consent/i18n/es.po index d7e0b9c..5c47d5f 100644 --- a/privacy_consent/i18n/es.po +++ b/privacy_consent/i18n/es.po @@ -372,6 +372,11 @@ msgstr "Contacto duplicado en esta actividad de tratamiento" msgid "Email Templates" msgstr "Plantillas de correo electrónico" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Asistente de redacción de correo electrónico" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" @@ -658,6 +663,3 @@ msgstr "Ha rechazado dicho tratamiento." #: model:ir.ui.view,arch_db:privacy_consent.form msgid "You have accepted such processing." msgstr "Ha aceptado dicho tratamiento." - -#~ msgid "Email composition wizard" -#~ msgstr "Asistente de redacción de correo electrónico" diff --git a/privacy_consent/i18n/fr.po b/privacy_consent/i18n/fr.po index d32c4e6..31c82d9 100644 --- a/privacy_consent/i18n/fr.po +++ b/privacy_consent/i18n/fr.po @@ -6,7 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:04+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: fr\n" @@ -283,7 +282,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "Generate and enqueue missing consent requests" +msgid "Generate and send missing consent requests" msgstr "" #. module: privacy_consent @@ -488,7 +487,7 @@ msgstr "" #. module: privacy_consent #: model:ir.ui.view,arch_db:privacy_consent.activity_form -msgid "This could enqueue many consent emails, are you sure to proceed?" +msgid "This could send many consent emails, are you sure to proceed?" msgstr "" #. module: privacy_consent diff --git a/privacy_consent/i18n/privacy_consent.pot b/privacy_consent/i18n/privacy_consent.pot index 8e0642f..cf3cd1a 100644 --- a/privacy_consent/i18n/privacy_consent.pot +++ b/privacy_consent/i18n/privacy_consent.pot @@ -6,6 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-05-13 17:04+0000\n" +"PO-Revision-Date: 2019-05-13 17:04+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -237,6 +239,11 @@ msgstr "" msgid "Email Templates" msgstr "" +#. module: privacy_consent +#: model:ir.model,name:privacy_consent.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + #. module: privacy_consent #: model:ir.model.fields,field_description:privacy_consent.field_privacy_activity_consent_template_id msgid "Email template" diff --git a/privacy_consent/i18n/pt.po b/privacy_consent/i18n/pt.po index 5928e40..83bdd04 100644 --- a/privacy_consent/i18n/pt.po +++ b/privacy_consent/i18n/pt.po @@ -2,7 +2,6 @@ msgid "" msgstr "" "Project-Id-Version: Portuguese (data-protection-10.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:04+0000\n" "PO-Revision-Date: 2018-12-15 21:58+0000\n" "Last-Translator: alvarorib \n" "Language-Team: Portuguese `_: * Jairo Llopis + +* `initOS GmbH `_: + + * Florian Kantelberg diff --git a/privacy_consent/tests/test_consent.py b/privacy_consent/tests/test_consent.py index 4c6f11c..8de1e56 100644 --- a/privacy_consent/tests/test_consent.py +++ b/privacy_consent/tests/test_consent.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2018 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -204,7 +203,7 @@ class ActivityCase(HttpCase): self.assertNotIn(reject_url, messages[1].body) # Visit tokenized accept URL with self.release_cr(): - result = self.url_open(accept_url).read() + result = self.url_open(accept_url).text self.assertIn("accepted", result) self.assertIn(reject_url, result) self.assertIn(self.activity_manual.name, result) @@ -220,7 +219,7 @@ class ActivityCase(HttpCase): ) # Visit tokenized reject URL with self.release_cr(): - result = self.url_open(reject_url).read() + result = self.url_open(reject_url).text self.assertIn("rejected", result) self.assertIn(accept_url, result) self.assertIn(self.activity_manual.name, result) From 921b4fbacb384a8ecbae79020fb7868c6dcff910 Mon Sep 17 00:00:00 2001 From: fkantelberg Date: Fri, 5 Jul 2019 08:17:38 +0200 Subject: [PATCH 25/30] Fix deprecated widget --- privacy/views/privacy_activity_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy/views/privacy_activity_view.xml b/privacy/views/privacy_activity_view.xml index 50da021..2642a97 100644 --- a/privacy/views/privacy_activity_view.xml +++ b/privacy/views/privacy_activity_view.xml @@ -42,7 +42,7 @@ Date: Fri, 5 Jul 2019 09:39:09 +0200 Subject: [PATCH 26/30] Change icon to handshake --- privacy_consent/views/privacy_activity.xml | 3 +-- privacy_consent/views/res_partner.xml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/privacy_consent/views/privacy_activity.xml b/privacy_consent/views/privacy_activity.xml index b13bce2..ef72275 100644 --- a/privacy_consent/views/privacy_activity.xml +++ b/privacy_consent/views/privacy_activity.xml @@ -10,12 +10,11 @@

    -
  • Bugs are tracked on GitHub Issues. 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.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -493,6 +493,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    Authors

    • Tecnativa
    • +
    • initOS GmbH
    @@ -502,6 +503,10 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Jairo Llopis
  • +
  • initOS GmbH:
      +
    • Florian Kantelberg
    • +
    +
  • @@ -511,7 +516,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    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.

    -

    This module is part of the OCA/data-protection project on GitHub.

    +

    This module is part of the OCA/data-protection project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    From 090503fffa06825168ab08a4f8b497ef9f7ca7e9 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 5 Jul 2019 09:26:10 +0000 Subject: [PATCH 30/30] [ADD] setup.py --- setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + setup/privacy_consent/odoo/addons/privacy_consent | 1 + setup/privacy_consent/setup.cfg | 2 ++ setup/privacy_consent/setup.py | 6 ++++++ 5 files changed, 11 insertions(+), 1 deletion(-) create mode 120000 setup/privacy_consent/odoo/addons/privacy_consent create mode 100644 setup/privacy_consent/setup.cfg create mode 100644 setup/privacy_consent/setup.py diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 3b091b2..27c495f 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -11.0.20190321.0 \ No newline at end of file +11.0.20190705.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index becc6b2..16a1025 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -10,6 +10,7 @@ setuptools.setup( install_requires=[ 'odoo11-addon-contact_search_form', 'odoo11-addon-privacy', + 'odoo11-addon-privacy_consent', 'odoo11-addon-privacy_partner_report', 'odoo11-addon-website_contact_extend', ], diff --git a/setup/privacy_consent/odoo/addons/privacy_consent b/setup/privacy_consent/odoo/addons/privacy_consent new file mode 120000 index 0000000..f558b8c --- /dev/null +++ b/setup/privacy_consent/odoo/addons/privacy_consent @@ -0,0 +1 @@ +../../../../privacy_consent \ No newline at end of file diff --git a/setup/privacy_consent/setup.cfg b/setup/privacy_consent/setup.cfg new file mode 100644 index 0000000..3c6e79c --- /dev/null +++ b/setup/privacy_consent/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal=1 diff --git a/setup/privacy_consent/setup.py b/setup/privacy_consent/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/privacy_consent/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)
    \n" +" \n" "

    \n" " Sent by\n" -" ${object.activity_id.controller_id.display_name|safe}.\n" +" " +"${object.activity_id.controller_id.display_name|safe}.\n" "

    \n" "