You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
3.1 KiB
77 lines
3.1 KiB
# Copyright 2017 Jairo Llopis <jairo.llopis@tecnativa.com>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from __future__ import division
|
|
from datetime import datetime
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class ResPartner(models.Model):
|
|
_inherit = "res.partner"
|
|
|
|
phonecall_available = fields.Boolean(
|
|
"Available to call",
|
|
compute="_compute_phonecall_available",
|
|
search="_search_phonecall_available",
|
|
help="Is it now a good time to call this partner?",
|
|
)
|
|
phonecall_calendar_ids = fields.Many2many(
|
|
comodel_name="resource.calendar",
|
|
string="Phonecall schedule",
|
|
help="Best schedule when the contact expects to be called.",
|
|
)
|
|
phonecall_calendar_attendance_ids = fields.One2many(
|
|
comodel_name="resource.calendar.attendance",
|
|
string="Aggregated phonecall schedule",
|
|
compute="_compute_phonecall_calendar_ids",
|
|
help="Aggregation of all available phonecall schedules.",
|
|
)
|
|
|
|
@api.depends("phonecall_calendar_ids", "phonecall_calendar_attendance_ids")
|
|
def _compute_phonecall_available(self):
|
|
"""Know if a partner is available to call right now."""
|
|
Attendance = self.env["resource.calendar.attendance"]
|
|
for one in self:
|
|
domain = [
|
|
("calendar_id", "in", one.phonecall_calendar_ids.ids)
|
|
] + one._phonecall_available_domain()
|
|
found = Attendance.search(domain, limit=1)
|
|
one.phonecall_available = bool(found)
|
|
|
|
@api.depends("phonecall_calendar_ids")
|
|
def _compute_phonecall_calendar_ids(self):
|
|
"""Fill attendance aggregation."""
|
|
for one in self:
|
|
one.phonecall_calendar_attendance_ids = one.mapped(
|
|
"phonecall_calendar_ids.attendance_ids")
|
|
|
|
def _search_phonecall_available(self, operator, value):
|
|
"""Search quickly if partner is available to call right now."""
|
|
Attendance = self.env["resource.calendar.attendance"]
|
|
available = Attendance.search(
|
|
self._phonecall_available_domain(),
|
|
)
|
|
if operator == "!=" or "not" in operator:
|
|
value = not value
|
|
operator = "in" if value else "not in"
|
|
return [("phonecall_calendar_ids.attendance_ids",
|
|
operator, available.ids)]
|
|
|
|
def _phonecall_available_domain(self):
|
|
"""Get a domain to know if we are available to call a partner."""
|
|
now = self.env.context.get("now", datetime.now())
|
|
try:
|
|
now = fields.Datetime.from_string(now)
|
|
except TypeError:
|
|
# `now` is already a datetime object
|
|
pass
|
|
date = fields.Date.to_string(now)
|
|
now_tz = fields.Datetime.context_timestamp(self, now)
|
|
float_time = now_tz.hour + ((now_tz.minute / 60) + now_tz.second) / 60
|
|
return [
|
|
("dayofweek", "=", str(now.weekday())),
|
|
"|", ("date_from", "=", False), ("date_from", "<=", date),
|
|
"|", ("date_to", "=", False), ("date_to", ">=", date),
|
|
("hour_from", "<=", float_time),
|
|
("hour_to", ">=", float_time),
|
|
]
|