poli_planning/polyclinic_scheduling/apps/schedule/templates/schedule/schedule_new.html

1110 lines
48 KiB
HTML

{% extends 'base.html' %} <!-- Add this for inheritance -->
{% load i18n %}
{% load static %}
{% block title %}
{% if form.status.value == 'draft' %}
{% trans "Resume schedule" %}
{% elif form.json.value %}
{% trans "Clone schedule" %}
{% else %}
{% trans "New schedule" %}
{% endif %}
{% endblock %}
{% block pagetitle %}
{% if form.status.value == 'draft' %}
{% trans "Resume schedule" %}
{% elif form.json.value %}
{% trans "Clone schedule" %}
{% else %}
{% trans "New schedule" %}
{% endif %}
{% endblock %}
{% block content %}
{% if form.status.value == 'draft' %}
<form method="POST" action="" id="new_schedule_form">
{% else %}
<form method="POST" action="{% url 'schedule:new' %}" id="new_schedule_form">
{% endif %}
{% csrf_token %}
{{ form.json }}
{{ form.status }}
<h1>Algemene informatie</h1>
<p>Als een afdeling meerdere wachtkamers heeft, vul dan dit formulier meerdere keren in; een keer voor elke groep van behandelkamers die een wachtkamer delen.</p>
<table>
<tbody>
<tr>
<th>
<label for="id_name">Naam van de afdeling</label>
</th>
</tr>
<tr>
<td>
<input type="text" class="form-control" id="id_name" name="name" aria-describedby="afdelingnaamHelp" required>
<small id="afdelingnaamHelp" class="form-text text-muted">Geef de naam op van de afdeling</small>
</td>
</tr>
<tr>
<th>
<label for="id_email">Emailadres voor de resultaten</label>
</th>
</tr>
<tr>
<td>
<input type="email" class="form-control" id="id_email" name="email" aria-describedby="emailadresHelp" required value={{user.email}}>
<small id="emailadresHelp" class="form-text text-muted">Geef het emailadres op om de uitkomsten te ontvangen</small>
</td>
</tr>
<tr>
<th>
<label for="patienten">Aantal patiënten dat kan wachten in wachtkamer</label>
</th>
</tr>
<tr>
<td>
<input type="number" class="form-control" id="patienten" name="patienten" min="1" max="100" aria-describedby="patientenHelp" required>
<small id="patientenHelp" class="form-text text-muted">Met bewaren 1,5m afstand tussen lopende en zittende patiënten!</small>
</td>
</tr>
</tbody>
</table>
<br />
<hr>
<br />
<h1>Specialisaties binnen de afdeling</h1>
<div class="poliekliniek_specialisatie">
<table>
<tbody>
<tr>
<th>
<label for="specialisatie_0" class="h4">Specialisatie 1</label>
</th>
</tr>
<tr>
<td>
<input type="text" class="form-control" style="font-size: 1.5em" id="specialisatie_0" name="specialisatie_0" aria-describedby="specialisatie_0Help" required>
<small id="specialisatie_0Help" class="form-text text-muted" style="float:right;display:none"><a href="#">Verwijder</a></small>
</td>
</tr>
<tr>
<th>
<label for="specialisatie_afkorting_0">Specialisatie afkorting</label>
</th>
</tr>
<tr>
<td>
<input type="text" class="form-control" maxlength="5" id="specialisatie_afkorting_0" name="specialisatie_afkorting_0" aria-describedby="specialisatie_afkorting_0Help" required>
<small id="specialisatie_0Help" class="form-text text-muted">Geef een afkorting op voor deze specialisatie. Deze gebruiken wij in de figuren van de rapportage.</small>
</td>
</tr>
<tr>
<th>
<label for="specialisatie_aantal_kamers_0">Aantal behandelkamers</label>
</th>
</tr>
<tr>
<td>
<input type="number" class="form-control" min="1" max="100" id="specialisatie_aantal_kamers_0" name="specialisatie_aantal_kamers_0" aria-describedby="specialisatie_aantal_kamers_0Help" required>
<small id="specialisatie_aantal_kamers_0Help" class="form-text text-muted">Aantal behandelkamers dat beschikbaar is per specialisatie</small>
</td>
</tr>
<tr>
<th>
<label for="specialisatie_aantal_artsen_0">Aantal artsen</label>
</th>
</tr>
<tr>
<td>
<input type="number" class="form-control" min="1" max="100" id="specialisatie_aantal_artsen_0" name="specialisatie_aantal_artsen_0" aria-describedby="specialisatie_aantal_artsen_0Help" required>
<small id="specialisatie_aantal_artsen_0Help" class="form-text text-muted">Maximaal aantal artsen dat op enig moment tegelijk aan het werk kan zijn (dit kan niet meer zijn dan het aantal behandelkamers).<br /><strong>Let op</strong>: dit gaat om fulltime artsen, twee 50% parttime artsen moet worden ingevuld als één arts.</small>
<br /><br />
</td>
</tr>
<tr>
<th>
<label>Werktijden <small class="text-danger" style="display:none"> Nog niet volledig</small></label>
</th>
</tr>
<tr>
<td>
<div class="form-group werktijden">
<table>
<tbody>
<tr>
<th>de hele werkdag</th>
<td>
<select class="form-control" id="werkdag_start_afdeling_0" name="werkdag_start_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0600">06:00</option>
<option value="0615">06:15</option>
<option value="0630">06:30</option>
<option value="0645">06:45</option>
<option value="0700">07:00</option>
<option value="0715">07:15</option>
<option value="0730">07:30</option>
<option value="0745">07:45</option>
<option value="0800">08:00</option>
<option value="0815">08:15</option>
<option value="0830">08:30</option>
<option value="0845">08:45</option>
<option value="0900">09:00</option>
<option value="0915">09:15</option>
<option value="0930">09:30</option>
<option value="0945">09:45</option>
<option value="1000">10:00</option>
</select>
</td>
<td>
<select class="form-control" id="werkdag_end_afdeling_0" name="werkdag_end_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="1200">12:00</option>
<option value="1215">12:15</option>
<option value="1230">12:30</option>
<option value="1245">12:45</option>
<option value="1300">13:00</option>
<option value="1315">13:15</option>
<option value="1330">13:30</option>
<option value="1345">13:45</option>
<option value="1400">14:00</option>
<option value="1415">14:15</option>
<option value="1430">14:30</option>
<option value="1445">14:45</option>
<option value="1500">15:00</option>
<option value="1515">15:15</option>
<option value="1530">15:30</option>
<option value="1545">15:45</option>
<option value="1600">16:00</option>
<option value="1615">16:15</option>
<option value="1630">16:30</option>
<option value="1645">16:45</option>
<option value="1700">17:00</option>
<option value="1715">17:15</option>
<option value="1720">17:30</option>
<option value="1745">17:45</option>
<option value="1800">18:00</option>
<option value="1815">18:15</option>
<option value="1830">18:30</option>
<option value="1845">18:45</option>
<option value="1900">19:00</option>
<option value="1915">19:15</option>
<option value="1930">19:30</option>
<option value="1945">19:45</option>
<option value="2000">20:00</option>
</select>
</td>
</tr>
<tr>
<th>ochtendpauze</th>
<td>
<select class="form-control" id="ochtend_pauze_start_afdeling_0" name="ochtend_pauze_start_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="0900">09:00</option>
<option value="0915">09:15</option>
<option value="0930">09:30</option>
<option value="0945">09:45</option>
<option value="1000">10:00</option>
<option value="1015">10:15</option>
<option value="1030">10:30</option>
<option value="1045">10:45</option>
<option value="1100">11:00</option>
</select>
</td>
<td>
<select class="form-control" id="ochtend_pauze_end_afdeling_0" name="ochtend_pauze_end_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="0915">09:15</option>
<option value="0930">09:30</option>
<option value="0945">09:45</option>
<option value="1000">10:00</option>
<option value="1015">10:15</option>
<option value="1030">10:30</option>
<option value="1045">10:45</option>
<option value="1100">11:00</option>
<option value="1115">11:15</option>
<option value="1130">11:30</option>
</select>
</td>
</tr>
<tr>
<th>lunchpauze</th>
<td>
<select class="form-control" id="lunch_pauze_start_afdeling_0" name="lunch_pauze_start_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="1130">11:30</option>
<option value="1145">11:45</option>
<option value="1200">12:00</option>
<option value="1215">12:15</option>
<option value="1230">12:30</option>
<option value="1245">12:45</option>
<option value="1300">13:00</option>
<option value="1315">13:15</option>
<option value="1330">13:30</option>
<option value="1345">13:45</option>
<option value="1400">14:00</option>
</select>
</td>
<td>
<select class="form-control" id="lunch_pauze_end_afdeling_0" name="lunch_pauze_end_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="1200">12:00</option>
<option value="1215">12:15</option>
<option value="1230">12:30</option>
<option value="1245">12:45</option>
<option value="1300">13:00</option>
<option value="1315">13:15</option>
<option value="1330">13:30</option>
<option value="1345">13:45</option>
<option value="1400">14:00</option>
<option value="1415">14:15</option>
<option value="1430">14:30</option>
</select>
</td>
</tr>
<tr>
<th>middagpauze</th>
<td>
<select class="form-control" id="middag_pauze_start_afdeling_0" name="middag_pauze_start_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="1430">14:30</option>
<option value="1445">14:45</option>
<option value="1500">15:00</option>
<option value="1515">15:15</option>
<option value="1530">15:30</option>
<option value="1545">15:45</option>
<option value="1600">16:00</option>
<option value="1615">16:15</option>
<option value="1630">16:30</option>
<option value="1645">16:45</option>
<option value="1700">17:00</option>
<option value="1715">17:15</option>
<option value="1730">17:30</option>
<option value="1745">17:45</option>
<option value="1800">18:00</option>
</select>
</td>
<td>
<select class="form-control" id="middag_pauze_end_afdeling_0" name="middag_pauze_end_afdeling_0" required>
<option value="">Maak een keuze</option>
<option value="0">Geen pauze</option>
<option value="1445">14:45</option>
<option value="1500">15:00</option>
<option value="1515">15:15</option>
<option value="1530">15:30</option>
<option value="1545">15:45</option>
<option value="1600">16:00</option>
<option value="1615">16:15</option>
<option value="1630">16:30</option>
<option value="1645">16:45</option>
<option value="1700">17:00</option>
<option value="1715">17:15</option>
<option value="1730">17:30</option>
<option value="1745">17:45</option>
<option value="1800">18:00</option>
<option value="1815">18:15</option>
<option value="1830">18:30</option>
<option value="1845">18:45</option>
<option value="1900">19:00</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_specialisatie">klik hier om een extra specialisatie toe te voegen</a></div>
<br />
<hr>
<br />
<h1>Behandelingen</h1>
<p>In het model worden slots van 5 minuten gebruikt voor het bepalen van starttijden. etc. Afspraken starten daarmee om bijv. 10.00, 10.05, 10.10.<br />Afspraakduur wordt daarmee ook in veelvouden van 5 minuten gevraagd.</p>
<p>Zowel afspraken waar de patiënt fysiek in het ziekenhuis is, als wel telefoongesprekken worden hier gevraagd. Beide type afspraken kunnen in het raster worden gepland.</p>
<p>Normaal aantal: Geef hier het aantal afspraken op dat van dit type <strong style="text-decoration: underline">per dag</strong> gebruikelijk was, voordat COVID-19 begon.<br />Gewenst als op 30%: Geef hier het aantal afspraken <strong style="text-decoration: underline">per dag</strong> op dat u zou willen hebben als de afdeling maar op 30% van de normale capaciteit zou kunnen draaien.</p>
<table id="tabel_behandelingen">
<thead>
<tr>
<th class="pointer">Naam behandeling</th>
<th class="pointer">Duur (in minuten)</th>
<th class="pointer">Specialisatie</th>
<th class="pointer">Methode</th>
<th class="pointer">Normaal aantal</th>
<th class="pointer">Gewenst als op 30%</th>
</tr>
</thead>
<tbody>
<tr class="behandeling">
<td><input type="text" class="form-control" id="behandeling_0" name="behandeling_0" maxlength="20" required></td>
<td>
<select class="form-control" id="behandeling_duration_0" name="behandeling_duration_0" required>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
<option value="40">40</option>
<option value="45">45</option>
<option value="50">50</option>
<option value="55">55</option>
<option value="60">60</option>
<option value="65">65</option>
<option value="70">70</option>
<option value="75">75</option>
<option value="80">80</option>
<option value="85">85</option>
<option value="90">90</option>
<option value="120">120</option>
<option value="150">150</option>
<option value="180">180</option>
<option value="210">210</option>
<option value="240">240</option>
</select>
</td>
<td>
<select class="form-control specialismes" id="behandeling_specialisme_0" name="behandeling_specialisme_0" required></select>
</td>
<td>
<select class="form-control" id="behandeling_method_0" name="behandeling_method_0" required>
<option value="live">in persoon</option>
<option value="phone">telefonisch</option>
</select>
</td>
<td>
<input type="number" class="form-control behandeling_calc" id="behandeling_100p_0" name="behandeling_100p_0" min="0" max="100" required>
</td>
<td>
<input type="number" class="form-control behandeling_calc" id="behandeling_30p_0" name="behandeling_30p_0" min="0" max="100" required>
<small style="float:right;"><a href="#">Verwijder</a></small>
</td>
</tr>
</tbody>
</table>
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_behandeling">klik hier om een nieuwe behandeling toe te voegen</a></div>
<table>
<tbody>
<tr class="behandeling_calc_summary">
<th>Totaal aantal afspraken</th>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
</tr>
<tr>
<td colspan="3">
<div class="behandeling_calc_remarks"></div>
</td>
</tr>
<tr>
<td colspan="3" class="behandeling_calc_time"></td>
</tr>
</tbody>
</table>
<br />
<hr>
<br />
<table>
<tr>
<td><input type="checkbox" value="1" name="privacy_verklaring" required > </td>
<td>Met het verzenden van dit formulier gaat u akkoord met de <a href="https://www.rug.nl/about-us/organization/rules-and-regulations/algemeen/20180423-algemeen-privacyverklaring-rug.pdf" target="_blank" title="RUG Privacyverklaring">privacyverklaring</a> van de Rijksuniversiteit Groningen.</td>
</tr>
<tr>
<td><input type="checkbox" value="1" name="rug_vrijwaring" required > </td>
<td>De Rijksuniversiteit Groningen (RUG) biedt geen garantie terzake van de juistheid of de bruikbaarheid van het door haar ontwikkelde model en aanverwante documenten. De afnemer/gebruiker vrijwaart de RUG voor aanspraken van derden die jegens RUG mochten worden gedaan naar aanleiding van schades, voortvloeiend uit het gebruik of de toepassing van het model en aanverwante documenten. Alle rechten, waaronder de intellectuele eigendomsrechten, op het model en bijbehorende documenten, blijven te allen tijde voorbehouden aan de RUG.</td>
</tr>
<tr>
<td><input type="checkbox" value="1" name="data_verwerking" required > </td>
<td>De gebruiker geeft de RUG toestemming om de ingevoerde data te verwerken in het kader van wetenschappelijk onderzoek en in het kader van het verbeteren van haar tools. De RUG zal over het onderzoek mogen publiceren, ook in andere vormen dan genoemde eindrapportage. De data kunnen in geanonimiseerde vorm in de publicaties worden opgenomen.</td>
</tr>
</table>
<br />
<hr>
<br />
<button type="submit" id="save_draft" class="btn btn-primary">{% trans "Save as draft" %}</button>
-
<button type="submit" id="save_new" class="btn btn-primary">{% trans "Submit" %}</button>
</form>
<script type="text/javascript">
function addSpecialisatie() {
var clone = jQuery('div.poliekliniek_specialisatie:first').clone()
clone.find('input').val('');
clone.find('option:disabled').removeAttr('disabled');
clone.find('small.text-muted').show();
clone.insertAfter('div.poliekliniek_specialisatie:last');
updateSpecialisaties();
loadRemoveSpecialisatie();
}
function loadRemoveSpecialisatie() {
jQuery('div.poliekliniek_specialisatie small a').off('click').on('click',function(event){
event.preventDefault();
jQuery(this).parentsUntil('.poliekliniek_specialisatie').parent().remove();
updateSpecialisaties();
updateSpecialisatieValues();
calculateBehandelingen();
});
}
function updateSpecialisaties() {
jQuery('div.poliekliniek_specialisatie').each(function(counter,element){
if (counter > 0) {
element = jQuery(element);
var nr = counter; // We are starting with 0 so the amount is the new number
element.find('label').first().text('Specialisatie ' + (nr + 1));
element.find('select,input,label').each(function(index,selectitem){
selectitem = jQuery(selectitem);
if (selectitem.is('label')) {
selectitem.prop('for',selectitem.prop('for').replace(/_\d+$/,'_' + nr));
} else {
//console.log(selectitem,selectitem.prop('name'),selectitem.prop('id') );
selectitem.prop('name',selectitem.prop('name').replace(/_\d+$/,'_' + nr));
selectitem.prop('id',selectitem.prop('id').replace(/_\d+$/,'_' + nr));
if (selectitem.attr('aria-describedby')) {
selectitem.attr('aria-describedby',selectitem.attr('aria-describedby').replace(/_\d+Help$/,'_' + nr + 'Help'));
}
}
});
}
});
jQuery('div.poliekliniek_specialisatie input').off('change').on('change',function(){
updateSpecialisatieValues();
});
jQuery('input[name^="specialisatie_aantal_artsen_"]').off('change keyup').on('change keyup',function(){
calculateBehandelingen();
validate_doctors_vs_rooms();
});
jQuery('input[name^="specialisatie_aantal_kamers_"]').off('change keyup').on('change keyup',function(){
validate_doctors_vs_rooms();
});
jQuery('div.werktijden select').off('change').on('change',function(event){
check_working_hours(jQuery(this).parentsUntil('.werktijden').parent());
calculateBehandelingen();
});
}
function updateSpecialisatieValues() {
var specialismes = [];
jQuery('div.poliekliniek_specialisatie').each(function(){
specialismes.push(jQuery('input:first',this).val());
});
jQuery('select.specialismes').each(function(counter,element){
element = jQuery(element);
let selected_index = element[0].selectedIndex;
element.find('option').remove();
jQuery.each(specialismes,function(index,item) {
element.append(jQuery('<option>').val(item).text(item));
});
if (selected_index > -1) {
element[0].selectedIndex = selected_index;
}
});
}
function addBehandeling() {
var clone = jQuery('tr.behandeling:first').clone()
clone.find('input').val('');
clone.find('selected').val('');
clone.find('small').show();
clone.insertAfter('tr.behandeling:last');
jQuery('tr.behandeling :input').off('change keyup').on('change keyup',function(){
calculateBehandelingen();
});
updateBehandelingen();
loadRemoveBehandeling();
}
function loadRemoveBehandeling() {
jQuery('tr.behandeling small a').off('click').on('click',function(event){
event.preventDefault();
jQuery(this).parentsUntil('.behandeling').parent().remove();
updateBehandelingen();
calculateBehandelingen();
});
}
function updateBehandelingen() {
jQuery('tr.behandeling').each(function(counter,element){
jQuery(element).find('select,input').each(function(index,selectitem){
selectitem = jQuery(selectitem);
selectitem.prop('name',selectitem.prop('name').replace(/_\d+$/,'_' + counter));
selectitem.prop('id',selectitem.prop('id').replace(/_\d+$/,'_' + counter));
});
});
jQuery('tr.behandeling td small').show();
jQuery('tr.behandeling:first td small').hide();
}
function calculateBehandelingen() {
const max_limit = 0.4; // Max 40% van het maximum
let total = 0, percentage = 0;
let error = false;
let show_message = false;
jQuery('tr.behandeling').each(function(counter,row){
row = jQuery(row);
if (row.find('select[name^="behandeling_method_"]').val() == 'live') {
if (!show_message) {
show_message = ( row.find('input[name^="behandeling_"]').val() !== ''
&& row.find('select[name^="behandeling_specialisme_"]').val() !== ''
&& row.find('input[name^="behandeling_100p_"]').val() !== ''
&& row.find('input[name^="behandeling_30p_"]').val() !== '' )
}
total += (row.find('input[name*="_100p_"]').val() != '' ? row.find('input[name*="_100p_"]').val() * 1 : 0);
percentage += (row.find('input[name*="_30p_"]').val() != '' ? row.find('input[name*="_30p_"]').val() * 1 : 0);
}
});
jQuery('tr.behandeling_calc_summary td:nth-child(2)').text(total);
jQuery('tr.behandeling_calc_summary td:nth-child(3)').text(percentage);
let calc_message = '';
let class_message = '';
if (percentage > (total * max_limit)) {
calc_message = 'U heeft ' + Math.ceil(percentage - (total * max_limit)) + ' afspraken teveel geselecteerd voor het 30% scenario';
class_message = 'alert-danger';
error = true;
} else if ((total * max_limit) - percentage >= 1) {
//calc_message = 'U kunt nog '+ Math.floor((total * max_limit - percentage) +' afspraken toevoegen voor het 30% scenario';
//class_message = 'alert-warning';
} else {
calc_message = 'Dit klopt precies';
class_message = 'alert-success';
}
jQuery('div.behandeling_calc_remarks').removeClass('alert-danger alert-warning alert-success').html('');
if (show_message) {
jQuery('div.behandeling_calc_remarks').addClass(class_message).text(calc_message);
}
validate_behandeling_hours();
return !error;
}
function sort_behandelingen(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("tabel_behandelingen");
switching = true;
// Set the sorting direction to ascending:
dir = "asc";
/* Make a loop that will continue until
no switching has been done: */
// Normal sorting is done on text based.
mode = 'text';
if ([1,4,5].indexOf(n) !== -1) {
// but for some colums, we want to use number soring.
mode = 'number';
}
while (switching) {
// Start by saying: no switching is done:
switching = false;
rows = table.rows;
/* Loop through all table rows (except the
first, which contains table headers): */
for (i = 1; i < (rows.length - 1); i++) {
// Start by saying there should be no switching:
shouldSwitch = false;
/* Get the two elements you want to compare,
one from current row and one from the next: */
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/* Check if the two rows should switch place,
based on the direction, asc or desc: */
var value_x = jQuery(x).find('select').length > 0 ? jQuery(x).find('select') : jQuery(x).find('input');
var value_y = jQuery(y).find('select').length > 0 ? jQuery(y).find('select') : jQuery(y).find('input');
if (dir == "asc") {
if (
('text' == mode && value_x.val().toLowerCase() > value_y.val().toLowerCase()) ||
('number' == mode && (value_x.val() * 1) > (value_y.val() * 1))
) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (
('text' == mode && value_x.val().toLowerCase() < value_y.val().toLowerCase()) ||
('number' == mode && (value_x.val() * 1) < (value_y.val() * 1))
) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/* If a switch has been marked, make the switch
and mark that a switch has been done: */
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
// Each time a switch is done, increase this count by 1:
switchcount ++;
} else {
/* If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again. */
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
updateBehandelingen();
}
function validate_doctors_vs_rooms() {
//let behandelingen = {};
jQuery('div.poliekliniek_specialisatie').each(function(index,element){
element = jQuery(element);
let amount_of_doctors = element.find('input[name^="specialisatie_aantal_artsen_"]').val() * 1;
let amount_of_rooms = element.find('input[name^="specialisatie_aantal_kamers_"]').val() * 1;
// Use HTML5 validators from the browser and chage the max value based on the amount of rooms available
element.find('input[name^="specialisatie_aantal_artsen_"]').prop('max',amount_of_rooms);
});
}
function validate_behandeling_hours() {
let behandelingen = {};
jQuery('div.poliekliniek_specialisatie').each(function(index,element){
element = jQuery(element);
let specialisme = element.find('input[name^="specialisatie_"]').val();
behandelingen[specialisme] = {
name : element.find('input[name^="specialisatie_"]').val(),
artsen : element.find('input[name^="specialisatie_aantal_artsen_"]').val() * 1,
max_time : 0,
used_time : 0
};
// Hole working day, first time row
let time_start_value = element.find('select[name^="werkdag_start_afdeling_"]').val() * 1;
let time_end_value = element.find('select[name^="werkdag_end_afdeling_"]').val() * 1;
if ('' != time_start_value && '' != time_end_value && time_start_value > 0 && time_end_value > 0) {
let time_start = new Date()
time_start.setHours(Math.floor(time_start_value / 100));
time_start.setMinutes(time_start_value % 100);
time_start.setSeconds(0);
time_start.setMilliseconds(0);
let time_end = new Date()
time_end.setHours(Math.floor(time_end_value / 100));
time_end.setMinutes(time_end_value % 100);
time_end.setSeconds(0);
time_end.setMilliseconds(0);
behandelingen[specialisme]['max_time'] = ((time_end - time_start) / (1000 * 60));
}
// Morning break. Second row
time_start_value = element.find('select[name^="ochtend_pauze_start_afdeling_"]').val() * 1;
time_end_value = element.find('select[name^="ochtend_pauze_end_afdeling_"]').val() * 1;
if ('' != time_start_value && '' != time_end_value && time_start_value > 0 && time_end_value > 0) {
let time_start = new Date()
time_start.setHours(Math.floor(time_start_value / 100));
time_start.setMinutes(time_start_value % 100);
time_start.setSeconds(0);
time_start.setMilliseconds(0);
let time_end = new Date()
time_end.setHours(Math.floor(time_end_value / 100));
time_end.setMinutes(time_end_value % 100);
time_end.setSeconds(0);
time_end.setMilliseconds(0);
behandelingen[specialisme]['max_time'] -= ((time_end - time_start) / (1000 * 60));
}
time_start_value = element.find('select[name^="lunch_pauze_start_afdeling_"]').val() * 1;
time_end_value = element.find('select[name^="lunch_pauze_end_afdeling_"]').val() * 1;
if ('' != time_start_value && '' != time_end_value && time_start_value > 0 && time_end_value > 0) {
let time_start = new Date()
time_start.setHours(Math.floor(time_start_value / 100));
time_start.setMinutes(time_start_value % 100);
time_start.setSeconds(0);
time_start.setMilliseconds(0);
let time_end = new Date()
time_end.setHours(Math.floor(time_end_value / 100));
time_end.setMinutes(time_end_value % 100);
time_end.setSeconds(0);
time_end.setMilliseconds(0);
//console.log(time_start,time_end);
behandelingen[specialisme]['max_time'] -= ((time_end - time_start) / (1000 * 60));
}
time_start_value = element.find('select[name^="middag_pauze_start_afdeling_"]').val() * 1;
time_end_value = element.find('select[name^="middag_pauze_end_afdeling_"]').val() * 1;
if ('' != time_start_value && '' != time_end_value && time_start_value > 0 && time_end_value > 0) {
let time_start = new Date()
time_start.setHours(Math.floor(time_start_value / 100));
time_start.setMinutes(time_start_value % 100);
time_start.setSeconds(0);
time_start.setMilliseconds(0);
let time_end = new Date()
time_end.setHours(Math.floor(time_end_value / 100));
time_end.setMinutes(time_end_value % 100);
time_end.setSeconds(0);
time_end.setMilliseconds(0);
//console.log(time_start,time_end);
behandelingen[specialisme]['max_time'] -= ((time_end - time_start) / (1000 * 60));
}
});
jQuery('tr.behandeling').each(function(index,element){
element = jQuery(element);
if (element.find('select[name^="behandeling_method_"]').val() == 'live') {
let specialisme = element.find('select[name^="behandeling_specialisme_"]').val();
let duration = element.find('select[name^="behandeling_duration_"]').val();
let amount100 = element.find('input[name^="behandeling_100p_"]').val();
if (specialisme && duration && amount100) {
behandelingen[specialisme]['used_time'] += duration * amount100;
}
}
});
let error = false;
let message = jQuery('td.behandeling_calc_time');
message.html('')
jQuery.each(behandelingen,function(specialisme,obj){
if ('' == specialisme) {
return;
}
if ((obj.artsen * obj.max_time) - obj.used_time < 0) {
error = true;
duration_to_much = (obj.used_time - (obj.artsen * obj.max_time)) * 60 * 1000;
duration_to_much = humanizeDuration(duration_to_much, {language: moment.locale(), delimiter: ' {% trans "and" %} ', units: ['h','m']});
message.append(jQuery('<div>').addClass('alert-danger').html('<strong>' + specialisme + ' </strong>: Te veel behandelingen voor het aantal artsen en werktijd. ' + duration_to_much + ' te veel.'));
} else if ((obj.artsen * obj.max_time) - obj.used_time == 0) {
message.append(jQuery('<div>').addClass('alert-success').html('<strong>' + specialisme + ' </strong>: Perfect! Alle tijd is ingedeeld.'));
} else {
// do not show this message here, as it is hard to predict the maximum available time
// message.append(jQuery('<div>').addClass('alert-warning').html('<strong>' + specialisme + ' </strong>: Uw heeft nog ' + moment.duration((obj.artsen * obj.max_time) - obj.used_time,'minutes').humanize() + ' tijd over voor meer afspraken.'));
}
});
return !error;
}
function validate_working_hours() {
jQuery('div.werktijden').each(function(index,element){
jQuery(element).find('select').removeClass('is-invalid');
check_working_hours(element,true);
jQuery(element).find('select').filter(function(){ let value = jQuery(this).val(); return !(value != null && value != '') }).addClass('is-invalid');
});
return jQuery('small.text-danger:visible').length == 0;
}
function check_working_hours(html, showerror) {
if (Array.isArray(html)) {
html = html[0];
}
html = jQuery(html);
let day_start = html.find('select[name^="werkdag_start_afdeling_"]');
let day_end = html.find('select[name^="werkdag_end_afdeling_"]');
let morning_break_start = html.find('select[name^="ochtend_pauze_start_afdeling_"]');
let morning_break_end = html.find('select[name^="ochtend_pauze_end_afdeling_"]');
let lunch_start = html.find('select[name^="lunch_pauze_start_afdeling_"]');
let lunch_end = html.find('select[name^="lunch_pauze_end_afdeling_"]');
let afternoon_break_start = html.find('select[name^="middag_pauze_start_afdeling_"]');
let afternoon_break_end = html.find('select[name^="middag_pauze_end_afdeling_"]');
morning_break_start.find('option').each(function(index,element){
if ('' !== element.value && element.value > 0) {
// Only allow options that are between the day start and day end.
let time = day_start.val();
let disable = (time && element.value < day_start.val()) || (day_end.val() && element.value >= day_end.val());
if (element.selected && disable) {
morning_break_start.val('');
}
element.disabled = disable;
}
});
morning_break_end.find('option').each(function(index,element){
if ('' !== element.value && element.value >= 0) {
// Only allow options that are between the day start and day end.
// Or when morning_break_start is selected and valid, add period time for end time selections
// When start time is selected, the option 'no break' is not valid (value 0)
let time = ('' != morning_break_start.val() ? morning_break_start.val() : day_start.val());
let disable = false;
// Selected no-break at morning starting time and select no-break here
if (time == 0 && element.value == 0) {
disable = false;
} else if (time == 0) {
disable = element.value != 0;
} else if (element.value == 0) {
disable = '' != morning_break_start.val();
} else {
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
}
if(element.selected && disable) {
morning_break_end.val('');
}
element.disabled = disable;
}
});
if (morning_break_start.val() == '0') {
morning_break_end.val('0');
}
lunch_start.find('option').each(function(index,element){
if ('' !== element.value && element.value > 0) {
// Only allow options that are between the day start and day end.
// Or when morning_break_end is selected and valid, add period time for end time selections
let time = ('' != morning_break_end.val() ? morning_break_end.val() : day_start.val());
let disable = (time && element.value < time) || (day_end.val() && element.value >= day_end.val());
if (element.selected && disable) {
lunch_start.val('');
}
element.disabled = disable;
}
});
lunch_end.find('option').each(function(index,element){
if ('' !== element.value && element.value >= 0) {
// Only allow options that are between the day start and day end.
// Or when lunch_start is selected and valid, add period time for end time selections
// When start time is selected, the option 'no break' is not valid (value 0)
let time = ('' != lunch_start.val() ? lunch_start.val() : day_start.val()) * 1;
let disable = false;
if (time == 0 && element.value == 0) {
disable = false;
} else if (time == 0) {
disable = element.value != 0;
} else if (element.value == 0) {
disable = '' != lunch_start.val();
} else {
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
}
if (element.selected && disable) {
lunch_end.val('');
}
element.disabled = disable;
}
});
if (lunch_start.val() == '0') {
lunch_end.val('0');
}
afternoon_break_start.find('option').each(function(index,element){
if ('' !== element.value && element.value > 0) {
// Only allow options that are between the day start and day end.
// Or when lunch_end is selected and valid, add period time for end time selections
let time = ('' != lunch_end.val() ? lunch_end.val() : day_start.val());
let disable = (time && element.value < time) || (day_end.val() && element.value >= day_end.val())
if (element.selected && disable) {
afternoon_break_start.val('');
}
element.disabled = disable;
}
});
afternoon_break_end.find('option').each(function(index,element){
if ('' !== element.value && element.value >= 0) {
// Only allow options that are between the day start and day end.
// Or when morning_break_start is selected and valid, add period time for end time selections
// When start time is selected, the option 'no break' is not valid (value 0)
let time = ('' != afternoon_break_start.val() ? afternoon_break_start.val() : day_start.val());
let disable = false;
if (time == 0 && element.value == 0) {
disable = false;
} else if (time == 0) {
disable = element.value != 0;
} else if (element.value == 0) {
disable = '' != afternoon_break_start.val();
} else {
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
}
if (element.selected && disable) {
afternoon_break_end.val('');
}
element.disabled = disable;
}
});
if (afternoon_break_start.val() == '0') {
afternoon_break_end.val('0');
}
if (showerror) {
html.find('small.text-danger').toggle(day_start.val() == '' || day_start.val() == null ||
day_end.val() == '' || day_end.val() == null ||
morning_break_start.val() == '' || morning_break_start.val() == null ||
morning_break_end.val() == '' || morning_break_end.val() == null ||
lunch_start.val() == '' || lunch_start.val() == null ||
lunch_end.val() == '' || lunch_end.val() == null ||
afternoon_break_start.val() == '' || afternoon_break_start.val() == null ||
afternoon_break_end.val() == '' || afternoon_break_end.val() == null);
}
}
function load_clone_data() {
if (jQuery('input#id_json').val() != '') {
let form = jQuery('form#new_schedule_form');
let json_data = JSON.parse(form.find('input#id_json').val());
jQuery.each(json_data,function(key,value){
let input = form.find(':input[name="' + key + '"]');
if (input.length == 0) {
// check for second or more specilism or treatment
if (key.indexOf('behandeling') >= 0) {
addBehandeling();
} else {
addSpecialisatie();
}
input = form.find(':input[name="' + key + '"]');
}
input.val(value);
updateSpecialisatieValues();
});
validate_working_hours();
calculateBehandelingen();
validate_behandeling_hours();
}
}
jQuery(function() {
jQuery('a.add_specialisatie').on('click',function(event){
event.preventDefault();
addSpecialisatie();
});
jQuery('div.poliekliniek_specialisatie input').off('change').on('change',function(){
updateSpecialisatieValues();
});
jQuery('a.add_behandeling').on('click',function(event){
event.preventDefault();
addBehandeling();
});
jQuery('div.werktijden select').off('change').on('change',function(event){
check_working_hours(jQuery(this).parentsUntil('.werktijden').parent());
calculateBehandelingen();
});
jQuery('table#tabel_behandelingen thead tr th').each(function(index,element){
jQuery(element).on('click',function(){
sort_behandelingen(index);
});
});
jQuery('input[name^="specialisatie_aantal_artsen_"]').off('change keyup').on('change keyup',function(){
calculateBehandelingen();
validate_doctors_vs_rooms();
});
jQuery('input[name^="specialisatie_aantal_kamers_"]').off('change keyup').on('change keyup',function(){
validate_doctors_vs_rooms();
});
jQuery('tr.behandeling :input').off('change keyup').on('change keyup',function(event){
calculateBehandelingen();
});
jQuery('#save_draft').on('click',function(event){
jQuery('input#id_status').val('draft');
});
jQuery('#save_new').on('click',function(event){
jQuery('input#id_status').val('new');
});
jQuery('form#new_schedule_form').on('submit',function(event){
if (validate_working_hours() &&
calculateBehandelingen() &&
validate_behandeling_hours()) {
let formdata = new FormData(this);
formdata.delete('csrfmiddlewaretoken');
formdata.delete('json');
formdata.delete('status');
// Display the key/value pairs. This is needed to support stupid IE. Mici$oft is still having hardtime playing nice :(
let json_data = {};
var formDataEntries = formdata.entries(), formDataEntry = formDataEntries.next(), pair;
while (!formDataEntry.done) {
pair = formDataEntry.value;
json_data[pair[0]] = pair[1];
formDataEntry = formDataEntries.next();
}
jQuery('input#id_json').val(JSON.stringify(json_data));
return true;
} else {
alert('Er zijn wat problemen met het formulier. Controleer de invoer velden');
}
return false;
});
updateBehandelingen();
load_clone_data();
});
</script>
{% endblock %}