Revision 3e9b47e9
Added by Benjamin Dauvergne over 12 years ago
.gitignore | ||
---|---|---|
36 | 36 |
calebasse.sqlite3 |
37 | 37 |
scripts/*/*/*.csv |
38 | 38 |
scripts/*/*.json |
39 |
scripts/*.csv |
|
40 |
scripts/*.json |
|
41 |
calebasse/calebasse.log |
calebasse/agenda/forms.py | ||
---|---|---|
12 | 12 |
from ajax_select import make_ajax_field |
13 | 13 |
from models import Event, EventWithAct, EventType |
14 | 14 |
|
15 |
class NewAppointmentForm(forms.ModelForm):
|
|
15 |
class BaseForm(forms.ModelForm):
|
|
16 | 16 |
date = forms.DateField(label=u'Date', localize=True) |
17 | 17 |
time = forms.TimeField(label=u'Heure de début') |
18 | 18 |
duration = forms.CharField(label=u'Durée', |
19 | 19 |
help_text=u'en minutes; vous pouvez utiliser la roulette de votre souris.') |
20 |
|
|
21 | 20 |
participants = make_ajax_field(EventWithAct, 'participants', 'worker-or-group', True) |
21 |
|
|
22 |
|
|
23 |
class NewAppointmentForm(BaseForm): |
|
22 | 24 |
patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False) |
23 | 25 |
|
24 | 26 |
class Meta: |
... | ... | |
99 | 101 |
) |
100 | 102 |
|
101 | 103 |
|
102 |
class NewEventForm(forms.ModelForm): |
|
103 |
|
|
104 |
class NewEventForm(BaseForm): |
|
104 | 105 |
title = forms.CharField(label=u"Complément de l'intitulé", max_length=32, required=False) |
105 |
date = forms.DateField(label=u'Date', localize=True) |
|
106 |
time = forms.TimeField(label=u'Heure de début') |
|
107 |
duration = forms.CharField(label=u'Durée', |
|
108 |
help_text=u'en minutes; vous pouvez utiliser la roulette de votre souris.') |
|
109 |
|
|
110 |
participants = make_ajax_field(Event, 'participants', 'worker-or-group', True) |
|
111 | 106 |
|
112 | 107 |
class Meta: |
113 | 108 |
model = Event |
calebasse/agenda/models.py | ||
---|---|---|
381 | 381 |
def is_event_absence(self): |
382 | 382 |
return False |
383 | 383 |
|
384 |
RECURRENCE_DESCRIPTION = [ |
|
385 |
u'Tous les %s', #(1, None, None), |
|
386 |
u'Un %s sur deux', #(2, None, None), |
|
387 |
u'Un %s sur trois', #(3, None, None), |
|
388 |
u'Un %s sur quatre', #(4, None, None), |
|
389 |
u'Un %s sur cinq', #(5, None, None), |
|
390 |
u'Le premier %s du mois', #(None, 0, None), |
|
391 |
u'Le deuxième %s du mois', #(None, 1, None), |
|
392 |
u'Le troisième %s du mois', #(None, 2, None), |
|
393 |
u'Le quatrième %s du mois', #(None, 3, None), |
|
394 |
u'Le dernier %s du mois', #(None, 4, None), |
|
395 |
u'Les %s les semaines paires', #(None, None, 0), |
|
396 |
u'Les %s les semaines impaires', #(None, None, 1) |
|
397 |
] |
|
398 |
|
|
399 |
WEEKDAY_DESRIPTION = [ |
|
400 |
u'lundi', |
|
401 |
u'mardi', |
|
402 |
u'mercredi', |
|
403 |
u'jeudi', |
|
404 |
u'vendredi', |
|
405 |
u'samedi', |
|
406 |
u'dimanche' |
|
407 |
] |
|
408 |
|
|
409 |
def recurrence_description(self): |
|
410 |
'''Self description of this recurring event''' |
|
411 |
if not self.recurrence_periodicity: |
|
412 |
return None |
|
413 |
parts = [] |
|
414 |
parts.append(self.RECURRENCE_DESCRIPTION[self.recurrence_periodicity] \ |
|
415 |
% self.WEEKDAY_DESRIPTION[self.recurrence_week_day]) |
|
416 |
if self.recurrence_end_date: |
|
417 |
parts.append(u'du') |
|
418 |
else: |
|
419 |
parts.append(u'à partir du') |
|
420 |
parts.append(self.start_datetime.strftime('%d/%m/%Y')) |
|
421 |
if self.recurrence_end_date: |
|
422 |
parts.append(u'au') |
|
423 |
parts.append(self.recurrence_end_date.strftime('%d/%m/%Y')) |
|
424 |
return u' '.join(parts) |
|
425 |
|
|
426 |
|
|
427 |
|
|
428 |
|
|
429 |
|
|
384 | 430 |
def __unicode__(self): |
385 | 431 |
return self.title |
386 | 432 |
|
calebasse/agenda/templates/agenda/appointment.html | ||
---|---|---|
2 | 2 |
{{ form.non_field_errors }} |
3 | 3 |
{{ form.start_datetime }} |
4 | 4 |
{{ form.start_datetime.errors }} |
5 |
<table id="new-appointment-table">
|
|
6 |
<tr>
|
|
7 |
<td {% if form.date.field.required %}class="required"{% endif %}>
|
|
8 |
<p class="datepicker">
|
|
9 |
{{ form.date.label_tag }}
|
|
10 |
{{ form.date|add_class:"datepicker-date" }}
|
|
11 |
{{ form.date.errors }}
|
|
12 |
</p>
|
|
13 |
</td>
|
|
14 |
<td {% if form.time.field.required %}class="required"{% endif %}>
|
|
15 |
<p>
|
|
16 |
{{ form.time.label_tag }}
|
|
17 |
{{ form.time }}
|
|
18 |
{{ form.time.errors }}
|
|
19 |
</p>
|
|
20 |
</td>
|
|
21 |
<td {% if form.duration.field.required %}class="required"{% endif %}>
|
|
22 |
<p>
|
|
23 |
{{ form.duration.label_tag }}
|
|
24 |
{{ form.duration|add_class:"mousewheel"|attr:"data-mousewheel-increment:5" }}
|
|
25 |
{{ form.duration.errors }}
|
|
26 |
<div>
|
|
27 |
{{ form.duration.help_text }}
|
|
28 |
</div>
|
|
29 |
</p>
|
|
30 |
</td>
|
|
31 |
</tr>
|
|
32 |
<tr>
|
|
33 |
<td>
|
|
34 |
<p>
|
|
35 |
{{ form.room.label_tag }}
|
|
36 |
{{ form.room }}
|
|
37 |
{{ form.room.errors }}
|
|
38 |
</p>
|
|
39 |
</td>
|
|
40 |
</tr>
|
|
41 |
<tr>
|
|
42 |
<td {% if form.participants.field.required %}class="required"{% endif %}>
|
|
43 |
<h4>{{ form.participants.label_tag }}</h4>
|
|
44 |
<div id="intervenants">
|
|
45 |
{{ form.participants }}
|
|
46 |
{{ form.participants.errors }}
|
|
47 |
</div>
|
|
48 |
</td>
|
|
49 |
<td {% if form.patient.field.required %}class="required"{% endif %}>
|
|
50 |
<h4>{{ form.patient.label_tag }}</h4>
|
|
51 |
{{ form.patient }}
|
|
52 |
{{ form.patient.errors }}
|
|
53 |
</td>
|
|
54 |
<td {% if form.act_type.field.required %}class="required"{% endif %}>
|
|
55 |
<h4>{{ form.act_type.label_tag }}</h4>
|
|
56 |
{{ form.act_type }}
|
|
57 |
{{ form.act_type.errors }}
|
|
58 |
</td>
|
|
59 |
</tr>
|
|
60 |
</table>
|
|
5 |
<table id="new-appointment-table"> |
|
6 |
<tr> |
|
7 |
<td {% if form.date.field.required %}class="required"{% endif %}> |
|
8 |
<p class="datepicker"> |
|
9 |
{{ form.date.label_tag }} |
|
10 |
{{ form.date|add_class:"datepicker-date" }} |
|
11 |
{{ form.date.errors }} |
|
12 |
</p> |
|
13 |
</td> |
|
14 |
<td {% if form.time.field.required %}class="required"{% endif %}> |
|
15 |
<p> |
|
16 |
{{ form.time.label_tag }} |
|
17 |
{{ form.time }} |
|
18 |
{{ form.time.errors }} |
|
19 |
</p> |
|
20 |
</td> |
|
21 |
<td {% if form.duration.field.required %}class="required"{% endif %}> |
|
22 |
<p> |
|
23 |
{{ form.duration.label_tag }} |
|
24 |
{{ form.duration|add_class:"mousewheel"|attr:"data-mousewheel-increment:5" }} |
|
25 |
{{ form.duration.errors }} |
|
26 |
<div> |
|
27 |
{{ form.duration.help_text }} |
|
28 |
</div> |
|
29 |
</p> |
|
30 |
</td> |
|
31 |
</tr> |
|
32 |
<tr> |
|
33 |
<td> |
|
34 |
<p> |
|
35 |
{{ form.room.label_tag }} |
|
36 |
{{ form.room }} |
|
37 |
{{ form.room.errors }} |
|
38 |
</p> |
|
39 |
</td> |
|
40 |
</tr> |
|
41 |
<tr> |
|
42 |
<td {% if form.participants.field.required %}class="required"{% endif %}> |
|
43 |
<h4>{{ form.participants.label_tag }}</h4> |
|
44 |
<div id="intervenants"> |
|
45 |
{{ form.participants }} |
|
46 |
{{ form.participants.errors }} |
|
47 |
</div> |
|
48 |
</td> |
|
49 |
<td {% if form.patient.field.required %}class="required"{% endif %}> |
|
50 |
<h4>{{ form.patient.label_tag }}</h4> |
|
51 |
{{ form.patient }} |
|
52 |
{{ form.patient.errors }} |
|
53 |
</td> |
|
54 |
<td {% if form.act_type.field.required %}class="required"{% endif %}> |
|
55 |
<h4>{{ form.act_type.label_tag }}</h4> |
|
56 |
{{ form.act_type }} |
|
57 |
{{ form.act_type.errors }} |
|
58 |
</td> |
|
59 |
</tr> |
|
60 |
</table> |
|
61 | 61 |
|
62 |
<!-- <hr/>--> |
|
63 |
<!-- <table id="new-appointment-table">--> |
|
64 |
<!-- <tr>--> |
|
65 |
<!-- <td {% if form.recurrence_periodicity.field.required %}class="required"{% endif %}>--> |
|
66 |
<!-- <p>--> |
|
67 |
<!-- {{ form.recurrence_periodicity.label_tag }}--> |
|
68 |
<!-- {{ form.recurrence_periodicity }}--> |
|
69 |
<!-- {{ form.recurrence_periodicity.errors }}--> |
|
70 |
<!-- </p>--> |
|
71 |
<!-- </td>--> |
|
72 |
<!-- <td {% if form.recurrence_end_date.field.required %}class="required"{% endif %}>--> |
|
73 |
<!-- <p class="datepicker">--> |
|
74 |
<!-- {{ form.recurrence_end_date.label_tag }}--> |
|
75 |
<!-- {{ form.recurrence_end_date|add_class:"datepicker-date" }}--> |
|
76 |
<!-- {{ form.recurrence_end_date.errors }}--> |
|
77 |
<!-- </p>--> |
|
78 |
<!-- </td>--> |
|
79 |
<!-- </tr>--> |
|
80 |
<!-- </table>--> |
|
81 |
<!-- <button>Configurer la périodicité</button> --> |
|
62 |
{% if object.exception_to %} |
|
63 |
<hr/> |
|
64 |
<div>Occurence du {{object.exception_date}} de la série d'evènements {{ object.exception_to.recurrence_description|lower }}</div> |
|
65 |
<button type="button" data-id="{{ object.exception_to.id }}" class="update-periodic-rdv">Éditer le rendez-vous périodique</button> |
|
66 |
{% endif %} |
calebasse/agenda/templates/agenda/event.html | ||
---|---|---|
71 | 71 |
</tr> |
72 | 72 |
</table> |
73 | 73 |
|
74 |
<hr/> |
|
75 |
|
|
76 |
<table id="new-appointment-table"> |
|
77 |
<tr> |
|
78 |
<td {% if form.recurrence_periodicity.field.required %}class="required"{% endif %}> |
|
79 |
<p> |
|
80 |
{{ form.recurrence_periodicity.label_tag }} |
|
81 |
{{ form.recurrence_periodicity }} |
|
82 |
{{ form.recurrence_periodicity.errors }} |
|
83 |
</p> |
|
84 |
</td> |
|
85 |
<td {% if form.recurrence_end_date.field.required %}class="required"{% endif %}> |
|
86 |
<p class="datepicker"> |
|
87 |
{{ form.recurrence_end_date.label_tag }} |
|
88 |
{{ form.recurrence_end_date|add_class:"datepicker-date" }} |
|
89 |
{{ form.recurrence_end_date.errors }} |
|
90 |
</p> |
|
91 |
</td> |
|
92 |
</tr> |
|
93 |
</table> |
|
74 |
{% if object.exception_to %} |
|
75 |
<hr/> |
|
76 |
<div>Occurence du {{object.exception_date}} de la série de rendez-vous {{ object.exception_to.recurrence_description|lower }}</div> |
|
77 |
<button type="button" data-id="{{ object.exception_to.id }}" class="update-periodic-event">Éditer l'évènement périodique</button> |
|
78 |
{% endif %} |
calebasse/agenda/templates/agenda/new-appointment.html | ||
---|---|---|
1 |
<form action="{{ request.get_full_path}}" method="post"> |
|
2 |
{% csrf_token %} |
|
3 |
{% include "agenda/appointment.html" %} |
|
4 |
{% include "agenda/periodicity.html" %} |
|
5 |
</form> |
calebasse/agenda/templates/agenda/new-event.html | ||
---|---|---|
1 | 1 |
<form action="{{ request.get_full_path}}" method="post"> |
2 | 2 |
{% csrf_token %} |
3 | 3 |
{% include "agenda/event.html" %} |
4 |
{% include "agenda/periodicity.html" %} |
|
4 | 5 |
</form> |
calebasse/agenda/templates/agenda/nouveau-rdv.html | ||
---|---|---|
1 |
<form action="{{ request.get_full_path}}" method="post"> |
|
2 |
{% csrf_token %} |
|
3 |
{% include "agenda/appointment.html" %} |
|
4 |
</form> |
calebasse/agenda/templates/agenda/periodicity.html | ||
---|---|---|
1 |
<hr/> |
|
2 |
<table id="new-appointment-table"> |
|
3 |
<tr> |
|
4 |
<td {% if form.recurrence_periodicity.field.required %}class="required"{% endif %}> |
|
5 |
<p> |
|
6 |
{{ form.recurrence_periodicity.label_tag }} |
|
7 |
{{ form.recurrence_periodicity }} |
|
8 |
{{ form.recurrence_periodicity.errors }} |
|
9 |
</p> |
|
10 |
</td> |
|
11 |
<td {% if form.recurrence_end_date.field.required %}class="required"{% endif %}> |
|
12 |
<p class="datepicker"> |
|
13 |
{{ form.recurrence_end_date.label_tag }} |
|
14 |
{{ form.recurrence_end_date }} |
|
15 |
{{ form.recurrence_end_date.errors }} |
|
16 |
</p> |
|
17 |
</td> |
|
18 |
</tr> |
|
19 |
</table> |
calebasse/agenda/urls.py | ||
---|---|---|
10 | 10 |
UpdateEventView, AgendaServiceActValidationView, AutomatedValidationView, |
11 | 11 |
UnlockAllView, AgendasTherapeutesView, JoursNonVerrouillesView, |
12 | 12 |
RessourcesView, AjaxWorkerTabView, AjaxWorkerDisponibilityColumnView, |
13 |
DeleteEventView) |
|
13 |
DeleteEventView, UpdatePeriodicEventView, UpdatePeriodicAppointmentView)
|
|
14 | 14 |
|
15 | 15 |
agenda_patterns = patterns('', |
16 | 16 |
url(r'^$', |
... | ... | |
23 | 23 |
url(r'^update-rdv/(?P<pk>\d+)$', |
24 | 24 |
UpdateAppointmentView.as_view(), |
25 | 25 |
name='update-rdv'), |
26 |
url(r'^update-periodic-rdv/(?P<pk>\d+)$', |
|
27 |
UpdatePeriodicAppointmentView.as_view(), |
|
28 |
name='update-periodic-rdv'), |
|
26 | 29 |
url(r'^new-event/$', |
27 | 30 |
NewEventView.as_view(), |
28 | 31 |
name='new-event'), |
29 | 32 |
url(r'^update-event/(?P<pk>\d+)$', |
30 | 33 |
UpdateEventView.as_view(), |
31 | 34 |
name='update-event'), |
35 |
url(r'^update-periodic-event/(?P<pk>\d+)$', |
|
36 |
UpdatePeriodicEventView.as_view(), |
|
37 |
name='update-periodic-event'), |
|
32 | 38 |
url(r'^delete-event/(?P<pk>\d+)$', |
33 | 39 |
validator_only(csrf_exempt(DeleteEventView.as_view())), |
34 | 40 |
name='delete-event'), |
calebasse/agenda/views.py | ||
---|---|---|
19 | 19 |
from calebasse.actes.validation import (automated_validation, unlock_all_acts_of_the_day) |
20 | 20 |
from calebasse import cbv |
21 | 21 |
|
22 |
from forms import (NewAppointmentForm, NewEventForm, UpdateAppointmentForm, UpdateEventForm) |
|
22 |
from forms import (NewAppointmentForm, NewEventForm, |
|
23 |
UpdateAppointmentForm, UpdateEventForm) |
|
24 |
|
|
23 | 25 |
|
24 | 26 |
def redirect_today(request, service): |
25 | 27 |
'''If not date is given we redirect on the agenda for today''' |
26 | 28 |
return redirect('agenda', date=datetime.date.today().strftime('%Y-%m-%d'), |
27 | 29 |
service=service) |
28 | 30 |
|
29 |
class AgendaHomepageView(TemplateView): |
|
30 | 31 |
|
32 |
class AgendaHomepageView(TemplateView): |
|
31 | 33 |
template_name = 'agenda/index.html' |
32 | 34 |
|
33 | 35 |
def post(self, request, *args, **kwargs): |
... | ... | |
62 | 64 |
|
63 | 65 |
return context |
64 | 66 |
|
65 |
class AgendaServiceActivityView(TemplateView): |
|
66 | 67 |
|
68 |
class AgendaServiceActivityView(TemplateView): |
|
67 | 69 |
template_name = 'agenda/service-activity.html' |
68 | 70 |
|
69 | 71 |
def get_context_data(self, **kwargs): |
... | ... | |
117 | 119 |
class NewAppointmentView(cbv.ReturnToObjectMixin, cbv.ServiceFormMixin, CreateView): |
118 | 120 |
model = EventWithAct |
119 | 121 |
form_class = NewAppointmentForm |
120 |
template_name = 'agenda/nouveau-rdv.html'
|
|
122 |
template_name = 'agenda/new-appointment.html'
|
|
121 | 123 |
success_url = '..' |
122 | 124 |
|
123 | 125 |
def get_initial(self): |
... | ... | |
134 | 136 |
kwargs['service'] = self.service |
135 | 137 |
return kwargs |
136 | 138 |
|
139 |
|
|
137 | 140 |
class TodayOccurrenceMixin(object): |
138 | 141 |
def get_object(self, queryset=None): |
139 | 142 |
o = super(TodayOccurrenceMixin, self).get_object(queryset) |
140 | 143 |
return o.today_occurrence(self.date) |
141 | 144 |
|
142 |
class UpdateAppointmentView(TodayOccurrenceMixin, UpdateView): |
|
145 |
|
|
146 |
class BaseAppointmentView(UpdateView): |
|
143 | 147 |
model = EventWithAct |
144 | 148 |
form_class = UpdateAppointmentForm |
145 | 149 |
template_name = 'agenda/update-rdv.html' |
146 | 150 |
success_url = '..' |
147 | 151 |
|
148 | 152 |
def get_initial(self): |
149 |
initial = super(UpdateView, self).get_initial()
|
|
153 |
initial = super(BaseAppointmentView, self).get_initial()
|
|
150 | 154 |
initial['start_datetime'] = self.date |
151 | 155 |
initial['date'] = self.object.start_datetime.date() |
152 | 156 |
initial['time'] = self.object.start_datetime.time() |
... | ... | |
160 | 164 |
return initial |
161 | 165 |
|
162 | 166 |
def get_form_kwargs(self): |
163 |
kwargs = super(UpdateAppointmentView, self).get_form_kwargs()
|
|
167 |
kwargs = super(BaseAppointmentView, self).get_form_kwargs()
|
|
164 | 168 |
kwargs['service'] = self.service |
165 | 169 |
return kwargs |
166 | 170 |
|
167 | 171 |
|
172 |
class UpdateAppointmentView(TodayOccurrenceMixin, BaseAppointmentView): |
|
173 |
pass |
|
174 |
|
|
175 |
|
|
176 |
class UpdatePeriodicAppointmentView(BaseAppointmentView): |
|
177 |
form_class = NewAppointmentForm |
|
178 |
template_name = 'agenda/new-appointment.html' |
|
179 |
|
|
180 |
|
|
168 | 181 |
class NewEventView(CreateView): |
169 | 182 |
model = Event |
170 | 183 |
form_class = NewEventForm |
... | ... | |
187 | 200 |
return kwargs |
188 | 201 |
|
189 | 202 |
|
190 |
class UpdateEventView(TodayOccurrenceMixin, UpdateView):
|
|
203 |
class BaseEventView(UpdateView):
|
|
191 | 204 |
model = Event |
192 | 205 |
form_class = UpdateEventForm |
193 | 206 |
template_name = 'agenda/update-event.html' |
194 | 207 |
success_url = '..' |
195 | 208 |
|
196 | 209 |
def get_initial(self): |
197 |
initial = super(UpdateEventView, self).get_initial()
|
|
210 |
initial = super(BaseEventView, self).get_initial()
|
|
198 | 211 |
initial['start_datetime'] = self.date |
199 | 212 |
initial['date'] = self.object.start_datetime.date() |
200 | 213 |
initial['time'] = self.object.start_datetime.time() |
... | ... | |
208 | 221 |
return initial |
209 | 222 |
|
210 | 223 |
def get_form_kwargs(self): |
211 |
kwargs = super(UpdateEventView, self).get_form_kwargs()
|
|
224 |
kwargs = super(BaseEventView, self).get_form_kwargs()
|
|
212 | 225 |
kwargs['service'] = self.service |
213 | 226 |
return kwargs |
214 | 227 |
|
228 |
|
|
229 |
class UpdateEventView(TodayOccurrenceMixin, BaseEventView): |
|
230 |
pass |
|
231 |
|
|
232 |
|
|
233 |
class UpdatePeriodicEventView(BaseEventView): |
|
234 |
form_class = NewEventForm |
|
235 |
template_name = 'agenda/new-event.html' |
|
236 |
|
|
237 |
|
|
215 | 238 |
class DeleteEventView(TodayOccurrenceMixin, cbv.DeleteView): |
216 | 239 |
model = Event |
217 | 240 |
success_url = '..' |
... | ... | |
220 | 243 |
super(DeleteEventView, self).delete(request, *args, **kwargs) |
221 | 244 |
return HttpResponse(status=204) |
222 | 245 |
|
246 |
|
|
223 | 247 |
class AgendaServiceActValidationView(TemplateView): |
224 | 248 |
template_name = 'agenda/act-validation.html' |
225 | 249 |
|
calebasse/static/js/calebasse.agenda.js | ||
---|---|---|
80 | 80 |
}); |
81 | 81 |
return false; |
82 | 82 |
}); |
83 |
$(base).on('click', '.update-periodic-rdv', function () { |
|
84 |
$('.ui-dialog-content').dialog('destroy'); |
|
85 |
$('.ui-dialog-content').empty(); |
|
86 |
generic_ajaxform_dialog('update-periodic-rdv/' + $(this).data('id'), |
|
87 |
'Modifier un rendez-vous périodique', '#ajax-dlg', '800px', 'Modifier'); |
|
88 |
}); |
|
89 |
$(base).on('click', '.update-periodic-event', function () { |
|
90 |
$('.ui-dialog-content').dialog('destroy'); |
|
91 |
$('.ui-dialog-content').empty(); |
|
92 |
generic_ajaxform_dialog('update-periodic-event/' + $(this).data('id'), |
|
93 |
'Modifier un évènement périodique', '#ajax-dlg', '800px', 'Modifier'); |
|
94 |
}); |
|
83 | 95 |
} |
84 | 96 |
|
85 | 97 |
function reorder_disponibility_columns() { |
Also available in: Unified diff
agenda: add editing of periodic events