Merge branch 'master' into demo
This commit is contained in:
commit
04e3ad2193
2
INSTALL
2
INSTALL
|
@ -6,4 +6,4 @@ Installation with virtualenv on Debian
|
|||
. ./venv/bin/activate
|
||||
pip install -U setuptools
|
||||
pip install -U pip
|
||||
pip install -r requirements
|
||||
pip install -r requirements.txt
|
||||
|
|
|
@ -18,6 +18,7 @@ class ActSearchForm(forms.Form):
|
|||
('lost', u'Perdus'),
|
||||
('pause-invoicing', u'En pause facturation'),
|
||||
('invoiced', u'Facturés'),
|
||||
('group', u'De groupe'),
|
||||
# ('current-invoicing', u'Facturation en cours')
|
||||
)
|
||||
|
||||
|
|
|
@ -221,7 +221,8 @@ class Act(models.Model):
|
|||
# END Specific to sessad healthcare
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(Act, self).save(*args, **kwargs)
|
||||
if self.parent_event and not self.parent_event.canceled:
|
||||
super(Act, self).save(*args, **kwargs)
|
||||
|
||||
def duration(self):
|
||||
'''Return a displayable duration for this field.'''
|
||||
|
|
|
@ -8,6 +8,8 @@ from django.shortcuts import redirect
|
|||
|
||||
from calebasse.cbv import ListView, UpdateView, DeleteView
|
||||
from calebasse.agenda.views import NewAppointmentView
|
||||
from calebasse.agenda.models import EventWithAct
|
||||
from calebasse.agenda.forms import UpdateAppointmentForm, NewAppointmentForm
|
||||
|
||||
import copy
|
||||
import models
|
||||
|
@ -28,6 +30,7 @@ class ActListingView(ListView):
|
|||
qs = qs.filter(date=self.date)
|
||||
self.search_form = forms.ActSearchForm(data=self.request.GET or None)
|
||||
last_name = self.request.GET.get('last_name')
|
||||
group = self.request.GET.get('group')
|
||||
patient_record_id = self.request.GET.get('patient_record_id')
|
||||
social_security_number = self.request.GET.get('social_security_number')
|
||||
doctor_name = self.request.GET.get('doctor_name')
|
||||
|
@ -40,6 +43,8 @@ class ActListingView(ListView):
|
|||
qs = qs.filter(doctors__last_name__icontains=doctor_name)
|
||||
if 'valide' in filters:
|
||||
qs = qs.exclude(last_validation_state__state_name__exact='VALIDE')
|
||||
if 'group' in filters:
|
||||
qs = qs.filter(act_type__group=True)
|
||||
if 'pointe' in filters:
|
||||
qs = qs.filter(last_validation_state__isnull=False). \
|
||||
exclude(last_validation_state__state_name__exact='NON_VALIDE')
|
||||
|
@ -74,6 +79,8 @@ class ActListingView(ListView):
|
|||
class NewAct(NewAppointmentView):
|
||||
success_url = '.'
|
||||
success_msg = u'Acte enregistré avec succès.'
|
||||
model = EventWithAct
|
||||
form_class = UpdateAppointmentForm
|
||||
|
||||
def form_valid(self, form):
|
||||
result = super(NewAct, self).form_valid(form)
|
||||
|
|
|
@ -10,7 +10,7 @@ from ..ressources.models import ActType
|
|||
from ..middleware.request import get_request
|
||||
|
||||
from ajax_select import make_ajax_field
|
||||
from ajax_select.fields import AutoCompleteSelectField
|
||||
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
||||
from models import Event, EventWithAct, EventType
|
||||
|
||||
class BaseForm(forms.ModelForm):
|
||||
|
@ -22,7 +22,7 @@ class BaseForm(forms.ModelForm):
|
|||
|
||||
|
||||
class NewAppointmentForm(BaseForm):
|
||||
patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
|
||||
patient = AutoCompleteSelectMultipleField('patientrecord')
|
||||
|
||||
class Meta:
|
||||
model = EventWithAct
|
||||
|
@ -65,7 +65,12 @@ class NewAppointmentForm(BaseForm):
|
|||
try:
|
||||
return int(duration)
|
||||
except ValueError:
|
||||
return 0
|
||||
raise forms.ValidationError('Veuillez saisir un entier')
|
||||
|
||||
def clean_patient(self):
|
||||
patients = self.cleaned_data['patient']
|
||||
if patients:
|
||||
return [patient for patient in PatientRecord.objects.filter(pk__in=patients)]
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(NewAppointmentForm, self).clean()
|
||||
|
@ -74,8 +79,37 @@ class NewAppointmentForm(BaseForm):
|
|||
if cleaned_data.has_key('date') and cleaned_data.has_key('time'):
|
||||
cleaned_data['start_datetime'] = datetime.combine(cleaned_data['date'],
|
||||
cleaned_data['time'])
|
||||
if 'patient' in cleaned_data and isinstance(cleaned_data['patient'], list):
|
||||
# nasty trick to store the list of patients and pass the form
|
||||
# validation
|
||||
cleaned_data['patients'] = cleaned_data['patient']
|
||||
cleaned_data['patient'] = cleaned_data['patient'][0]
|
||||
return cleaned_data
|
||||
|
||||
def save(self, commit=True):
|
||||
|
||||
patients = self.cleaned_data.pop('patients')
|
||||
for patient in patients:
|
||||
appointment = forms.save_instance(self, self._meta.model(), commit=False)
|
||||
appointment.start_datetime = datetime.combine(self.cleaned_data['date'],
|
||||
self.cleaned_data['time'])
|
||||
appointment.end_datetime = appointment.start_datetime + timedelta(
|
||||
minutes=self.cleaned_data['duration'])
|
||||
appointment.creator = get_request().user
|
||||
appointment.clean()
|
||||
if commit:
|
||||
appointment.patient = patient
|
||||
appointment.save()
|
||||
self.save_m2m()
|
||||
appointment.services = [self.service]
|
||||
|
||||
class UpdateAppointmentForm(NewAppointmentForm):
|
||||
|
||||
patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
|
||||
|
||||
def clean_patient(self):
|
||||
return self.cleaned_data['patient']
|
||||
|
||||
def save(self, commit=True):
|
||||
appointment = super(NewAppointmentForm, self).save(commit=False)
|
||||
appointment.start_datetime = datetime.combine(self.cleaned_data['date'],
|
||||
|
@ -86,25 +120,13 @@ class NewAppointmentForm(BaseForm):
|
|||
appointment.clean()
|
||||
if commit:
|
||||
appointment.save()
|
||||
self.save_m2m()
|
||||
appointment.services = [self.service]
|
||||
return appointment
|
||||
|
||||
class UpdateAppointmentForm(NewAppointmentForm):
|
||||
|
||||
class Meta(NewAppointmentForm.Meta):
|
||||
fields = (
|
||||
'start_datetime',
|
||||
'date',
|
||||
'time',
|
||||
'duration',
|
||||
'patient',
|
||||
'participants',
|
||||
'ressource',
|
||||
'act_type',
|
||||
)
|
||||
|
||||
|
||||
class UpdatePeriodicAppointmentForm(NewAppointmentForm):
|
||||
class UpdatePeriodicAppointmentForm(UpdateAppointmentForm):
|
||||
patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
|
||||
recurrence_periodicity = forms.ChoiceField(label=u"Périodicité",
|
||||
choices=Event.PERIODICITIES, required=True)
|
||||
|
||||
|
@ -152,7 +174,7 @@ class NewEventForm(BaseForm):
|
|||
'services',
|
||||
'description',
|
||||
'recurrence_periodicity',
|
||||
'recurrence_end_date'
|
||||
'recurrence_end_date',
|
||||
)
|
||||
widgets = {
|
||||
'start_datetime': forms.HiddenInput,
|
||||
|
|
|
@ -49,7 +49,7 @@ class EventQuerySet(InheritanceQuerySet):
|
|||
occurences = ( e.today_occurrence(today) for e in self )
|
||||
return sorted(occurences, key=lambda e: e.start_datetime)
|
||||
|
||||
def daily_disponibilities(self, date, events, participants, time_tables,
|
||||
def daily_disponibilities(self, date, events, participant, time_tables,
|
||||
holidays):
|
||||
'''Slice the day into quarters between 8:00 and 19:00, and returns the
|
||||
list of particpants with their status amon free, busy and away for each
|
||||
|
@ -63,35 +63,64 @@ class EventQuerySet(InheritanceQuerySet):
|
|||
'''
|
||||
result = dict()
|
||||
quarter = 0
|
||||
events_set = {}
|
||||
timetables_set = {}
|
||||
holidays_set = {}
|
||||
for participant in participants:
|
||||
events_set[participant.id] = IntervalSet((o.to_interval() for o in events[participant.id] if not o.is_event_absence()))
|
||||
timetables_set[participant.id] = IntervalSet((t.to_interval(date) for t in time_tables[participant.id]))
|
||||
holidays_set[participant.id] = IntervalSet((h.to_interval(date) for h in holidays[participant.id]))
|
||||
|
||||
events_intervals = IntervalSet((o.to_interval() for o in events if not o.is_event_absence()))
|
||||
|
||||
timetables_intervals = IntervalSet((t.to_interval(date) for t in time_tables))
|
||||
holidays_intervals = IntervalSet((h.to_interval(date) for h in holidays))
|
||||
|
||||
start_datetime = datetime(date.year, date.month, date.day, 8, 0)
|
||||
end_datetime = datetime(date.year, date.month, date.day, 8, 15)
|
||||
while (start_datetime.hour <= 19):
|
||||
for participant in participants:
|
||||
if not result.has_key(start_datetime.hour):
|
||||
result[start_datetime.hour] = [[], [], [], []]
|
||||
quarter = 0
|
||||
interval = IntervalSet.between(start_datetime, end_datetime, False)
|
||||
mins = quarter * 15
|
||||
if interval.intersection(events_set[participant.id]):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'busy'}))
|
||||
elif interval.intersection(holidays_set[participant.id]):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'busy'}))
|
||||
elif not interval.intersection(timetables_set[participant.id]):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'away'}))
|
||||
else:
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'free'}))
|
||||
|
||||
if not result.has_key(start_datetime.hour):
|
||||
result[start_datetime.hour] = [[], [], [], []]
|
||||
quarter = 0
|
||||
interval = IntervalSet.between(start_datetime, end_datetime, False)
|
||||
mins = quarter * 15
|
||||
crossed_events = self.overlap_occurences(start_datetime, events)
|
||||
if len(crossed_events) > 1:
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'overlap'}))
|
||||
elif interval.intersection(events_intervals):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'busy'}))
|
||||
elif interval.intersection(holidays_intervals):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'busy'}))
|
||||
elif not interval.intersection(timetables_intervals):
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'away'}))
|
||||
else:
|
||||
result[start_datetime.hour][quarter].append((mins, {'id': participant.id, 'dispo': 'free'}))
|
||||
quarter += 1
|
||||
start_datetime += timedelta(minutes=15)
|
||||
end_datetime += timedelta(minutes=15)
|
||||
return result
|
||||
|
||||
def overlap_occurences(self, date_time=None, events=None):
|
||||
"""
|
||||
returns the list of overlapping event occurences which do not begin and end
|
||||
at the same time and have the same act type
|
||||
"""
|
||||
date_time = date_time or datetime.now()
|
||||
if events is None:
|
||||
events = self.today_occurrences(date_time.date())
|
||||
overlap = filter(lambda e: e.start_datetime <= date_time and e.end_datetime > date_time \
|
||||
and not e.is_absent(), events)
|
||||
same_type_events = []
|
||||
different_overlap = []
|
||||
for event in overlap:
|
||||
if different_overlap:
|
||||
for e in different_overlap:
|
||||
try:
|
||||
if event.start_datetime == e.start_datetime and \
|
||||
event.end_datetime == e.end_datetime and \
|
||||
event.act_type == e.act_type:
|
||||
continue
|
||||
different_overlap.append(event)
|
||||
except AttributeError:
|
||||
continue
|
||||
else:
|
||||
different_overlap.append(event)
|
||||
return different_overlap
|
||||
|
||||
|
||||
class EventManager(PassThroughManager.for_queryset_class(EventQuerySet),
|
||||
InheritanceManager):
|
||||
|
|
|
@ -393,6 +393,9 @@ class Event(models.Model):
|
|||
def is_event_absence(self):
|
||||
return False
|
||||
|
||||
def get_inactive_participants(self):
|
||||
return self.participants.filter(worker__enabled=False)
|
||||
|
||||
def get_missing_participants(self):
|
||||
missing_participants = []
|
||||
for participant in self.participants.all():
|
||||
|
@ -446,6 +449,12 @@ class Event(models.Model):
|
|||
parts.append(self.recurrence_end_date.strftime('%d/%m/%Y'))
|
||||
return u' '.join(parts)
|
||||
|
||||
def is_absent(self):
|
||||
try:
|
||||
return self.eventwithact.is_absent()
|
||||
except self.DoesNotExist:
|
||||
return False
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
|
@ -512,7 +521,7 @@ class EventWithAct(Event):
|
|||
act.save = old_save
|
||||
old_save(*args, **kwargs)
|
||||
act.comment = self.description
|
||||
act.doctors = self.participants.select_subclasses()
|
||||
act.doctors = (participant.worker for participant in self.participants.all())
|
||||
last_validation_state = ActValidationState.objects.create(
|
||||
act=act, state_name='NON_VALIDE',
|
||||
author=self.creator, previous_state=None)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<div class="worker-agenda">
|
||||
<h2>
|
||||
<strong>{{ service_name }}</strong> - Planning de {{ worker_agenda.worker.first_name }} <span class="lastname">{{ worker_agenda.worker.last_name }}</span>
|
||||
<input type="checkbox" class="printable" checked>
|
||||
<input type="checkbox" class="printable" {% if worker_agenda.has_events %}checked{% endif %}>
|
||||
</h2>
|
||||
<h3>{{ date|date:"DATE_FORMAT"|title }}</h3>
|
||||
|
||||
|
|
|
@ -4,30 +4,43 @@
|
|||
<div>
|
||||
{% for appointment in ressource_agenda.appointments %}
|
||||
<h3 class="{{ appointment.type }} {% if appointment.act_absence %}act-absence{% endif %} appointment"
|
||||
{% if appointment.act_absence %}title="{{appointment.act_absence}}"{% endif %}>
|
||||
{% if appointment.act_absence %}title="{{appointment.act_absence}}"{% endif %} id="{{ appointment.event_id }}">
|
||||
<span class="hour">{{ appointment.begin_hour }}</span>
|
||||
{% if appointment.event_type %} — {{ appointment.event_type }} {% endif %}
|
||||
{% if appointment.title %} — {{ appointment.title }} {% endif %}
|
||||
{% if appointment.length %} — {{ appointment.length }}m {% endif %}
|
||||
{% if appointment.ressources_initial %} —{{ appointment.ressources_initial }} {% endif %}
|
||||
{% if appointment.act_type %} — {{ appointment.act_type }} {% endif %}
|
||||
{% if appointment.ressource %} — {{ appointment.ressource }} {% endif %}
|
||||
{% if appointment.title %}<span class="title">{{ appointment.title }}</span>{% endif %}
|
||||
{% if appointment.length %}<span class="length">{{ appointment.length }} min</span> {% endif %}
|
||||
{% if appointment.act_type %}<span class="act_type">{{ appointment.act_type }}</span>{% endif %}
|
||||
<span class="participants">
|
||||
{% if appointment.len_workers > 4 %}
|
||||
{% if appointment.workers_absent %}<span class="absent" title="Au moins un intervenant est absent">{% endif %}
|
||||
{{ appointment.len_workers }} inter.
|
||||
{% if appointment.workers_absent %}</span>{% endif %}
|
||||
{% else %}
|
||||
{% if appointment.workers %}
|
||||
{% for worker in appointment.workers %}
|
||||
{% if worker in appointment.workers_absent %}<span class="absent" title="Absent">{% endif %}
|
||||
{{ worker.worker.initials }}{% if not forloop.last %} {% endif %}
|
||||
{% if worker in appointment.workers_absent %}</span>{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
<span class="right">
|
||||
{% for service_name in appointment.other_services_names %}
|
||||
<span class="box {{ service_name }}" title="{{ service_name }}"></span>
|
||||
{% endfor %}
|
||||
{% if appointment.description %}
|
||||
<span title="Un commentaire existe" class="icon-comment"></span>
|
||||
{% endif %}
|
||||
<span title="Un commentaire existe" class="icon-comment" {% if appointment.description %}style='display: inline'{% endif %}></span>
|
||||
{% if appointment.event_id %}
|
||||
{% if appointment.is_recurrent %} R {% endif %}
|
||||
{% if appointment.patient_record_id %}
|
||||
<button title="Éditer un rendez-vous" class="edit-appointment icon-edit" data-event-id="{{ appointment.event_id }}"></button>
|
||||
{% else %}
|
||||
<button title="Éditer un événement" class="edit-event icon-edit" data-event-id="{{ appointment.event_id }}">
|
||||
{% if service in appointment.services_names %}
|
||||
{% if appointment.patient_record_id %}
|
||||
<button title="Éditer un rendez-vous" class="edit-appointment icon-edit" data-event-id="{{ appointment.event_id }}"></button>
|
||||
{% else %}
|
||||
<button title="Éditer un événement" class="edit-event icon-edit" data-event-id="{{ appointment.event_id }}">
|
||||
{% endif %}
|
||||
<button class="remove-appointment icon-remove-sign" title="Supprimer un rendez-vous" data-url="{% url 'delete-occurrence' date=date service=service pk=appointment.event_id %}" data-rdv="{{ appointment.title }}"></button>
|
||||
<button class="remove-appointment icon-remove-sign" title="Supprimer un rendez-vous" data-url="{% url 'delete-occurrence' date=date service=service pk=appointment.event_id %}" data-rdv="{{ appointment.title }}"></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</h3>
|
||||
|
||||
|
@ -45,11 +58,15 @@
|
|||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="tabs-ressource-{{ ressource_agenda.ressource.id }} textedit">
|
||||
<span></span>
|
||||
<textarea>{{ appointment.description }}</textarea>
|
||||
<button disabled="disabled" data-event-id="{{ appointment.event_id }}">✔</button>
|
||||
</div>
|
||||
{% if service in appointment.services_names %}
|
||||
<div class="tabs-ressource-{{ ressource_agenda.ressource.id }} textedit">
|
||||
<span></span>
|
||||
<textarea>{{ appointment.description }}</textarea>
|
||||
<button disabled="disabled" data-event-id="{{ appointment.event_id }}" data-date="{{ date|date:"Y-m-d" }}">✔</button>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{{ appointment.description }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if appointment.patient_record_id %}
|
||||
<p class="phones">
|
||||
|
@ -57,7 +74,9 @@
|
|||
{% if address.place_of_life and address.phone %}
|
||||
<span title="{{ address.number }} {{ address.street }} {{ address.zip_code }} {{ address.city }}" class="icon-home-space">{{ address.phone }}</span>
|
||||
{% for contact in address.patientcontact_set.all %}
|
||||
<span title="{{ contact.first_name }} {{ contact.last_name|upper }}" class="icon-user-space">{{ contact.mobile }}</span>
|
||||
{% if contact.mobile %}
|
||||
<span title="{{ contact.first_name }} {{ contact.last_name|upper }}" class="icon-user-space">{{ contact.mobile }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
<p><a href="{% url 'periodic-events-for-worker' service=service date=date worker_id=worker_agenda.worker.id %}">Rendez-vous périodiques</a></p>
|
||||
<div {% if appointment.event_id %}data-event-id="{{ appointment.event_id }}"{% endif %}>
|
||||
{% for appointment in worker_agenda.appointments %}
|
||||
<h3 class="{{ appointment.type }} {% if appointment.act_absence %}act-absence{% endif %} appointment"
|
||||
<h3 id="{{ appointment.event_id }}" class="{{ appointment.type }} {% if appointment.act_absence %}act-absence{% endif %} appointment"
|
||||
{% if appointment.act_absence %}title="{{appointment.act_absence}}"{% endif %}>
|
||||
<span class="hour">{{ appointment.begin_hour }}</span>
|
||||
<span class="length">{% if appointment.length %}{% if appointment.length|str_length_lt:3 %} {% endif %}{{ appointment.length }} mn{% endif %}</span>
|
||||
<span class="length">{% if appointment.length %}{% if appointment.length|str_length_lt:3 %} {% endif %}{{ appointment.length }} min{% endif %}</span>
|
||||
<span class="title">{% if appointment.title %}{{ appointment.title }}{% endif %}
|
||||
{% if appointment.patient.paper_id %} {{ appointment.patient.paper_id }} {% endif %}</span>
|
||||
<span class="participants">
|
||||
|
@ -33,9 +33,7 @@
|
|||
{% for service_name in appointment.other_services_names %}
|
||||
<span class="box {{ service_name }}" title="{{ service_name }}"></span>
|
||||
{% endfor %}
|
||||
{% if appointment.description %}
|
||||
<span title="Un commentaire existe" class="icon-comment"></span>
|
||||
{% endif %}
|
||||
<span title="Un commentaire existe" class="icon-comment" {% if appointment.description %}style='display: inline'{% endif %}></span>
|
||||
{% if appointment.event_id %}
|
||||
{% if appointment.is_recurrent %} R {% endif %}
|
||||
{% if appointment.patient.confidential %}
|
||||
|
|
|
@ -49,12 +49,14 @@
|
|||
</td>
|
||||
<td {% if form.patient.field.required %}class="required"{% endif %}>
|
||||
<h4>{{ form.patient.label_tag }}</h4>
|
||||
<div id="patient">
|
||||
{% if object.exception_to and not object.exception_to.canceled %}
|
||||
{{ object.patient }}
|
||||
{% else %}
|
||||
{{ form.patient }}
|
||||
{{ form.patient.errors }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td {% if form.act_type.field.required %}class="required"{% endif %}>
|
||||
<h4>{{ form.act_type.label_tag }}</h4>
|
||||
|
@ -76,12 +78,12 @@
|
|||
{% if object.exception_to %}
|
||||
<hr/>
|
||||
{% if object.id != object.exception_to.id %}
|
||||
<p><em>Attention: cette objet est une exception à un rendez-vous périodique; si
|
||||
<p><em>Attention: cet objet est une exception à un rendez-vous périodique; si
|
||||
vous modifiez ou supprimiez ce rendez-vous périodique, l'exception n'en serait pas
|
||||
affecté.</em></p>
|
||||
affectée.</em></p>
|
||||
{% endif %}
|
||||
<div>Occurence du {{object.exception_date}} d'un rendez-vous périodique
|
||||
{% if object.exception_to.canceled %}<em>supprimé</em> et initialement prévu{% endif %}
|
||||
{% if object.exception_to.canceled %}<em>supprimée</em> et initialement prévue{% endif %}
|
||||
{{ object.exception_to.recurrence_description|lower }}</div>
|
||||
{% if not object.exception_to.canceled %}
|
||||
<button type="button" data-delete-url="{% url 'delete-event' service=service date=date pk=object.exception_to.pk %}" data-id="{{ object.exception_to.id }}" class="update-periodic-rdv">Éditer le rendez-vous périodique</button>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{% load url from future %}
|
||||
|
||||
{% block extrascripts %}
|
||||
{{ block.super }}
|
||||
<script src="{{ STATIC_URL }}js/json2.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.agenda.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.datesel.js"></script>
|
||||
|
|
|
@ -84,12 +84,12 @@
|
|||
{% if object.exception_to %}
|
||||
<hr/>
|
||||
{% if object.id != object.exception_to.id %}
|
||||
<p><em>Attention: cette objet est une exception à un évènement périodique; si
|
||||
<p><em>Attention: cet objet est une exception à un évènement périodique; si
|
||||
vous modifiez ou supprimiez cet évènement périodique, l'exception n'en serait pas
|
||||
affecté.</em></p>
|
||||
affectée.</em></p>
|
||||
{% endif %}
|
||||
<div>Occurence du {{object.exception_date}} d'un évènement périodique
|
||||
{% if object.exception_to.canceled %}<em>supprimé</em> et initialement prévu{% endif %}
|
||||
{% if object.exception_to.canceled %}<em>supprimée</em> et initialement prévue{% endif %}
|
||||
{{ object.exception_to.recurrence_description|lower }}</div>
|
||||
{% if not object.exception_to.canceled %}
|
||||
<button type="button" data-delete-url="{% url 'delete-event' service=service date=date pk=object.exception_to.pk %}" data-id="{{ object.exception_to.id }}" class="update-periodic-event">Éditer l'évènement périodique</button>
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<span class="hour">{{ event.start_datetime.time }}</span>
|
||||
{% if event.title %} — {{ event.title }} {% endif %}
|
||||
{% if event.patient.paper_id %} — {{ event.patient.paper_id }} {% endif %}
|
||||
{% if event.length %} — {{ event.length }} mn {% endif %}
|
||||
{% if event.length %} — {{ event.length }} min {% endif %}
|
||||
{% if event.workers_initial %} — {{ event.workers_initial }} {% endif %}
|
||||
{% if event.ressource %} — {{ event.ressource }} {% endif %}
|
||||
<span class="right">
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
{% extends "agenda/base.html" %}
|
||||
{% load url from future %}
|
||||
{% load apptags %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>Agenda</h2>
|
||||
<a href="../">Retourner à l'agenda</a>
|
||||
<button class="newevent" data-hour="" data-url="{% url 'new-event' service=service date=date %}">Nouvel événement</button>
|
||||
<button class="newrdv" data-hour="" data-url="{% url 'nouveau-rdv' service=service date=date %}">Nouveau rendez-vous patient</button>
|
||||
{% endblock %}
|
||||
|
||||
{% block beforecontent %}
|
||||
<div id="users">
|
||||
<div id="filtre">
|
||||
<input type="text"/>
|
||||
</div>
|
||||
<dl>
|
||||
{% for ressources_type in ressources_types %}
|
||||
<dt>{{ ressources_type.type }}</dt>
|
||||
<dd><ul>
|
||||
{% for ressource in ressources_type.ressources %}
|
||||
<li id="selector-ressource-{{ressource.id}}" class="ressource-item" data-ressource-id="{{ressource.id}}" data-target=".ressource-{{ressource.id}}.agenda">{{ ressource.name }} <span class="toggle" title="cliquer pour déselectionner">(-)</span></li>
|
||||
{% endfor %}
|
||||
</ul></dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block agenda-content %}
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td id="dispos">
|
||||
<button id="close-all-ressource-agendas" style="display: none">Fermer tous les agendas</button>
|
||||
Disponibilités
|
||||
<table>
|
||||
<tr class="initials"><td></td></tr>
|
||||
{% for start_time in disponibility_start_times %}
|
||||
<tr class="hour-mark">
|
||||
<td rowspan="4">{{ start_time }}:00</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr></tr>
|
||||
<tr></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td id="agendas">
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
{% for ressource_agenda in ressources_agenda %}
|
||||
<li style="display: none" class="ressource-{{ ressource_agenda.ressource.id }} agenda">
|
||||
<a id="link-tab-ressource-{{ ressource_agenda.ressource.id }}" href="#tabs-ressource-{{ ressource_agenda.ressource.id }}" class="tab" data-id="{{ ressource_agenda.ressource.id }}">{{ ressource_agenda.ressource.name }}</a>
|
||||
<a href="#" style="padding: 3px;cursor: auto;" class="close-tab" data-target="selector-ressource-{{ ressource_agenda.ressource.id }}"><span class="ui-icon ui-icon-circle-close"></span></a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% for ressource_agenda in ressources_agenda %}
|
||||
<div id="tabs-ressource-{{ ressource_agenda.ressource.id }}" class="tabs agenda ressource-{{ ressource_agenda.ressource.id }}" style="display: none;">
|
||||
<a class="print" href="#">Imprimer</a>
|
||||
<div>
|
||||
{% for appointment in ressource_agenda.appointments %}
|
||||
<h3 class="{{ appointment.type }} {% if appointment.act_absence %}act-absence{% endif %} appointment"
|
||||
{% if appointment.act_absence %}title="{{appointment.act_absence}}"{% endif %}>
|
||||
<span class="hour">{{ appointment.begin_hour }}</span>
|
||||
{% if appointment.event_type %} — {{ appointment.event_type }} {% endif %}
|
||||
{% if appointment.title %} — {{ appointment.title }} {% endif %}
|
||||
{% if appointment.length %} — {{ appointment.length }}m {% endif %}
|
||||
{% if appointment.ressources_initial %} —{{ appointment.ressources_initial }} {% endif %}
|
||||
{% if appointment.act_type %} — {{ appointment.act_type }} {% endif %}
|
||||
{% if appointment.ressource %} — {{ appointment.ressource }} {% endif %}
|
||||
<span class="right">
|
||||
{% for service_name in appointment.other_services_names %}
|
||||
<span class="box {{ service_name }}" title="{{ service_name }}"></span>
|
||||
{% endfor %}
|
||||
{% if appointment.description %}
|
||||
<span title="Un commentaire existe" class="icon-comment"></span>
|
||||
{% endif %}
|
||||
{% if appointment.event_id %}
|
||||
{% if appointment.is_recurrent %} R {% endif %}
|
||||
{% if appointment.patient_record_id %}
|
||||
<button title="Éditer un rendez-vous" class="edit-appointment icon-edit" data-event-id="{{ appointment.event_id }}"></button>
|
||||
{% else %}
|
||||
<button title="Éditer un événement" class="edit-event icon-edit" data-event-id="{{ appointment.event_id }}">
|
||||
{% endif %}
|
||||
<button class="remove-appointment icon-remove-sign" title="Supprimer un rendez-vous" data-url="{% url 'delete-occurrence' date=date service=service pk=appointment.event_id %}" data-rdv="{{ appointment.title }}"></button>
|
||||
{% endif %}
|
||||
</span>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
{% if appointment.type == 'free' %}
|
||||
<button class='newrdv' data-url="{% url 'nouveau-rdv' service=service date=date %}" data-hour="{{ appointment.begin_hour }}">Nouveau rendez-vous patient</button>
|
||||
<button class='newevent' data-url="{% url 'new-event' service=service date=date %}" data-hour="{{ appointment.begin_hour }}">Nouvel événement</button>
|
||||
{% endif %}
|
||||
{% if appointment.event_id %}
|
||||
{% if appointment.workers %}
|
||||
<p class="workers">
|
||||
Intervenants :
|
||||
{% for worker in appointment.workers %}
|
||||
{{ worker.first_name }} <span class="lastname">{{ worker.last_name }}</span>{% if forloop.last %}.{% else %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="tabs-ressource-{{ ressource_agenda.ressource.id }} textedit">
|
||||
<span></span>
|
||||
<textarea>{{ appointment.description }}</textarea>
|
||||
<button disabled="disabled" data-event-id="{{ appointment.event_id }}">✔</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if appointment.patient_record_id %}
|
||||
<p class="phones">
|
||||
{% for address in appointment.patient.addresses.all %}
|
||||
{% if address.place_of_life and address.phone %}
|
||||
<span title="{{ address.number }} {{ address.street }} {{ address.zip_code }} {{ address.city }}" class="icon-home-space">{{ address.phone }}</span>
|
||||
{% for contact in address.patientcontact_set.all %}
|
||||
<span title="{{ contact.first_name }} {{ contact.last_name|upper }}" class="icon-user-space">{{ contact.mobile }}</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<a href="/{{ service }}/dossiers/{{ appointment.patient_record_id }}/view" target="_blank">Dossier patient</a> -
|
||||
<a href="/{{ service }}/dossiers/{{ appointment.patient_record_id }}/view#tab=5" target="_blank">Prochains rendez-vous</a> -
|
||||
<a href="#" class="generate-mail-btn" data-dossier-id="{{ appointment.patient_record_id }}" data-date="{{date|date:"Y-m-d"}}" data-event-id="{{ appointment.event_id }}" data-next-url="{{ request.get_full_path }}">Courrier</a>
|
||||
{% endif %}
|
||||
{% if appointment.validation %}
|
||||
<div><span>{% if appointment.validation.1 %}<strong>{{ appointment.validation.2 }}</strong>, le {{ appointment.validation.1.created }} par {{ appointment.validation.1.author }}
|
||||
{% if appointment.validation.1.auto %}(par validation automatique){% endif %}. {% if appointment.validation.0.is_billed %}<strong>Acte facturé</strong>{% endif %}
|
||||
{% else %}
|
||||
Non pointé.
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if not appointment.validation.0.validation_locked and appointment.validation.3 %}
|
||||
<form method="post" class="inline-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" value="{{appointment.validation.0.id}}" name="acte-id">
|
||||
<select data-previous="{{ last_status.state_name }}" name="act_state">
|
||||
{% for state_name, display_state_name in appointment.validation.3.items %}
|
||||
<option value="{{ state_name }}" {% if state_name == appointment.validation.1.state_name %}selected{% endif %}>{{ display_state_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button>Modifier</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block dialogs %}
|
||||
<div id="rdv" style="display: none;"></div>
|
||||
<div id="ajax-dlg" style="display: none;"></div>
|
||||
{% endblock %}
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
{% block agenda-content %}
|
||||
|
||||
<div class="print-only page-header">{{ date|date:"DATE_FORMAT"|lower }}</div>
|
||||
|
||||
<h2 class="print-only">Activité du {{ service_name }} - {{ date|date:"DATE_FORMAT"|title }}</h2>
|
||||
|
||||
<table class="main" id="activity">
|
||||
|
|
|
@ -7,7 +7,7 @@ from itertools import chain
|
|||
from django.contrib import messages
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import redirect, get_object_or_404
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.http import HttpResponseRedirect, HttpResponse, Http404
|
||||
from django.conf import settings
|
||||
|
||||
from calebasse.cbv import TemplateView, CreateView, UpdateView
|
||||
|
@ -24,7 +24,7 @@ from calebasse.actes.validation import (automated_validation, unlock_all_acts_of
|
|||
from calebasse import cbv
|
||||
|
||||
from calebasse.agenda.forms import (NewAppointmentForm, NewEventForm, UpdatePeriodicAppointmentForm,
|
||||
DisablePatientAppointmentForm, UpdateAppointmentForm, UpdatePeriodicEventForm,
|
||||
DisablePatientAppointmentForm, UpdateAppointmentForm, UpdatePeriodicEventForm,
|
||||
UpdateEventForm, PeriodicEventsSearchForm)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -133,7 +133,7 @@ class AgendaServiceActivityView(TemplateView, cbv.ServiceViewMixin):
|
|||
return context
|
||||
|
||||
|
||||
class NewAppointmentView(cbv.ReturnToObjectMixin, cbv.ServiceFormMixin, CreateView):
|
||||
class NewAppointmentView(cbv.ServiceFormMixin, CreateView):
|
||||
model = EventWithAct
|
||||
form_class = NewAppointmentForm
|
||||
template_name = 'agenda/new-appointment.html'
|
||||
|
@ -150,23 +150,22 @@ class NewAppointmentView(cbv.ReturnToObjectMixin, cbv.ServiceFormMixin, CreateVi
|
|||
initial['duration'] = self.request.GET.get('duration')
|
||||
return initial
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super(NewAppointmentView, self).get_form_kwargs()
|
||||
kwargs['service'] = self.service
|
||||
return kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
return self.request.META.get('HTTP_REFERER', '..')
|
||||
|
||||
def form_valid(self, form):
|
||||
obj = super(NewAppointmentView, self).form_valid(form)
|
||||
messages.add_message(self.request, messages.INFO, self.success_msg)
|
||||
return super(NewAppointmentView, self).form_valid(form)
|
||||
return obj
|
||||
|
||||
|
||||
class TodayOccurrenceMixin(object):
|
||||
def get_object(self, queryset=None):
|
||||
o = super(TodayOccurrenceMixin, self).get_object(queryset)
|
||||
return o.today_occurrence(self.date)
|
||||
obj = o.today_occurrence(self.date)
|
||||
if obj:
|
||||
return obj
|
||||
raise Http404
|
||||
|
||||
|
||||
class BaseAppointmentView(UpdateView):
|
||||
|
@ -204,7 +203,6 @@ class UpdateAppointmentView(TodayOccurrenceMixin, BaseAppointmentView):
|
|||
else:
|
||||
return self.form_class
|
||||
|
||||
|
||||
class UpdatePeriodicAppointmentView(BaseAppointmentView):
|
||||
form_class = UpdatePeriodicAppointmentForm
|
||||
template_name = 'agenda/new-appointment.html'
|
||||
|
@ -278,12 +276,19 @@ class UpdatePeriodicEventView(BaseEventView):
|
|||
template_name = 'agenda/new-event.html'
|
||||
|
||||
def delete_eventwithact(event):
|
||||
assert event.event_type == 1
|
||||
if event.act.id \
|
||||
and not event.act.is_billed:
|
||||
event.act.delete()
|
||||
if not event.act.id or \
|
||||
not event.act.is_billed:
|
||||
assert event.event_type_id == 1
|
||||
|
||||
# in case of "event" is an instance of "Event" model and not "EventWithAct"
|
||||
# and so doesn't have 'act' attribute
|
||||
try:
|
||||
if event.act.id \
|
||||
and not event.act.is_billed:
|
||||
event.act.delete()
|
||||
|
||||
if not event.act.id or \
|
||||
not event.act.is_billed:
|
||||
event.delete()
|
||||
except AttributeError:
|
||||
event.delete()
|
||||
|
||||
class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):
|
||||
|
@ -293,7 +298,7 @@ class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):
|
|||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
if self.object.event_type == 1:
|
||||
if self.object.event_type_id == 1:
|
||||
delete_eventwithact(self.object)
|
||||
else:
|
||||
self.object.delete()
|
||||
|
@ -312,12 +317,12 @@ class DeleteEventView(cbv.DeleteView):
|
|||
exception.recurrence_periodicity = None
|
||||
exception.exception_to = None
|
||||
exception.save()
|
||||
if exception.event_type == 1:
|
||||
if exception.event_type_id == 1:
|
||||
delete_eventwithact(exception)
|
||||
else:
|
||||
exception.delete()
|
||||
|
||||
if self.object.event_type == 1:
|
||||
if self.object.event_type_id == 1:
|
||||
delete_eventwithact(self.object)
|
||||
else:
|
||||
self.object.delete()
|
||||
|
@ -507,7 +512,8 @@ class AgendasTherapeutesView(AgendaHomepageView):
|
|||
if all(map(lambda x: x.holiday, daily_appointments)):
|
||||
continue
|
||||
context['workers_agenda'].append({'worker': worker,
|
||||
'appointments': daily_appointments})
|
||||
'appointments': daily_appointments,
|
||||
'has_events': True if events_worker else False})
|
||||
|
||||
for worker_agenda in context.get('workers_agenda', []):
|
||||
patient_appointments = [x for x in worker_agenda['appointments'] if x.patient_record_id]
|
||||
|
@ -627,14 +633,17 @@ class AjaxDisponibilityColumnView(TemplateView):
|
|||
mins = quarter * 15
|
||||
|
||||
if events:
|
||||
event = events[0]
|
||||
|
||||
if event.start_datetime <= start_datetime and event.end_datetime >= end_datetime:
|
||||
dispo = 'busy'
|
||||
for event in events:
|
||||
overlap_events = Event.objects.overlap_occurences(start_datetime, events)
|
||||
if len(overlap_events) > 1:
|
||||
dispo = 'overlap'
|
||||
elif event.start_datetime <= start_datetime and event.end_datetime >= end_datetime:
|
||||
dispo = 'busy'
|
||||
disponibility[start_datetime.hour][quarter].append((mins, {'id': ressource_id, 'dispo': dispo}))
|
||||
quarter += 1
|
||||
start_datetime += datetime.timedelta(minutes=15)
|
||||
end_datetime += datetime.timedelta(minutes=15)
|
||||
|
||||
context['disponibility'] = disponibility
|
||||
return context
|
||||
|
||||
|
@ -642,11 +651,11 @@ class AjaxDisponibilityColumnView(TemplateView):
|
|||
def get_worker_context_data(self, worker_id, context):
|
||||
worker = Worker.objects.get(pk=worker_id)
|
||||
|
||||
time_tables_worker = TimeTable.objects.select_related('worker'). \
|
||||
time_tables = TimeTable.objects.select_related('worker'). \
|
||||
filter(services=self.service, worker=worker). \
|
||||
for_today(self.date). \
|
||||
order_by('start_date')
|
||||
holidays_worker = Holiday.objects.for_worker(worker). \
|
||||
holidays = Holiday.objects.for_worker(worker). \
|
||||
for_period(self.date, self.date). \
|
||||
order_by('start_date')
|
||||
events = Event.objects.for_today(self.date) \
|
||||
|
@ -664,13 +673,13 @@ class AjaxDisponibilityColumnView(TemplateView):
|
|||
|
||||
events = list(events) + list(eventswithact)
|
||||
events = [ e.today_occurrence(self.date) for e in events ]
|
||||
time_tables_workers = {worker.id: time_tables_worker}
|
||||
time_tables_workers = {worker.id: time_tables}
|
||||
events_workers = {worker.id: events}
|
||||
holidays_workers = {worker.id: holidays_worker}
|
||||
holidays_workers = {worker.id: holidays}
|
||||
|
||||
context['initials'] = worker.initials
|
||||
context['disponibility'] = Event.objects.daily_disponibilities(self.date,
|
||||
events_workers, [worker], time_tables_workers, holidays_workers)
|
||||
events, worker, time_tables, holidays)
|
||||
return context
|
||||
|
||||
def get_context_data(self, ressource_type, ressource_id, **kwargs):
|
||||
|
|
|
@ -18,6 +18,7 @@ from calebasse.ressources.models import (HealthCenter, LargeRegime,
|
|||
CodeCFTMEA, SocialisationDuration, MDPHRequest, MDPHResponse)
|
||||
|
||||
from ajax_select import make_ajax_field
|
||||
from django_select2.widgets import Select2MultipleWidget
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -111,10 +112,6 @@ class CivilStatusForm(ModelForm):
|
|||
fields = ('first_name', 'last_name', 'birthdate', 'birthplace', 'gender', 'nationality')
|
||||
|
||||
|
||||
class FilteredSelectMultipleMise(django.contrib.admin.widgets.FilteredSelectMultiple):
|
||||
def __init__(self, **kwargs):
|
||||
super(FilteredSelectMultipleMise, self).__init__(u'Catégorie', False)
|
||||
|
||||
class PhysiologyForm(ModelForm):
|
||||
cranium_perimeter = forms.DecimalField(label=u"Périmètre cranien",
|
||||
max_digits=5, decimal_places=2, localize=True,
|
||||
|
@ -135,10 +132,11 @@ class PhysiologyForm(ModelForm):
|
|||
'deficiency_polyhandicap', 'deficiency_behavioral_disorder',
|
||||
'deficiency_in_diagnostic', 'deficiency_other_disorder')
|
||||
widgets = {
|
||||
'mises_1': FilteredSelectMultipleMise,
|
||||
'mises_2': FilteredSelectMultipleMise,
|
||||
'mises_3': FilteredSelectMultipleMise,
|
||||
}
|
||||
'mises_1': Select2MultipleWidget(attrs={'style': 'width: 32em'}),
|
||||
'mises_2': Select2MultipleWidget(attrs={'style': 'width: 32em'}),
|
||||
'mises_3': Select2MultipleWidget(attrs={'style': 'width: 32em'}),
|
||||
}
|
||||
|
||||
|
||||
def __init__(self, instance, **kwargs):
|
||||
super(PhysiologyForm, self).__init__(instance=instance, **kwargs)
|
||||
|
|
|
@ -34,9 +34,6 @@ class PatientRecordLookup(CalebasseLookup):
|
|||
|
||||
return chain(qs, closed)
|
||||
|
||||
def format_match(self,obj):
|
||||
return self.format_item_display(texte)
|
||||
|
||||
def get_result(self, obj):
|
||||
return self.format_item_display(obj)
|
||||
|
||||
|
|
|
@ -479,7 +479,7 @@ class PatientRecord(ServiceLinkedAbstractModel, PatientContact):
|
|||
deficiency_polyhandicap = models.BooleanField(verbose_name=u'Polyhandicap',
|
||||
default=False)
|
||||
deficiency_behavioral_disorder = models.IntegerField(max_length=1,
|
||||
verbose_name=u"Troubles du comportement et de la communication",
|
||||
verbose_name=u"Troubles de la conduite et du comportement",
|
||||
choices=DEFICIENCY_CHOICES,
|
||||
default=0)
|
||||
deficiency_in_diagnostic = models.BooleanField(verbose_name=u'En diagnostic',
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
|
||||
{% block extrascripts %}
|
||||
{{ block.super }}
|
||||
<script src="{{ STATIC_URL }}js/jquery.parse-url.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.dossiers.js"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
{% endif %}
|
||||
|
||||
|
||||
<form method="post" action="tab1" id="create-directory-form" action="create-directory">{% csrf_token %}
|
||||
<form method="post" action="{% url "create_directory" service object.id %}" id="create-directory-form">{% csrf_token %}
|
||||
<button>Créer répertoire patient</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div id="tabs-5">
|
||||
{% for state, last_rdvs in history %}
|
||||
<div class="frame">
|
||||
<h3>{{ state.status.name }} depuis le {{ state.date_selected|date:"SHORT_DATE_FORMAT" }}</h3>
|
||||
<h3>{% if state %}{{ state.status.name }} depuis le {{ state.date_selected|date:"SHORT_DATE_FORMAT" }}{% else %}Indéfini{% endif %}</h3>
|
||||
{% if last_rdvs %}
|
||||
<table class="basic">
|
||||
<thead>
|
||||
|
|
|
@ -4,15 +4,23 @@
|
|||
<tr> <th>Date</th> <th>Pointage</th> <th>Type d'acte</th> <th>Intervenants</th> <th>Commentaire</th> </tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for event, state, missing_participants in next_rdvs %}
|
||||
{% for event, state, missing_participants, inactive_participants in next_rdvs %}
|
||||
<tr>
|
||||
<td>{% firstof event.start_datetime|date:"l d/m/y H:i"|title %}{% if missing_participants %} <span title="Au moins un intervenant est absent" class="icon-warning-sign absent"></span>{% endif %}</td>
|
||||
<td>{% firstof event.start_datetime|date:"l d/m/y H:i"|title %}{% if missing_participants or inactive_participants %} <span title="Au moins un intervenant est absent ou ne fait plus partie du service" class="icon-warning-sign absent"></span>{% endif %}</td>
|
||||
<td>{% if state %}{% if state.state_name != 'VALIDE' %}<strong>{% endif %}{{ state }}{% if state.state_name != 'VALIDE' %}</strong>{% endif %}{% else %}Non pointé.{% endif %}</td>
|
||||
<td>{{ event.act_type }}</td>
|
||||
<td class="width-limited">{% for participant in event.participants.all %}
|
||||
{% if participant in missing_participants %}<span class="absent" title="Absent">{% endif %}
|
||||
{% if participant in missing_participants %}
|
||||
<span class="absent" title="Absent">
|
||||
{{ participant.first_name }} <span class="lastname">{{ participant.last_name }}</span>
|
||||
{% if participant in missing_participants %}</span>{% endif %}
|
||||
</span>
|
||||
{% elif participant in inactive_participants %}
|
||||
<span class="inactive" title="Ne fait plus parti du service">
|
||||
{{ participant.first_name }} <span class="lastname">{{ participant.last_name }}</span>
|
||||
</span>
|
||||
{% else %}
|
||||
{{ participant.first_name }} <span class="lastname">{{ participant.last_name }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}</td>
|
||||
{% if event.act.id %}
|
||||
<td class="width-limited">{{ event.act.comment }}</td>
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
{% for duration in object.socialisation_durations.all %}
|
||||
<div class="subframe">
|
||||
Arrivée le <strong>{{ duration.start_date }}</strong> dans {% if duration.school %}l'établissement <strong>{{ duration.school }}</strong>{% else %}un établissement non renseigné{% endif %}{% if duration.level %} (en {{ duration.level }}){% endif %}
|
||||
<ul>
|
||||
{% if duration.school.address %}
|
||||
<li><label>Adresse établissement : </label>{{ duration.school.address }}, {{ duration.school.zip_code }} {{ duration.school.city }}</span></li>
|
||||
{% endif %}
|
||||
{% if duration.school.phone %}
|
||||
<li><span class="icon-phone">{{ duration.school.phone }}</span></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="buttons">
|
||||
<button type="button" data-id="{{ duration.id }}" class="del-duration icon-minus" title="Supprimer"></button>
|
||||
<button type="button" data-id="{{ duration.id }}" class="update-duration-btn icon-edit" title="Modifier"></button>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
{% extends "dossiers/base.html" %}
|
||||
{% load url from future %}
|
||||
{% load dossiers %}
|
||||
{% block extrastyles %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}filter-widget/css/filter-widget.css"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrascripts %}
|
||||
<link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}filter-widget/css/filter-widget.css"/>
|
||||
{{ block.super }}
|
||||
<script src="{{ STATIC_URL }}js/jquery.parse-url.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.dossiers.js"></script>
|
||||
<script src="{{ STATIC_URL }}filter-widget/js/i18n.js"></script>
|
||||
<script src="{{ STATIC_URL }}filter-widget/js/core.js"></script>
|
||||
<script src="{{ STATIC_URL }}filter-widget/js/SelectBox.js"></script>
|
||||
<script src="{{ STATIC_URL }}filter-widget/js/SelectFilter2.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{{ object.last_name }} {{ object.first_name }}{% if object.paper_id %} - Dossier {{ object.paper_id}}{% endif %}{% endblock %}
|
||||
|
|
|
@ -49,7 +49,7 @@ urlpatterns = patterns('calebasse.dossiers.views',
|
|||
url(r'^(?P<patientrecord_id>\d+)/mdph_response/(?P<pk>\d+)/update$', 'update_mdph_response'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/mdph_response/(?P<pk>\d+)/del$', 'delete_mdph_response'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/generate$', 'generate_rtf_form'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/create-directory$', 'create_directory'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/create-directory$', 'create_directory', name="create_directory"),
|
||||
url(r'^(?P<patientrecord_id>\d+)/prescription-transport$', 'prescription_transport'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/protection/new$', 'new_protection'),
|
||||
url(r'^(?P<patientrecord_id>\d+)/protection/(?P<pk>\d+)/update$', 'update_protection'),
|
||||
|
|
|
@ -270,10 +270,12 @@ class PatientRecordGeneralView(cbv.UpdateView):
|
|||
ctx['last_rdv'] = get_last_rdv(ctx['object'])
|
||||
ctx['next_rdv'] = get_next_rdv(ctx['object'])
|
||||
current_state = ctx['object'].get_current_state()
|
||||
if STATES_MAPPING.has_key(current_state.status.type):
|
||||
if current_state.status and STATES_MAPPING.has_key(current_state.status.type):
|
||||
state = STATES_MAPPING[current_state.status.type]
|
||||
else:
|
||||
elif current_state.status:
|
||||
state = current_state.status.name
|
||||
else:
|
||||
state = "Aucun"
|
||||
ctx['current_state'] = current_state
|
||||
ctx['status'], ctx['hc_status'] = get_status(ctx, self.request.user)
|
||||
ctx['missing_policy'] = False
|
||||
|
@ -433,7 +435,7 @@ class PatientRecordNextAppointmentsView(cbv.DetailView):
|
|||
state = event.act.get_state()
|
||||
if state and not state.previous_state and state.state_name == 'NON_VALIDE':
|
||||
state = None
|
||||
ctx['next_rdvs'].append((event, state, event.get_missing_participants()))
|
||||
ctx['next_rdvs'].append((event, state, event.get_missing_participants(), event.get_inactive_participants()))
|
||||
return ctx
|
||||
|
||||
tab6_next_rdv = PatientRecordNextAppointmentsView.as_view()
|
||||
|
|
|
@ -14,7 +14,7 @@ def get_status(ctx, user):
|
|||
"""
|
||||
status = []
|
||||
close_btn = STATES_BTN_MAPPER['CLOS']
|
||||
if 'next_rdv' in ctx:
|
||||
if ctx.get('next_rdv'):
|
||||
close_btn = STATES_BTN_MAPPER['CLOS_RDV']
|
||||
if ctx['object'].service.slug == "cmpp":
|
||||
ctx['can_rediag'] = ctx['object'].create_diag_healthcare(user)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
{% extends "facturation/base.html" %}
|
||||
{% load url from future %}
|
||||
{% block extrascripts %}
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>{% if service_name == "CMPP" %}Facturation{% else %}Décompte{% endif %}</h2>
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
|
||||
{% block title %}{{ block.super }} - Gestion des personnes {% endblock %}
|
||||
{% block extrascripts %}
|
||||
{{ block.super }}
|
||||
<script src="{{ STATIC_URL }}js/calebasse.absences.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyles %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/personnes.css" />
|
||||
{% endblock %}
|
||||
{{ block.super }}
|
||||
<script src="{{ STATIC_URL }}js/calebasse.absences.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block header %}
|
||||
{{ block.super }}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% extends "personnes/base.html" %}
|
||||
|
||||
{% block extrascripts %}
|
||||
{{ block.super }}
|
||||
<script>
|
||||
$(function() {
|
||||
$('#new-membre').click(function() {
|
||||
|
|
|
@ -168,8 +168,7 @@ class WorkerUpdateView(cbv.ServiceViewMixin, cbv.MultiUpdateView):
|
|||
ctx['timetables'] = timetable
|
||||
ctx['holidays'] = models.Holiday.objects \
|
||||
.for_worker(self.object) \
|
||||
.future() \
|
||||
.order_by('start_date')
|
||||
.order_by('-start_date')
|
||||
try:
|
||||
holiday = models.Holiday.objects \
|
||||
.for_worker(self.object) \
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import itertools
|
||||
|
||||
from calebasse.lookups import CalebasseLookup
|
||||
from calebasse.personnes.models import Worker
|
||||
from calebasse.ressources.models import Service
|
||||
from calebasse.ressources.models import Service, School
|
||||
|
||||
class FakeGroup:
|
||||
pk = None
|
||||
|
@ -56,3 +57,28 @@ class WorkerOrGroupLookup(CalebasseLookup):
|
|||
|
||||
class AllWorkerOrGroupLookup(WorkerOrGroupLookup):
|
||||
enabled = False
|
||||
|
||||
class SchoolLookup(CalebasseLookup):
|
||||
model = School
|
||||
search_field = 'name'
|
||||
|
||||
def get_result(self, obj):
|
||||
return self.format_item_display(obj)
|
||||
|
||||
def format_match(self, obj):
|
||||
return self.format_item_display(obj)
|
||||
|
||||
def format_item_display(self, obj):
|
||||
text = ''
|
||||
if obj.school_type.name != 'Inconnu':
|
||||
text = unicode(obj.school_type) + ' ' + obj.name
|
||||
else:
|
||||
text = obj.name
|
||||
if obj.address:
|
||||
text += " - " + obj.address
|
||||
if obj.private:
|
||||
text += " (Privé)"
|
||||
else:
|
||||
text += " (Public)"
|
||||
return text
|
||||
|
||||
|
|
|
@ -0,0 +1,320 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'ActType.group'
|
||||
db.add_column(u'ressources_acttype', 'group',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'ActType.group'
|
||||
db.delete_column(u'ressources_acttype', 'group')
|
||||
|
||||
|
||||
models = {
|
||||
u'ressources.acttype': {
|
||||
'Meta': {'ordering': "('-display_first', 'name')", 'object_name': 'ActType'},
|
||||
'billable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'display_first': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'group': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'service': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.Service']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.advicegiver': {
|
||||
'Meta': {'object_name': 'AdviceGiver'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.analysemotive': {
|
||||
'Meta': {'object_name': 'AnalyseMotive'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.codecftmea': {
|
||||
'Meta': {'ordering': "['ordering_code']", 'object_name': 'CodeCFTMEA'},
|
||||
'axe': ('django.db.models.fields.IntegerField', [], {'max_length': '1'}),
|
||||
'code': ('django.db.models.fields.IntegerField', [], {}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'ordering_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.familymotive': {
|
||||
'Meta': {'object_name': 'FamilyMotive'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.familysituationtype': {
|
||||
'Meta': {'object_name': 'FamilySituationType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.healthcenter': {
|
||||
'Meta': {'object_name': 'HealthCenter'},
|
||||
'abbreviation': ('django.db.models.fields.CharField', [], {'default': 'True', 'max_length': '8', 'null': 'True'}),
|
||||
'accounting_number': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
|
||||
'address_complement': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
|
||||
'code': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}),
|
||||
'computer_center_code': ('django.db.models.fields.CharField', [], {'default': 'True', 'max_length': '8', 'null': 'True'}),
|
||||
'correspondant': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
|
||||
'dest_organism': ('django.db.models.fields.CharField', [], {'max_length': '8'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
|
||||
'fax': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
|
||||
'hc_invoice': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['ressources.HealthCenter']", 'null': 'True', 'blank': 'True'}),
|
||||
'health_fund': ('django.db.models.fields.CharField', [], {'max_length': '3'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'large_regime': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.LargeRegime']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'phone': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '8'})
|
||||
},
|
||||
u'ressources.holidaytype': {
|
||||
'Meta': {'object_name': 'HolidayType'},
|
||||
'for_group': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.inscriptionmotive': {
|
||||
'Meta': {'object_name': 'InscriptionMotive'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.job': {
|
||||
'Meta': {'object_name': 'Job'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.largeregime': {
|
||||
'Meta': {'object_name': 'LargeRegime'},
|
||||
'code': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.managementcode': {
|
||||
'Meta': {'object_name': 'ManagementCode'},
|
||||
'code': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.maritalstatustype': {
|
||||
'Meta': {'object_name': 'MaritalStatusType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.mdph': {
|
||||
'Meta': {'object_name': 'MDPH'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'address_complement': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
|
||||
'department': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
|
||||
'fax': ('calebasse.models.PhoneNumberField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'phone': ('calebasse.models.PhoneNumberField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'website': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'zip_code': ('calebasse.models.ZipCodeField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.mdphrequest': {
|
||||
'Meta': {'object_name': 'MDPHRequest'},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mdph': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.MDPH']"}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {})
|
||||
},
|
||||
u'ressources.mdphresponse': {
|
||||
'Meta': {'object_name': 'MDPHResponse'},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'end_date': ('django.db.models.fields.DateField', [], {}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mdph': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.MDPH']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'rate': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'type_aide': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '1'})
|
||||
},
|
||||
u'ressources.nationality': {
|
||||
'Meta': {'object_name': 'Nationality'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.office': {
|
||||
'Meta': {'object_name': 'Office'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'address_complement': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
|
||||
'fax': ('calebasse.models.PhoneNumberField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'phone': ('calebasse.models.PhoneNumberField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'zip_code': ('calebasse.models.ZipCodeField', [], {'default': 'None', 'max_length': '5', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.outmotive': {
|
||||
'Meta': {'object_name': 'OutMotive'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.outto': {
|
||||
'Meta': {'object_name': 'OutTo'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.parentalauthoritytype': {
|
||||
'Meta': {'object_name': 'ParentalAuthorityType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.parentalcustodytype': {
|
||||
'Meta': {'object_name': 'ParentalCustodyType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.patientrelatedlink': {
|
||||
'Meta': {'object_name': 'PatientRelatedLink'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_camsp_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_cmpp_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_sessad_dys_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_sessad_ted_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.priceperact': {
|
||||
'Meta': {'object_name': 'PricePerAct'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '5', 'decimal_places': '2'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {})
|
||||
},
|
||||
u'ressources.provenance': {
|
||||
'Meta': {'object_name': 'Provenance'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_service': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.provenanceplace': {
|
||||
'Meta': {'object_name': 'ProvenancePlace'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.ressource': {
|
||||
'Meta': {'object_name': 'Ressource'},
|
||||
'etablissement': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.Office']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.school': {
|
||||
'Meta': {'object_name': 'School'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'address_complement': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
|
||||
'director_name': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '70', 'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'max_length': '75', 'null': 'True', 'blank': 'True'}),
|
||||
'fax': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '30', 'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_service': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'phone': ('calebasse.models.PhoneNumberField', [], {'default': 'None', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'school_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.SchoolType']"}),
|
||||
'zip_code': ('calebasse.models.ZipCodeField', [], {'default': 'None', 'max_length': '5', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.schoollevel': {
|
||||
'Meta': {'object_name': 'SchoolLevel'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_service': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.schoolteacherrole': {
|
||||
'Meta': {'object_name': 'SchoolTeacherRole'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.schooltype': {
|
||||
'Meta': {'object_name': 'SchoolType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'services': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['ressources.Service']", 'symmetrical': 'False'})
|
||||
},
|
||||
u'ressources.service': {
|
||||
'Meta': {'object_name': 'Service'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
|
||||
'fax': ('calebasse.models.PhoneNumberField', [], {'max_length': '20'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'phone': ('calebasse.models.PhoneNumberField', [], {'max_length': '20'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
|
||||
},
|
||||
u'ressources.sessiontype': {
|
||||
'Meta': {'object_name': 'SessionType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.socialisationduration': {
|
||||
'Meta': {'object_name': 'SocialisationDuration'},
|
||||
'comment': ('django.db.models.fields.TextField', [], {'max_length': '3000', 'null': 'True', 'blank': 'True'}),
|
||||
'contact': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.SchoolLevel']", 'null': 'True', 'blank': 'True'}),
|
||||
'redoublement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'school': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ressources.School']", 'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {})
|
||||
},
|
||||
u'ressources.transportcompany': {
|
||||
'Meta': {'object_name': 'TransportCompany'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'address_complement': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
|
||||
'correspondant': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
|
||||
'fax': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '30', 'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
|
||||
'old_camsp_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_cmpp_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_sessad_dys_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'old_sessad_ted_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'phone': ('calebasse.models.PhoneNumberField', [], {'default': 'None', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'zip_code': ('calebasse.models.ZipCodeField', [], {'default': 'None', 'max_length': '5', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'ressources.transporttype': {
|
||||
'Meta': {'object_name': 'TransportType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
u'ressources.uninvoicablecode': {
|
||||
'Meta': {'object_name': 'UninvoicableCode'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
u'ressources.workertype': {
|
||||
'Meta': {'object_name': 'WorkerType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'intervene': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['ressources']
|
|
@ -401,6 +401,7 @@ class ActType(NamedAbstractModel, ServiceLinkedAbstractModel):
|
|||
old_id = models.CharField(max_length=256,
|
||||
verbose_name=u'Ancien ID', blank=True, null=True)
|
||||
display_first = models.BooleanField(default=False, verbose_name=u"Acte principalement utilisé")
|
||||
group = models.BooleanField(default=False, verbose_name=u'De groupe')
|
||||
|
||||
class Meta(NamedAbstractModel.Meta):
|
||||
verbose_name = u'Type d\'actes'
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
{% extends "ressources/list.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% if object_list %}
|
||||
<table id="ressource-list" class="main">
|
||||
<thead>
|
||||
<th class="col-id">Identifiant</th>
|
||||
<th class="col-label">Libellé</th>
|
||||
<th class="col-service">Service</th>
|
||||
<th class="col-action"></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for object in object_list %}
|
||||
<tr id="ressource-{{ object.pk }}" {% if new_id == object.pk %}class="new-object"{% endif %}>
|
||||
<td class="col-id">{{object.pk}}</td>
|
||||
<td class="col-label"><a href="{{ object.pk }}">{{object}}</a></td>
|
||||
<td class="col-service"><span class="box {{object.service.slug}}" title="{{object.service.name}}"></span></td>
|
||||
<td class="col-action"><button class="dialog-button delete-object-button"
|
||||
data-url="{{ object.pk }}/delete/ #form-content">Supprimer</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<script type="text/javascript">$('.new-object').effect('highlight', {}, 3000);</script>
|
||||
{% else %}
|
||||
<div class="big-msg-info">
|
||||
<p>
|
||||
Cliquez sur le bouton « Ajouter » en haut à droite pour ajouter un
|
||||
élément.
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -39,11 +39,15 @@ def homepage(request, service):
|
|||
|
||||
def list_view(request, service, model_name):
|
||||
model = get_ressource_model(model_name)
|
||||
if model_name == 'acttype':
|
||||
template = 'ressources/acttype_list.html'
|
||||
else:
|
||||
template = 'ressources/list.html'
|
||||
if model is None:
|
||||
raise Http404
|
||||
view = ListView.as_view(model=model,
|
||||
queryset=model.objects.select_related(),
|
||||
template_name='ressources/list.html')
|
||||
template_name=template)
|
||||
return view(request, service=service)
|
||||
|
||||
class RessourceCreateView(CreateView):
|
||||
|
|
|
@ -151,6 +151,7 @@ INSTALLED_APPS = (
|
|||
'south',
|
||||
'django.contrib.admin',
|
||||
'ajax_select',
|
||||
'django_select2',
|
||||
#'debug_toolbar',
|
||||
'widget_tweaks',
|
||||
# Uncomment the next line to enable admin documentation:
|
||||
|
@ -235,7 +236,8 @@ AJAX_LOOKUP_CHANNELS = {
|
|||
#'patientrecord' : {'model':'dossiers.PatientRecord', 'search_field':'display_name'}
|
||||
#'coordinators' : {'model':'dossiers.PatientRecord', 'search_field':'display_name'}
|
||||
'patientrecord' : ('calebasse.dossiers.lookups', 'PatientRecordLookup'),
|
||||
'school' : {'model':'ressources.School', 'search_field':'name'},
|
||||
#'school' : {'model':'ressources.School', 'search_field':'name'},
|
||||
'school' : ('calebasse.ressources.lookups', 'SchoolLookup'),
|
||||
'addresses' : ('calebasse.dossiers.lookups', 'PatientAddressLookup'),
|
||||
'worker-or-group' : ('calebasse.ressources.lookups', 'WorkerOrGroupLookup'),
|
||||
'all-worker-or-group' : ('calebasse.ressources.lookups', 'AllWorkerOrGroupLookup'),
|
||||
|
|
|
@ -178,6 +178,10 @@ li.away {
|
|||
background: #ccc;
|
||||
}
|
||||
|
||||
li.overlap {
|
||||
background: #640018;
|
||||
}
|
||||
|
||||
li#time {
|
||||
margin-top: -0.15em;
|
||||
}
|
||||
|
@ -219,4 +223,12 @@ ul.addresses {
|
|||
button.screen-only {
|
||||
margin: 1em 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
h3 .icon-comment {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.worker-agenda {
|
||||
margin-top: 2em;
|
||||
}
|
|
@ -112,3 +112,14 @@ div#tabs-4 div div.buttons {
|
|||
margin-top: .4em;
|
||||
}
|
||||
|
||||
.select2-choices {
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
#id_school_text {
|
||||
min-width: 600px;
|
||||
}
|
||||
|
||||
#ajax-dlg input, ul.ui-autocomplete, .results_on_deck {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ div#content div.worker-agenda h2 {
|
|||
margin-bottom: 1ex;
|
||||
color: black;
|
||||
background: none;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.worker-agenda+.worker-agenda {
|
||||
|
@ -41,11 +40,11 @@ div#content div.worker-agenda h2 {
|
|||
}
|
||||
|
||||
div.worker-agenda table{
|
||||
font-size: 1.25em;
|
||||
font-size: 70%;
|
||||
}
|
||||
|
||||
table#activity{
|
||||
font-size: 95%;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
div.worker-agenda h3 {
|
||||
|
@ -78,3 +77,8 @@ div.summary {
|
|||
div#sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.page-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ div#wrap-large {
|
|||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#agendas span.box {
|
||||
#agendas span.box, #ressource-list span.box {
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
|
@ -472,6 +472,11 @@ span.absent{
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
span.inactive {
|
||||
color: #8B008B;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
td#agendas {
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
|
@ -1187,12 +1192,11 @@ a [class^="icon-"], a [class*=" icon-"] {
|
|||
right: 10px;
|
||||
}
|
||||
|
||||
#id_participants_on_deck {
|
||||
#id_participants_on_deck, #id_patient_on_deck {
|
||||
max-height: 7em;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
ul.messages, ul.ajax_messages {
|
||||
position: absolute;
|
||||
width: 30em;
|
||||
|
|
|
@ -44,14 +44,14 @@ function get_initial_fields(button, base) {
|
|||
function enable_new_appointment(base) {
|
||||
var base = base || 'body';
|
||||
$(base).find('.newrdv').click(function() {
|
||||
event_dialog($(this).data('url') + "?" + get_initial_fields(this, base), 'Nouveau rendez-vous', '850px', 'Ajouter');
|
||||
add_dialog('#ajax-dlg', $(this).data('url') + "?" + get_initial_fields(this, base), 'Nouveau rendez-vous', '880px', 'Ajouter');
|
||||
});
|
||||
}
|
||||
|
||||
function enable_new_event(base) {
|
||||
var base = base || 'body';
|
||||
$(base).find('.newevent').click(function() {
|
||||
event_dialog($(this).data('url') + "?" + get_initial_fields(this, base), 'Nouvel événement', '850px', 'Ajouter');
|
||||
add_dialog('#ajax-dlg', $(this).data('url') + "?" + get_initial_fields(this, base), 'Nouvel événement', '850px', 'Ajouter');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -61,12 +61,13 @@ function enable_events(base) {
|
|||
});
|
||||
$(base).find('.textedit button').on('click', function() {
|
||||
var textarea = $(this).prev();
|
||||
var span = textarea.prev()
|
||||
var btn = $(this)
|
||||
var span = textarea.prev();
|
||||
var btn = $(this);
|
||||
var comment = {description: textarea.val()};
|
||||
var data = JSON.stringify(comment);
|
||||
if ($(this).data('act-id'))
|
||||
{
|
||||
var data = {comment: textarea.val() };
|
||||
var data = JSON.stringify(data);
|
||||
|
||||
$.ajax({
|
||||
url: '/api/v1/act/' + $(this).data("act-id") + '/?format=json&date=' + $(this).data('date'),
|
||||
type: 'PATCH',
|
||||
|
@ -74,21 +75,29 @@ function enable_events(base) {
|
|||
data: data,
|
||||
success: function(data) {
|
||||
btn.attr('disabled', 'disabled');
|
||||
if (comment['description']) {
|
||||
$('h3#' + btn.data("event-id") + ' span.icon-comment').fadeIn();
|
||||
}
|
||||
else {
|
||||
$('h3#' + btn.data("event-id") + ' span.icon-comment').fadeOut();
|
||||
}
|
||||
span.html('Commentaire modifié avec succès');
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = {description: textarea.val() };
|
||||
var data = JSON.stringify(data);
|
||||
$.ajax({
|
||||
url: '/api/v1/event/' + $(this).data("event-id") + '/?format=json&date=' + $(this).data('date'),
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
data: data,
|
||||
success: function(data) {
|
||||
success: function(response) {
|
||||
btn.attr('disabled', 'disabled');
|
||||
if (comment['description'])
|
||||
$('h3#' + btn.data("event-id") + ' span.icon-comment').fadeIn();
|
||||
else
|
||||
$('h3#' + btn.data("event-id") + ' span.icon-comment').fadeOut();
|
||||
span.html('Commentaire modifié avec succès');
|
||||
}
|
||||
});
|
||||
|
@ -264,9 +273,14 @@ function toggle_ressource(ressource) {
|
|||
return $(ressource_target).find('a.tab');
|
||||
}
|
||||
|
||||
function init_datepickers(dialog) {
|
||||
$('.datepicker-date', dialog).datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
$('.datepicker input', dialog).datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
}
|
||||
|
||||
function event_dialog(url, title, width, btn_text) {
|
||||
|
||||
function add_periodic_events(base) {
|
||||
init_datepickers(base);
|
||||
$(base).on('click', '.update-periodic-event', function () {
|
||||
$('.ui-icon-closethick').click();
|
||||
// remove the form from previous hidden layer in order to prevent two
|
||||
|
@ -294,11 +308,7 @@ function event_dialog(url, title, width, btn_text) {
|
|||
}
|
||||
};
|
||||
generic_ajaxform_dialog('/' + service + '/' + app_name + '/' + current_date + '/update-periodic-event/' + id,
|
||||
'Modifier un évènement périodique', '#ajax-dlg', '900px', 'Modifier', null,
|
||||
function (dialog) {
|
||||
$('#ajax-dlg .datepicker-date').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
}, null, delete_button
|
||||
);
|
||||
'Modifier un évènement périodique', '#ajax-dlg', '900px', 'Modifier', null, init_datepickers, null, delete_button);
|
||||
});
|
||||
$(base).on('click', '.update-periodic-rdv', function () {
|
||||
$('.ui-icon-closethick').click();
|
||||
|
@ -323,11 +333,7 @@ function event_dialog(url, title, width, btn_text) {
|
|||
}
|
||||
};
|
||||
generic_ajaxform_dialog('/' + service + '/' + app_name + '/' + current_date + '/update-periodic-rdv/' + id,
|
||||
'Modifier un rendez-vous périodique', '#ajax-dlg', '900px', 'Modifier', null,
|
||||
function (dialog) {
|
||||
$('#ajax-dlg .datepicker-date').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
}, null, delete_button
|
||||
);
|
||||
'Modifier un rendez-vous périodique', '#ajax-dlg', '900px', 'Modifier', null, init_datepickers, null, delete_button);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ function generic_ajaxform_dialog(url, title, id, width, btn_submit_name, redirec
|
|||
height = 'auto';
|
||||
$(id).load(url,
|
||||
function () {
|
||||
$('.datepicker-date').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
$('.datepicker input').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
function onsuccess(response, status, xhr, form) {
|
||||
enable_button($('#submit-btn'));
|
||||
var parse = $(response);
|
||||
|
@ -76,11 +78,33 @@ function generic_ajaxform_dialog(url, title, id, width, btn_submit_name, redirec
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform form(s) to ajax forms
|
||||
* id: jQuery id where you want to replace form by ajaxForm
|
||||
*/
|
||||
function calebasse_ajax_form(id) {
|
||||
function onsuccess(response, status, xhr, form) {
|
||||
if ($('.errorlist', response).length != 0) {
|
||||
$(id).html(response);
|
||||
$('form').ajaxForm({
|
||||
success: onsuccess,
|
||||
});
|
||||
}
|
||||
else {
|
||||
window.location.reload(true);
|
||||
}
|
||||
}
|
||||
$('form').ajaxForm({
|
||||
success: onsuccess,
|
||||
});
|
||||
}
|
||||
|
||||
function add_dialog(on, url, title, width, btn_text) {
|
||||
// function used to add patient schedules, events and acts
|
||||
|
||||
function init_dialog() {
|
||||
$('#rdv .datepicker-date').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
$('.datepicker-date').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
$('.datepicker input').datepicker({dateFormat: 'd/m/yy', showOn: 'button'});
|
||||
$('#id_description').attr('rows', '3');
|
||||
$('#id_description').attr('cols', '30');
|
||||
var deck = $('#id_participants_on_deck');
|
||||
|
|
|
@ -131,6 +131,7 @@ function load_tab2_adm() {
|
|||
'#ajax-dlg', '500px', 'Supprimer');
|
||||
});
|
||||
$('input#id_id-birthdate').datepicker({dateFormat: 'd/m/yy', showOn: 'button' });
|
||||
calebasse_ajax_form('#tabs-2');
|
||||
}
|
||||
|
||||
function load_tab3_addresses() {
|
||||
|
@ -323,6 +324,7 @@ function load_tab7_socialisation() {
|
|||
}
|
||||
|
||||
function load_tab8_medical() {
|
||||
calebasse_ajax_form('#tabs-8');
|
||||
SelectFilter.init("id_mises_1", "Catégorie", 0, "/static/admin/");
|
||||
SelectFilter.init("id_mises_2", "Catégorie", 0, "/static/admin/");
|
||||
SelectFilter.init("id_mises_3", "Catégorie", 0, "/static/admin/");
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
/*!
|
||||
* jQuery Form Plugin
|
||||
* version: 3.18 (28-SEP-2012)
|
||||
* @requires jQuery v1.5 or later
|
||||
*
|
||||
* version: 3.50.0-2014.02.05
|
||||
* Requires jQuery v1.5 or later
|
||||
* Copyright (c) 2013 M. Alsup
|
||||
* Examples and documentation at: http://malsup.com/jquery/form/
|
||||
* Project repository: https://github.com/malsup/form
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://malsup.github.com/mit-license.txt
|
||||
* http://malsup.github.com/gpl-license-v2.txt
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* https://github.com/malsup/form#copyright-and-license
|
||||
*/
|
||||
/*global ActiveXObject alert */
|
||||
;(function($) {
|
||||
/*global ActiveXObject */
|
||||
|
||||
// AMD support
|
||||
(function (factory) {
|
||||
"use strict";
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// using AMD; register as anon module
|
||||
define(['jquery'], factory);
|
||||
} else {
|
||||
// no AMD; invoke directly
|
||||
factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto );
|
||||
}
|
||||
}
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
|
@ -37,7 +49,7 @@
|
|||
target: '#output'
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
|
||||
form does not have to exist when you invoke ajaxForm:
|
||||
|
||||
|
@ -45,7 +57,7 @@
|
|||
delegation: true,
|
||||
target: '#output'
|
||||
});
|
||||
|
||||
|
||||
When using ajaxForm, the ajaxSubmit function will be invoked for you
|
||||
at the appropriate time.
|
||||
*/
|
||||
|
@ -57,6 +69,23 @@ var feature = {};
|
|||
feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
|
||||
feature.formdata = window.FormData !== undefined;
|
||||
|
||||
var hasProp = !!$.fn.prop;
|
||||
|
||||
// attr2 uses prop when it can but checks the return type for
|
||||
// an expected string. this accounts for the case where a form
|
||||
// contains inputs with names like "action" or "method"; in those
|
||||
// cases "prop" returns the element
|
||||
$.fn.attr2 = function() {
|
||||
if ( ! hasProp ) {
|
||||
return this.attr.apply(this, arguments);
|
||||
}
|
||||
var val = this.prop.apply(this, arguments);
|
||||
if ( ( val && val.jquery ) || typeof val === 'string' ) {
|
||||
return val;
|
||||
}
|
||||
return this.attr.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* ajaxSubmit() provides a mechanism for immediately submitting
|
||||
* an HTML form using AJAX.
|
||||
|
@ -69,15 +98,19 @@ $.fn.ajaxSubmit = function(options) {
|
|||
log('ajaxSubmit: skipping submit process - no element selected');
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
var method, action, url, $form = this;
|
||||
|
||||
if (typeof options == 'function') {
|
||||
options = { success: options };
|
||||
}
|
||||
else if ( options === undefined ) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
method = options.type || this.attr2('method');
|
||||
action = options.url || this.attr2('action');
|
||||
|
||||
method = this.attr('method');
|
||||
action = this.attr('action');
|
||||
url = (typeof action === 'string') ? $.trim(action) : '';
|
||||
url = url || window.location.href || '';
|
||||
if (url) {
|
||||
|
@ -88,7 +121,7 @@ $.fn.ajaxSubmit = function(options) {
|
|||
options = $.extend(true, {
|
||||
url: url,
|
||||
success: $.ajaxSettings.success,
|
||||
type: method || 'GET',
|
||||
type: method || $.ajaxSettings.type,
|
||||
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
|
||||
}, options);
|
||||
|
||||
|
@ -111,7 +144,7 @@ $.fn.ajaxSubmit = function(options) {
|
|||
if ( traditional === undefined ) {
|
||||
traditional = $.ajaxSettings.traditional;
|
||||
}
|
||||
|
||||
|
||||
var elements = [];
|
||||
var qx, a = this.formToArray(options.semantic, elements);
|
||||
if (options.data) {
|
||||
|
@ -135,7 +168,7 @@ $.fn.ajaxSubmit = function(options) {
|
|||
var q = $.param(a, traditional);
|
||||
if (qx) {
|
||||
q = ( q ? (q + '&' + qx) : qx );
|
||||
}
|
||||
}
|
||||
if (options.type.toUpperCase() == 'GET') {
|
||||
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
|
||||
options.data = null; // data is null for 'get'
|
||||
|
@ -165,14 +198,34 @@ $.fn.ajaxSubmit = function(options) {
|
|||
}
|
||||
|
||||
options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
|
||||
var context = options.context || this ; // jQuery 1.4+ supports scope context
|
||||
var context = options.context || this ; // jQuery 1.4+ supports scope context
|
||||
for (var i=0, max=callbacks.length; i < max; i++) {
|
||||
callbacks[i].apply(context, [data, status, xhr || $form, $form]);
|
||||
}
|
||||
};
|
||||
|
||||
if (options.error) {
|
||||
var oldError = options.error;
|
||||
options.error = function(xhr, status, error) {
|
||||
var context = options.context || this;
|
||||
oldError.apply(context, [xhr, status, error, $form]);
|
||||
};
|
||||
}
|
||||
|
||||
if (options.complete) {
|
||||
var oldComplete = options.complete;
|
||||
options.complete = function(xhr, status) {
|
||||
var context = options.context || this;
|
||||
oldComplete.apply(context, [xhr, status, $form]);
|
||||
};
|
||||
}
|
||||
|
||||
// are there files to upload?
|
||||
var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
|
||||
|
||||
// [value] (issue #113), also see comment:
|
||||
// https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
|
||||
var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; });
|
||||
|
||||
var hasFileInputs = fileInputs.length > 0;
|
||||
var mp = 'multipart/form-data';
|
||||
var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
|
||||
|
@ -207,8 +260,9 @@ $.fn.ajaxSubmit = function(options) {
|
|||
$form.removeData('jqxhr').data('jqxhr', jqxhr);
|
||||
|
||||
// clear element array
|
||||
for (var k=0; k < elements.length; k++)
|
||||
for (var k=0; k < elements.length; k++) {
|
||||
elements[k] = null;
|
||||
}
|
||||
|
||||
// fire 'notify' event
|
||||
this.trigger('form-submit-notify', [this, options]);
|
||||
|
@ -216,13 +270,16 @@ $.fn.ajaxSubmit = function(options) {
|
|||
|
||||
// utility fn for deep serialization
|
||||
function deepSerialize(extraData){
|
||||
var serialized = $.param(extraData).split('&');
|
||||
var serialized = $.param(extraData, options.traditional).split('&');
|
||||
var len = serialized.length;
|
||||
var result = {};
|
||||
var result = [];
|
||||
var i, part;
|
||||
for (i=0; i < len; i++) {
|
||||
// #252; undo param space replacement
|
||||
serialized[i] = serialized[i].replace(/\+/g,' ');
|
||||
part = serialized[i].split('=');
|
||||
result[decodeURIComponent(part[0])] = decodeURIComponent(part[1]);
|
||||
// #278; use array instead of object storage, favoring array serializations
|
||||
result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -237,9 +294,11 @@ $.fn.ajaxSubmit = function(options) {
|
|||
|
||||
if (options.extraData) {
|
||||
var serializedData = deepSerialize(options.extraData);
|
||||
for (var p in serializedData)
|
||||
if (serializedData.hasOwnProperty(p))
|
||||
formdata.append(p, serializedData[p]);
|
||||
for (i=0; i < serializedData.length; i++) {
|
||||
if (serializedData[i]) {
|
||||
formdata.append(serializedData[i][0], serializedData[i][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options.data = null;
|
||||
|
@ -250,13 +309,13 @@ $.fn.ajaxSubmit = function(options) {
|
|||
cache: false,
|
||||
type: method || 'POST'
|
||||
});
|
||||
|
||||
|
||||
if (options.uploadProgress) {
|
||||
// workaround because jqXHR does not expose upload property
|
||||
s.xhr = function() {
|
||||
var xhr = jQuery.ajaxSettings.xhr();
|
||||
var xhr = $.ajaxSettings.xhr();
|
||||
if (xhr.upload) {
|
||||
xhr.upload.onprogress = function(event) {
|
||||
xhr.upload.addEventListener('progress', function(event) {
|
||||
var percent = 0;
|
||||
var position = event.loaded || event.position; /*event.position is deprecated*/
|
||||
var total = event.total;
|
||||
|
@ -264,18 +323,25 @@ $.fn.ajaxSubmit = function(options) {
|
|||
percent = Math.ceil(position / total * 100);
|
||||
}
|
||||
options.uploadProgress(event, position, total, percent);
|
||||
};
|
||||
}, false);
|
||||
}
|
||||
return xhr;
|
||||
};
|
||||
}
|
||||
|
||||
s.data = null;
|
||||
var beforeSend = s.beforeSend;
|
||||
s.beforeSend = function(xhr, o) {
|
||||
var beforeSend = s.beforeSend;
|
||||
s.beforeSend = function(xhr, o) {
|
||||
//Send FormData() provided by user
|
||||
if (options.formData) {
|
||||
o.data = options.formData;
|
||||
}
|
||||
else {
|
||||
o.data = formdata;
|
||||
if(beforeSend)
|
||||
beforeSend.call(this, xhr, o);
|
||||
}
|
||||
if(beforeSend) {
|
||||
beforeSend.call(this, xhr, o);
|
||||
}
|
||||
};
|
||||
return $.ajax(s);
|
||||
}
|
||||
|
@ -283,25 +349,23 @@ $.fn.ajaxSubmit = function(options) {
|
|||
// private function for handling file uploads (hat tip to YAHOO!)
|
||||
function fileUploadIframe(a) {
|
||||
var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
|
||||
var useProp = !!$.fn.prop;
|
||||
var deferred = $.Deferred();
|
||||
|
||||
if ($(':input[name=submit],:input[id=submit]', form).length) {
|
||||
// if there is an input with a name or id of 'submit' then we won't be
|
||||
// able to invoke the submit fn on the form (at least not x-browser)
|
||||
alert('Error: Form elements must not have name or id of "submit".');
|
||||
deferred.reject();
|
||||
return deferred;
|
||||
}
|
||||
|
||||
// #341
|
||||
deferred.abort = function(status) {
|
||||
xhr.abort(status);
|
||||
};
|
||||
|
||||
if (a) {
|
||||
// ensure that every serialized input is still enabled
|
||||
for (i=0; i < elements.length; i++) {
|
||||
el = $(elements[i]);
|
||||
if ( useProp )
|
||||
if ( hasProp ) {
|
||||
el.prop('disabled', false);
|
||||
else
|
||||
}
|
||||
else {
|
||||
el.removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,11 +374,13 @@ $.fn.ajaxSubmit = function(options) {
|
|||
id = 'jqFormIO' + (new Date().getTime());
|
||||
if (s.iframeTarget) {
|
||||
$io = $(s.iframeTarget);
|
||||
n = $io.attr('name');
|
||||
if (!n)
|
||||
$io.attr('name', id);
|
||||
else
|
||||
n = $io.attr2('name');
|
||||
if (!n) {
|
||||
$io.attr2('name', id);
|
||||
}
|
||||
else {
|
||||
id = n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
|
||||
|
@ -336,20 +402,25 @@ $.fn.ajaxSubmit = function(options) {
|
|||
var e = (status === 'timeout' ? 'timeout' : 'aborted');
|
||||
log('aborting upload... ' + e);
|
||||
this.aborted = 1;
|
||||
// #214
|
||||
if (io.contentWindow.document.execCommand) {
|
||||
try { // #214
|
||||
|
||||
try { // #214, #257
|
||||
if (io.contentWindow.document.execCommand) {
|
||||
io.contentWindow.document.execCommand('Stop');
|
||||
} catch(ignore) {}
|
||||
}
|
||||
}
|
||||
catch(ignore) {}
|
||||
|
||||
$io.attr('src', s.iframeSrc); // abort op in progress
|
||||
xhr.error = e;
|
||||
if (s.error)
|
||||
if (s.error) {
|
||||
s.error.call(s.context, xhr, e, status);
|
||||
if (g)
|
||||
}
|
||||
if (g) {
|
||||
$.event.trigger("ajaxError", [xhr, s, e]);
|
||||
if (s.complete)
|
||||
}
|
||||
if (s.complete) {
|
||||
s.complete.call(s.context, xhr, e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -387,15 +458,44 @@ $.fn.ajaxSubmit = function(options) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var CLIENT_TIMEOUT_ABORT = 1;
|
||||
var SERVER_ABORT = 2;
|
||||
|
||||
|
||||
function getDoc(frame) {
|
||||
var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
|
||||
/* it looks like contentWindow or contentDocument do not
|
||||
* carry the protocol property in ie8, when running under ssl
|
||||
* frame.document is the only valid response document, since
|
||||
* the protocol is know but not on the other two objects. strange?
|
||||
* "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
|
||||
*/
|
||||
|
||||
var doc = null;
|
||||
|
||||
// IE8 cascading access check
|
||||
try {
|
||||
if (frame.contentWindow) {
|
||||
doc = frame.contentWindow.document;
|
||||
}
|
||||
} catch(err) {
|
||||
// IE8 access denied under ssl & missing protocol
|
||||
log('cannot get iframe.contentWindow document: ' + err);
|
||||
}
|
||||
|
||||
if (doc) { // successful getting content
|
||||
return doc;
|
||||
}
|
||||
|
||||
try { // simply checking may throw in ie8 under ssl or mismatched protocol
|
||||
doc = frame.contentDocument ? frame.contentDocument : frame.document;
|
||||
} catch(err) {
|
||||
// last attempt
|
||||
log('cannot get iframe.contentDocument: ' + err);
|
||||
doc = frame.document;
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
// Rails CSRF hack (thanks to Yvan Barthelemy)
|
||||
var csrf_token = $('meta[name=csrf-token]').attr('content');
|
||||
var csrf_param = $('meta[name=csrf-param]').attr('content');
|
||||
|
@ -407,11 +507,14 @@ $.fn.ajaxSubmit = function(options) {
|
|||
// take a breath so that pending repaints get some cpu time before the upload starts
|
||||
function doSubmit() {
|
||||
// make sure form attrs are set
|
||||
var t = $form.attr('target'), a = $form.attr('action');
|
||||
var t = $form.attr2('target'),
|
||||
a = $form.attr2('action'),
|
||||
mp = 'multipart/form-data',
|
||||
et = $form.attr('enctype') || $form.attr('encoding') || mp;
|
||||
|
||||
// update form attrs in IE friendly way
|
||||
form.setAttribute('target',id);
|
||||
if (!method) {
|
||||
if (!method || /post/i.test(method) ) {
|
||||
form.setAttribute('method', 'POST');
|
||||
}
|
||||
if (a != s.url) {
|
||||
|
@ -430,20 +533,22 @@ $.fn.ajaxSubmit = function(options) {
|
|||
if (s.timeout) {
|
||||
timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
|
||||
}
|
||||
|
||||
|
||||
// look for server aborts
|
||||
function checkState() {
|
||||
try {
|
||||
var state = getDoc(io).readyState;
|
||||
log('state = ' + state);
|
||||
if (state && state.toLowerCase() == 'uninitialized')
|
||||
if (state && state.toLowerCase() == 'uninitialized') {
|
||||
setTimeout(checkState,50);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
log('Server abort: ' , e, ' (', e.name, ')');
|
||||
cb(SERVER_ABORT);
|
||||
if (timeoutHandle)
|
||||
if (timeoutHandle) {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
timeoutHandle = undefined;
|
||||
}
|
||||
}
|
||||
|
@ -457,11 +562,11 @@ $.fn.ajaxSubmit = function(options) {
|
|||
// if using the $.param format that allows for multiple values with the same name
|
||||
if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
|
||||
extraInputs.push(
|
||||
$('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
|
||||
$('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
|
||||
.appendTo(form)[0]);
|
||||
} else {
|
||||
extraInputs.push(
|
||||
$('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
|
||||
$('<input type="hidden" name="'+n+'">').val(s.extraData[n])
|
||||
.appendTo(form)[0]);
|
||||
}
|
||||
}
|
||||
|
@ -471,17 +576,27 @@ $.fn.ajaxSubmit = function(options) {
|
|||
if (!s.iframeTarget) {
|
||||
// add iframe to doc and submit the form
|
||||
$io.appendTo('body');
|
||||
if (io.attachEvent)
|
||||
io.attachEvent('onload', cb);
|
||||
else
|
||||
io.addEventListener('load', cb, false);
|
||||
}
|
||||
if (io.attachEvent) {
|
||||
io.attachEvent('onload', cb);
|
||||
}
|
||||
else {
|
||||
io.addEventListener('load', cb, false);
|
||||
}
|
||||
setTimeout(checkState,15);
|
||||
form.submit();
|
||||
|
||||
try {
|
||||
form.submit();
|
||||
} catch(err) {
|
||||
// just in case form has element with name/id of 'submit'
|
||||
var submitFn = document.createElement('form').submit;
|
||||
submitFn.apply(form);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// reset attrs and remove "extra" input elements
|
||||
form.setAttribute('action',a);
|
||||
form.setAttribute('enctype', et); // #380
|
||||
if(t) {
|
||||
form.setAttribute('target', t);
|
||||
} else {
|
||||
|
@ -504,11 +619,10 @@ $.fn.ajaxSubmit = function(options) {
|
|||
if (xhr.aborted || callbackProcessed) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
doc = getDoc(io);
|
||||
}
|
||||
catch(ex) {
|
||||
log('cannot access response document: ', ex);
|
||||
|
||||
doc = getDoc(io);
|
||||
if(!doc) {
|
||||
log('cannot access response document');
|
||||
e = SERVER_ABORT;
|
||||
}
|
||||
if (e === CLIENT_TIMEOUT_ABORT && xhr) {
|
||||
|
@ -524,13 +638,16 @@ $.fn.ajaxSubmit = function(options) {
|
|||
|
||||
if (!doc || doc.location.href == s.iframeSrc) {
|
||||
// response not received yet
|
||||
if (!timedOut)
|
||||
if (!timedOut) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (io.detachEvent)
|
||||
if (io.detachEvent) {
|
||||
io.detachEvent('onload', cb);
|
||||
else
|
||||
}
|
||||
else {
|
||||
io.removeEventListener('load', cb, false);
|
||||
}
|
||||
|
||||
var status = 'success', errMsg;
|
||||
try {
|
||||
|
@ -557,11 +674,12 @@ $.fn.ajaxSubmit = function(options) {
|
|||
var docRoot = doc.body ? doc.body : doc.documentElement;
|
||||
xhr.responseText = docRoot ? docRoot.innerHTML : null;
|
||||
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
|
||||
if (isXml)
|
||||
if (isXml) {
|
||||
s.dataType = 'xml';
|
||||
}
|
||||
xhr.getResponseHeader = function(header){
|
||||
var headers = {'content-type': s.dataType};
|
||||
return headers[header];
|
||||
return headers[header.toLowerCase()];
|
||||
};
|
||||
// support for XHR 'status' & 'statusText' emulation :
|
||||
if (docRoot) {
|
||||
|
@ -599,15 +717,15 @@ $.fn.ajaxSubmit = function(options) {
|
|||
try {
|
||||
data = httpData(xhr, dt, s);
|
||||
}
|
||||
catch (e) {
|
||||
catch (err) {
|
||||
status = 'parsererror';
|
||||
xhr.error = errMsg = (e || status);
|
||||
xhr.error = errMsg = (err || status);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
log('error caught: ',e);
|
||||
catch (err) {
|
||||
log('error caught: ',err);
|
||||
status = 'error';
|
||||
xhr.error = errMsg = (e || status);
|
||||
xhr.error = errMsg = (err || status);
|
||||
}
|
||||
|
||||
if (xhr.aborted) {
|
||||
|
@ -621,40 +739,52 @@ $.fn.ajaxSubmit = function(options) {
|
|||
|
||||
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
|
||||
if (status === 'success') {
|
||||
if (s.success)
|
||||
if (s.success) {
|
||||
s.success.call(s.context, data, 'success', xhr);
|
||||
}
|
||||
deferred.resolve(xhr.responseText, 'success', xhr);
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxSuccess", [xhr, s]);
|
||||
}
|
||||
}
|
||||
else if (status) {
|
||||
if (errMsg === undefined)
|
||||
if (errMsg === undefined) {
|
||||
errMsg = xhr.statusText;
|
||||
if (s.error)
|
||||
}
|
||||
if (s.error) {
|
||||
s.error.call(s.context, xhr, status, errMsg);
|
||||
}
|
||||
deferred.reject(xhr, 'error', errMsg);
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxError", [xhr, s, errMsg]);
|
||||
}
|
||||
}
|
||||
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxComplete", [xhr, s]);
|
||||
}
|
||||
|
||||
if (g && ! --$.active) {
|
||||
$.event.trigger("ajaxStop");
|
||||
}
|
||||
|
||||
if (s.complete)
|
||||
if (s.complete) {
|
||||
s.complete.call(s.context, xhr, status);
|
||||
}
|
||||
|
||||
callbackProcessed = true;
|
||||
if (s.timeout)
|
||||
if (s.timeout) {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
|
||||
// clean up
|
||||
setTimeout(function() {
|
||||
if (!s.iframeTarget)
|
||||
if (!s.iframeTarget) {
|
||||
$io.remove();
|
||||
}
|
||||
else { //adding else to clean up existing iframe response.
|
||||
$io.attr('src', s.iframeSrc);
|
||||
}
|
||||
xhr.responseXML = null;
|
||||
}, 100);
|
||||
}
|
||||
|
@ -682,8 +812,9 @@ $.fn.ajaxSubmit = function(options) {
|
|||
data = xml ? xhr.responseXML : xhr.responseText;
|
||||
|
||||
if (xml && data.documentElement.nodeName === 'parsererror') {
|
||||
if ($.error)
|
||||
if ($.error) {
|
||||
$.error('parsererror');
|
||||
}
|
||||
}
|
||||
if (s && s.dataFilter) {
|
||||
data = s.dataFilter(data, type);
|
||||
|
@ -720,7 +851,7 @@ $.fn.ajaxSubmit = function(options) {
|
|||
$.fn.ajaxForm = function(options) {
|
||||
options = options || {};
|
||||
options.delegation = options.delegation && $.isFunction($.fn.on);
|
||||
|
||||
|
||||
// in jQuery 1.3+ we can fix mistakes with the ready state
|
||||
if (!options.delegation && this.length === 0) {
|
||||
var o = { s: this.selector, c: this.context };
|
||||
|
@ -750,23 +881,23 @@ $.fn.ajaxForm = function(options) {
|
|||
.bind('click.form-plugin', options, captureSubmittingElement);
|
||||
};
|
||||
|
||||
// private event handlers
|
||||
// private event handlers
|
||||
function doAjaxSubmit(e) {
|
||||
/*jshint validthis:true */
|
||||
var options = e.data;
|
||||
if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
|
||||
e.preventDefault();
|
||||
$(this).ajaxSubmit(options);
|
||||
$(e.target).ajaxSubmit(options); // #365
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function captureSubmittingElement(e) {
|
||||
/*jshint validthis:true */
|
||||
var target = e.target;
|
||||
var $el = $(target);
|
||||
if (!($el.is(":submit,input:image"))) {
|
||||
if (!($el.is("[type=submit],[type=image]"))) {
|
||||
// is this a child element of the submit el? (ex: a span within a button)
|
||||
var t = $el.closest(':submit');
|
||||
var t = $el.closest('[type=submit]');
|
||||
if (t.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -815,8 +946,23 @@ $.fn.formToArray = function(semantic, elements) {
|
|||
}
|
||||
|
||||
var form = this[0];
|
||||
var formId = this.attr('id');
|
||||
var els = semantic ? form.getElementsByTagName('*') : form.elements;
|
||||
if (!els) {
|
||||
var els2;
|
||||
|
||||
if (els && !/MSIE [678]/.test(navigator.userAgent)) { // #390
|
||||
els = $(els).get(); // convert to standard array
|
||||
}
|
||||
|
||||
// #386; account for inputs outside the form which use the 'form' attribute
|
||||
if ( formId ) {
|
||||
els2 = $(':input[form=' + formId + ']').get();
|
||||
if ( els2.length ) {
|
||||
els = (els || []).concat(els2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!els || !els.length) {
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -824,13 +970,13 @@ $.fn.formToArray = function(semantic, elements) {
|
|||
for(i=0, max=els.length; i < max; i++) {
|
||||
el = els[i];
|
||||
n = el.name;
|
||||
if (!n) {
|
||||
if (!n || el.disabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (semantic && form.clk && el.type == "image") {
|
||||
// handle image inputs on the fly when semantic == true
|
||||
if(!el.disabled && form.clk == el) {
|
||||
if(form.clk == el) {
|
||||
a.push({name: n, value: $(el).val(), type: el.type });
|
||||
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
|
||||
}
|
||||
|
@ -839,15 +985,17 @@ $.fn.formToArray = function(semantic, elements) {
|
|||
|
||||
v = $.fieldValue(el, true);
|
||||
if (v && v.constructor == Array) {
|
||||
if (elements)
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
for(j=0, jmax=v.length; j < jmax; j++) {
|
||||
a.push({name: n, value: v[j]});
|
||||
}
|
||||
}
|
||||
else if (feature.fileapi && el.type == 'file' && !el.disabled) {
|
||||
if (elements)
|
||||
else if (feature.fileapi && el.type == 'file') {
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
var files = el.files;
|
||||
if (files.length) {
|
||||
for (j=0; j < files.length; j++) {
|
||||
|
@ -860,8 +1008,9 @@ $.fn.formToArray = function(semantic, elements) {
|
|||
}
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined') {
|
||||
if (elements)
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
a.push({name: n, value: v, type: el.type, required: el.required});
|
||||
}
|
||||
}
|
||||
|
@ -924,19 +1073,19 @@ $.fn.fieldSerialize = function(successful) {
|
|||
* <input name="C" type="radio" value="C2" />
|
||||
* </fieldset></form>
|
||||
*
|
||||
* var v = $(':text').fieldValue();
|
||||
* var v = $('input[type=text]').fieldValue();
|
||||
* // if no values are entered into the text inputs
|
||||
* v == ['','']
|
||||
* // if values entered into the text inputs are 'foo' and 'bar'
|
||||
* v == ['foo','bar']
|
||||
*
|
||||
* var v = $(':checkbox').fieldValue();
|
||||
* var v = $('input[type=checkbox]').fieldValue();
|
||||
* // if neither checkbox is checked
|
||||
* v === undefined
|
||||
* // if both checkboxes are checked
|
||||
* v == ['B1', 'B2']
|
||||
*
|
||||
* var v = $(':radio').fieldValue();
|
||||
* var v = $('input[type=radio]').fieldValue();
|
||||
* // if neither radio is checked
|
||||
* v === undefined
|
||||
* // if first radio is checked
|
||||
|
@ -957,10 +1106,12 @@ $.fn.fieldValue = function(successful) {
|
|||
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
|
||||
continue;
|
||||
}
|
||||
if (v.constructor == Array)
|
||||
if (v.constructor == Array) {
|
||||
$.merge(val, v);
|
||||
else
|
||||
}
|
||||
else {
|
||||
val.push(v);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
@ -994,7 +1145,7 @@ $.fieldValue = function(el, successful) {
|
|||
if (op.selected) {
|
||||
var v = op.value;
|
||||
if (!v) { // extra pain for IE...
|
||||
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
|
||||
v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
|
||||
}
|
||||
if (one) {
|
||||
return v;
|
||||
|
@ -1037,14 +1188,22 @@ $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
|
|||
else if (tag == 'select') {
|
||||
this.selectedIndex = -1;
|
||||
}
|
||||
else if (t == "file") {
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
$(this).replaceWith($(this).clone(true));
|
||||
} else {
|
||||
$(this).val('');
|
||||
}
|
||||
}
|
||||
else if (includeHidden) {
|
||||
// includeHidden can be the value true, or it can be a selector string
|
||||
// indicating a special test; for example:
|
||||
// $('#myForm').clearForm('.special:hidden')
|
||||
// the above would clean hidden inputs that have the class of 'special'
|
||||
if ( (includeHidden === true && /hidden/.test(t)) ||
|
||||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) )
|
||||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) ) {
|
||||
this.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1103,8 +1262,9 @@ $.fn.ajaxSubmit.debug = false;
|
|||
|
||||
// helper fn for console logging
|
||||
function log() {
|
||||
if (!$.fn.ajaxSubmit.debug)
|
||||
if (!$.fn.ajaxSubmit.debug) {
|
||||
return;
|
||||
}
|
||||
var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(msg);
|
||||
|
@ -1114,4 +1274,5 @@ function log() {
|
|||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
}));
|
||||
|
||||
|
|
|
@ -1213,7 +1213,7 @@ def patients_synthesis(statistic):
|
|||
nb_patients, acts.count())])
|
||||
data_tables.append(data)
|
||||
data = []
|
||||
data.append(['Féminin', 'Masculin'])
|
||||
data.append(['Filles', 'Garçons'])
|
||||
data.append([(patients.filter(gender='2').count(),
|
||||
patients.filter(gender='1').count())])
|
||||
data_tables.append(data)
|
||||
|
@ -1342,16 +1342,17 @@ def patients_synthesis(statistic):
|
|||
data = []
|
||||
data.append(["Code ANAP", "Tranche d'âge (au %s)" \
|
||||
% formats.date_format(statistic.in_end_date, "SHORT_DATE_FORMAT"),
|
||||
"Nombre de dossiers", "%"])
|
||||
"Nombre de dossiers", "%", "Filles", "%", "Garçons", "%"])
|
||||
values = []
|
||||
for i in range(len(lower_bounds)):
|
||||
lower_bound = lower_bounds[i]
|
||||
if i == len(lower_bounds) - 1:
|
||||
values.append([anap_code, "De %d ans et plus" % lower_bound, 0, None])
|
||||
values.append([anap_code, "De %d ans et plus" % lower_bound, 0, 0, 0, 0, 0, 0])
|
||||
else:
|
||||
values.append([anap_code, "De %d à %d ans" % (lower_bound, lower_bounds[i + 1] - 1), 0, None])
|
||||
values.append([anap_code, "De %d à %d ans" % (lower_bound, lower_bounds[i + 1] - 1), 0, 0, 0, 0, 0, 0])
|
||||
anap_code += 1
|
||||
unknown = 0
|
||||
patients_sorted = {}
|
||||
unknowns = [0, 0]
|
||||
for patient in patients:
|
||||
try:
|
||||
age = statistic.in_end_date.date() - patient.birthdate
|
||||
|
@ -1361,12 +1362,29 @@ def patients_synthesis(statistic):
|
|||
i += 1
|
||||
if i == len(lower_bounds) - 1:
|
||||
break
|
||||
values[i][2] += 1
|
||||
patients_sorted.setdefault(i, [0, 0])
|
||||
if patient.gender == 1:
|
||||
patients_sorted[i][0] += 1
|
||||
else:
|
||||
patients_sorted[i][1] += 1
|
||||
except:
|
||||
unknown += 1
|
||||
for value in values:
|
||||
value[3] = "%.2f" % (value[2] / float(len(patients)) * 100)
|
||||
values.append(['', "Non renseignée", unknown, "%.2f" % (unknown / float(len(patients)) * 100)])
|
||||
if patient.gender == 1:
|
||||
unknowns[0] += 1
|
||||
else:
|
||||
unknowns[1] += 1
|
||||
|
||||
for k, v in patients_sorted.items():
|
||||
values[k][2] = v[0] + v[1]
|
||||
values[k][3] = "%.2f" % (values[k][2] / float(len(patients)) * 100)
|
||||
values[k][4] = v[1]
|
||||
values[k][5] = "%.2f" % (v[1] / float(values[k][2]) * 100)
|
||||
values[k][6] = v[0]
|
||||
values[k][7] = "%.2f" % (v[0] / float(values[k][2]) * 100)
|
||||
l_ukn = unknowns[0] + unknowns[1]
|
||||
if l_ukn:
|
||||
values.append(['', "Non renseigné", l_ukn, "%.2f" % (l_ukn / float(len(patients)) * 100),
|
||||
unknowns[1], "%.2f" % (unknowns[1] / float(l_ukn) * 100),
|
||||
unknowns[0], "%.2f" % (unknowns[0] / float(l_ukn) * 100)])
|
||||
data.append(values)
|
||||
data_tables.append(data)
|
||||
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
<script src="{{ STATIC_URL }}js/ajax_select.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/jquery.mousewheel.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.mousewheel.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.dialog.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.tables.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/calebasse.text_input_wrapper.js"></script>
|
||||
<script src="{{ STATIC_URL }}/js/calebasse.checkboxwidget.js"></script>
|
||||
<script src="{{ STATIC_URL }}/js/calebasse.divmenu.js"></script>
|
||||
{% block extrascripts %}
|
||||
<script src="{{ STATIC_URL }}js/calebasse.dialog.js"></script>
|
||||
{% endblock %}
|
||||
{% block extrastyles %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -27,6 +27,7 @@ service_patterns = patterns('',
|
|||
url(r'^personnes/', include('calebasse.personnes.urls')),
|
||||
url(r'^ressources/', include('calebasse.ressources.urls')),
|
||||
url(r'^statistics/', include('calebasse.statistics.urls')),
|
||||
url(r'^select2/', include('django_select2.urls')),
|
||||
)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
--allow-external pyPdf
|
||||
--allow-unverified pyPdf
|
||||
pyPdf
|
||||
Django >= 1.4, < 1.6
|
||||
south > 0.7
|
||||
django-reversion == 1.6.6
|
||||
|
@ -17,4 +18,5 @@ django-localflavor
|
|||
raven >= 3.5.2, < 3.6
|
||||
M2Crypto
|
||||
--allow-external pycairo
|
||||
django_select2 < 4.3
|
||||
#PyGTK doesn't work with pip
|
||||
|
|
Reference in New Issue