1 |
1097fd0a
|
Benjamin Dauvergne
|
# -*- coding: utf-8 -*-
|
2 |
|
|
|
3 |
1eab6c73
|
Frédéric Péters
|
from datetime import datetime, date, time as datetime_time
|
4 |
7a0a30d7
|
Benjamin Dauvergne
|
|
5 |
1097fd0a
|
Benjamin Dauvergne
|
from django.db import models
|
6 |
f7d9fa12
|
Benjamin Dauvergne
|
from django.db.models import query
|
7 |
1097fd0a
|
Benjamin Dauvergne
|
from django.contrib.auth.models import User
|
8 |
706c6be7
|
Benjamin Dauvergne
|
from django.template.defaultfilters import date as date_filter
|
9 |
f8f903c3
|
Benjamin Dauvergne
|
from django import forms
|
10 |
1097fd0a
|
Benjamin Dauvergne
|
|
11 |
37093bfa
|
Benjamin Dauvergne
|
from model_utils.managers import InheritanceManager
|
12 |
366eb65a
|
Benjamin Dauvergne
|
|
13 |
ee47faa1
|
Jérôme Schneider
|
from calebasse.models import PhoneNumberField
|
14 |
aceeeca7
|
Mikaël Ates
|
from calebasse.ressources.models import Service, NamedAbstractModel
|
15 |
688c7fbe
|
Mikaël Ates
|
from calebasse.models import (BaseModelMixin, WeekRankField,
|
16 |
|
|
PhoneNumberField, ZipCodeField)
|
17 |
f8f903c3
|
Benjamin Dauvergne
|
from calebasse.utils import weeks_since_epoch, weekday_ranks
|
18 |
7a0a30d7
|
Benjamin Dauvergne
|
|
19 |
|
|
from interval import Interval
|
20 |
1097fd0a
|
Benjamin Dauvergne
|
|
21 |
1a43d77a
|
Benjamin Dauvergne
|
from model_utils import Choices
|
22 |
f7d9fa12
|
Benjamin Dauvergne
|
from model_utils.managers import PassThroughManager
|
23 |
|
|
|
24 |
a01d85be
|
Serghei MIHAI
|
from ..middleware.request import get_request
|
25 |
|
|
|
26 |
aceeeca7
|
Mikaël Ates
|
class Role(NamedAbstractModel):
|
27 |
|
|
users = models.ManyToManyField(User,
|
28 |
|
|
verbose_name=u'Utilisateurs', blank=True)
|
29 |
|
|
|
30 |
9e738c5d
|
Benjamin Dauvergne
|
class People(BaseModelMixin, models.Model):
|
31 |
8e6fe119
|
Jérôme Schneider
|
GENDERS = Choices(
|
32 |
b8b97c77
|
Mikaël Ates
|
(1, 'Masculin'),
|
33 |
|
|
(2, 'Féminin'),
|
34 |
f8f903c3
|
Benjamin Dauvergne
|
)
|
35 |
8e6fe119
|
Jérôme Schneider
|
|
36 |
37093bfa
|
Benjamin Dauvergne
|
objects = InheritanceManager()
|
37 |
f10536ea
|
Jérôme Schneider
|
last_name = models.CharField(max_length=128, verbose_name=u'Nom',
|
38 |
|
|
db_index=True)
|
39 |
1178f357
|
Mikaël Ates
|
first_name = models.CharField(max_length=128, verbose_name=u'Prénom(s)',
|
40 |
cd8a83dc
|
Jérôme Schneider
|
blank=True, null=True)
|
41 |
9e738c5d
|
Benjamin Dauvergne
|
display_name = models.CharField(max_length=256,
|
42 |
08a6bedd
|
Benjamin Dauvergne
|
verbose_name=u'Nom complet', editable=False, db_index=True)
|
43 |
1a43d77a
|
Benjamin Dauvergne
|
gender = models.IntegerField(verbose_name=u"Genre", choices=GENDERS,
|
44 |
1a9b2fe9
|
Jérôme Schneider
|
max_length=1, blank=True, null=True)
|
45 |
ee47faa1
|
Jérôme Schneider
|
email = models.EmailField(blank=True, null=True)
|
46 |
|
|
phone = PhoneNumberField(verbose_name=u"Téléphone", blank=True, null=True)
|
47 |
1097fd0a
|
Benjamin Dauvergne
|
|
48 |
e39efb4a
|
Jérôme Schneider
|
def save(self, **kwargs):
|
49 |
1178f357
|
Mikaël Ates
|
if self.first_name:
|
50 |
|
|
self.display_name = self.first_name + ' ' + self.last_name.upper()
|
51 |
|
|
else:
|
52 |
|
|
self.display_name = self.last_name.upper()
|
53 |
e39efb4a
|
Jérôme Schneider
|
super(People, self).save(**kwargs)
|
54 |
1097fd0a
|
Benjamin Dauvergne
|
|
55 |
9e738c5d
|
Benjamin Dauvergne
|
def __unicode__(self):
|
56 |
|
|
return self.display_name
|
57 |
|
|
|
58 |
b60abafc
|
Frédéric Péters
|
def get_initials(self):
|
59 |
|
|
initials = []
|
60 |
|
|
if self.first_name:
|
61 |
43a788f8
|
Mikaël Ates
|
initials = [name[0].upper() for name in ' '.join(self.first_name.split('-')).split()]
|
62 |
|
|
initials += [name[0].upper() for name in ' '.join(self.last_name.split('-')).split()]
|
63 |
b60abafc
|
Frédéric Péters
|
return ''.join(initials)
|
64 |
|
|
|
65 |
957da834
|
Benjamin Dauvergne
|
class Meta:
|
66 |
|
|
ordering = ['last_name', 'first_name']
|
67 |
|
|
|
68 |
f7d9fa12
|
Benjamin Dauvergne
|
class WorkerQuerySet(query.QuerySet):
|
69 |
0f0cacbb
|
Jérôme Schneider
|
def for_service(self, service, type=None):
|
70 |
|
|
if type:
|
71 |
c0f82cd1
|
Frédéric Péters
|
return self.filter(enabled=True, services__in=[service], type=type)
|
72 |
0f0cacbb
|
Jérôme Schneider
|
else:
|
73 |
c0f82cd1
|
Frédéric Péters
|
return self.filter(enabled=True, services__in=[service])
|
74 |
0f0cacbb
|
Jérôme Schneider
|
|
75 |
6e58dbc4
|
Mikaël Ates
|
|
76 |
96f613c6
|
Benjamin Dauvergne
|
class Worker(People):
|
77 |
f7d9fa12
|
Benjamin Dauvergne
|
objects = PassThroughManager.for_queryset_class(WorkerQuerySet)()
|
78 |
97bee351
|
Jérôme Schneider
|
|
79 |
7967cb73
|
Jérôme Schneider
|
initials = models.CharField(max_length=5, verbose_name=u'Initiales', default='', blank=True)
|
80 |
9e738c5d
|
Benjamin Dauvergne
|
type = models.ForeignKey('ressources.WorkerType',
|
81 |
|
|
verbose_name=u'Type de personnel')
|
82 |
38d1b4f8
|
Mikaël Ates
|
services = models.ManyToManyField('ressources.Service', blank=True, null=True)
|
83 |
6e58dbc4
|
Mikaël Ates
|
enabled = models.BooleanField(verbose_name=u'Actif',
|
84 |
|
|
default=True)
|
85 |
|
|
old_camsp_id = models.CharField(max_length=256,
|
86 |
|
|
verbose_name=u'Ancien ID au CAMSP', blank=True, null=True)
|
87 |
|
|
old_cmpp_id = models.CharField(max_length=256,
|
88 |
|
|
verbose_name=u'Ancien ID au CMPP', blank=True, null=True)
|
89 |
|
|
old_sessad_dys_id = models.CharField(max_length=256,
|
90 |
|
|
verbose_name=u'Ancien ID au SESSAD TED', blank=True, null=True)
|
91 |
|
|
old_sessad_ted_id = models.CharField(max_length=256,
|
92 |
|
|
verbose_name=u'Ancien ID au SESSAD DYS', blank=True, null=True)
|
93 |
|
|
|
94 |
97bee351
|
Jérôme Schneider
|
def save(self, **kwargs):
|
95 |
|
|
if not self.initials:
|
96 |
|
|
self.initials = self.get_initials()
|
97 |
|
|
super(Worker, self).save(**kwargs)
|
98 |
|
|
|
99 |
6e58dbc4
|
Mikaël Ates
|
def is_active(self):
|
100 |
|
|
return self.enabled
|
101 |
9e738c5d
|
Benjamin Dauvergne
|
|
102 |
957da834
|
Benjamin Dauvergne
|
def is_away(self):
|
103 |
f8f903c3
|
Benjamin Dauvergne
|
if self.timetable_set.filter(weekday=date.today().weekday()).exists():
|
104 |
957da834
|
Benjamin Dauvergne
|
return False
|
105 |
|
|
return True
|
106 |
|
|
|
107 |
b478e27e
|
Benjamin Dauvergne
|
@models.permalink
|
108 |
|
|
def get_absolute_url(self):
|
109 |
|
|
return ('worker_update', (), {
|
110 |
|
|
'service': self.services.all()[0].name.lower(),
|
111 |
|
|
'pk': self.pk })
|
112 |
|
|
|
113 |
96f613c6
|
Benjamin Dauvergne
|
class Meta:
|
114 |
|
|
verbose_name = u'Personnel'
|
115 |
|
|
verbose_name_plural = u'Personnels'
|
116 |
1097fd0a
|
Benjamin Dauvergne
|
|
117 |
688c7fbe
|
Mikaël Ates
|
class ExternalWorker(People):
|
118 |
|
|
description = models.TextField(blank=True, null=True, default=None)
|
119 |
|
|
address = models.CharField(max_length=120,
|
120 |
|
|
verbose_name=u"Adresse", blank=True, null=True, default=None)
|
121 |
|
|
address_complement = models.CharField(max_length=120,
|
122 |
|
|
blank=True,
|
123 |
|
|
null=True,
|
124 |
|
|
default=None,
|
125 |
|
|
verbose_name=u"Complément d'adresse")
|
126 |
|
|
zip_code = ZipCodeField(verbose_name=u"Code postal",
|
127 |
|
|
blank=True, null=True, default=None)
|
128 |
|
|
city = models.CharField(max_length=80, verbose_name=u"Ville",
|
129 |
|
|
blank=True, null=True, default=None)
|
130 |
|
|
phone_work = PhoneNumberField(verbose_name=u"Téléphone du travail",
|
131 |
|
|
blank=True, null=True, default=None)
|
132 |
|
|
fax = models.CharField(max_length=30,
|
133 |
|
|
blank=True, null=True, default=None)
|
134 |
|
|
type = models.ForeignKey('ressources.WorkerType',
|
135 |
26a5dbc0
|
Jérôme Schneider
|
verbose_name=u'Spécialité', default=18)
|
136 |
688c7fbe
|
Mikaël Ates
|
old_id = models.CharField(max_length=256,
|
137 |
|
|
verbose_name=u'Ancien ID', blank=True, null=True)
|
138 |
|
|
old_service = models.CharField(max_length=256,
|
139 |
|
|
verbose_name=u'Ancien Service', blank=True, null=True)
|
140 |
|
|
class Meta:
|
141 |
|
|
verbose_name = u'Intervenant extérieur'
|
142 |
|
|
verbose_name_plural = u'Intervenants extérieurs'
|
143 |
|
|
|
144 |
|
|
class ExternalTherapist(People):
|
145 |
|
|
description = models.TextField(blank=True, null=True, default=None)
|
146 |
|
|
address = models.CharField(max_length=120,
|
147 |
|
|
verbose_name=u"Adresse", blank=True, null=True, default=None)
|
148 |
|
|
address_complement = models.CharField(max_length=120,
|
149 |
|
|
blank=True,
|
150 |
|
|
null=True,
|
151 |
|
|
default=None,
|
152 |
|
|
verbose_name=u"Complément d'adresse")
|
153 |
|
|
zip_code = ZipCodeField(verbose_name=u"Code postal",
|
154 |
|
|
blank=True, null=True, default=None)
|
155 |
|
|
city = models.CharField(max_length=80, verbose_name=u"Ville",
|
156 |
|
|
blank=True, null=True, default=None)
|
157 |
|
|
phone_work = PhoneNumberField(verbose_name=u"Téléphone du travail",
|
158 |
|
|
blank=True, null=True, default=None)
|
159 |
|
|
fax = models.CharField(max_length=30,
|
160 |
|
|
blank=True, null=True, default=None)
|
161 |
|
|
type = models.ForeignKey('ressources.WorkerType',
|
162 |
26a5dbc0
|
Jérôme Schneider
|
verbose_name=u'Spécialité', default=18)
|
163 |
688c7fbe
|
Mikaël Ates
|
old_id = models.CharField(max_length=256,
|
164 |
|
|
verbose_name=u'Ancien ID', blank=True, null=True)
|
165 |
|
|
old_service = models.CharField(max_length=256,
|
166 |
|
|
verbose_name=u'Ancien Service', blank=True, null=True)
|
167 |
|
|
old_id = models.CharField(max_length=256,
|
168 |
|
|
verbose_name=u'Ancien ID', blank=True, null=True)
|
169 |
|
|
old_service = models.CharField(max_length=256,
|
170 |
|
|
verbose_name=u'Ancien Service', blank=True, null=True)
|
171 |
|
|
class Meta:
|
172 |
|
|
verbose_name = u'Médecin extérieur'
|
173 |
|
|
verbose_name_plural = u'Médecins extérieurs'
|
174 |
|
|
|
175 |
65141e8b
|
Benjamin Dauvergne
|
class UserWorker(BaseModelMixin, models.Model):
|
176 |
|
|
user = models.OneToOneField('auth.User')
|
177 |
9e738c5d
|
Benjamin Dauvergne
|
worker = models.ForeignKey('Worker',
|
178 |
|
|
verbose_name=u'Personnel')
|
179 |
96f613c6
|
Benjamin Dauvergne
|
|
180 |
9e738c5d
|
Benjamin Dauvergne
|
def __unicode__(self):
|
181 |
65141e8b
|
Benjamin Dauvergne
|
return u'Lien entre la personne {0} et l\'utilisateur {1}'.format(
|
182 |
|
|
self.worker, self.user)
|
183 |
1097fd0a
|
Benjamin Dauvergne
|
|
184 |
96f613c6
|
Benjamin Dauvergne
|
class SchoolTeacher(People):
|
185 |
|
|
schools = models.ManyToManyField('ressources.School')
|
186 |
1cba0446
|
Benjamin Dauvergne
|
role = models.ForeignKey('ressources.SchoolTeacherRole')
|
187 |
1097fd0a
|
Benjamin Dauvergne
|
|
188 |
f7d9fa12
|
Benjamin Dauvergne
|
class TimeTableQuerySet(query.QuerySet):
|
189 |
f8f903c3
|
Benjamin Dauvergne
|
def current(self, today=None):
|
190 |
|
|
if today is None:
|
191 |
|
|
today = date.today()
|
192 |
33e71e35
|
Benjamin Dauvergne
|
return self.filter(models.Q(start_date__lte=today) | models.Q(start_date__isnull=True)) \
|
193 |
|
|
.filter(models.Q(end_date__gte=today) | models.Q(end_date__isnull=True))
|
194 |
04022fee
|
Benjamin Dauvergne
|
|
195 |
f8f903c3
|
Benjamin Dauvergne
|
def for_today(self, today=None):
|
196 |
|
|
if today is None:
|
197 |
|
|
today = date.today()
|
198 |
|
|
qs = self.current(today)
|
199 |
3fae7dcc
|
Benjamin Dauvergne
|
qs = qs.filter(weekday=today.weekday())
|
200 |
f8f903c3
|
Benjamin Dauvergne
|
filters = []
|
201 |
|
|
# week periods
|
202 |
|
|
for week_period in range(1,5):
|
203 |
|
|
filters.append(models.Q(week_period=week_period,
|
204 |
|
|
week_offset=weeks_since_epoch(today) % week_period))
|
205 |
|
|
# week parity
|
206 |
797b7721
|
Benjamin Dauvergne
|
parity = today.isocalendar()[1] % 2
|
207 |
f8f903c3
|
Benjamin Dauvergne
|
filters.append(models.Q(week_parity=parity))
|
208 |
|
|
# week ranks
|
209 |
|
|
filters.append(models.Q(week_rank__in=weekday_ranks(today)))
|
210 |
|
|
qs = qs.filter(reduce(models.Q.__or__, filters))
|
211 |
|
|
return qs
|
212 |
|
|
|
213 |
eeb26fe2
|
Mikaël Ates
|
PERIODICITIES = (
|
214 |
|
|
(1, u'Toutes les semaines'),
|
215 |
|
|
(2, u'Une semaine sur deux'),
|
216 |
|
|
(3, u'Une semaine sur trois'),
|
217 |
|
|
(4, u'Une semaine sur quatre'),
|
218 |
|
|
(5, u'Une semaine sur cinq'),
|
219 |
|
|
(6, u'La première semaine du mois'),
|
220 |
|
|
(7, u'La deuxième semaine du mois'),
|
221 |
|
|
(8, u'La troisième semaine du mois'),
|
222 |
|
|
(9, u'La quatrième semaine du mois'),
|
223 |
|
|
(10, u'La dernière semaine du mois'),
|
224 |
|
|
(11, u'Les semaines paires'),
|
225 |
|
|
(12, u'Les semaines impaires')
|
226 |
|
|
)
|
227 |
|
|
|
228 |
f8f903c3
|
Benjamin Dauvergne
|
|
229 |
9e738c5d
|
Benjamin Dauvergne
|
class TimeTable(BaseModelMixin, models.Model):
|
230 |
f7d9fa12
|
Benjamin Dauvergne
|
objects = PassThroughManager.for_queryset_class(TimeTableQuerySet)()
|
231 |
9e738c5d
|
Benjamin Dauvergne
|
worker = models.ForeignKey(Worker,
|
232 |
|
|
verbose_name=u'Intervenant')
|
233 |
52d3b722
|
Benjamin Dauvergne
|
services = models.ManyToManyField('ressources.Service')
|
234 |
f8f903c3
|
Benjamin Dauvergne
|
WEEKDAYS = Choices(*enumerate(('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',
|
235 |
|
|
'samedi', 'dimanche')))
|
236 |
aceeeca7
|
Mikaël Ates
|
|
237 |
f8f903c3
|
Benjamin Dauvergne
|
weekday = models.PositiveIntegerField(
|
238 |
|
|
verbose_name=u"Jour de la semaine",
|
239 |
|
|
choices=WEEKDAYS)
|
240 |
9e738c5d
|
Benjamin Dauvergne
|
start_time = models.TimeField(
|
241 |
|
|
verbose_name=u'Heure de début')
|
242 |
|
|
end_time = models.TimeField(
|
243 |
|
|
verbose_name=u'Heure de fin')
|
244 |
|
|
start_date = models.DateField(
|
245 |
3f7c000d
|
Benjamin Dauvergne
|
verbose_name=u'Début',
|
246 |
|
|
help_text=u'format: jj/mm/aaaa')
|
247 |
9e738c5d
|
Benjamin Dauvergne
|
end_date = models.DateField(
|
248 |
3f7c000d
|
Benjamin Dauvergne
|
verbose_name=u'Fin', blank=True, null=True,
|
249 |
|
|
help_text=u'format: jj/mm/aaaa')
|
250 |
1097fd0a
|
Benjamin Dauvergne
|
|
251 |
eaf1d7af
|
Mikaël Ates
|
periodicity = models.PositiveIntegerField(
|
252 |
|
|
choices=PERIODICITIES,
|
253 |
|
|
verbose_name=u"Périodicité",
|
254 |
|
|
default=1,
|
255 |
|
|
blank=True,
|
256 |
|
|
null=True)
|
257 |
|
|
|
258 |
f8f903c3
|
Benjamin Dauvergne
|
PERIODS = (
|
259 |
|
|
(1, u'Toutes les semaines'),
|
260 |
|
|
(2, u'Une semaine sur deux'),
|
261 |
|
|
(3, u'Une semaine sur trois'),
|
262 |
eaf1d7af
|
Mikaël Ates
|
(4, u'Une semaine sur quatre'),
|
263 |
|
|
(5, u'Une semaine sur cinq')
|
264 |
f8f903c3
|
Benjamin Dauvergne
|
)
|
265 |
|
|
OFFSET = range(0,4)
|
266 |
|
|
week_offset = models.PositiveIntegerField(
|
267 |
|
|
choices=zip(OFFSET, OFFSET),
|
268 |
aceeeca7
|
Mikaël Ates
|
verbose_name=u"Décalage en semaines par rapport au 1/1/1970 pour le calcul de période",
|
269 |
f8f903c3
|
Benjamin Dauvergne
|
default=0)
|
270 |
|
|
week_period = models.PositiveIntegerField(
|
271 |
|
|
choices=PERIODS,
|
272 |
aceeeca7
|
Mikaël Ates
|
verbose_name=u"Période en semaines",
|
273 |
eeb26fe2
|
Mikaël Ates
|
blank=True, null=True)
|
274 |
f8f903c3
|
Benjamin Dauvergne
|
|
275 |
|
|
PARITIES = (
|
276 |
eaf1d7af
|
Mikaël Ates
|
(0, u'Les semaines paires'),
|
277 |
|
|
(1, u'Les semaines impaires')
|
278 |
f8f903c3
|
Benjamin Dauvergne
|
)
|
279 |
|
|
week_parity = models.PositiveIntegerField(
|
280 |
|
|
choices=PARITIES,
|
281 |
|
|
verbose_name=u"Parité des semaines",
|
282 |
|
|
blank=True, null=True)
|
283 |
|
|
|
284 |
|
|
WEEK_RANKS = (
|
285 |
|
|
(0, u'La première semaine du mois'),
|
286 |
|
|
(1, u'La deuxième semaine du mois'),
|
287 |
|
|
(2, u'La troisième semaine du mois'),
|
288 |
|
|
(3, u'La quatrième semaine du mois'),
|
289 |
|
|
(4, u'La dernière semaine du mois')
|
290 |
|
|
)
|
291 |
|
|
|
292 |
eeb26fe2
|
Mikaël Ates
|
week_rank = models.PositiveIntegerField(
|
293 |
f8f903c3
|
Benjamin Dauvergne
|
verbose_name=u"Rang de la semaine dans le mois",
|
294 |
|
|
choices=WEEK_RANKS,
|
295 |
eeb26fe2
|
Mikaël Ates
|
blank=True, null=True)
|
296 |
f8f903c3
|
Benjamin Dauvergne
|
|
297 |
|
|
def clean(self):
|
298 |
|
|
if (self.week_period is None) + (self.week_parity is None) + \
|
299 |
|
|
(self.week_rank is None) != 2:
|
300 |
eeb26fe2
|
Mikaël Ates
|
raise forms.ValidationError('Only one periodicity criteria can be used')
|
301 |
f8f903c3
|
Benjamin Dauvergne
|
if self.week_period and self.start_date:
|
302 |
|
|
self.week_offset = weeks_since_epoch(self.start_date) % self.week_period
|
303 |
|
|
|
304 |
9e738c5d
|
Benjamin Dauvergne
|
def __unicode__(self):
|
305 |
52d3b722
|
Benjamin Dauvergne
|
s = u'%s pour au %s le %s de %s à %s' % \
|
306 |
|
|
(self.worker, ', '.join(map(unicode, self.services.all())), self.weekday, self.start_time,
|
307 |
9e738c5d
|
Benjamin Dauvergne
|
self.end_time)
|
308 |
|
|
if self.end_time:
|
309 |
|
|
s += u' à partir du %s' % self.start_date
|
310 |
|
|
else:
|
311 |
|
|
s += u' du %s au %s' % (self.start_data, self.end_date)
|
312 |
|
|
return s
|
313 |
1097fd0a
|
Benjamin Dauvergne
|
|
314 |
9e738c5d
|
Benjamin Dauvergne
|
class Meta:
|
315 |
|
|
verbose_name = u'Emploi du temps'
|
316 |
|
|
verbose_name_plural = u'Emplois du temps'
|
317 |
7a0a30d7
|
Benjamin Dauvergne
|
|
318 |
|
|
def to_interval(self, date):
|
319 |
|
|
return Interval(datetime.combine(date, self.start_time),
|
320 |
|
|
datetime.combine(date, self.end_time))
|
321 |
04022fee
|
Benjamin Dauvergne
|
|
322 |
f7d9fa12
|
Benjamin Dauvergne
|
class HolidayQuerySet(query.QuerySet):
|
323 |
61fd471b
|
Mikaël Ates
|
# To grab group holidays:
|
324 |
|
|
# No worker AND
|
325 |
|
|
# Either the holiday has no service, that means for all
|
326 |
|
|
# Or the user must be in the service of the holiday
|
327 |
04022fee
|
Benjamin Dauvergne
|
def for_worker(self, worker):
|
328 |
f7d9fa12
|
Benjamin Dauvergne
|
filter_query = models.Q(worker=worker) \
|
329 |
04022fee
|
Benjamin Dauvergne
|
| models.Q(worker__isnull=True,
|
330 |
5b90c12e
|
Serghei MIHAI
|
services = None) \
|
331 |
61fd471b
|
Mikaël Ates
|
| models.Q(worker__isnull=True,
|
332 |
5b90c12e
|
Serghei MIHAI
|
services__in = worker.services.all())
|
333 |
f16d675e
|
Serghei MIHAI
|
return self.filter(filter_query).distinct()
|
334 |
04022fee
|
Benjamin Dauvergne
|
|
335 |
61fd471b
|
Mikaël Ates
|
def for_worker_id(self, worker_id):
|
336 |
|
|
worker = None
|
337 |
|
|
try:
|
338 |
|
|
worker = Worker.objects.get(pk=worker_id)
|
339 |
|
|
except:
|
340 |
|
|
return None
|
341 |
|
|
filter_query = models.Q(worker=worker) \
|
342 |
|
|
| models.Q(worker__isnull=True,
|
343 |
5b90c12e
|
Serghei MIHAI
|
services = None) \
|
344 |
61fd471b
|
Mikaël Ates
|
| models.Q(worker__isnull=True,
|
345 |
5b90c12e
|
Serghei MIHAI
|
services__in = worker.services.all())
|
346 |
61fd471b
|
Mikaël Ates
|
return self.filter(filter_query)
|
347 |
|
|
|
348 |
|
|
def for_type(self, holiday_type):
|
349 |
5b90c12e
|
Serghei MIHAI
|
return self.filter(holiday_type = holiday_type)
|
350 |
61fd471b
|
Mikaël Ates
|
|
351 |
04022fee
|
Benjamin Dauvergne
|
def for_service(self, service):
|
352 |
5b90c12e
|
Serghei MIHAI
|
return self.filter(worker__isnull = True) \
|
353 |
|
|
.filter(models.Q(services = service)
|
354 |
|
|
|models.Q(services__isnull = True))
|
355 |
04022fee
|
Benjamin Dauvergne
|
|
356 |
1dba86d1
|
Benjamin Dauvergne
|
def for_service_workers(self, service):
|
357 |
5b90c12e
|
Serghei MIHAI
|
return self.filter(models.Q(worker__services = [service])
|
358 |
|
|
|models.Q(services__in = [service])
|
359 |
|
|
|models.Q(worker__isnull=True, services__isnull = True))
|
360 |
a5bdc8ec
|
Benjamin Dauvergne
|
|
361 |
|
|
def future(self):
|
362 |
|
|
return self.filter(end_date__gte=date.today())
|
363 |
|
|
|
364 |
bcb35e14
|
Benjamin Dauvergne
|
def today(self, today=None):
|
365 |
|
|
today = today or date.today()
|
366 |
a5bdc8ec
|
Benjamin Dauvergne
|
return self.filter(start_date__lte=today,
|
367 |
|
|
end_date__gte=today)
|
368 |
|
|
|
369 |
|
|
def for_period(self, start_date, end_date):
|
370 |
|
|
return self.filter(start_date__lte=end_date, end_date__gte=start_date)
|
371 |
04022fee
|
Benjamin Dauvergne
|
|
372 |
e6b125bd
|
Mikaël Ates
|
def for_timed_period(self, date, start_time, end_time):
|
373 |
|
|
filter_query = models.Q(start_date__lt=date, end_date__gt=date) \
|
374 |
|
|
| models.Q(start_date=date, start_time__isnull=True, end_date__gt=date) \
|
375 |
|
|
| models.Q(start_date=date, start_time__lt=end_time, end_date__gt=date) \
|
376 |
|
|
| models.Q(start_date__lt=date, end_date=date, end_time__isnull=True) \
|
377 |
|
|
| models.Q(start_date__lt=date, end_date=date, end_time__gt=start_time) \
|
378 |
|
|
| models.Q(start_date=date, end_date=date, start_time__isnull=True, end_time__isnull=True) \
|
379 |
|
|
| models.Q(start_date=date, end_date=date, start_time__isnull=True, end_time__gt=start_time) \
|
380 |
|
|
| models.Q(start_date=date, end_date=date, start_time__lt=end_time, end_time__isnull=True) \
|
381 |
|
|
| models.Q(start_date=date, end_date=date, start_time__lte=start_time, end_time__gt=start_time) \
|
382 |
fb7b45d2
|
Serghei MIHAI
|
| models.Q(start_date=date, end_date=date, start_time__lt=end_time, end_time__gte=end_time)
|
383 |
e6b125bd
|
Mikaël Ates
|
return self.filter(filter_query)
|
384 |
|
|
|
385 |
706c6be7
|
Benjamin Dauvergne
|
def time2french(time):
|
386 |
|
|
if time.minute:
|
387 |
|
|
return '{0}h{1}'.format(time.hour, time.minute)
|
388 |
|
|
return '{0}h'.format(time.hour)
|
389 |
|
|
|
390 |
04022fee
|
Benjamin Dauvergne
|
class Holiday(BaseModelMixin, models.Model):
|
391 |
f7d9fa12
|
Benjamin Dauvergne
|
objects = PassThroughManager().for_queryset_class(HolidayQuerySet)()
|
392 |
04022fee
|
Benjamin Dauvergne
|
|
393 |
61fd471b
|
Mikaël Ates
|
holiday_type = models.ForeignKey('ressources.HolidayType',
|
394 |
|
|
verbose_name=u'Type de congé')
|
395 |
04022fee
|
Benjamin Dauvergne
|
worker = models.ForeignKey(Worker, blank=True, null=True,
|
396 |
|
|
verbose_name=u"Personnel")
|
397 |
fc35a6fd
|
Serghei MIHAI
|
services = models.ManyToManyField(Service, blank = False, null = False,
|
398 |
|
|
verbose_name = u'Services')
|
399 |
3f7c000d
|
Benjamin Dauvergne
|
start_date = models.DateField(verbose_name=u"Date de début",
|
400 |
|
|
help_text=u'format: jj/mm/aaaa')
|
401 |
|
|
end_date = models.DateField(verbose_name=u"Date de fin",
|
402 |
|
|
help_text=u'format: jj/mm/aaaa')
|
403 |
d5122c5e
|
Benjamin Dauvergne
|
start_time = models.TimeField(verbose_name=u"Horaire de début", blank=True,
|
404 |
|
|
null=True)
|
405 |
|
|
end_time = models.TimeField(verbose_name=u"Horaire de fin", blank=True,
|
406 |
|
|
null=True)
|
407 |
a39c35ec
|
Benjamin Dauvergne
|
comment = models.TextField(verbose_name=u'Commentaire', blank=True)
|
408 |
04022fee
|
Benjamin Dauvergne
|
|
409 |
|
|
class Meta:
|
410 |
|
|
verbose_name = u'Congé'
|
411 |
|
|
verbose_name_plural = u'Congés'
|
412 |
5d69a81c
|
Benjamin Dauvergne
|
ordering = ('start_date', 'start_time')
|
413 |
04022fee
|
Benjamin Dauvergne
|
|
414 |
|
|
def is_current(self):
|
415 |
|
|
return self.start_date <= date.today() <= self.end_date
|
416 |
|
|
|
417 |
5b90c12e
|
Serghei MIHAI
|
def for_all_services(self):
|
418 |
|
|
return self.services.count() == Service.objects.count()
|
419 |
|
|
|
420 |
706c6be7
|
Benjamin Dauvergne
|
def __unicode__(self):
|
421 |
|
|
ret = ''
|
422 |
|
|
if self.start_date == self.end_date:
|
423 |
|
|
ret = u'le {0}'.format(date_filter(self.start_date, 'j F Y'))
|
424 |
61fd471b
|
Mikaël Ates
|
if self.start_time:
|
425 |
|
|
ret += u', à partir de {0}'.format(time2french(self.start_time))
|
426 |
|
|
if self.end_time:
|
427 |
|
|
ret += u", jusqu'à {0}".format(time2french(self.end_time))
|
428 |
706c6be7
|
Benjamin Dauvergne
|
else:
|
429 |
61fd471b
|
Mikaël Ates
|
ret = u'du {0}'.format(date_filter(self.start_date, 'j F Y'))
|
430 |
|
|
if self.start_time:
|
431 |
|
|
ret += u' (à partir de {0})'.format(time2french(self.start_time))
|
432 |
|
|
ret += u' au {0}'.format(date_filter(self.end_date, 'j F Y'))
|
433 |
|
|
if self.end_time:
|
434 |
|
|
ret += u" (jusqu'à {0})".format(time2french(self.end_time))
|
435 |
706c6be7
|
Benjamin Dauvergne
|
return ret
|
436 |
428081e0
|
Jérôme Schneider
|
|
437 |
84614733
|
Benjamin Dauvergne
|
def to_interval(self, date=None):
|
438 |
1eab6c73
|
Frédéric Péters
|
if date == self.start_date:
|
439 |
|
|
start_time = self.start_time or datetime_time(8, 0)
|
440 |
|
|
else:
|
441 |
|
|
start_time = datetime_time(8, 0)
|
442 |
|
|
if date == self.end_date:
|
443 |
|
|
end_time = self.end_time or datetime_time(20, 0)
|
444 |
|
|
else:
|
445 |
|
|
end_time = datetime_time(20, 0)
|
446 |
|
|
return Interval(datetime.combine(self.start_date, start_time),
|
447 |
|
|
datetime.combine(self.end_date, end_time))
|