commit 3b4bba4a8e0eccf877e5b955bb13ffa2b93bc108
Author: Serghei MIHAI <smihai@entrouvert.com>
Date:   Thu Aug 21 17:03:42 2014 +0200

    dossiers: printing the whole patient record in pdf format
    
    Closes #3109

diff --git a/calebasse/dossiers/templates/dossiers/patientrecord_print.html b/calebasse/dossiers/templates/dossiers/patientrecord_print.html
new file mode 100644
index 00000000..9c3ac5ff
--- /dev/null
+++ b/calebasse/dossiers/templates/dossiers/patientrecord_print.html
@@ -0,0 +1,325 @@
+{% load dossiers %}
+<html>
+  <style type="text/css">
+    @page {
+    size: a4 landscape;
+    @frame {
+    top: 2cm;
+    left: 1cm;
+    width: 27.7cm;
+    background-color:black;
+    height: 18cm;
+    }
+    @frame header_frame {
+    -pdf-frame-content: header_frame;
+    top: 1cm;
+    margin-top: 0;
+    margin-left: 1cm;
+    margin-right: 1cm;
+    height: 1cm;
+    }
+    }
+    body {font-size: 0.4cm;}
+    table {margin-top:5pt;font-weight: normal}
+    td, th {padding: 3pt 4pt; text-align:left; border: 1pt solid #aaaaaa}
+    button {display: none; }
+    li {list-style-type: none;}
+    div.frame h3 {border-bottom: 1pt solid #555; padding: 2pt 3pt}
+    .normal {font-weight: normal}
+    .block h3 {background-color:#cccccc;padding: 2pt 5pt}
+    label {font-weight: bold}
+    .screen-only {display: none}
+
+
+    div.block h2 { background-color: #EFEFEF; padding: 2pt 5pt}
+    table th, table td {background-color:#aaaaaa;font-weight: normal}
+  </style>
+
+  <div id="header_frame">
+    <h1><span class="lastname">{{ object.last_name }}</span> {{ object.first_name }} - Dossier {{ object.id }}</h1>
+  </div>
+
+  <div class="block">
+    <h2>Général</h2>
+    <ul>
+      <li><label>N° dossier papier :</label> {{ object.paper_id|default_if_none:"Non renseigné" }}</li>
+      <li><label>N° dossier informatique :</label> <span class="lightgray">{{ object.id }}</span></li>
+      <li><label>Nom :</label> <span class="lastname">{{ object.last_name }}</span></li>
+      <li><label>Prénom :</label> {{ object.first_name }}</li>
+      <li><label>Genre :</label> {{ object.get_gender_display|default_if_none:"Non renseigné" }}</li>
+      <li><label>Date de naissance :</label> {% if object.birthdate %}{{ object.birthdate|date:"d/m/Y" }} ({{ object.age }}){% else %}Non renseignée{% endif %}</li>
+      <li>
+        {% if nb_place_of_lifes == 1 %}
+        <label>Lieux de vie :</label>
+        {% elif nb_place_of_lifes > 1 %}
+        <label class="highlight">{{ nb_place_of_lifes }} lieux de vie :</label>
+        {% else %}
+        <label class="highlight">Aucun lieu de vie d'indiqué</label>
+        {% endif %}
+        {% if object.contact_comment %}<pre>{{ object.contact_comment }}</pre>{% endif %}
+        {% if object.addresses.all %}
+        <ul>
+          {% for address in object.addresses.all %}
+          {% if address.place_of_life %}<li>{{ address.display_name }}</li>{% endif %}
+          {% endfor %}
+        </ul>
+        {% endif %}
+      </li>
+      <li><label>Date de contact :</label> {{ initial_state.date_selected|date:"d/m/Y" }}</li>
+      <li><label>Date de création :</label> {{ object.created|date:"d/m/Y" }}</li>
+      <li><label>Lieu de socialisation :</label> {{ object.school|default_if_none:"Non renseigné" }}</li>
+      {% include "dossiers/patientrecord_print_coordinators.html" %}
+      <li><label>Commentaire </label><br/>
+        {{ object.comment }}
+      </li>
+      <li><label>Dernier acte :</label>
+        {% if last_rdv %}
+        {% if last_rdv.is_absent %}<span style="font-weight: bold;">{% endif %}
+          {{ last_rdv.start_datetime|date:"d/m/Y" }} -
+          {% for participant in last_rdv.participants %}
+          <span class="lastname">{{ participant.last_name }}</span> -
+          {% endfor %}
+          {{ last_rdv.act_type }}
+          {% else %}
+          Aucun
+          {% endif %}
+          {% if last_rdv.is_absent %} ({{ last_rdv.act_state }})</span>{% endif %}
+      </li>
+      <li><label>Prochain rendez-vous :</label>
+        {% if next_rdv %}
+        {% if next_rdv.is_absent %}<span style="font-weight: bold;">{% endif %}
+          {{ next_rdv.start_datetime|date:"d/m/Y" }} -
+          {% for participant in next_rdv.participants.all %}
+          <span class="lastname">{{ participant.last_name }}</span> -
+          {% endfor %}
+          {{ next_rdv.act_type }}
+          {% else %}
+          Aucun
+          {% endif %}
+          {% if next_rdv.is_absent %} ({{ next_rdv.act.get_state }})</span>{% endif %}
+      </li>
+    </ul>
+    {% if future_state %}
+    <p><strong>État à venir du dossier:</strong>  {{ current_state.status.name.lower }} à partir du {{ current_state.date_selected|date:"d/m/Y" }}</p>
+    {% else %}
+    <p><strong>État courant du dossier:</strong> {{ current_state.status.name.lower }} depuis le {{ current_state.date_selected|date:"d/m/Y" }}</p>
+    {% endif %}
+    {% if object.pause_comment %}<p><label>Commentaire de la pause facturation:</label><br />{{ object.pause_comment }}</p>{% endif %}
+  </div>
+
+  <pdf:nextpage />
+
+  <div class="block">
+    <h2>Fiche administrative</h2>
+    <h3>Inscription</h3>
+    <ul>
+      <li><label>Motif(analyse)</label> {{ object.analysemotive|default_if_none:'' }}</li>
+      <li><label>Motif(famille)</label> {{ object.familymotive|default_if_none:'' }}</li>
+      <li><label>Conseilleur</label> {{ object.provenance|default_if_none:'' }}</li>
+      <li><label>Demandeur</label> {{ object.advicegiver|default_if_none:'' }}</li>
+      <li><label>Lieu de provenance</label> {{ object.provenanceplace|default_if_none:'' }}</li>
+    </ul>
+
+    <h3>Sortie</h3>
+    <ul>
+      <li><label>Motif de sortie</label> {{ object.outmotive|default_if_none:'' }}</li>
+      <li><label>Orientation</label> {{ object.outto|default_if_none:'' }}</li>
+    </ul>
+
+    <h3>Famille</h3>
+    <ul>
+      <li><label>Place dans la fratrie</label> {{ object.sibship_place|default_if_none:'' }}</li>
+      <li><label>Nombre d'enfants dans la fratrie</label> {{ object.nb_children_family|default_if_none:'' }}</li>
+      <li><label>Rang (gémellité)</label> {{ object.twinning_rank|default_if_none:'Aucun' }}</li>
+      <li><label>Autorité parentale</label> {{ object.parental_authority|default_if_none:'' }}</li>
+      <li><label>Situation familiale</label> {{ object.family_situation|default_if_none:'' }}</li>
+      <li><label>Garde parentale</label> {{ object.child_custody|default_if_none:'' }}</li>
+      <li><label>Profession de la mère</label> {{ object.job_mother|default_if_none:'' }}</li>
+      <li><label>Profession du père</label> {{ object.job_father|default_if_none:'' }}</li>
+      <li><label>Régime matrimonial de la mère</label> {{ object.rm_mother|default_if_none:'' }}</li>
+      <li><label>Régime matrimonial du père</label> {{ object.rm_father|default_if_none:'' }}</li>
+      <li><label>Commentaire</label> {{ object.family_comment|default_if_none:'' }}</li>
+    </ul>
+
+    <h3>Transport</h3>
+    <ul>
+      <li><label>Type de transport</label> {{ object.transporttype|default_if_none:'' }}</li>
+      <li><label>Compagnie de transport</label> {{ object.transportcompany|default_if_none:'' }}</li>
+      {% if last_prescription %}<li><label>Dernière prescription le</label> {{ last_prescription.created }}</li>{% endif %}
+    </ul>
+
+    <h3 style="background-color:#cccccc">Suivi du patient</h3>
+    <ul>
+      {% include "dossiers/patientrecord_print_coordinators.html" %}
+      <li><label>Médecin extérieur</label> {{ object.externaldoctor|default_if_none:'' }}</li>
+      <li><label>Intervenant extérieur</label> {{ object.externalintervener|default_if_none:'' }}</li>
+    </ul>
+
+    <h3>Mesures de protection</h3>
+    <ul>
+      {% for protection in object.protectionstate_set.all %}
+      <li>
+        <p>Depuis le {{ protection.start_date }} : {{ protection.status.name }}</p>
+        <ul>
+          {% if protection.end_date %}<li><label>Date de fin</label> : {{ protection.end_date }}</li>{% endif %}
+          {% if protection.comment %}<li><label>Commentaire</label> : {{ protection.comment }}</li>{% endif %}
+        </ul>
+      </li>
+      {% endfor %}
+    </ul>
+  </div>
+
+  <pdf:nextpage />
+
+  <div class="block">
+    <h2>Adresses/contacts</h2>
+    {% if object.policyholder.contact_comment %}
+    <p>
+      <label>Commentaire</label>
+      {{ object.policyholder.contact_comment }}
+    </p>
+    {% endif %}
+    <div>
+      <table>
+        <tr><td><h4 class="icon-user-space">Patient{% if object.policyholder.id == object.id %}<span class="normal">(Assuré)</span>{% endif %}</h4></td><td>{% include "dossiers/patientrecord_tab3_contact.html" with contact=object %}</td></tr>
+        {% for contact in object.contacts.all %}
+        {% if not contact.addresses.all %}
+        <tr><td><h4>{% if contact.gender == 1 %}M.{% elif contact.gender == 2 %}Mme{% endif %}
+              {{ contact.first_name }} <span class="lastname">{{ contact.last_name }}</span>{% if object.policyholder.id == contact.id %}<span class="normal">(Assuré)</span>{% endif %} {% if contact.id == object.id %} (PATIENT){% endif %}</h4></td><td>
+            {% include "dossiers/patientrecord_tab3_contact.html" %}
+        </td></tr>
+        {% endif %}
+        {% endfor %}
+      </table>
+    </div>
+
+    <div>
+      <table>
+        {% for address in addresses %}
+        <tr><td colspan="2">
+            <h3>{{ address }}{% if address.place_of_life %}<span class="normal">(lieu de vie)</span>{% endif %}</h3>
+            {% if address.phone %}<p><label>Téléphone</label> {{ address.phone|phone }}</span></p>{% endif %}
+{% if address.comment %}<p><label>Commentaire :</label>{{ address.comment }}</p>{% endif %}</td></tr>
+{% for contact in address.patientcontact_set.all  %}
+{% if contact.id != object.id %}
+<tr><td>
+    <h4>{% if contact.gender == 1 %}M.{% elif contact.gender == 2 %}Mme{% endif %}{{ contact.first_name }} <span class="lastname">{{ contact.last_name }}</span>{% if object.policyholder.id == contact.id %}<span class="normal">(Assuré)</span>{% endif %}{% if contact.id == object.id %} (PATIENT){% endif %}</h4>
+  </td><td>
+    <div>
+      {% include "dossiers/patientrecord_tab3_contact.html" %}
+    </div>
+</td></tr>
+{% endif %}
+{% endfor %}
+</div>
+</table>
+</div>
+{% endfor %}
+</div>
+
+<pdf:nextpage />
+
+<div class="block">
+  <h2>Prise en charge</h2>
+  {% include "dossiers/patientrecord_tab4_notifs.html" %}
+</div>
+
+<pdf:nextpage />
+
+<div class="block">
+  <h2>Actes passés</h2>
+  {% include "dossiers/patientrecord_tab5_actes_passes.html" %}
+</div>
+
+<pdf:nextpage />
+
+<div class="block">
+  <h2>Prochains rendez-vous</h2>
+  {% include "dossiers/patientrecord_tab6_next_rdv.html" %}
+</div>
+
+<pdf:nextpage />
+
+<div class="block">
+  <h2>Socialisation</h2>
+  {% include "dossiers/patientrecord_tab7_socialisation.html" %}
+</div>
+
+<pdf:nextpage />
+
+<div class="block">
+  <h2>Données à caractère médical</h2>
+    <ul>
+      <li><label>Taille (cm):</label> {{ object.size|default_if_none:'' }}</li>
+      <li><label>Poids (gr):</label> {{ object.weight|default_if_none:'' }}</li>
+      <li><label>Terme en semaines:</label> {{ object.pregnancy_term|default_if_none:'' }}</li>
+      <li><label>Périmètre cranien:</label> {{ object.cranium_perimeter|default_if_none:'' }}</li>
+      <li><label>Périmètre thoracique:</label> {{ object.chest_perimeter|default_if_none:'' }}</li>
+      <li><label>Test d'Apgar (1):</label> {{ object.apgar_score_one|default_if_none:'' }}</li>
+      <li><label>Test d'Apgar (5):</label> {{ object.apgar_score_two|default_if_none:'' }}</li>
+      <li><label>Axe I : catégories cliniques</label>
+        <ul>
+        {% for m in object.mises_1.all %}
+        <li>{{ m }}</li>
+        {% endfor %}
+        </ul>
+      </li>
+
+      <li><label>Axe II : facteurs organiques</label>
+        <ul>
+        {% for m in object.mises_2.all %}
+        <li>{{ m }}</li>
+        {% endfor %}
+        </ul>
+      </li>
+
+      <li><label>Axe III : facteurs environnementaux</label>
+        <ul>
+        {% for m in object.mises_3.all %}
+        <li>{{ m }}</li>
+        {% endfor %}
+        </ul>
+      </li>
+      {% if object.deficiency_intellectual %}
+      <li><label>Déficiences intellectuelles: </label> {{ object.get_deficiency_intellectual_display }}</li>
+      {% endif %}
+      {% if object.deficiency_autism_and_other_ted %}
+      <li><label>Autisme et autres TED:</label> {{ object.get_deficiency_autism_and_other_ted_display }}</li>
+      {% endif %}
+      {% if object.deficiency_mental_disorder %}
+      <li><label>Troubles psychiques:</label> {{ object.get_deficiency_mental_disorder_display }}</li>
+      {% endif %}
+      {% if object.deficiency_learning_disorder %}
+      <li><label>Troubles du langage et des apprentissages:</label> {{ object.get_deficiency_learning_disorder_display }}</li>
+      {% endif %}
+      {% if object.deficiency_auditory %}
+      <li><label>Déficiences auditives:</label> {{ object.get_deficiency_auditory_display }}</li>
+      {% endif %}
+      {% if object.deficiency_visual %}
+      <li><label>Déficiences visuelles:</label> {{ object.get_deficiency_visual_display }}</li>
+      {% endif %}
+      {% if object.deficiency_motor %}
+      <li><label>Déficiences motrices:</label> {{ object.get_deficiency_motor_display }}</li>
+      {% endif %}
+      {% if object.deficiency_metabolic_disorder %}
+      <li><label>Déficiences métaboliques:</label> {{ object.get_deficiency_metabolic_disorder_display }}</li>
+      {% endif %}
+      {% if object.deficiency_brain_damage %}
+      <li><label>Cérébro-lésions:</label> {{ object.get_deficiency_brain_damage_display }}</li>
+      {% endif %}
+      {% if object.deficiency_polyhandicap %}
+      <li><label>Polyhandicap</label></li>
+      {% endif %}
+      {% if object.deficiency_behavioral_disorder %}
+      <li><label>Troubles de la conduite et du comportement:</label> {{ object.get_deficiency_brain_damage_display }}</li>
+      {% endif %}
+      {% if object.deficiency_in_diagnostic %}
+      <li><label>En diagnostic</label></li>
+      {% endif %}
+      {% if object.deficiency_other_disorder %}
+      <li><label>Autres types de déficience:</label> {{ object.get_deficiency_other_disorder_display }}</li>
+      {% endif %}
+    </ul>
+</div>
+
+</html>
diff --git a/calebasse/dossiers/templates/dossiers/patientrecord_print_coordinators.html b/calebasse/dossiers/templates/dossiers/patientrecord_print_coordinators.html
new file mode 100644
index 00000000..3cdf86fb
--- /dev/null
+++ b/calebasse/dossiers/templates/dossiers/patientrecord_print_coordinators.html
@@ -0,0 +1,9 @@
+<li><label>Coordinateurs :</label>
+  {% if object.coordinators.all %}
+  <ul>
+    {% for coordinator in object.coordinators.all %}
+    <li>{{ coordinator.first_name }} <span class="lastname">{{ coordinator.last_name }}</span></li>
+    {% endfor %}
+  </ul>
+  {% else %}Aucun{% endif %}
+</li>
diff --git a/calebasse/dossiers/templates/dossiers/patientrecord_update.html b/calebasse/dossiers/templates/dossiers/patientrecord_update.html
index 71af27a6..fe499a19 100644
--- a/calebasse/dossiers/templates/dossiers/patientrecord_update.html
+++ b/calebasse/dossiers/templates/dossiers/patientrecord_update.html
@@ -19,6 +19,9 @@
 <h2><strong>{% if current_state.status.type == 'CLOS' %}<span class="highlight">{% endif %}<span class="lastname">{{ object.last_name }}</span> {{ object.first_name }}{% if object.paper_id %} - Dossier {{ object.paper_id}}{% endif %}{% if current_state.status.type == 'CLOS' %} clos</span>{% endif %}</strong></h2>
 <span id="ajax-redirect" data-url="{{ object.id }}/view"/>
 <a href="..">Retourner aux dossiers</a>
+<form action="{% url "patientrecord_print" service object.id%}">
+<button class="icon-print">{% trans "Imprimer tout le dossier" %}</button>
+</form>
 {% if 'validator' in role %}{% if object.can_be_deleted %}<button type="button" id="patientrecord-delete">Supprimer</button>{% endif %}{% endif %}
 {% endblock %}
 
diff --git a/calebasse/dossiers/urls.py b/calebasse/dossiers/urls.py
index 0108c576..cbd251ba 100644
--- a/calebasse/dossiers/urls.py
+++ b/calebasse/dossiers/urls.py
@@ -11,6 +11,7 @@ urlpatterns = patterns('calebasse.dossiers.views',
         url(r'^waiting-queue$', 'patientrecord_waiting_queue'),
         url(r'^new$', 'new_patient_record'),
         url(r'^(?P<pk>\d+)/view$', 'patient_record'),
+        url(r'^(?P<pk>\d+)/print$', 'patient_record_print', name='patientrecord_print'),
         url(r'^(?P<pk>\d+)/tab1$', 'tab1_general'),
         url(r'^(?P<pk>\d+)/tab2$', 'tab2_fiche_adm'),
         url(r'^(?P<pk>\d+)/tab3$', 'tab3_addresses'),
diff --git a/calebasse/dossiers/views.py b/calebasse/dossiers/views.py
index ad43c13b..199a093a 100644
--- a/calebasse/dossiers/views.py
+++ b/calebasse/dossiers/views.py
@@ -32,6 +32,7 @@ from calebasse.dossiers.states import STATES_MAPPING, STATES_BTN_MAPPER
 from calebasse.ressources.models import (Service,
     SocialisationDuration, MDPHRequest, MDPHResponse)
 from calebasse.facturation.list_acts import list_acts_for_billing_CMPP_per_patient
+from calebasse.facturation.invoice_header import render_to_pdf_file
 
 from calebasse.decorators import validator_only
 
@@ -262,6 +263,35 @@ class PatientRecordView(cbv.UpdateView):
 
 patient_record = PatientRecordView.as_view()
 
+class PatientRecordPrint(cbv.DetailView):
+    model = PatientRecord
+    content_type = 'application/pdf'
+    template_name = 'dossiers/patientrecord_print.html'
+
+    def get_context_data(self, *args, **kwargs):
+        context = super(PatientRecordPrint, self).get_context_data(*args, **kwargs)
+        for view in (PatientRecordGeneralView, PatientRecordAdmView,
+                     PatientRecordAddrView, PatientRecordNotifsView, PatientRecordOldActs,
+                     PatientRecordNextAppointmentsView, PatientRecordSocialisationView):
+            view_instance = view(request=self.request, object=self.object,
+                                 service=self.service)
+            context.update(view_instance.get_context_data(object=self.object))
+        return context
+
+    def get(self, request, *args, **kwargs):
+        self.object = self.get_object()
+        path = render_to_pdf_file([self.template_name],
+                                  self.get_context_data(object = self.object))
+        content = File(file(path))
+        response = HttpResponse(content, self.content_type)
+        response['Content-Length'] = content.size
+        output = 'dossier_%s.pdf' % self.object.id
+        response['Content-Disposition'] = \
+            'attachment; filename="%s"' % output
+        return response
+
+patient_record_print = PatientRecordPrint.as_view()
+
 class PatientRecordGeneralView(cbv.UpdateView):
     model = PatientRecord
     form_class = forms.GeneralForm
diff --git a/calebasse/static/js/calebasse.dialog.js b/calebasse/static/js/calebasse.dialog.js
index 265bdbdb..149e98e6 100644
--- a/calebasse/static/js/calebasse.dialog.js
+++ b/calebasse/static/js/calebasse.dialog.js
@@ -85,10 +85,11 @@ function generic_ajaxform_dialog(url, title, id, width, btn_submit_name, redirec
  * id: jQuery id where you want to replace form by ajaxForm
 */
 function calebasse_ajax_form(id) {
+  var selector = id + ' form';
   function onsuccess(response, status, xhr, form) {
     if ($('.errorlist', response).length != 0) {
       $(id).parent().html(response);
-      $('form').ajaxForm({
+      $(selector).ajaxForm({
         success: onsuccess,
       });
     }
@@ -96,7 +97,7 @@ function calebasse_ajax_form(id) {
       window.location.reload(true);
     }
   }
-  $('form').ajaxForm({
+  $(selector).ajaxForm({
     success: onsuccess,
   });
 }
