Files
odoo_source/addons/crm/models/res_partner.py
T
Nicolas Lempereur 35809389a6 [FIX] crm: show newly created meetings in calendar
When clicking on the stat button "Meetings" on a contact:

- before dac91bc18 (November 2019): only meetings with participant
  matching contact name are shown

- after dac91bc18 (November 2019): all meetings are shown => this was
  because the view was used to create new meeting, so it makes sense to
  see other meetings and not have a conflict.

- after 16206d72 (August 2020): only meeting of the contact are shown

- after 7449c8a6 and d11fb611 (November 2020): more complicated logic
  that will also show partner events, and child partner events.

Since August 2020, when you create a new event, since we are showing a
list of IDs at the time the button was clicked, the new event will not
appear unless you go back to the contact, then click on "Meetings" anew.

With this changeset, we still show a list of IDs, but add an alternative
to also show the events of the current partner (that should be in the
list of IDs, but will match new events).

opw-2374021
closes #61490

closes odoo/odoo#61690

X-original-commit: eb6e03908bfb6ed8bbe231da2a4422ec2e149834
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2020-11-12 17:41:06 +00:00

116 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class Partner(models.Model):
_name = 'res.partner'
_inherit = 'res.partner'
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):
rec = super(Partner, self).default_get(fields)
active_model = self.env.context.get('active_model')
if active_model == 'crm.lead' and len(self.env.context.get('active_ids', [])) <= 1:
lead = self.env[active_model].browse(self.env.context.get('active_id')).exists()
if lead:
rec.update(
phone=lead.phone,
mobile=lead.mobile,
function=lead.function,
title=lead.title.id,
website=lead.website,
street=lead.street,
street2=lead.street2,
city=lead.city,
state_id=lead.state_id.id,
country_id=lead.country_id.id,
zip=lead.zip,
)
return rec
def _compute_opportunity_count(self):
# retrieve all children partners and prefetch 'parent_id' on them
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
all_partners.read(['parent_id'])
opportunity_data = self.env['crm.lead'].read_group(
domain=[('partner_id', 'in', all_partners.ids)],
fields=['partner_id'], groupby=['partner_id']
)
self.opportunity_count = 0
for group in opportunity_data:
partner = self.browse(group['partner_id'][0])
while partner:
if partner in self:
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.
'''
action = self.env['ir.actions.act_window']._for_xml_id('crm.crm_lead_opportunities')
if self.is_company:
action['domain'] = [('partner_id.commercial_partner_id.id', '=', self.id)]
else:
action['domain'] = [('partner_id.id', '=', self.id)]
return action