diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 23e3daf24..f79128675 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -14,6 +14,7 @@ 'mail_activity_board', ], 'data': [ + 'views/calendar_event.xml', 'views/assets_backend.xml', 'security/ir.model.access.csv', 'security/mail_activity_team_security.xml', diff --git a/mail_activity_team/migrations/11.0.2.2.0/post-migration.py b/mail_activity_team/migrations/11.0.2.2.0/post-migration.py new file mode 100644 index 000000000..f2411a492 --- /dev/null +++ b/mail_activity_team/migrations/11.0.2.2.0/post-migration.py @@ -0,0 +1,17 @@ +# Copyright 2019 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl +from openupgradelib import openupgrade + + +@openupgrade.migrate(use_env=True) +def migrate(env, version): + rule = env.ref('calendar.calendar_event_rule_private') + rule.write({ + 'name': 'Private or group events', + 'domain_force': "['|', '|', " + "('privacy', 'not in', ['private', 'team'])," + "'&', ('privacy', '=', 'private')," + "('partner_ids', 'in', user.partner_id.id)," + "'&', ('privacy', '=', 'team')," + "('team_id', 'in', user.activity_team_ids.ids)]" + }) diff --git a/mail_activity_team/models/__init__.py b/mail_activity_team/models/__init__.py index 635ee6958..3a4420b37 100644 --- a/mail_activity_team/models/__init__.py +++ b/mail_activity_team/models/__init__.py @@ -2,3 +2,4 @@ from . import mail_activity_team from . import mail_activity from . import res_users from . import mail_activity_mixin +from . import calendar_event diff --git a/mail_activity_team/models/calendar_event.py b/mail_activity_team/models/calendar_event.py new file mode 100644 index 000000000..e6dab2737 --- /dev/null +++ b/mail_activity_team/models/calendar_event.py @@ -0,0 +1,68 @@ +# Copyright 2019 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ + + +class CalendarEvent(models.Model): + _inherit = 'calendar.event' + + def _get_default_team_id(self, user_id=None): + if not user_id: + user_id = self.env.uid + res_model = self.env.context.get('default_res_model') + model = self.env['ir.model'].search( + [('model', '=', res_model)], limit=1) + domain = [('member_ids', 'in', [user_id])] + if res_model: + domain.extend(['|', ('res_model_ids', '=', False), + ('res_model_ids', 'in', model.ids)]) + return self.env['mail.activity.team'].search(domain, limit=1) + + privacy = fields.Selection(selection_add=[ + ('team', 'Only team'), + ]) + team_id = fields.Many2one( + comodel_name='mail.activity.team', + default=lambda s: s._get_default_team_id(), + ) + + @api.multi + def read(self, fields=None, load='_classic_read'): + expected_fields = ['privacy', 'team_id'] + extra_fields = [] + fixed_fields = [ + 'id', 'allday', 'start', 'stop', 'display_start', 'display_stop', + 'duration', 'user_id', 'state', 'interval', 'count', + 'recurrent_id_date', 'rrule' + ] + if not fields: + fields = list(self._fields) + for field in expected_fields: + if field not in fields: + fields.append(field) + extra_fields.append(field) + result = super().read(fields, load) + for r in result: + if r['team_id'] and r['privacy'] == 'team': + team_id = r['team_id'] + if isinstance(team_id, tuple): + team_id = team_id[0] + team = self.env['mail.activity.team'].browse(team_id) + users = team.member_ids + if self.env.user not in users: + for f in r: + recurrent_fields = self._get_recurrent_fields() + public_fields = list(set( + recurrent_fields + fixed_fields)) + if f not in public_fields: + if isinstance(r[f], list): + r[f] = [] + else: + r[f] = False + if f == 'name': + r[f] = _('Busy') + for f in extra_fields: + if f in r: + del r[f] + return result diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 8eb118a48..2b4eaf36d 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -72,3 +72,9 @@ class MailActivity(models.Model): activity.user_id not in activity.team_id.member_ids: raise ValidationError( _('The assigned user is not member of the team.')) + + @api.multi + def action_create_calendar_event(self): + res = super().action_create_calendar_event() + res['context']['default_team_id'] = self.team_id.id or False + return res diff --git a/mail_activity_team/readme/CONTRIBUTORS.rst b/mail_activity_team/readme/CONTRIBUTORS.rst index 6bb24056e..a01fe5e30 100644 --- a/mail_activity_team/readme/CONTRIBUTORS.rst +++ b/mail_activity_team/readme/CONTRIBUTORS.rst @@ -2,3 +2,5 @@ * Jordi Ballester Alomar (jordi.ballester@eficent.com) * Miquel Raïch (miquel.raich@eficent.com) + +* Enric Tobella diff --git a/mail_activity_team/security/mail_activity_team_security.xml b/mail_activity_team/security/mail_activity_team_security.xml index e19398ab2..e7a492339 100644 --- a/mail_activity_team/security/mail_activity_team_security.xml +++ b/mail_activity_team/security/mail_activity_team_security.xml @@ -12,4 +12,9 @@ + + Private or group events + ['|', '|', ('privacy', 'not in', ['private', 'team']), '&', ('privacy', '=', 'private'), ('partner_ids', 'in', user.partner_id.id), '&', ('privacy', '=', 'team'), ('team_id', 'in', user.activity_team_ids.ids)] + + diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 1dbf8f7ac..eac0ae029 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -2,6 +2,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo.tests.common import TransactionCase from odoo.exceptions import ValidationError +from odoo.fields import Datetime +from datetime import timedelta class TestMailActivityTeam(TransactionCase): @@ -75,6 +77,56 @@ class TestMailActivityTeam(TransactionCase): 'user_id': self.employee.id, }) + self.act3 = self.env['mail.activity'].sudo(self.employee).create({ + 'activity_type_id': self.browse_ref( + 'mail.mail_activity_data_meeting').id, + 'note': 'Meeting activity 3.', + 'res_id': self.partner_client.id, + 'res_model_id': self.partner_ir_model.id, + 'user_id': self.employee.id, + 'team_id': self.team1.id, + 'summary': 'Metting activity' + }) + self.start = Datetime.now() + self.stop = Datetime.to_string( + Datetime.from_string(self.start) + timedelta(hours=1) + ) + + def test_meeting_blank(self): + meeting = self.env['calendar.event'].sudo(self.employee).create({ + 'start': self.start, + 'stop': self.stop, + 'name': 'Test meeting' + }) + self.assertTrue(meeting.team_id) + + def test_meeting_from_activity(self): + action = self.act3.with_context( + default_res_id=self.act3.res_id, + default_res_model=self.act3.res_model, + ).action_create_calendar_event() + + meeting = self.env['calendar.event'].sudo(self.employee).with_context( + **action['context'] + ).create({ + 'start': self.start, + 'stop': self.stop + }) + self.assertTrue(meeting.team_id) + self.assertTrue(meeting.read(['description'])[0]['description']) + self.assertTrue( + meeting.sudo(self.employee2).read( + ['description'])[0]['description'], + 'He should be able to read the record as it is public by default', + ) + meeting.write({'privacy': 'team'}) + self.assertFalse( + meeting.sudo(self.employee2).read( + ['description'])[0]['description'], + 'He shouldn\'t be able to read the record as it is ' + 'public by default', + ) + def test_missing_activities(self): self.assertFalse( self.act1.team_id, 'Error: Activity 1 should not have a team.') diff --git a/mail_activity_team/views/calendar_event.xml b/mail_activity_team/views/calendar_event.xml new file mode 100644 index 000000000..8ed959144 --- /dev/null +++ b/mail_activity_team/views/calendar_event.xml @@ -0,0 +1,35 @@ + + + + + + + calendar.event.form (in mail_activity_team) + calendar.event + + + + + + + + + + calendar.event.search + calendar.event + + + + + + + + + + + + +