partner-contact/partner_phonecall_schedule/models/res_partner.py

78 lines
3.1 KiB
Python
Raw Permalink Normal View History

2021-03-23 19:36:29 +00:00
# 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 flectra 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),
]