Project

General

Profile

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

calebasse / calebasse / agenda / managers.py @ 477e1b65

1

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

    
5
from django.db import models
6
from model_utils.managers import InheritanceManager
7

    
8
from calebasse.agenda.conf import default
9
from calebasse import agenda
10

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

    
16
class EventManager(InheritanceManager):
17
    """ This class allows you to manage events, appointment, ...
18
    """
19

    
20
    def _set_event(self, event, participants=[], description='', services=[],
21
            start_datetime=None, end_datetime=None, note=None, room=None, **rrule_params):
22
        """ Private method to configure an Event or an EventAct
23
        """
24
        event.description = description
25
        event.participants = participants
26
        event.services = services
27
        event.room = room
28
        if note is not None:
29
            event.notes.create(note=note)
30
        start_datetime = start_datetime or datetime.now().replace(
31
            minute=0, second=0, microsecond=0
32
        )
33
        occurence_duration = default.DEFAULT_OCCURRENCE_DURATION
34
        end_datetime = end_datetime or start_datetime + occurence_duration
35
        event.add_occurrences(start_datetime, end_datetime, **rrule_params)
36
        event.save()
37

    
38
        return event
39

    
40

    
41
    def create_event(self, title, event_type, participants=[], description='',
42
        services=[], start_datetime=None, end_datetime=None, room=None, note=None,
43
        **rrule_params):
44
        """
45
        Convenience function to create an ``Event``, optionally create an 
46
        ``EventType``, and associated ``Occurrence``s. ``Occurrence`` creation
47
        rules match those for ``Event.add_occurrences``.
48

    
49
        Args:
50
            event_type: can be either an ``EventType`` object or the label
51
            is either created or retrieved.
52
            participants: List of CalebasseUser
53
            start_datetime: will default to the current hour if ``None``
54
            end_datetime: will default to ``start_datetime`` plus
55
            default.DEFAULT_OCCURRENCE_DURATION hour if ``None``
56
            freq, count, rrule_params:
57
            follow the ``dateutils`` API (see http://labix.org/python-dateutil)
58
        Returns:
59
            Event object
60
        """
61

    
62
        if isinstance(event_type, str):
63
            event_type, created = agenda.models.EventType.objects.get_or_create(
64
                label=event_type
65
            )
66
        event = self.create(title=title, event_type=event_type)
67

    
68
        return self._set_event(event, participants, services = services,
69
                start_datetime = start_datetime, end_datetime = end_datetime,
70
                room=room, **rrule_params)
71

    
72
    def create_holiday(self, start_date, end_date, peoples=[], services=[], motive=''):
73
        event_type, created = agenda.models.EventType.objects.get_or_create(
74
                label=u"Vacances"
75
                )
76
        event = self.create(title="Conge", event_type=event_type)
77
        start_datetime = datetime(start_date.year, start_date.month, start_date.day)
78
        end_datetime = datetime(end_date.year, end_date.month, end_date.day, 23, 59)
79
        return self._set_event(event, peoples, motive, services, start_datetime, end_datetime)
80

    
81
class OccurrenceManager(models.Manager):
82

    
83
    def daily_occurrences(self, date=None, participants=None, services=None,
84
            event_type=None):
85
        '''
86
        Returns a queryset of for instances that have any overlap with a 
87
        particular day.
88

    
89
        Args:
90
            date: may be either a datetime.datetime, datetime.date object, or
91
            ``None``. If ``None``, default to the current day.
92
            participants: a list of CalebasseUser
93
            services: a list of services
94
            event_type: a single, or a list of, event types
95
        '''
96
        date = date or datetime.now()
97
        start = datetime(date.year, date.month, date.day)
98
        end = start.replace(hour=23, minute=59, second=59)
99
        qs = self.select_related('event').filter(
100
            models.Q(
101
                start_time__gte=start,
102
                start_time__lte=end,
103
            ) |
104
            models.Q(
105
                end_time__gte=start,
106
                end_time__lte=end,
107
            ) |
108
            models.Q(
109
                start_time__lt=start,
110
                end_time__gt=end,
111
            )
112
        )
113

    
114
        if participants:
115
            qs = qs.filter(event__participants__in=participants)
116
        if services:
117
            qs = qs.filter(event__services__in=services)
118
        if event_type:
119
            if type(event_type) is list:
120
                qs = qs.filter(event__event_type__in=event_type)
121
            else:
122
                qs = qs.filter(event__event_type=event_type)
123
        return qs
124

    
125
    def daily_disponiblity(self, date, occurrences, participants, time_tables):
126
        result = dict()
127
        quater = 0
128
        occurrences_set = {}
129
        timetables_set = {}
130
        for participant in participants:
131
            occurrences_set[participant.id] = IntervalSet((o.to_interval() for o in occurrences[participant.id]))
132
            timetables_set[participant.id] = IntervalSet((t.to_interval(date) for t in time_tables[participant.id]))
133
        start_datetime = datetime(date.year, date.month, date.day, 8, 0)
134
        end_datetime = datetime(date.year, date.month, date.day, 8, 15)
135
        while (start_datetime.hour <= 19):
136
            for participant in participants:
137
                if not result.has_key(start_datetime.hour):
138
                    result[start_datetime.hour] = [0, 1, 2, 3]
139
                    result[start_datetime.hour][0] = []
140
                    result[start_datetime.hour][1] = []
141
                    result[start_datetime.hour][2] = []
142
                    result[start_datetime.hour][3] = []
143
                    quater = 0
144

    
145
                interval = IntervalSet.between(start_datetime, end_datetime, False)
146
                if interval.intersection(occurrences_set[participant.id]):
147
                    result[start_datetime.hour][quater].append({'id': participant.id, 'dispo': 'busy'})
148
                elif not interval.intersection(timetables_set[participant.id]):
149
                    result[start_datetime.hour][quater].append({'id': participant.id, 'dispo': 'away'})
150
                else:
151
                    result[start_datetime.hour][quater].append({'id': participant.id, 'dispo': 'free'})
152
            quater += 1
153
            start_datetime += timedelta(minutes=15)
154
            end_datetime += timedelta(minutes=15)
155
        return result
156

    
157
    def next_appoinment(self, patient_record):
158
        qs = self.filter(start_time__gt=datetime.now()).\
159
                filter(event__event_type__id=1).\
160
                filter(event__eventact__patient=patient_record).\
161
                prefetch_related('event__eventact').\
162
                order_by('start_time')
163
        if qs:
164
            return qs[0]
165
        else:
166
            return None
167

    
168
    def last_appoinment(self, patient_record):
169
        qs = self.filter(start_time__lt=datetime.now()).\
170
                filter(event__event_type__id=1).\
171
                filter(event__eventact__patient=patient_record).\
172
                prefetch_related('event__eventact').\
173
                order_by('-start_time')
174
        if qs:
175
            return qs[0]
176
        else:
177
            return None
178

    
(6-6/10)