Odoo18-Base/addons/crm/models/crm_team_member.py
2025-01-06 10:57:38 +07:00

86 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
import logging
from ast import literal_eval
from odoo import api, exceptions, fields, models, _
from odoo.tools import float_round
_logger = logging.getLogger(__name__)
class TeamMember(models.Model):
_inherit = 'crm.team.member'
# assignment
assignment_enabled = fields.Boolean(related="crm_team_id.assignment_enabled")
assignment_domain = fields.Char('Assignment Domain', tracking=True)
assignment_optout = fields.Boolean('Skip auto assignment')
assignment_max = fields.Integer('Average Leads Capacity (on 30 days)', default=30)
lead_day_count = fields.Integer(
'Leads (last 24h)', compute='_compute_lead_day_count',
help='Lead assigned to this member this last day (lost one excluded)')
lead_month_count = fields.Integer(
'Leads (30 days)', compute='_compute_lead_month_count',
help='Lead assigned to this member those last 30 days')
@api.depends('user_id', 'crm_team_id')
def _compute_lead_day_count(self):
day_date = fields.datetime.now() - datetime.timedelta(hours=24)
daily_leads_counts = self._get_lead_from_date(day_date)
for member in self:
member.lead_day_count = daily_leads_counts.get((member.user_id.id, member.crm_team_id.id), 0)
@api.depends('user_id', 'crm_team_id')
def _compute_lead_month_count(self):
month_date = fields.Datetime.now() - datetime.timedelta(days=30)
monthly_leads_counts = self._get_lead_from_date(month_date)
for member in self:
member.lead_month_count = monthly_leads_counts.get((member.user_id.id, member.crm_team_id.id), 0)
def _get_lead_from_date(self, date_from, active_test=False):
return {
(user.id, team.id): count for user, team, count in self.env['crm.lead'].with_context(active_test=active_test)._read_group(
[
('date_open', '>=', date_from),
('team_id', 'in', self.crm_team_id.ids),
('user_id', 'in', self.user_id.ids),
],
['user_id', 'team_id'],
['__count'],
)
}
@api.constrains('assignment_domain')
def _constrains_assignment_domain(self):
for member in self:
try:
domain = literal_eval(member.assignment_domain or '[]')
if domain:
self.env['crm.lead'].search(domain, limit=1)
except Exception:
raise exceptions.ValidationError(_(
'Member assignment domain for user %(user)s and team %(team)s is incorrectly formatted',
user=member.user_id.name, team=member.crm_team_id.name
))
# ------------------------------------------------------------
# LEAD ASSIGNMENT
# ------------------------------------------------------------
def _get_assignment_quota(self, force_quota=False):
""" Return the remaining daily quota based
on the assignment_max and the lead already assigned in the past 24h
:param bool force_quota: see ``CrmTeam._action_assign_leads()``;
"""
quota = float_round(self.assignment_max / 30.0, precision_digits=0, rounding_method='HALF-UP')
if force_quota:
return quota
return quota - self.lead_day_count