diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 3824dc139..f13fc68e6 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -84,35 +84,38 @@ Authors Contributors ------------ -- `ForgeFlow `__: +- `ForgeFlow `__: - - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - - Miquel Raïch (miquel.raich@forgeflow.com) - - Bernat Puig Font (bernat.puig@forgeflow.com) + - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) + - Miquel Raïch (miquel.raich@forgeflow.com) + - Bernat Puig Font (bernat.puig@forgeflow.com) -- Pedro Gonzalez (pedro.gonzalez@pesol.es) -- `Tecnativa `__: +- Pedro Gonzalez (pedro.gonzalez@pesol.es) +- `Tecnativa `__: - - David Vidal + - David Vidal -- `Dynapps `__: +- `Dynapps `__: - - Raf Ven + - Raf Ven -- [Trobz] (https://trobz.com): +- [Trobz] (https://trobz.com): - - Son Ho sonhd@trobz.com + - Son Ho sonhd@trobz.com -- [Camptocamp] (https://camptocamp.com): +- [Camptocamp] (https://camptocamp.com): - - Vincent Van Rossem vincent.vanrossem@camptocamp.com - - Italo Lopes italo.lopes@camptocamp.com + - Vincent Van Rossem vincent.vanrossem@camptocamp.com + - Italo Lopes italo.lopes@camptocamp.com -- `CorporateHub `__ +- `CorporateHub `__ - - Alexey Pelykh alexey.pelykh@corphub.eu + - Alexey Pelykh alexey.pelykh@corphub.eu -- Stefan Rijnhart (stefan@opener.amsterdam) +- Stefan Rijnhart (stefan@opener.amsterdam) +- `glueckkanja AG `__ + + - Christopher Rogos (crogos@gmail.com) Other credits ------------- diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 9b10e5835..c5aee889a 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -25,6 +25,9 @@ "views/mail_activity_views.xml", "views/res_users_views.xml", ], + "demo": [ + "demo/mail_activity_team.xml", + ], "assets": { "web.assets_backend": [ "mail_activity_team/static/src/components/*/*", diff --git a/mail_activity_team/demo/mail_activity_team.xml b/mail_activity_team/demo/mail_activity_team.xml new file mode 100644 index 000000000..b4662a225 --- /dev/null +++ b/mail_activity_team/demo/mail_activity_team.xml @@ -0,0 +1,79 @@ + + + + + Administrator Team + True + + + + + + + Support Team + True + + + + + + + + + + + + + Schedule follow-up call + + + + + + + + + + Send quotation + + + + + + + + + + + Create support ticket + + + + + + + + + + Technical support call + + + diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index c2e864461..5c5215495 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -3,6 +3,9 @@ from odoo import SUPERUSER_ID, api, fields, models from odoo.exceptions import ValidationError +from odoo.tools.misc import get_lang + +from odoo.addons.mail.tools.discuss import Store class MailActivity(models.Model): @@ -74,15 +77,70 @@ def create(self, vals_list): # odoo import api, fields, models the default one linked to the activity type. # We don't want this behavior because using the team_id, we want to assign the # activity to the whole team. + new_vals_list = [] for vals in vals_list: + new_vals = vals.copy() # we need to be sure that we are in a context where the team_id is set, # and we don't want to use user_id - if vals.get("team_id"): + if new_vals.get("team_id"): # using team, we have user_id = team_user_id, # so if we don't have a user_team_id we don't want user_id too - if "user_id" in vals and not vals.get("team_user_id"): - del vals["user_id"] - return super().create(vals_list) + if "user_id" in new_vals and not new_vals.get("team_user_id"): + del new_vals["user_id"] + # team_user_id is a related field pointing to user_id (readonly=False). + # If left in vals, the ORM places it in the 'inversed' bucket and + # calls _inverse_related *after* the initial INSERT while user_id is + # still NULL. That triggers Model.write({'user_id': …}) which in turn + # fires action_notify() → action_notify_team() a first time, and then + # core mail.activity.create()'s post-hook fires action_notify() a + # second time — causing duplicate notifications for team members. + # Eagerly resolving team_user_id to user_id here ensures user_id is + # stored in the INSERT so no inverse write occurs. + if "team_user_id" in new_vals: + team_user_id_val = new_vals.pop("team_user_id") + new_vals.setdefault("user_id", team_user_id_val) + new_vals_list.append(new_vals) + activities = super().create(new_vals_list) + if not self.env.context.get("mail_activity_quick_update"): + # Core create() triggers action_notify() only for activities assigned to + # users different from the current one. Notify team members here only for + # activities not covered by that path to avoid duplicate notifications. + activities_without_core_notify = activities.filtered( + lambda activity: activity.user_id == self.env.user + ) + activities_without_core_notify.action_notify_team() + return activities + + def write(self, values): + # Notify the new team, but prevent duplicate notifications by excluding + # activities that will be notified by core write()->action_notify() + # when the user changes. + team_notify_activities = self.env["mail.activity"] + core_notified_activities = self.env["mail.activity"] + if not self.env.context.get("mail_activity_quick_update", False): + new_team_id = values.get("team_id", False) + team_notify_activities = self.filtered( + lambda activity, new_team_id=new_team_id: new_team_id + and activity.team_id.id != new_team_id + ) + new_user_id = values.get("user_id", False) + user_changed_activities = self.filtered( + lambda activity, new_user_id=new_user_id: new_user_id + and activity.user_id.id != new_user_id + ) + team_notify_activities |= user_changed_activities + + # Core write() calls action_notify() for user changes except when + # assigning to the current user; avoid re-sending team notifications. + if new_user_id != self.env.uid: + core_notified_activities = user_changed_activities + + res = super().write(values) + # notify new responsibles + + if not self.env.context.get("mail_activity_quick_update", False): + (team_notify_activities - core_notified_activities).action_notify_team() + return res @api.onchange("team_id") def _onchange_team_id(self): @@ -130,3 +188,84 @@ def _onchange_activity_type_id(self): if self.user_id not in members and members: self.user_id = members[:1] return res + + def _to_store_defaults(self, target): + values = super()._to_store_defaults(target) + values.append(Store.One("team_id", "name")) + return values + + def action_notify_team(self): + # Like action_notify(), but for team members. + classified = self._classify_by_model() + for model, activity_data in classified.items(): + records_sudo = self.env[model].sudo().browse(activity_data["record_ids"]) + # in case record was cascade-deleted in DB, skipping unlink override + activity_data["record_ids"] = records_sudo.exists().ids + + for activity in self: + if activity.res_id not in classified[activity.res_model]["record_ids"]: + continue + if not activity.team_id.notify_members: + continue + + record = activity.env[activity.res_model].browse(activity.res_id) + # Notify each team member except the assigned user and the current user + members = activity.team_id.member_ids.filtered( + lambda member, assigned_user_id=activity.user_id: self.env.uid + not in member.user_ids.ids + and ( + not assigned_user_id + or (assigned_user_id and assigned_user_id not in member.user_ids) + ) + ) + for member in members: + activity_ctx = ( + activity.with_context(lang=member.lang) if member.lang else activity + ) + model_description = ( + activity_ctx.env["ir.model"] + ._get(activity_ctx.res_model) + .display_name + ) + body = activity_ctx.env["ir.qweb"]._render( + "mail.message_activity_assigned", + { + "activity": activity_ctx, + "model_description": model_description, + "is_html_empty": lambda value: not value + or value == "


", + }, + minimal_qcontext=True, + ) + record.message_notify( + partner_ids=member.sudo().partner_id.ids, + body=body, + model_description=model_description, + email_layout_xmlid="mail.mail_notification_layout", + subject=self.env._( + "%(activity_name)s: %(summary)s (Team Activity)", + activity_name=activity_ctx.res_name, + summary=activity_ctx.summary + or activity_ctx.activity_type_id.name, + ), + subtitles=[ + self.env._("Activity: %s", activity_ctx.activity_type_id.name), + self.env._("Team: %s", activity_ctx.team_id.name), + self.env._( + "Deadline: %s", + ( + activity_ctx.date_deadline.strftime( + get_lang(activity_ctx.env).date_format + ) + if hasattr(activity_ctx.date_deadline, "strftime") + else str(activity_ctx.date_deadline) + ), + ), + ], + ) + + def action_notify(self): + """Override to notify team members when notify_members is enabled.""" + result = super().action_notify() + self.action_notify_team() + return result diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py index 88cd01cd6..0021f5983 100644 --- a/mail_activity_team/models/mail_activity_team.py +++ b/mail_activity_team/models/mail_activity_team.py @@ -45,6 +45,11 @@ def _compute_missing_activities(self): string="Team Members", ) user_id = fields.Many2one(comodel_name="res.users", string="Team Leader") + notify_members = fields.Boolean( + default=False, + help="When enabled, all team members will be notified " + "when an activity is assigned to this team.", + ) count_missing_activities = fields.Integer( string="Missing Activities", compute="_compute_missing_activities", default=0 ) diff --git a/mail_activity_team/readme/CONTRIBUTORS.md b/mail_activity_team/readme/CONTRIBUTORS.md index b1d175340..ba6097434 100644 --- a/mail_activity_team/readme/CONTRIBUTORS.md +++ b/mail_activity_team/readme/CONTRIBUTORS.md @@ -15,3 +15,5 @@ - [CorporateHub](https://corporatehub.eu/) - Alexey Pelykh - Stefan Rijnhart () +- [glueckkanja AG](https://glueckkanja.com/) + - Christopher Rogos () \ No newline at end of file diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 105529b11..b233945a3 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -458,6 +458,10 @@

Contributors

  • Stefan Rijnhart (stefan@opener.amsterdam)
  • +
  • glueckkanja AG +
  • diff --git a/mail_activity_team/static/src/core/web/activity.xml b/mail_activity_team/static/src/core/web/activity.xml index 50455e416..cbbc1d811 100644 --- a/mail_activity_team/static/src/core/web/activity.xml +++ b/mail_activity_team/static/src/core/web/activity.xml @@ -7,46 +7,33 @@ t-inherit-mode="extension" > - - props.activity.user_id - - - + props.activity.user_id - + (Team ) + >(Team ) props.activity.user_id Team - + diff --git a/mail_activity_team/static/src/models/activity.esm.js b/mail_activity_team/static/src/models/activity.esm.js new file mode 100644 index 000000000..1aa9b3386 --- /dev/null +++ b/mail_activity_team/static/src/models/activity.esm.js @@ -0,0 +1,13 @@ +import {Activity} from "@mail/core/common/activity_model"; +import {fields} from "@mail/core/common/record"; +import {patch} from "@web/core/utils/patch"; + +patch(Activity.prototype, { + setup() { + super.setup(...arguments); + this.team_id = fields.One("mail.activity.team"); + }, + serialize() { + return JSON.parse(JSON.stringify(this.toData(["user_id", "team_id"]))); + }, +}); diff --git a/mail_activity_team/static/src/models/mail_activity_team.esm.js b/mail_activity_team/static/src/models/mail_activity_team.esm.js new file mode 100644 index 000000000..544feff13 --- /dev/null +++ b/mail_activity_team/static/src/models/mail_activity_team.esm.js @@ -0,0 +1,15 @@ +import {Record} from "@mail/core/common/record"; + +export class MailActivityTeam extends Record { + static _name = "mail.activity.team"; + static id = "id"; + + id; + name; + + get displayName() { + return this.name; + } +} + +MailActivityTeam.register(); diff --git a/mail_activity_team/tests/test_mail_activity.py b/mail_activity_team/tests/test_mail_activity.py index 72ace0758..f62da81ef 100644 --- a/mail_activity_team/tests/test_mail_activity.py +++ b/mail_activity_team/tests/test_mail_activity.py @@ -287,3 +287,62 @@ def test_create_keeps_user_when_team_explicitly_false(self): ) self.assertFalse(activity.team_id) self.assertEqual(activity.user_id, self.user2) + + def test_activity_format_includes_team_id(self): + """Store payload should include team_id relation and team name data.""" + team = self.env["mail.activity.team"].create( + { + "name": "Store Team", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Check store serialization", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.user.id, + "team_id": team.id, + } + ) + + payload = activity.activity_format() + self.assertIn("mail.activity", payload) + self.assertTrue(payload["mail.activity"]) + activity_data = next( + rec for rec in payload["mail.activity"] if rec["id"] == activity.id + ) + self.assertIn("team_id", activity_data) + self.assertTrue(activity_data["team_id"]) + + self.assertIn("mail.activity.team", payload) + self.assertIn( + team.id, + [team_data["id"] for team_data in payload["mail.activity.team"]], + ) + team_data = next( + rec for rec in payload["mail.activity.team"] if rec["id"] == team.id + ) + self.assertEqual(team_data["name"], team.name) + + def test_activity_format_with_no_team(self): + """Store payload should expose an empty team_id when no team is assigned.""" + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "No team assigned", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.user.id, + "team_id": False, + } + ) + + payload = activity.activity_format() + activity_data = next( + rec for rec in payload["mail.activity"] if rec["id"] == activity.id + ) + self.assertIn("team_id", activity_data) + self.assertFalse(activity_data["team_id"]) diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 8841aa8af..ed48f2ac6 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -97,6 +97,7 @@ def setUpClass(cls): "name": "Team 2", "res_model_ids": [Command.set([cls.partner_ir_model.id])], "member_ids": [Command.set([cls.employee.id, cls.employee2.id])], + "notify_members": True, } ) cls.act2 = ( @@ -592,6 +593,334 @@ def test_web_search_read(self): set(self.partner_client.ids), ) + def test_notify_members_disabled(self): + """Test that when notify_members is False, only assigned user is notified.""" + # Create an activity for the team + self.team1.member_ids = [ + (6, 0, [self.employee.id, self.employee2.id, self.employee3.id]) + ] + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test activity without notify_members.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "team_user_id": self.employee.id, + "team_id": self.team1.id, + } + ) + + # Count initial messages for team members + initial_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + initial_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + initial_msg_count_emp3 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee3.partner_id.id])] + ) + ) + + # Call action_notify + activity.action_notify() + + # Verify only the assigned user (employee) received a notification + final_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + final_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + final_msg_count_emp3 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee3.partner_id.id])] + ) + ) + + self.assertGreater( + final_msg_count_emp, + initial_msg_count_emp, + "Assigned user should receive notification", + ) + self.assertEqual( + final_msg_count_emp2, + initial_msg_count_emp2, + "Non-assigned team member should not receive notification", + ) + self.assertEqual( + final_msg_count_emp3, + initial_msg_count_emp3, + "Non-assigned team member should not receive notification", + ) + + def test_notify_members_enabled(self): + """Test that when notify_members is True, all team members are notified.""" + # Create an activity for the team + self.team2.member_ids = [ + (6, 0, [self.employee.id, self.employee2.id, self.employee3.id]) + ] + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test activity with notify_members enabled.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "team_user_id": self.employee.id, + "team_id": self.team2.id, + } + ) + + # Count initial messages for team members + initial_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + initial_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + initial_msg_count_emp3 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee3.partner_id.id])] + ) + ) + + # Call action_notify + activity.action_notify() + + # Verify all team members received notifications + final_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + final_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + final_msg_count_emp3 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee3.partner_id.id])] + ) + ) + + self.assertGreater( + final_msg_count_emp, + initial_msg_count_emp, + "Assigned user should receive notification", + ) + self.assertGreater( + final_msg_count_emp2, + initial_msg_count_emp2, + "Team member 2 should receive notification", + ) + self.assertGreater( + final_msg_count_emp3, + initial_msg_count_emp3, + "Team member 3 should receive notification", + ) + + def test_notify_members_no_duplicate_for_assigned_user(self): + """Test that the assigned user doesn't get duplicate notifications.""" + # Create an activity assigned to employee (who is in the team) + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test no duplicate notifications.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.employee.id, + "team_id": self.team2.id, + } + ) + + # Count initial messages for the assigned user + initial_msg_count = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + + # Call action_notify + activity.action_notify() + + # Verify the assigned user received exactly one new notification + final_msg_count = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + + # The assigned user should receive only 1 notification (from parent method) + # not 2 (parent + team member notification) + self.assertEqual( + final_msg_count - initial_msg_count, + 1, + "Assigned user should receive exactly one notification, not duplicates", + ) + + def test_notify_members_activity_without_team(self): + """Test that activities without a team still work correctly.""" + # Create an activity without a team + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test activity without team.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.employee.id, + } + ) + + # Count initial messages + initial_msg_count = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + + # Call action_notify - should not raise any error + activity.action_notify() + + # Verify the assigned user received a notification + final_msg_count = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + + self.assertGreater( + final_msg_count, + initial_msg_count, + "Assigned user should receive notification even without team", + ) + + def test_notify_members_activity_without_assigned_user(self): + """Test that team notifications work when activity has no assigned user.""" + # Create an activity without an assigned user + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test activity without assigned user.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "team_id": self.team2.id, + } + ) + + # Count initial messages for team members + initial_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + initial_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + + # Call action_notify + activity.action_notify() + + # Verify all team members received notifications + final_msg_count_emp = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee.partner_id.id])] + ) + ) + final_msg_count_emp2 = len( + self.env["mail.message"].search( + [("partner_ids", "in", [self.employee2.partner_id.id])] + ) + ) + + self.assertGreater( + final_msg_count_emp, + initial_msg_count_emp, + "Team member 1 should receive notification", + ) + self.assertGreater( + final_msg_count_emp2, + initial_msg_count_emp2, + "Team member 2 should receive notification", + ) + + def test_notify_no_duplicate_when_team_and_user_assigned_on_create(self): + """ + Activity created by user A, assigned to team A (user B and C, + notify_members=True) and explicitly to user B. + Verifies that B and C are each notified exactly once through the full + create flow. + + Setup: + - employee = user A (creator, not in team) + - team2: notify_members=True, members: employee2 (B) and employee3 (C) + - Activity assigned to team2 AND employee2 (B) via team_user_id + + Expected: B gets 1 notification (from action_notify), C gets 1 notification + (from action_notify_team) — no duplicate for C due to action_notify_team + being called twice in create. + """ + self.team2.write( + {"member_ids": [(6, 0, [self.employee2.id, self.employee3.id])]} + ) + partner = self.env["res.partner"].create( + {"name": "Test No Dup On Create Partner"} + ) + employee_b_pid = self.employee2.partner_id.id + employee_c_pid = self.employee3.partner_id.id + + before_b = self.env["mail.message"].search_count( + [("partner_ids", "in", [employee_b_pid])] + ) + before_c = self.env["mail.message"].search_count( + [("partner_ids", "in", [employee_c_pid])] + ) + + # User A (employee) creates activity for team A (team2) and assigns to user B + self.env["mail.activity"].with_user(self.employee).create( + { + "activity_type_id": self.activity1.id, + "note": "Dedup test: team + assigned user on create.", + "res_id": partner.id, + "res_model_id": self.partner_ir_model.id, + "team_id": self.team2.id, + "team_user_id": self.employee2.id, + } + ) + + after_b = self.env["mail.message"].search_count( + [("partner_ids", "in", [employee_b_pid])] + ) + after_c = self.env["mail.message"].search_count( + [("partner_ids", "in", [employee_c_pid])] + ) + + self.assertEqual( + after_b - before_b, + 1, + "User B (assigned user and team member) should be notified exactly once", + ) + self.assertEqual( + after_c - before_c, + 1, + "User C (team member only) should be notified exactly once, not twice", + ) + def test_mail_activity_plan_ui_logic(self): """Check team/team user consistency in plan template view""" plan = self.env["mail.activity.plan"].create( diff --git a/mail_activity_team/views/mail_activity_plan_template_views.xml b/mail_activity_team/views/mail_activity_plan_template_views.xml index cf9a2e093..8a79622f2 100644 --- a/mail_activity_team/views/mail_activity_plan_template_views.xml +++ b/mail_activity_team/views/mail_activity_plan_template_views.xml @@ -7,6 +7,7 @@ + team_id - - - + + + + + + + + + + + + diff --git a/mail_activity_team/wizard/mail_activity_schedule.xml b/mail_activity_team/wizard/mail_activity_schedule.xml index 02fcf6077..7ab7f6444 100644 --- a/mail_activity_team/wizard/mail_activity_schedule.xml +++ b/mail_activity_team/wizard/mail_activity_schedule.xml @@ -13,9 +13,9 @@ /> -