diff --git a/smash/web/forms.py b/smash/web/forms.py index 768a5e8fa550c2d30b7e0757e17e6e0b1427638c..c2ba00899b0c070b8114a7895b8f3eb6e95a98d0 100644 --- a/smash/web/forms.py +++ b/smash/web/forms.py @@ -49,6 +49,7 @@ class SubjectAddForm(ModelForm): class Meta: model = Subject fields = '__all__' + exclude = ['dead', 'resigned'] def clean(self): subject = self.cleaned_data @@ -78,10 +79,20 @@ class SubjectEditForm(ModelForm): ) def __init__(self, *args, **kwargs): + was_dead = kwargs.get('was_dead', False) + was_resigned = kwargs.get('was_resigned', False) + if 'was_resigned' in kwargs: + kwargs.pop('was_resigned') + if 'was_dead' in kwargs: + kwargs.pop('was_dead') super(SubjectEditForm, self).__init__(*args, **kwargs) instance = getattr(self, 'instance', None) if instance and instance.id: self.fields['screening_number'].widget.attrs['readonly'] = True + if was_dead: + self.fields['dead'].disabled = True + if was_resigned: + self.fields['resigned'].disabled = True def clean_screening_number(self): instance = getattr(self, 'instance', None) diff --git a/smash/web/models/subject.py b/smash/web/models/subject.py index 2eddd765f1f0f1c2442d52b266cff76a7507a487..45e9082d0a7bdf0a6914861a38403602540ff630 100644 --- a/smash/web/models/subject.py +++ b/smash/web/models/subject.py @@ -25,15 +25,11 @@ class Subject(models.Model): def mark_as_dead(self): self.dead = True - self.save() - self.finish_all_visits() self.finish_all_appointments() - def mark_as_rejected(self): + def mark_as_resigned(self): self.resigned = True - self.save() - self.finish_all_visits() self.finish_all_appointments() @@ -55,16 +51,6 @@ class Subject(models.Model): verbose_name='Type' ) - dead = models.BooleanField( - verbose_name='Dead', - default=False, - editable=False - ) - resigned = models.BooleanField( - verbose_name='Resigned', - default=False, - editable=False - ) default_location = models.ForeignKey(Location, verbose_name='Default appointment location', ) @@ -160,6 +146,17 @@ class Subject(models.Model): verbose_name='Year of diagnosis (YYYY)' ) + dead = models.BooleanField( + verbose_name='Deceased', + default=False, + editable=True + ) + resigned = models.BooleanField( + verbose_name='Resigned', + default=False, + editable=True + ) + def latest_visit(self): visits = self.visit_set.all() if len(visits) == 0: diff --git a/smash/web/static/css/smash.css b/smash/web/static/css/smash.css index ca1d8dc0ecdbdac2987a5d6fb91b2fd4691abfb9..90663bb9f408b41852301da3312b6fe08ba495a6 100644 --- a/smash/web/static/css/smash.css +++ b/smash/web/static/css/smash.css @@ -14,8 +14,6 @@ height: 20px; } -.multi-checkboxes .form-control:not(select) { - -moz-appearance: initial; - -webkit-appearance: initial; - appearance: initial; +.checkbox { + margin-top: 10px !important; } \ No newline at end of file diff --git a/smash/web/templates/subjects/edit.html b/smash/web/templates/subjects/edit.html index 946d63f87abeb9e0e95f7c4c01814cf5e899e99e..1da6a65b6b820ba44e690e9e720cdb19274d71f5 100644 --- a/smash/web/templates/subjects/edit.html +++ b/smash/web/templates/subjects/edit.html @@ -58,24 +58,6 @@ </div> {% endfor %} - <div class="col-md-6"> - {% if not subject.resigned %} - <a href="{% url 'web.views.subject_mark' subject.id 'rejected' %}" - class="btn btn-warning btn-block">Mark as rejected</a> - {% else %} - <label for="{# TODO #}" class="col-sm-4 control-label">REJECTED</label> - <div class="col-sm-8">{{ subject.resigned }}</div> - {% endif %} - </div> - <div class="col-md-6"> - {% if not subject.dead %} - <a href="{% url 'web.views.subject_mark' subject.id 'dead' %}" - class="btn btn-danger btn-block">Mark as dead</a><br/> - {% else %} - <label for="{# TODO #}" class="col-sm-4 control-label">DEAD</label> - <div class="col-sm-8">{{ subject.dead }}</div> - {% endif %} - </div> </div> </div><!-- /.box-body --> @@ -92,6 +74,25 @@ </form> </div> + <div class="modal modal-danger fade" tabindex="-1" role="dialog"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span + aria-hidden="true">×</span></button> + <h4 class="modal-title">Are you sure that you want to perfom this operation?</h4> + </div> + <div class="modal-body"> + <p>Marking a subject resigned or deceased cannot be undone.</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-outline pull-left" data-dismiss="modal">Cancel</button> + <button type="button" id="confirm-save" class="btn btn-outline">Save changes</button> + </div> + </div><!-- /.modal-content --> + </div><!-- /.modal-dialog --> + </div><!-- /.modal --> + {% endblock %} @@ -103,7 +104,8 @@ <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script> <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script> <script> - $(function () { + var confirmed = false; + $(document).ready(function () { $('#table').DataTable({ "paging": true, "lengthChange": false, @@ -112,6 +114,22 @@ "info": true, "autoWidth": false }); + var dead_was_checked = $("#id_dead").is(":checked"); + var resigned_was_checked = $("#id_resigned").is(":checked"); + $("form").submit(function () { + if (confirmed) { + return true; + } + if ((!dead_was_checked && $("#id_dead").is(":checked")) || (!resigned_was_checked && $("#id_resigned").is(":checked"))) { + confirmed = false; + $(".modal").modal("show"); + return false; + } + }); + $("#confirm-save").click(function () { + confirmed = true; + $("form").submit(); + }); }); </script> diff --git a/smash/web/templates/subjects/index.html b/smash/web/templates/subjects/index.html index f46c7b189dd0e673481e033ae7f031b66937ae95..7d87064351bdc1b4b18c8fbbc031d240098bbfd3 100644 --- a/smash/web/templates/subjects/index.html +++ b/smash/web/templates/subjects/index.html @@ -35,7 +35,7 @@ <th>First name</th> <th>Last name</th> <th class="filter-select filter-exact" data-placeholder="Select location">Default location</th> - <th>Dead</th> + <th>Deceased</th> <th>Resigned</th> <th>Postponed</th> <th>Edit</th> diff --git a/smash/web/templatetags/filters.py b/smash/web/templatetags/filters.py index 6bf38bfc188195b39fe80d6accd5167811f06874..ec4a6f7c117353d3373e0a1f52e4ddd5fc0148fd 100644 --- a/smash/web/templatetags/filters.py +++ b/smash/web/templatetags/filters.py @@ -1,6 +1,6 @@ # See: http://stackoverflow.com/a/18962481 from django import template -from django.forms import CheckboxSelectMultiple +from django.forms import CheckboxSelectMultiple, CheckboxInput from django.utils.safestring import mark_safe register = template.Library() @@ -11,6 +11,8 @@ def add_class(value, arg): # Get all the field's initial css-classes if isinstance(value.field.widget, CheckboxSelectMultiple): return value + if isinstance(value.field.widget, CheckboxInput): + arg = 'checkbox' css_classes = value.field.widget.attrs.get('class', ' ').split(' ') # Filter out zero-length class names ('') css_classes = filter(lambda x: len(x) > 0, css_classes) @@ -31,6 +33,7 @@ def disable(value): def is_checkbox(value): return isinstance(value.field.widget, CheckboxSelectMultiple) + @register.filter(name="render_appointments") def render_appointments(statistics, appointment_type): html = "" diff --git a/smash/web/tests/test_model_subject.py b/smash/web/tests/test_model_subject.py index ce31aab861b51678adf6b78fe8b39846d06f7c1d..6401a89e5f16dad0b2696671a0cd0a74a053a5b5 100644 --- a/smash/web/tests/test_model_subject.py +++ b/smash/web/tests/test_model_subject.py @@ -20,12 +20,12 @@ class SubjectModelTests(TestCase): self.assertTrue(visit_finished) self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status) - def test_mark_as_rejected(self): + def test_mark_as_resigned(self): subject = create_subject() visit = create_visit(subject) appointment = create_appointment(visit) - subject.mark_as_rejected() + subject.mark_as_resigned() appointment_status = Appointment.objects.filter(id=appointment.id)[0].status visit_finsihed = Visit.objects.filter(id=visit.id)[0].is_finished diff --git a/smash/web/urls.py b/smash/web/urls.py index 6392138cb655cb16ce445ab0f1511f12b6824431..918bf46dcdc489c8c8e20ead08f1c03f14c8b220 100644 --- a/smash/web/urls.py +++ b/smash/web/urls.py @@ -51,7 +51,6 @@ urlpatterns = [ name='web.views.subject_visit_details'), url(r'^subjects/edit/(?P<id>\d+)$', views.subject.subject_edit, name='web.views.subject_edit'), url(r'^subjects/delete/(?P<id>\d+)$', views.subject.subject_delete, name='web.views.subject_delete'), - url(r'^subjects/mark/(?P<id>\d+)/(?P<as_what>[A-z]+)$', views.subject.subject_mark, name='web.views.subject_mark'), url(r'^doctors$', views.doctor.doctors, name='web.views.doctors'), url(r'^doctors/add$', views.doctor.doctor_add, name='web.views.doctor_add'), diff --git a/smash/web/views/subject.py b/smash/web/views/subject.py index d8987167f2c7db1be39b577d660853862ace54a1..a3556a99e038d54383fe5cf4fc0e374d74a0069a 100644 --- a/smash/web/views/subject.py +++ b/smash/web/views/subject.py @@ -54,13 +54,21 @@ def subject_require_contact(request): def subject_edit(request, id): the_subject = get_object_or_404(Subject, id=id) + was_dead = the_subject.dead + was_resigned = the_subject.resigned if request.method == 'POST': - form = SubjectEditForm(request.POST, request.FILES, instance=the_subject) + form = SubjectEditForm(request.POST, request.FILES, instance=the_subject, was_dead=was_dead, was_resigned=was_resigned) if form.is_valid(): form.save() + # check if subject was marked as dead or resigned + if form.cleaned_data['dead'] and not was_dead: + the_subject.mark_as_dead() + if form.cleaned_data['resigned'] and not was_resigned: + the_subject.mark_as_resigned() return redirect('web.views.subjects') else: - form = SubjectEditForm(instance=the_subject) + form = SubjectEditForm(instance=the_subject, was_dead=was_dead, was_resigned=was_resigned) + return wrap_response(request, 'subjects/edit.html', { 'form': form, 'subject': the_subject @@ -77,15 +85,6 @@ def subject_delete(request, id): return wrap_response(request, 'subjects/delete.html', {'form': form}) -def subject_mark(request, id, as_what): - who = get_object_or_404(Subject, id=id) - if as_what == 'dead': - who.mark_as_dead() - elif as_what == 'rejected': - who.mark_as_rejected() - return redirect('web.views.subject_edit', id=id) - - def subject_visit_details(request, id): locsubject = get_object_or_404(Subject, id=id) visits = locsubject.visit_set.all()