Project

General

Profile

Download (6.61 KB) Statistics
| Branch: | Tag: | Revision:

calebasse / calebasse / agenda / managers.py @ 76974b6f

1

    
2
from datetime import datetime, timedelta, date, time
3
from interval import IntervalSet
4

    
5
from django.db.models import Q
6
from model_utils.managers import InheritanceManager, PassThroughManager, InheritanceQuerySet
7

    
8
from calebasse.agenda.conf import default
9
from calebasse.utils import weeks_since_epoch
10
from calebasse import agenda
11

    
12
__all__ = (
13
    'EventManager',
14
)
15

    
16

    
17
class EventQuerySet(InheritanceQuerySet):
18
    def for_today(self, today=None):
19
        today = today or date.today()
20
        weeks = weeks_since_epoch(today)
21
        filters = [Q(start_datetime__gte=datetime.combine(today, time()),
22
               start_datetime__lte=datetime.combine(today, time(23,59,59))) ]
23
        base_q = Q(start_datetime__lte=datetime.combine(today, time(23,59,59))) & \
24
                (Q(recurrence_end_date__gte=today) |
25
                    Q(recurrence_end_date__isnull=True))
26
        for period in range(1, 6):
27
            filters.append(base_q & Q(recurrence_week_offset=weeks % period,
28
                recurrence_week_period=period, recurrence_week_day=today.weekday()))
29
        qs = self.filter(reduce(Q.__or__, filters))
30
        return qs
31

    
32
    def today_occurences(self, today=None):
33
        today = today or date.today()
34
        self = self.for_today(today)
35
        occurences = ( e.today_occurence(today) for e in self )
36
        return sorted(occurences, key=lambda e: e.start_datetime)
37

    
38
    def daily_disponibilities(self, date, events, participants, time_tables,
39
            holidays):
40
        '''Slice the day into quarters between 8:00 and 19:00, and returns the
41
           list of particpants with their status amon free, busy and away for each
42
           hour and quarters.
43

    
44
           date - the date of day we slice
45
           occurences - a dictionnary of iterable of events indexed by participants
46
           participants - an iterable of participants
47
           time_tables - a dictionnaty of timetable applying for this day indexed by participants
48
           holidays - a dictionnary of holidays applying for this day indexed by participants
49
        '''
50
        result = dict()
51
        quarter = 0
52
        events_set = {}
53
        timetables_set = {}
54
        holidays_set = {}
55
        for participant in participants:
56
            events_set[participant.id] = IntervalSet((o.to_interval() for o in events[participant.id] if not o.is_event_absence()))
57
            timetables_set[participant.id] = IntervalSet((t.to_interval(date) for t in time_tables[participant.id]))
58
            holidays_set[participant.id] = IntervalSet((h.to_interval(date) for h in holidays[participant.id]))
59
        start_datetime = datetime(date.year, date.month, date.day, 8, 0)
60
        end_datetime = datetime(date.year, date.month, date.day, 8, 15)
61
        while (start_datetime.hour <= 19):
62
            for participant in participants:
63
                if not result.has_key(start_datetime.hour):
64
                    result[start_datetime.hour] = [[], [], [], []]
65
                    quarter = 0
66
                interval = IntervalSet.between(start_datetime, end_datetime, False)
67
                if interval.intersection(events_set[participant.id]):
68
                    result[start_datetime.hour][quarter].append({'id': participant.id, 'dispo': 'busy'})
69
                elif interval.intersection(holidays_set[participant.id]):
70
                    result[start_datetime.hour][quarter].append({'id': participant.id, 'dispo': 'busy'})
71
                elif not interval.intersection(timetables_set[participant.id]):
72
                    result[start_datetime.hour][quarter].append({'id': participant.id, 'dispo': 'away'})
73
                else:
74
                    result[start_datetime.hour][quarter].append({'id': participant.id, 'dispo': 'free'})
75
            quarter += 1
76
            start_datetime += timedelta(minutes=15)
77
            end_datetime += timedelta(minutes=15)
78
        return result
79

    
80

    
81
class EventManager(PassThroughManager.for_queryset_class(EventQuerySet),
82
        InheritanceManager):
83
    """ This class allows you to manage events, appointment, ...
84
    """
85

    
86
    def create_event(self, creator, title, event_type, participants=[], description='',
87
            services=[], start_datetime=None, end_datetime=None, room=None, note=None, periodicity=1, until=False, **kwargs):
88
        """
89
        Convenience function to create an ``Event``, optionally create an
90
        ``EventType``.
91

    
92
        Args:
93
            event_type: can be either an ``EventType`` object or the label
94
            is either created or retrieved.
95
            participants: List of CalebasseUser
96
            start_datetime: will default to the current hour if ``None``
97
            end_datetime: will default to ``start_datetime`` plus
98
            default.DEFAULT_EVENT_DURATION hour if ``None``
99
        Returns:
100
            Event object
101
        """
102
        if isinstance(event_type, str):
103
            event_type, created = agenda.models.EventType.objects.get_or_create(
104
                label=event_type
105
            )
106
        if not start_datetime:
107
            now = datetime.now()
108
            start_datetime = datetime.combine(now.date, time(now.hour))
109
        if not end_datetime:
110
            end_datetime = start_datetime + default.DEFAULT_EVENT_DURATION
111
        if until is False:
112
            until = start_datetime.date()
113
        event = self.create(creator=creator,
114
                title=title, start_datetime=start_datetime,
115
                end_datetime=end_datetime, event_type=event_type,
116
                room=room, recurrence_week_period=periodicity,
117
                recurrence_end_date=until,
118
                recurrence_week_day=start_datetime.weekday(), **kwargs)
119
        event.services = services
120
        event.participants = participants
121
        return event
122

    
123
    def next_appointment(self, patient_record):
124
        qs = self.next_appointments(patient_record)
125
        if qs:
126
            return qs[0]
127
        else:
128
            return None
129

    
130
    def next_appointments(self, patient_record, today=None):
131
        from calebasse.actes.models import Act
132
        acts = Act.objects.next_acts(patient_record, today=today) \
133
                .filter(parent_event__isnull=False) \
134
                .select_related()
135
        return [ a.parent_event.today_occurence(a.date) for a in acts ]
136

    
137
    def last_appointment(self, patient_record):
138
        qs = self.last_appointments(patient_record)
139
        if qs:
140
            return qs[0]
141
        else:
142
            return None
143

    
144
    def last_appointments(self, patient_record, today=None):
145
        from calebasse.actes.models import Act
146
        acts = Act.objects.last_acts(patient_record, today=today) \
147
                .filter(parent_event__isnull=False) \
148
                .select_related()
149
        return [ a.parent_event.today_occurence(a.date) for a in acts ]
(6-6/10)