You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2018 Tecnativa - Jairo Llopis
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  4. from odoo import _, api, fields, models
  5. from odoo.exceptions import ValidationError
  6. from odoo.tools.safe_eval import safe_eval
  7. class PrivacyActivity(models.Model):
  8. _inherit = 'privacy.activity'
  9. server_action_id = fields.Many2one(
  10. "ir.actions.server",
  11. "Server action",
  12. domain=[
  13. ("model_id.model", "=", "privacy.consent"),
  14. ],
  15. help="Run this action when a new consent request is created or its "
  16. "acceptance status is updated.",
  17. )
  18. consent_ids = fields.One2many(
  19. "privacy.consent",
  20. "activity_id",
  21. "Consents",
  22. )
  23. consent_count = fields.Integer(
  24. "Consents",
  25. compute="_compute_consent_count",
  26. )
  27. consent_required = fields.Selection(
  28. [("auto", "Automatically"), ("manual", "Manually")],
  29. "Ask subjects for consent",
  30. help="Enable if you need to track any kind of consent "
  31. "from the affected subjects",
  32. )
  33. consent_template_id = fields.Many2one(
  34. "mail.template",
  35. "Email template",
  36. default=lambda self: self._default_consent_template_id(),
  37. domain=[
  38. ("model", "=", "privacy.consent"),
  39. ],
  40. help="Email to be sent to subjects to ask for consent. "
  41. "A good template should include details about the current "
  42. "consent request status, how to change it, and where to "
  43. "get more information.",
  44. )
  45. default_consent = fields.Boolean(
  46. "Accepted by default",
  47. help="Should we assume the subject has accepted if we receive no "
  48. "response?",
  49. )
  50. # Hidden helpers help user design new templates
  51. consent_template_default_body_html = fields.Text(
  52. compute="_compute_consent_template_defaults",
  53. )
  54. consent_template_default_subject = fields.Char(
  55. compute="_compute_consent_template_defaults",
  56. )
  57. @api.model
  58. def _default_consent_template_id(self):
  59. return self.env.ref("privacy_consent.template_consent", False)
  60. @api.depends("consent_ids")
  61. def _compute_consent_count(self):
  62. groups = self.env["privacy.consent"].read_group(
  63. [("activity_id", "in", self.ids)],
  64. ["activity_id"],
  65. ["activity_id"],
  66. )
  67. for group in groups:
  68. self.browse(group["activity_id"][0], self._prefetch) \
  69. .consent_count = group["activity_id_count"]
  70. def _compute_consent_template_defaults(self):
  71. """Used in context values, to help users design new templates."""
  72. template = self._default_consent_template_id()
  73. if template:
  74. self.update({
  75. "consent_template_default_body_html": template.body_html,
  76. "consent_template_default_subject": template.subject,
  77. })
  78. @api.constrains("consent_required", "consent_template_id")
  79. def _check_auto_consent_has_template(self):
  80. """Require a mail template to automate consent requests."""
  81. for one in self:
  82. if one.consent_required == "auto" and not one.consent_template_id:
  83. raise ValidationError(_(
  84. "Specify a mail template to ask automated consent."
  85. ))
  86. @api.constrains("consent_required", "subject_find")
  87. def _check_consent_required_subject_find(self):
  88. for one in self:
  89. if one.consent_required and not one.subject_find:
  90. raise ValidationError(_(
  91. "Require consent is available only for subjects "
  92. "in current database."
  93. ))
  94. @api.model
  95. def _cron_new_consents(self):
  96. """Ask all missing automatic consent requests."""
  97. automatic = self.search([("consent_required", "=", "auto")])
  98. automatic.action_new_consents()
  99. @api.onchange("consent_required")
  100. def _onchange_consent_required_subject_find(self):
  101. """Find subjects automatically if we require their consent."""
  102. if self.consent_required:
  103. self.subject_find = True
  104. def action_new_consents(self):
  105. """Generate new consent requests."""
  106. consents = self.env["privacy.consent"]
  107. # Skip activitys where consent is not required
  108. for one in self.with_context(active_test=False) \
  109. .filtered("consent_required"):
  110. domain = [
  111. ("id", "not in", one.mapped("consent_ids.partner_id").ids),
  112. ("email", "!=", False),
  113. ] + safe_eval(one.subject_domain)
  114. # Create missing consent requests
  115. for missing in self.env["res.partner"].search(domain):
  116. consents |= consents.create({
  117. "partner_id": missing.id,
  118. "accepted": one.default_consent,
  119. "activity_id": one.id,
  120. })
  121. # Avoid race condition where a user could click on accept/reject link
  122. # in his email before its consent record is saved to the database
  123. consents.env.cr.commit()
  124. # Send consent request emails for automatic activitys
  125. consents.action_auto_ask()
  126. # Redirect user to new consent requests generated
  127. return {
  128. "domain": [("id", "in", consents.ids)],
  129. "name": _("Generated consents"),
  130. "res_model": consents._name,
  131. "type": "ir.actions.act_window",
  132. "view_mode": "tree,form",
  133. }