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.

131 lines
4.4 KiB

[9.0][MIG][mass_mailing_custom_unsubscribe] Migrate. - Imported last updates from v8. - Adapted to v9. - Added a saner default to `mass_mailing.salt` configuration parameter by reusing `database.secret` if available, hoping that some day https://github.com/odoo/odoo/pull/12040 gets merged. - Updated README. - Increase security, drop backwards compatibility. Security got improved upstream, which would again break compatibility among current addon and future master upstream. I choose to break it now and keep it secured future-wise, so I drop the backwards compatibility features. - Includes tour tests. - Removes outdated tests. - Extends the mailing list management form when unsubscriber is a contact. - Adds a reason form even if he is not. - Avoids all methods that were not model-agnostic. [FIX][mass_mailing_custom_unsubscribe] Reasons noupdate After this fix, when you update the addon, you will not lose your customized reasons. [FIX] Compatibilize with mass_mailing_partner Current test code was based on the assumption that the `@api.model` decorator on `create()` ensured an empty recordset when running the method, but that's not true. This was causing an incompatibility betwee these tests and the `mass_mailing_partner` addon, which works assuming 0-1 recordsets. Now records are created from an empty recordset, and thus tests work everywhere. Update instructions If the user does not add the unsubscribe snippet, nothing will happen, so it's added to README to avoid confusion when testing/using the addon. [FIX] Use the right operator to preserve recordsets order Using `|=` sorts records at will each time (treating them as Python's `set`). Using `+=` always appends a record to the end of the set. Since we are using the record position in the set, this caused the test to work sometimes and fail other times. Now it works always.
8 years ago
[9.0][MIG][mass_mailing_custom_unsubscribe] Migrate. - Imported last updates from v8. - Adapted to v9. - Added a saner default to `mass_mailing.salt` configuration parameter by reusing `database.secret` if available, hoping that some day https://github.com/odoo/odoo/pull/12040 gets merged. - Updated README. - Increase security, drop backwards compatibility. Security got improved upstream, which would again break compatibility among current addon and future master upstream. I choose to break it now and keep it secured future-wise, so I drop the backwards compatibility features. - Includes tour tests. - Removes outdated tests. - Extends the mailing list management form when unsubscriber is a contact. - Adds a reason form even if he is not. - Avoids all methods that were not model-agnostic. [FIX][mass_mailing_custom_unsubscribe] Reasons noupdate After this fix, when you update the addon, you will not lose your customized reasons. [FIX] Compatibilize with mass_mailing_partner Current test code was based on the assumption that the `@api.model` decorator on `create()` ensured an empty recordset when running the method, but that's not true. This was causing an incompatibility betwee these tests and the `mass_mailing_partner` addon, which works assuming 0-1 recordsets. Now records are created from an empty recordset, and thus tests work everywhere. Update instructions If the user does not add the unsubscribe snippet, nothing will happen, so it's added to README to avoid confusion when testing/using the addon. [FIX] Use the right operator to preserve recordsets order Using `|=` sorts records at will each time (treating them as Python's `set`). Using `+=` always appends a record to the end of the set. Since we are using the record position in the set, this caused the test to work sometimes and fail other times. Now it works always.
8 years ago
[9.0][MIG][mass_mailing_custom_unsubscribe] Migrate. - Imported last updates from v8. - Adapted to v9. - Added a saner default to `mass_mailing.salt` configuration parameter by reusing `database.secret` if available, hoping that some day https://github.com/odoo/odoo/pull/12040 gets merged. - Updated README. - Increase security, drop backwards compatibility. Security got improved upstream, which would again break compatibility among current addon and future master upstream. I choose to break it now and keep it secured future-wise, so I drop the backwards compatibility features. - Includes tour tests. - Removes outdated tests. - Extends the mailing list management form when unsubscriber is a contact. - Adds a reason form even if he is not. - Avoids all methods that were not model-agnostic. [FIX][mass_mailing_custom_unsubscribe] Reasons noupdate After this fix, when you update the addon, you will not lose your customized reasons. [FIX] Compatibilize with mass_mailing_partner Current test code was based on the assumption that the `@api.model` decorator on `create()` ensured an empty recordset when running the method, but that's not true. This was causing an incompatibility betwee these tests and the `mass_mailing_partner` addon, which works assuming 0-1 recordsets. Now records are created from an empty recordset, and thus tests work everywhere. Update instructions If the user does not add the unsubscribe snippet, nothing will happen, so it's added to README to avoid confusion when testing/using the addon. [FIX] Use the right operator to preserve recordsets order Using `|=` sorts records at will each time (treating them as Python's `set`). Using `+=` always appends a record to the end of the set. Since we are using the record position in the set, this caused the test to work sometimes and fail other times. Now it works always.
8 years ago
  1. # Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import _, api, fields, models
  4. from odoo.addons.mass_mailing.models.mass_mailing import \
  5. MASS_MAILING_BUSINESS_MODELS
  6. from .. import exceptions
  7. class MailUnsubscription(models.Model):
  8. _name = "mail.unsubscription"
  9. _inherit = "mail.thread"
  10. _rec_name = "date"
  11. _order = "date DESC"
  12. date = fields.Datetime(
  13. default=lambda self: self._default_date(),
  14. required=True)
  15. email = fields.Char(
  16. required=True)
  17. action = fields.Selection(
  18. selection=[
  19. ("subscription", "Subscription"),
  20. ("unsubscription", "Unsubscription"),
  21. ],
  22. required=True,
  23. default="unsubscription",
  24. help="What did the (un)subscriber choose to do.",
  25. )
  26. mass_mailing_id = fields.Many2one(
  27. "mail.mass_mailing",
  28. "Mass mailing",
  29. required=True,
  30. help="Mass mailing from which he was unsubscribed.")
  31. unsubscriber_id = fields.Reference(
  32. lambda self: self._selection_unsubscriber_id(),
  33. "(Un)subscriber",
  34. help="Who was subscribed or unsubscribed.")
  35. mailing_list_id = fields.Many2many(
  36. comodel_name="mail.mass_mailing.list",
  37. string="Mailing list",
  38. ondelete="set null",
  39. compute="_compute_mailing_list_id",
  40. store=True,
  41. help="(Un)subscribed mass mailing list, if any.",
  42. readonly=False,
  43. )
  44. reason_id = fields.Many2one(
  45. "mail.unsubscription.reason",
  46. "Reason",
  47. ondelete="restrict",
  48. help="Why the unsubscription was made.")
  49. details = fields.Char(
  50. help="More details on why the unsubscription was made.")
  51. details_required = fields.Boolean(
  52. related="reason_id.details_required")
  53. metadata = fields.Text(
  54. readonly=True,
  55. help="HTTP request metadata used when creating this record.",
  56. )
  57. def map_mailing_list_models(self, models):
  58. model_mapped = []
  59. for model in models:
  60. if model == 'mail.mass_mailing.list':
  61. model_mapped.append(('mail.mass_mailing.contact', model))
  62. else:
  63. model_mapped.append((model, model))
  64. return model_mapped
  65. @api.model
  66. def _default_date(self):
  67. return fields.Datetime.now()
  68. @api.model
  69. def _selection_unsubscriber_id(self):
  70. """Models that can be linked to a ``mail.mass_mailing``."""
  71. model = self.env['ir.model'].search(
  72. [('model', 'in', MASS_MAILING_BUSINESS_MODELS)]).mapped('model')
  73. return self.map_mailing_list_models(model)
  74. @api.multi
  75. @api.constrains("action", "reason_id")
  76. def _check_reason_needed(self):
  77. """Ensure reason is given for unsubscriptions."""
  78. for one in self:
  79. if one.action == "unsubscription" and not one.reason_id:
  80. raise exceptions.ReasonRequiredError(
  81. _("Please indicate why are you unsubscribing."))
  82. @api.multi
  83. @api.constrains("details", "reason_id")
  84. def _check_details_needed(self):
  85. """Ensure details are given if required."""
  86. for one in self:
  87. if not one.details and one.details_required:
  88. raise exceptions.DetailsRequiredError(
  89. _("Please provide details on why you are unsubscribing."))
  90. @api.multi
  91. @api.depends("unsubscriber_id")
  92. def _compute_mailing_list_id(self):
  93. """Get the mass mailing list, if it is possible."""
  94. for one in self:
  95. try:
  96. one.mailing_list_id |= one.unsubscriber_id.mailing_list_id
  97. except AttributeError:
  98. # Possibly model != mail.mass_mailing.contact; no problem
  99. pass
  100. @api.model
  101. def create(self, vals):
  102. # No reasons for subscriptions
  103. if vals.get("action") == "subscription":
  104. vals = dict(vals, reason_id=False, details=False)
  105. return super(MailUnsubscription, self).create(vals)
  106. class MailUnsubscriptionReason(models.Model):
  107. _name = "mail.unsubscription.reason"
  108. _order = "sequence, name"
  109. name = fields.Char(
  110. index=True,
  111. translate=True,
  112. required=True)
  113. details_required = fields.Boolean(
  114. help="Check to ask for more details when this reason is selected.")
  115. sequence = fields.Integer(
  116. index=True,
  117. help="Position of the reason in the list.")