From d01e5c5cdb748a38b0ed5296ae0f0c68f052f446 Mon Sep 17 00:00:00 2001 From: nounoubensebia Date: Mon, 26 Apr 2021 10:41:20 +0000 Subject: [PATCH] [IMP] calendar, crm, hr_holidays: move meeting stat button to calendar Move the meeting stat button and kanban pill from CRM to Calendar, purpose is to allow its usage even if CRM is not installed as this makes more sense since this field is usually related to Calendar. Increase query number limit in company leave test, in order to take into account the newly introduced query in Calendar. UPG-PR: https://github.com/odoo/upgrade/pull/2423 Task-2514473 closes odoo/odoo#69846 Related: odoo/upgrade#2423 Signed-off-by: Thibault Delavallee (tde) --- addons/calendar/__manifest__.py | 1 + addons/calendar/models/res_partner.py | 52 +++++++++++++++++++ addons/calendar/views/res_partner_views.xml | 43 +++++++++++++++ addons/crm/models/res_partner.py | 51 ------------------ addons/crm/views/res_partner_views.xml | 8 --- .../hr_holidays/tests/test_company_leave.py | 2 +- 6 files changed, 97 insertions(+), 60 deletions(-) create mode 100644 addons/calendar/views/res_partner_views.xml diff --git a/addons/calendar/__manifest__.py b/addons/calendar/__manifest__.py index 8e068662534..a34889b121b 100644 --- a/addons/calendar/__manifest__.py +++ b/addons/calendar/__manifest__.py @@ -32,6 +32,7 @@ If you need to manage your meetings, you should install the CRM module. 'views/mail_activity_views.xml', 'views/calendar_templates.xml', 'views/calendar_views.xml', + 'views/res_partner_views.xml', ], 'installable': True, 'application': True, diff --git a/addons/calendar/models/res_partner.py b/addons/calendar/models/res_partner.py index 2cfe4551337..47d3b5ca5a6 100644 --- a/addons/calendar/models/res_partner.py +++ b/addons/calendar/models/res_partner.py @@ -9,9 +9,50 @@ from odoo import api, fields, models class Partner(models.Model): _inherit = 'res.partner' + meeting_count = fields.Integer("# Meetings", compute='_compute_meeting_count') + meeting_ids = fields.Many2many('calendar.event', 'calendar_event_res_partner_rel', 'res_partner_id', + 'calendar_event_id', string='Meetings', copy=False) + calendar_last_notif_ack = fields.Datetime( 'Last notification marked as read from base Calendar', default=fields.Datetime.now) + def _compute_meeting_count(self): + result = self._compute_meeting() + for p in self: + p.meeting_count = len(result.get(p.id, [])) + + def _compute_meeting(self): + if self.ids: + all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)]) + self.env.cr.execute(""" + SELECT res_partner_id, calendar_event_id, count(1) + FROM calendar_event_res_partner_rel + WHERE res_partner_id IN %s + GROUP BY res_partner_id, calendar_event_id + """, [tuple(all_partners.ids)]) + meeting_data = self.env.cr.fetchall() + + # Keep only valid meeting data based on record rules of events + events = [row[1] for row in meeting_data] + events = self.env['calendar.event'].search([('id', 'in', events)]).ids + meeting_data = [m for m in meeting_data if m[1] in events] + + # Create a dict {partner_id: event_ids} and fill with events linked to the partner + meetings = {p.id: set() for p in all_partners} + for m in meeting_data: + meetings[m[0]].add(m[1]) + + # Add the events linked to the children of the partner + all_partners.read(['parent_id']) + for p in all_partners: + partner = p + while partner: + if partner in self: + meetings[partner.id] |= meetings[p.id] + partner = partner.parent_id + return {p.id: list(meetings[p.id]) for p in self} + return {} + def get_attendee_detail(self, meeting_ids): """ Return a list of dict of the given meetings with the attendees details Used by: @@ -40,3 +81,14 @@ class Partner(models.Model): def _set_calendar_last_notif_ack(self): partner = self.env['res.users'].browse(self.env.context.get('uid', self.env.uid)).partner_id partner.write({'calendar_last_notif_ack': datetime.now()}) + + def schedule_meeting(self): + self.ensure_one() + partner_ids = self.ids + partner_ids.append(self.env.user.partner_id.id) + action = self.env["ir.actions.actions"]._for_xml_id("calendar.action_calendar_event") + action['context'] = { + 'default_partner_ids': partner_ids, + } + action['domain'] = ['|', ('id', 'in', self._compute_meeting()[self.id]), ('partner_ids', 'in', self.ids)] + return action diff --git a/addons/calendar/views/res_partner_views.xml b/addons/calendar/views/res_partner_views.xml new file mode 100644 index 00000000000..0542d010134 --- /dev/null +++ b/addons/calendar/views/res_partner_views.xml @@ -0,0 +1,43 @@ + + + + + + res.partner.view.kanban.calendar + res.partner + + + + + + + + + + + + + + + + + + res_partner.view.form.calendar + res.partner + + + + +
+ +
+
+
+
+ +
diff --git a/addons/crm/models/res_partner.py b/addons/crm/models/res_partner.py index 45a8bb2dadc..1110025ed6f 100644 --- a/addons/crm/models/res_partner.py +++ b/addons/crm/models/res_partner.py @@ -10,9 +10,7 @@ class Partner(models.Model): team_id = fields.Many2one('crm.team', string='Sales Team') opportunity_ids = fields.One2many('crm.lead', 'partner_id', string='Opportunities', domain=[('type', '=', 'opportunity')]) - meeting_ids = fields.Many2many('calendar.event', 'calendar_event_res_partner_rel', 'res_partner_id', 'calendar_event_id', string='Meetings', copy=False) opportunity_count = fields.Integer("Opportunity", compute='_compute_opportunity_count') - meeting_count = fields.Integer("# Meetings", compute='_compute_meeting_count') @api.model def default_get(self, fields): @@ -54,55 +52,6 @@ class Partner(models.Model): partner.opportunity_count += group['partner_id_count'] partner = partner.parent_id - def _compute_meeting_count(self): - result = self._compute_meeting() - for p in self: - p.meeting_count = len(result.get(p.id, [])) - - def _compute_meeting(self): - if self.ids: - all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)]) - self.env.cr.execute(""" - SELECT res_partner_id, calendar_event_id, count(1) - FROM calendar_event_res_partner_rel - WHERE res_partner_id IN %s - GROUP BY res_partner_id, calendar_event_id - """, [tuple(all_partners.ids)]) - meeting_data = self.env.cr.fetchall() - - # Keep only valid meeting data based on record rules of events - events = [row[1] for row in meeting_data] - events = self.env['calendar.event'].search([('id', 'in', events)]).ids - meeting_data = [m for m in meeting_data if m[1] in events] - - # Create a dict {partner_id: event_ids} and fill with events linked to the partner - meetings = {p.id: set() for p in all_partners} - for m in meeting_data: - meetings[m[0]].add(m[1]) - - # Add the events linked to the children of the partner - all_partners.read(['parent_id']) - for p in all_partners: - partner = p - while partner: - if partner in self: - meetings[partner.id] |= meetings[p.id] - partner = partner.parent_id - return {p.id: list(meetings[p.id]) for p in self} - return {} - - - def schedule_meeting(self): - self.ensure_one() - partner_ids = self.ids - partner_ids.append(self.env.user.partner_id.id) - action = self.env["ir.actions.actions"]._for_xml_id("calendar.action_calendar_event") - action['context'] = { - 'default_partner_ids': partner_ids, - } - action['domain'] = ['|', ('id', 'in', self._compute_meeting()[self.id]), ('partner_ids', 'in', self.ids)] - return action - def action_view_opportunity(self): ''' This function returns an action that displays the opportunities from partner. diff --git a/addons/crm/views/res_partner_views.xml b/addons/crm/views/res_partner_views.xml index 009f7d6f817..10947a6eb59 100644 --- a/addons/crm/views/res_partner_views.xml +++ b/addons/crm/views/res_partner_views.xml @@ -15,7 +15,6 @@ - @@ -37,13 +36,6 @@ context="{'default_partner_id': active_id}"> - diff --git a/addons/hr_holidays/tests/test_company_leave.py b/addons/hr_holidays/tests/test_company_leave.py index 53b528a5cc8..da2b444617f 100644 --- a/addons/hr_holidays/tests/test_company_leave.py +++ b/addons/hr_holidays/tests/test_company_leave.py @@ -313,7 +313,7 @@ class TestCompanyLeave(TransactionCase): }) company_leave._compute_date_from_to() - with self.assertQueryCount(__system__=842, admin=865): + with self.assertQueryCount(__system__=843, admin=865): # Original query count: 1987 # Without tracking/activity context keys: 5154 company_leave.action_validate()