diff options
author | Andrea Lepori <aleporia@gmail.com> | 2023-07-24 18:31:02 +0200 |
---|---|---|
committer | Andrea Lepori <aleporia@gmail.com> | 2023-07-24 18:31:03 +0200 |
commit | 0de1f0a309c62a9e6dd9eb48e38b32c552e09c6c (patch) | |
tree | abf8cbe64e242ffd7d29bfc9ae733531cee72891 | |
parent | improve index show multiple peoples (diff) | |
download | scout-subs-0de1f0a309c62a9e6dd9eb48e38b32c552e09c6c.tar.gz scout-subs-0de1f0a309c62a9e6dd9eb48e38b32c552e09c6c.zip |
create new persons and edit
Diffstat (limited to '')
-rw-r--r-- | accounts/templates/accounts/user_edit.html | 592 | ||||
-rw-r--r-- | accounts/urls.py | 1 | ||||
-rw-r--r-- | accounts/views.py | 399 | ||||
-rw-r--r-- | client/templates/client/index.html | 14 | ||||
-rw-r--r-- | templates/registration/base_admin.html | 4 | ||||
-rw-r--r-- | templates/registration/base_client.html | 4 | ||||
-rw-r--r-- | version.txt | 2 |
7 files changed, 1009 insertions, 7 deletions
diff --git a/accounts/templates/accounts/user_edit.html b/accounts/templates/accounts/user_edit.html new file mode 100644 index 0000000..21e3ed8 --- /dev/null +++ b/accounts/templates/accounts/user_edit.html @@ -0,0 +1,592 @@ +{% extends 'registration/base_client.html' %} +{% load static %} + +{% block title %}Modifica persona{% endblock %} + +{% block breadcrumb %} + <a class="breadcrumb hide-on-med-and-down">Persona</a> +{% endblock %} + +{% block content %} +<div class="tap-target {{color}}" data-target="home_btn"> + <div class="tap-target-content"> + <h5 style="color:white">Continua l'attivazione</h5> + <p style="color:white">Usa questo pulsante per tornare alla home e continuare il processo d'attivazione</p> + </div> +</div> + +<form action="{% url 'edit_user' code=ucode %}?saved=true" method="post" id="form1" enctype="multipart/form-data"> +<div id="personal" class="row"> + <div class="col l8 offset-l2 s12"> + <div class="card-panel"> + <div class="row"> + <div class="col 12"> + <input type="hidden" name="action" id="action"> + <input type="hidden" name="delete_vac" id="delete_vac"> + <input type="hidden" name="delete_health" id="delete_health"> + {% csrf_token %} + <div class="row"> + <div class="input-field col l4 s12"> + <input name="first_name" value="{{first_name}}" id="first_name" type="text" {{validation_dic.first_name|safe}} {{midata_disable}}> + <label for="first_name">Nome</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input name="last_name" value="{{last_name}}" id="last_name" type="text" {{validation_dic.last_name|safe}} {{midata_disable}}> + <label for="last_name">Cognome</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input name="birth_date" value="{{birth_date}}" id="birth_date" type="text" {{validation_dic.birth_date|safe}} {{midata_disable}}> + <label for="birth_date">Data di nascita</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + </div> + <div class="row"> + <div class="input-field col l4 s12"> + <select name="branca" disabled> + <option value="" disabled {{branca_default}}>Nessuna</option> + <option value="diga" {{branca_castorini}}>Castorini</option> + <option value="muta" {{branca_lupetti}}>Lupetti</option> + <option value="reparto" {{branca_esploratori}}>Esploratori</option> + <option value="posto" {{branca_pionieri}}>Pionieri</option> + <option value="clan" {{branca_rover}}>Rover</option> + </select> + <label>Branca (campo non modificabile)</label> + </div> + <div class="input-field col l4 s12"> + <input value="{{parent_name}}" name="parent_name" id="parent_name" type="text" {{validation_dic.parent_name|safe}}> + <label for="parent_name">Nome dei genitori</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{avs_number}}" name="avs_number" id="avs_number" type="text" placeholder="756.1234.5678.90" {{validation_dic.avs_number|safe}}> + <label for="avs_number" data-error="wrong">Numero AVS</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{via}}" name="via" id="via" type="text" {{validation_dic.via|safe}} {{midata_disable}}> + <label for="via">Via e numero</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{cap}}" name="cap" id="cap" type="text" {{validation_dic.cap|safe}} {{midata_disable}}> + <label for="cap">CAP</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{country}}" name="country" id="country" type="text" {{validation_dic.country|safe}} {{midata_disable}}> + <label for="country">Comune</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{nationality}}" name="nationality" id="nationality" type="text" {{validation_dic.nationality|safe}}> + <label for="nationality">Nazionalità</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{phone}}" name="phone" id="phone" type="text" {{validation_dic.phone|safe}}> + <label for="phone">Numero di cellulare</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{home_phone}}" name="home_phone" id="home_phone" type="text" {{validation_dic.home_phone|safe}}> + <label for="home_phone">Telefono di casa</label> + </div> + <div class="input-field col l8 s12"> + <input value="{{school}}" name="school" id="school" type="text" {{validation_dic.school|safe}}> + <label for="school">Scuola frequentata (o professione)</label> + </div> + <div class="input-field col l4 s12"> + <input value="{{year}}" name="year" id="year" type="text" {{validation_dic.year|safe}}> + <label for="year">Classe scolastica</label> + </div> + </div> + <div class="fixed-action-btn"> + <a class="btn-floating btn-large {{color}}" onclick="send('save')"> + <i class="large material-icons">save</i> + </a> + </div> + </div> + </div> + </div> + </div> +</div> + +<div id="medic" class="row"> + <div class="col l8 offset-l2 s12"> + <div class="card-panel"> + <div class="row"> + <div class="col s12"> + <h6>Persona di contatto in caso di necessità</h6> + </div> + </div> + <div class="row"> + <div class="input-field col l6 s12"> + <input name="emer_name" value="{{emer_name}}" id="emer_name" type="text" {{validation_dic.emer_name|safe}}> + <label for="emer_name">Nome e cognome</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l3 s12"> + <input name="emer_relative" value="{{emer_relative}}" id="emer_relative" type="text" {{validation_dic.emer_relative|safe}}> + <label for="emer_releative">Parentela</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l3 s12"> + <input name="cell_phone" value="{{cell_phone}}" id="cellphone" type="text" {{validation_dic.cell_phone|safe}}> + <label for="cell_phone">Cellulare</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l9 s12"> + <input value="{{address}}" name="address" id="address" type="text" {{validation_dic.address|safe}}> + <label for="address">Indirizzo completo</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l3 s12"> + <input value="{{emer_phone}}" name="emer_phone" id="emer_phone" type="text" {{validation_dic.emer_phone|safe}}> + <label for="emer_phone">Telefono di casa</label> + </div> + </div> + <div class="row"> + <div class="col s12"> + <h6>Assicurazione</h6> + </div> + </div> + <div class="row"> + <div class="input-field col l4 s12"> + <input value="{{health_care}}" name="health_care" id="health_care" type="text" {{validation_dic.health_care|safe}}> + <label for="health_care">Cassa Malati</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{injuries}}" name="injuries" id="injuries" type="text" {{validation_dic.injuries|safe}}> + <label for="injuries">Infortuni</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l4 s12"> + <input value="{{rc}}" name="rc" id="rc" type="text" {{validation_dic.rc|safe}}> + <label for="rc">Responsabilità civile</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + </div> + <div class="row"> + <div class="switch col s12"> + È sostenitore REGA + <label> + No + <input name="rega" type="checkbox" {{rega_check}}> + <span class="lever"></span> + Si + </label> + </div> + </div> + <div class="row"> + <div class="col s12"> + <h6>Medico di famiglia</h6> + </div> + <div class="input-field col l6 s12"> + <input value="{{medic_name}}" name="medic_name" id="medic_name" type="text" {{validation_dic.medic_name|safe}}> + <label for="medic_name">Nome e cognome</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l6 s12"> + <input value="{{medic_phone}}" name="medic_phone" id="medic_phone" type="text" {{validation_dic.medic_phone|safe}}> + <label for="medic_phone">Telefono studio</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + <div class="input-field col l12 s12"> + <input value="{{medic_address}}" name="medic_address" id="medic_address" type="text" {{validation_dic.medic_address|safe}}> + <label for="medic_address">Indirizzo completo</label> + <span class="helper-text" data-error="Campo richiesto"></span> + </div> + </div> + <div class="row"> + <div class="col s12"> + <h6>Scheda medica personale</h6> + </div> + <div class="input-field col s12"> + <input value="{{sickness}}" name="sickness" id="sickness" type="text" data-length="250"> + <label for="sickness">Principali malattie avute</label> + </div> + <div class="input-field col l8 s12"> + <input value="{{vaccine}}" name="vaccine" id="vaccine" type="text" data-length="250"> + <label for="vaccine">Vacinazioni fatte</label> + </div> + <div class="input-field col l4 s12"> + <label for="tetanus_date">Ultima vacinazione contro il tetano</label> + <input value="{{tetanus_date}}" name="tetanus_date" id="tetanus_date" type="text" class="datepicker"> + </div> + <div class="input-field col s12"> + <input value="{{allergy}}" name="allergy" id="allergy" type="text" data-length="250"> + <label for="allergy">Allergie particolari/Intolleraze alimentari</label> + </div> + <div class="switch col s12"> + Deve assumere regolarmente medicamenti + <label> + No + <input name="drugs_bool" type="checkbox" {{drugs_check}}> + <span class="lever"></span> + Si + </label> + </div> + <div class="col s12"> + <div class="card {{color}}"> + <div class="card-content"> + <p style="color:white"><b>In caso dovesse assumere farmaci, avvisare comunque i capi</b></p> + </div> + </div> + </div> + <div class="input-field col s12"> + <input value="{{drugs}}" name="drugs" id="drugs" type="text" data-length="250"> + <label for="drugs">Se sì quali, in che dosi e prescrizioni</label> + </div> + <div class="switch col s12"> + Informazioni particolari sullo stato di salute: (postumi di operazioni, incidenti, malattie, disturbi fisici) + <label> + No + <input name="misc_bool" type="checkbox" {{misc_check}}> + <span class="lever"></span> + Si + </label> + </div> + <div class="input-field col s12"> + <input value="{{misc}}" name="misc" id="misc" type="text" data-length="250"> + <label for="misc">Se sì quali</label> + </div> + </div> + <div class="row"> + <div class="col s12"> + <h6>Allegati</h6> + </div> + <div class="col s12"> + <div class="card"> + <div class="card-content"> + Certificato di vacinazione + <div class="file-field input-field"> + <div class="btn {{color}}"> + <span><i class="material-icons left">file_upload</i>File</span> + <input type="file" name="vac_certificate" id="vac_certificate" multiple> + </div> + <div class="file-path-wrapper"> + <input id="vac_file" value="{{vac_certificate}}" class="file-path" type="text" placeholder="Certificato di vacinazione"> + </div> + </div> + {% if vac_certificate != ''%} + <a class="btn {{color}}" onclick="send('download_vac')"><i class="material-icons left">file_download</i>Download</a> + <a class="btn {{color}}" onclick="delete_vac()"><i class="material-icons left">delete</i><span>Elimina</span></a> + {% endif %} + </div> + </div> + </div> + <div class="col s12"> + <div class="card"> + <div class="card-content"> + Tessera cassa malati + <div class="file-field input-field"> + <div class="btn {{color}}"> + <span><i class="material-icons left">file_upload</i>File</span> + <input type="file" name="health_care_certificate" id="health_care_certificate" multiple> + </div> + <div class="file-path-wrapper"> + <input id="health_care_file" value="{{health_care_certificate}}" class="file-path" type="text" placeholder="Tessera cassa malati"> + </div> + </div> + {% if health_care_certificate != ''%} + <a class="btn {{color}}" onclick="send('download_health')"><i class="material-icons left">file_download</i>Download</a> + <a class="btn {{color}}" onclick="delete_health()"><i class="material-icons left">delete</i><span>Elimina</span></a> + {% endif %} + </div> + </div> + </div> + </div> + <div class="fixed-action-btn"> + <a class="btn-floating btn-large {{color}}" onclick="send('save')"> + <i class="large material-icons">save</i> + </a> + </div> + </div> + </div> +</div> +</form> +{% endblock %} + +{% block script %} +function send(id) { + $('#form1').trigger('reinitialize.areYouSure'); + var form = document.getElementById('form1'); + var action = document.getElementById('action'); + action.setAttribute('value', id); + $(':disabled').each(function(e) { + $(this).removeAttr('disabled'); + }) + form.submit(); +} + +function delete_vac() { + var action = document.getElementById('delete_vac'); + var text = document.getElementById('vac_file'); + action.setAttribute('value', 'vac'); + text.setAttribute('value', ''); +} + +function delete_health() { + var action = document.getElementById('delete_health'); + var text = document.getElementById('health_care_file'); + action.setAttribute('value', 'health'); + text.setAttribute('value', ''); +} + +var elem = $('.tabs') +var options = { + yearRange:100, + format:'dd mmmm yyyy', + i18n: { + months: [ 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' ], + monthsShort: [ 'gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic' ], + weekdays: [ 'domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato' ], + weekdaysShort: [ 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab' ], + weekdaysAbbrev: [ 'D', 'L', 'M', 'M', 'G', 'V', 'S' ], + today: 'Oggi', + clear: 'Cancella', + close: 'Chiudi', + firstDay: 1, + format: 'dddd d mmmm yyyy', + formatSubmit: 'yyyy/mm/dd', + labelMonthNext: 'Mese successivo', + labelMonthPrev: 'Mese precedente', + labelMonthSelect: 'Seleziona un mese', + labelYearSelect: 'Seleziona un anno' + } +} + +$(document).ready(function() { + $('input#sickness, input#vaccine, input#allergy, input#drugs, input#misc').characterCounter(); + $('.datepicker').datepicker(options); + $('select').formSelect(); + $('.tap-target').tapTarget(); + {% for error in errors %} + M.toast({html: '{{ error }}', classes: 'orange'}) + {% endfor %} + {% if ok_message %} + M.toast({html: '{{ ok_message }}', classes: 'green'}) + {% endif %} + {% if home_tooltip %} + $('.tap-target').tapTarget('open'); + {% endif %} + document.getElementById("vac_certificate").onchange = function() { + for (i=0; i < this.files.length; i++) { + if(this.files[i].size > 1048576*10) { + M.toast({html: 'Il file è troppo grande. Grandezza massima 10MB', classes: 'orange'}); + this.value = ""; + break; + } + } + }; + + document.getElementById("health_care_certificate").onchange = function() { + for (i=0; i < this.files.length; i++) { + if(this.files[i].size > 1048576*10) { + M.toast({html: 'Il file è troppo grande. Grandezza massima 10MB', classes: 'orange'}); + this.value = ""; + break; + } + } + }; + +}); + +/*! + * jQuery Plugin: Are-You-Sure (Dirty Form Detection) + * https://github.com/codedance/jquery.AreYouSure/ + * + * Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/ + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Author: chris.dance@papercut.com + * Version: 1.9.0 + * Date: 13th August 2014 + */ +(function($) { + + $.fn.areYouSure = function(options) { + + var settings = $.extend( + { + 'message' : 'You have unsaved changes!', + 'dirtyClass' : 'dirty', + 'change' : null, + 'silent' : false, + 'addRemoveFieldsMarksDirty' : false, + 'fieldEvents' : 'change keyup propertychange input', + 'fieldSelector': ":input:not(input[type=submit]):not(input[type=button])" + }, options); + + var getValue = function($field) { + if ($field.hasClass('ays-ignore') + || $field.hasClass('aysIgnore') + || $field.attr('data-ays-ignore') + || $field.attr('name') === undefined) { + return null; + } + + if ($field.is(':disabled')) { + return 'ays-disabled'; + } + + var val; + var type = $field.attr('type'); + if ($field.is('select')) { + type = 'select'; + } + + switch (type) { + case 'checkbox': + case 'radio': + val = $field.is(':checked'); + break; + case 'select': + val = ''; + $field.find('option').each(function(o) { + var $option = $(this); + if ($option.is(':selected')) { + val += $option.val(); + } + }); + break; + default: + val = $field.val(); + } + + return val; + }; + + var storeOrigValue = function($field) { + $field.data('ays-orig', getValue($field)); + }; + + var checkForm = function(evt) { + + var isFieldDirty = function($field) { + var origValue = $field.data('ays-orig'); + if (undefined === origValue) { + return false; + } + return (getValue($field) != origValue); + }; + + var $form = ($(this).is('form')) + ? $(this) + : $(this).parents('form'); + + // Test on the target first as it's the most likely to be dirty + if (isFieldDirty($(evt.target))) { + setDirtyStatus($form, true); + return; + } + + $fields = $form.find(settings.fieldSelector); + + if (settings.addRemoveFieldsMarksDirty) { + // Check if field count has changed + var origCount = $form.data("ays-orig-field-count"); + if (origCount != $fields.length) { + setDirtyStatus($form, true); + return; + } + } + + // Brute force - check each field + var isDirty = false; + $fields.each(function() { + var $field = $(this); + if (isFieldDirty($field)) { + isDirty = true; + return false; // break + } + }); + + setDirtyStatus($form, isDirty); + }; + + var initForm = function($form) { + var fields = $form.find(settings.fieldSelector); + $(fields).each(function() { storeOrigValue($(this)); }); + $(fields).unbind(settings.fieldEvents, checkForm); + $(fields).bind(settings.fieldEvents, checkForm); + $form.data("ays-orig-field-count", $(fields).length); + setDirtyStatus($form, false); + }; + + var setDirtyStatus = function($form, isDirty) { + var changed = isDirty != $form.hasClass(settings.dirtyClass); + $form.toggleClass(settings.dirtyClass, isDirty); + + // Fire change event if required + if (changed) { + if (settings.change) settings.change.call($form, $form); + + if (isDirty) $form.trigger('dirty.areYouSure', [$form]); + if (!isDirty) $form.trigger('clean.areYouSure', [$form]); + $form.trigger('change.areYouSure', [$form]); + } + }; + + var rescan = function() { + var $form = $(this); + var fields = $form.find(settings.fieldSelector); + $(fields).each(function() { + var $field = $(this); + if (!$field.data('ays-orig')) { + storeOrigValue($field); + $field.bind(settings.fieldEvents, checkForm); + } + }); + // Check for changes while we're here + $form.trigger('checkform.areYouSure'); + }; + + var reinitialize = function() { + initForm($(this)); + } + + if (!settings.silent && !window.aysUnloadSet) { + window.aysUnloadSet = true; + $(window).bind('beforeunload', function() { + $dirtyForms = $("form").filter('.' + settings.dirtyClass); + if ($dirtyForms.length == 0) { + return; + } + // Prevent multiple prompts - seen on Chrome and IE + if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) { + if (window.aysHasPrompted) { + return; + } + window.aysHasPrompted = true; + window.setTimeout(function() {window.aysHasPrompted = false;}, 900); + } + return settings.message; + }); + } + + return this.each(function(elem) { + if (!$(this).is('form')) { + return; + } + var $form = $(this); + + $form.submit(function() { + $form.removeClass(settings.dirtyClass); + }); + $form.bind('reset', function() { setDirtyStatus($form, false); }); + // Add a custom events + $form.bind('rescan.areYouSure', rescan); + $form.bind('reinitialize.areYouSure', reinitialize); + $form.bind('checkform.areYouSure', checkForm); + initForm($form); + }); + }; +})(jQuery); +$('form').areYouSure(); + +{% endblock %}
\ No newline at end of file diff --git a/accounts/urls.py b/accounts/urls.py index b35796b..57a649d 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -6,6 +6,7 @@ urlpatterns = [ path('signup/', views.signup, name='signup'), path('login/', views.CustomLoginView.as_view(), name='login'), path('personal/', views.personal, name='personal'), + path('edit/<int:code>', views.edit, name='edit_user'), path('terms/', views.terms, name='terms'), path('oauth_login/', views.oauth_login, name='oauth_login'), path('auth/', views.auth, name='auth'), diff --git a/accounts/views.py b/accounts/views.py index 8ea48f2..35dca92 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -755,6 +755,405 @@ def personal_wrapper(request, errors): return render(request, 'accounts/index.html', context) +@login_required +def edit(request, code): + errors = [] + context = {} + ok_message = "" + personal_active = "active" + medic_active = "" + settings_active = "" + # additional user information + if (code == 0): + # generate code + while (True): + code = randint(100000, 999999) + if len(UserCode.objects.filter(code=code)) == 0: + break + medic = MedicalData() + medic.save() + userCode = UserCode(user=request.user, code=code, medic=medic) + userCode.save() + + usercode = UserCode.objects.filter(user=request.user, code=code) + + if (len(usercode) == 0): + # code is not authorised for this user + return + + usercode = usercode[0] + + # medical info + medic = usercode.medic + # values for multiple choice box + # TODO remove multiple choice + branca_default = "" + branca_castorini = "" + branca_lupetti = "" + branca_esploratori = "" + branca_pionieri = "" + branca_rover = "" + + # variables for validation + validation_dic = {} + required_fields = ["first_name", "last_name", "parent_name", "via", "cap", "country", "nationality", "phone", "avs_number", "emer_name", "emer_relative", "cell_phone", "address", "health_care", "injuries", "rc", "medic_name", "medic_phone", "medic_address"] + personal_fields = ["first_name", "last_name", "parent_name", "via", "cap", "country", "nationality", "phone", "avs_number"] + medic_fields = ["emer_name", "emer_relative", "cell_phone", "address", "health_care", "injuries", "rc", "medic_name", "medic_phone", "medic_address"] + + if request.method == "POST": + # requested download + if request.POST['action'] == "download_vac": + if medic.vac_certificate != None: + filename = os.path.basename(medic.vac_certificate.name) + filename = filename[filename.find("_")+1:] + if filename.rfind('.') != -1: + filename = filename[:filename.rfind('.')] + filename = filename + ".jpg" + + # encode in JPEG + im = Image.open(medic.vac_certificate.file) + im_io = BytesIO() + im.save(im_io, 'JPEG', quality=90) + im_io.seek(0) + return FileResponse(im_io, as_attachment=True, filename=filename) + + elif request.POST['action'] == "download_health": + if medic.health_care_certificate != None: + filename = os.path.basename(medic.health_care_certificate.name) + filename = filename[filename.find("_")+1:] + if filename.rfind('.') != -1: + filename = filename[:filename.rfind('.')] + filename = filename + ".jpg" + + # encode in JPEG + im = Image.open(medic.health_care_certificate.file) + im_io = BytesIO() + im.save(im_io, 'JPEG', quality=90) + im_io.seek(0) + return FileResponse(im_io, as_attachment=True, filename=filename) + + elif request.POST['action'] == "password": + # get form object + if request.user.has_usable_password(): + form2 = PasswordChangeForm(data=request.POST, user=request.user) + else: + form2 = SetPasswordForm(data=request.POST, user=request.user) + + # if form is valid and terms were accepted save user + if form2.is_valid(): + form2.save() + ok_message = "Password modificata con successo" + personal_active = "" + settings_active = "active" + else: + personal_active = "" + settings_active = "active" + for field in form2.errors.as_data().values(): + for err in field: + if err.code == "password_mismatch": + errors.append("Le due password non sono uguali") + elif err.code == "password_too_similar": + errors.append("La password è troppo simile all'username") + elif err.code == "password_too_short": + errors.append("La password è troppo corta") + elif err.code == "password_too_common": + errors.append("La password è troppo comune") + elif err.code == "password_entirely_numeric": + errors.append("La password deve contenere lettere") + elif err.code == "password_incorrect": + errors.append("La password attuale è incorretta") + + else: + # set all attributes + usercode.first_name = request.POST["first_name"] + usercode.last_name = request.POST["last_name"] + usercode.parent_name = request.POST["parent_name"] + usercode.via = request.POST["via"] + usercode.cap = request.POST["cap"] + usercode.country = request.POST["country"] + usercode.nationality = request.POST["nationality"] + usercode.born_date = dateparser.parse(request.POST["birth_date"]) + usercode.home_phone = request.POST["home_phone"] + usercode.phone = request.POST["phone"] + usercode.school = request.POST["school"] + usercode.avs_number = request.POST["avs_number"] + + if request.POST["year"].isdigit(): + usercode.year = request.POST["year"] + else: + errors.append("L'anno scolastico deve essere un numero") + + usercode.save() + + medic.emer_name = request.POST["emer_name"] + medic.emer_relative = request.POST["emer_relative"] + medic.cell_phone = request.POST["cell_phone"] + medic.address = request.POST["address"] + medic.emer_phone = request.POST["emer_phone"] + medic.health_care = request.POST["health_care"] + medic.injuries = request.POST["injuries"] + medic.rc = request.POST["rc"] + medic.rega = "rega" in request.POST + medic.medic_name = request.POST["medic_name"] + medic.medic_phone = request.POST["medic_phone"] + medic.medic_address = request.POST["medic_address"] + medic.sickness = request.POST["sickness"] + medic.vaccine = request.POST["vaccine"] + medic.tetanus_date = dateparser.parse(request.POST["tetanus_date"]) + medic.allergy = request.POST["allergy"] + medic.drugs_bool = "drugs_bool" in request.POST + medic.drugs = request.POST["drugs"] + medic.misc_bool = "misc_bool" in request.POST + medic.misc = request.POST["misc"] + medic.save() + + missing_fields = False + missing_personal_field = False + + if request.POST["birth_date"] == "" or request.POST["birth_date"] == "01 Gennaio 1970" or request.POST["birth_date"] == "None": + validation_dic["birth_date"] = 'class="datepicker validate invalid" required="" aria-required="true"' + missing_fields = True + missing_personal_field = True + else: + validation_dic["birth_date"] = 'class="datepicker validate" required="" aria-required="true"' + + for i in required_fields: + if request.POST[i] == "": + missing_fields = True + if i in personal_fields: + missing_personal_field = True + validation_dic[i] = 'class="validate invalid" required="" aria-required="true"' + else: + validation_dic[i] = 'class="validate" required="" aria-required="true"' + + if missing_fields: + errors.append("Alcuni campi richiesti non sono stati compilati") + if not missing_personal_field: + personal_active = "" + medic_active = "active" + + # if "branca" in request.POST: + # if request.POST["branca"] != "": + # request.user.groups.clear() + # request.user.groups.add( + # Group.objects.get(name=request.POST["branca"])) + + # check if user uploaded a file + if "vac_certificate" in request.FILES: + files = request.FILES.getlist('vac_certificate') + name = files[0].name + try: + # if multiple files concatenate pictures + im = Image.new("RGB", (0, 0), (255, 255, 255)) + for f in files: + if f.name.endswith(".pdf") or f.name.endswith(".PDF"): + images = convert_from_bytes(f.read()) + for i in images: + dst = Image.new('RGB', (max(im.width, i.width), im.height + i.height), (255, 255, 255)) + dst.paste(im, (0, 0)) + dst.paste(i, (0, im.height)) + im = dst + else: + i = Image.open(f) + dst = Image.new('RGB', (max(im.width, i.width), im.height + i.height), (255, 255, 255)) + dst.paste(im, (0, 0)) + dst.paste(i, (0, im.height)) + im = dst + + im_io = BytesIO() + # resize image if larger than max value + if im.height > 16383: + im = im.resize((round(im.width/im.height*16383), 16383)) + # compress image in WEBP + im.save(im_io, 'WEBP', quality=50, method=4) + medic.vac_certificate.save( + request.user.username+"_"+name, im_io) + medic.save() + except UnidentifiedImageError: + errors.append("Il certificato delle vaccinazioni non è un immagine valida") + except PDFPageCountError: + errors.append("Il certificato delle vaccinazioni non è un pdf valido") + except PDFSyntaxError: + errors.append("Il certificato delle vaccinazioni non è un pdf valido") + except IOError: + errors.append("Il certificato delle vaccinazioni è un immagine troppo grande") + + if "health_care_certificate" in request.FILES: + files = request.FILES.getlist('health_care_certificate') + name = files[0].name + try: + # if multiple files concatenate pictures + im = Image.new("RGB", (0, 0), (255, 255, 255)) + for f in files: + if f.name.endswith(".pdf") or f.name.endswith(".PDF"): + images = convert_from_bytes(f.read()) + for i in images: + dst = Image.new('RGB', (max(im.width, i.width), im.height + i.height), (255, 255, 255)) + dst.paste(im, (0, 0)) + dst.paste(i, (0, im.height)) + im = dst + else: + i = Image.open(f) + dst = Image.new('RGB', (max(im.width, i.width), im.height + i.height), (255, 255, 255)) + dst.paste(im, (0, 0)) + dst.paste(i, (0, im.height)) + im = dst + + im_io = BytesIO() + # resize image if larger than max value + if im.height > 16383: + im = im.resize((round(im.width/im.height*16383), 16383)) + # compress image in WEBP + im.save(im_io, 'WEBP', quality=50, method=4) + medic.health_care_certificate.save( + request.user.username+"_"+name, im_io) + medic.save() + except UnidentifiedImageError: + errors.append("La tessera della cassa malati non è un immagine valida") + except PDFPageCountError: + errors.append("La tessera della cassa malati non è un pdf valido") + except PDFSyntaxError: + errors.append("La tessera della cassa malati non è un pdf valido") + except IOError: + errors.append("La tessera della cassa malati è un immagine troppo grande") + + # user requested file delete + if request.POST["delete_vac"] == 'vac': + medic.vac_certificate = None + medic.save() + + if request.POST["delete_health"] == 'health': + medic.health_care_certificate = None + medic.save() + + # if there wasn't any error redirect to clear POST + if len(errors) == 0: + return HttpResponseRedirect(request.get_full_path()) + + else: + # no post, create empty validation + validation_dic["birth_date"] = 'class="datepicker validate" required="" aria-required="true"' + for i in required_fields: + validation_dic[i] = 'class="validate" required="" aria-required="true"' + + # check if user is in a group and set multiple choice to that + if len(request.user.groups.values_list('name', flat=True)) == 0: + branca_default = "selected" + else: + parent_group = request.user.groups.values_list('name', flat=True)[0] + if parent_group == "diga": + branca_castorini = "selected" + elif parent_group == "muta": + branca_lupetti = "selected" + elif parent_group == "reparto": + branca_esploratori = "selected" + elif parent_group == "posto": + branca_pionieri = "selected" + elif parent_group == "clan": + branca_rover = "selected" + else: + branca_default = "selected" + + # set checkbox status + rega = "" + if medic.rega: + rega = "checked='checked'" + drugs = "" + if medic.drugs_bool: + drugs = "checked='checked'" + misc = "" + if medic.misc_bool: + misc = "checked='checked'" + + # set file name for uploaded files + if (medic.vac_certificate != None): + vac_name = os.path.basename(medic.vac_certificate.name) + vac_name = vac_name[vac_name.find("_")+1:] + else: + vac_name = '' + + if (medic.health_care_certificate != None): + card_name = os.path.basename(medic.health_care_certificate.name) + card_name = card_name[card_name.find("_")+1:] + else: + card_name = '' + + # check if user is connected with midata + midata_user = (usercode.midata_id > 0) + midata_disable = "" + + # get user info from midata + if midata_user: + midata_disable = " readonly disabled" + if not copy_from_midata(request, usercode): + return HttpResponseRedirect(request.get_full_path()) + + usable_password = request.user.has_usable_password() + + # check if user has saved the form + home_tooltip = False + if "saved" in request.GET: + # show tooltip only if user is not approved and there are no errors + home_tooltip = (not request.user.has_perm("client.approved")) and (len(errors) == 0) + + # fill context + context = { + 'ucode': code, + 'validation_dic': validation_dic, + 'first_name': usercode.first_name, + 'last_name': usercode.last_name, + 'parent_name': usercode.parent_name, + 'via': usercode.via, + 'cap': usercode.cap, + 'country': usercode.country, + 'nationality': usercode.nationality, + 'birth_date': usercode.born_date, + 'home_phone': usercode.home_phone, + 'phone': usercode.phone, + 'school': usercode.school, + 'year': usercode.year, + 'avs_number': usercode.avs_number, + 'branca_default': branca_default, + 'branca_castorini': branca_castorini, + 'branca_lupetti': branca_lupetti, + 'branca_esploratori': branca_esploratori, + 'branca_pionieri': branca_pionieri, + 'branca_rover': branca_rover, + 'emer_name': medic.emer_name, + 'emer_relative': medic.emer_relative, + 'cell_phone': medic.cell_phone, + 'address': medic.address, + 'emer_phone': medic.emer_phone, + 'health_care': medic.health_care, + 'injuries': medic.injuries, + 'rc': medic.rc, + 'rega_check': rega, + 'medic_name': medic.medic_name, + 'medic_phone': medic.medic_phone, + 'medic_address': medic.medic_address, + 'sickness': medic.sickness, + 'vaccine': medic.vaccine, + 'tetanus_date': medic.tetanus_date, + 'allergy': medic.allergy, + 'drugs_check': drugs, + 'drugs': medic.drugs, + 'misc_check': misc, + 'misc': medic.misc, + 'health_care_certificate': card_name, + 'vac_certificate': vac_name, + 'errors': errors, + 'ok_message': ok_message, + 'midata_user': midata_user, + 'midata_disable': midata_disable, + 'usable_password': usable_password, + 'personal_active': personal_active, + 'medic_active': medic_active, + 'settings_active': settings_active, + 'midata_enabled': MIDATA_ENABLED, + 'home_tooltip': home_tooltip, + } + + return render(request, 'accounts/user_edit.html', context) # simple terms page, only static html def terms(request): diff --git a/client/templates/client/index.html b/client/templates/client/index.html index 0b0b25c..0350311 100644 --- a/client/templates/client/index.html +++ b/client/templates/client/index.html @@ -36,6 +36,8 @@ <div class="card-content"> <span class="card-title"> {{data.0.first_name}} {{data.0.last_name}} + <a href="{% url "edit_user" code=data.0.code %}" class="btn-flat"><i class="material-icons">edit</i></a> + <a href="" class="btn-flat"><i class="material-icons">delete</i></a> <div style="font-size: 0.5em; line-height: normal;">{{data.0.born_date}}</div> </span> <a id="add" class="btn-floating halfway-fab btn-large {{color}}" href="{% url 'create'%}"><i class="material-icons">add</i></a> @@ -434,18 +436,22 @@ {% endfor %} {% else %} <div class="row"> - <div class="col l4 offset-l4 m8 offset-m2 s12"> + <div class="col s12"> <div class="card"> <div class="card-content"> - <p>Il tuo utente non contiene nessuna persona fisica. Per creare una nuova persona aggiungerla - dal profilo utente. Seleziona il proprio nome in alto a destra e in seguito "Gestione account". - Torna in seguito su questa pagina per creare una nuova iscrizione. + <p>Il tuo utente non contiene nessuna persona fisica. Per creare una nuova persona utilizzare + il pulsante qua sotto. Una volta creata tornare in seguito su questa pagina per creare una nuova iscrizione. </p> </div> </div> </div> </div> {% endif %} +<div class="row"> + <div class="col s12"> + <a href="{% url "edit_user" code=0 %}" class="btn waves-effect waves-light {{color}}">Crea una nuova persona <i class="material-icons right">add</i></a> + </div> +</div> {% endblock %} {% block script %} diff --git a/templates/registration/base_admin.html b/templates/registration/base_admin.html index 9f78b43..1f484e6 100644 --- a/templates/registration/base_admin.html +++ b/templates/registration/base_admin.html @@ -110,7 +110,7 @@ <li class="userswitcher" data-target='userswitcher'><a href="#">{{ user.username }}</a></li> {% endif %} <ul id='userswitcher' class='dropdown-content'> - <li><a href="{% url 'personal' %}"><i class="material-icons">person</i>Gestione account</a></li> + <li><a href="{% url 'personal' %}"><i class="material-icons">person</i>Impostazioni</a></li> {% if user.is_staff or perms.client.staff %} <li><a href="{% url 'server' %}"><i class="material-icons">build</i>Pannello Admin</a></li> {% endif %} @@ -119,6 +119,7 @@ {% endif %} <li><a onclick="switcher_submit('logout')"><i class="material-icons">exit_to_app</i>Logout</a></li> + <!-- <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> @@ -133,6 +134,7 @@ <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> + --> <li><a href="{% url 'about' %}">Informazioni sul prodotto</a></li> </ul> </ul> diff --git a/templates/registration/base_client.html b/templates/registration/base_client.html index ad2fadc..357197a 100644 --- a/templates/registration/base_client.html +++ b/templates/registration/base_client.html @@ -126,7 +126,7 @@ <li class="userswitcher" data-target='userswitcher'><a href="#">{{ user.username }}</a></li> {% endif %} <ul id='userswitcher' class='dropdown-content'> - <li><a href="{% url 'personal' %}"><i class="material-icons">person</i>Gestione account</a></li> + <li><a href="{% url 'personal' %}"><i class="material-icons">person</i>Impostazioni</a></li> {% if user.is_staff or perms.client.staff %} <li><a href="{% url 'server' %}"><i class="material-icons">build</i>Pannello Admin</a></li> {% endif %} @@ -135,6 +135,7 @@ {% endif %} <li><a onclick="switcher_submit('logout')"><i class="material-icons">exit_to_app</i>Logout</a></li> + <!-- <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> @@ -149,6 +150,7 @@ <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li> + --> <li><a href="{% url 'about' %}">Informazioni sul prodotto</a></li> </ul> </ul> diff --git a/version.txt b/version.txt index 5fe012e..b80d385 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ version=0.6 -rev=27 +rev=28 |