diff --git a/smash/web/forms.py b/smash/web/forms.py index 982f312e85881650073c2ee867d67f0dd289dab3..dcb9c0ba48c2e1ffd0c95739c5d6293838d1827e 100644 --- a/smash/web/forms.py +++ b/smash/web/forms.py @@ -361,6 +361,26 @@ class ContactAttemptForm(ModelForm): self.fields['worker'].initial = self.user +class ContactAttemptEditForm(ModelForm): + datetime_when = forms.DateTimeField(label='When? (YYYY-MM-DD HH:MM)', + widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS) + ) + + class Meta: + model = ContactAttempt + fields = '__all__' + + def __init__(self, *args, **kwargs): + user = kwargs.pop('user', None) + if user is None: + raise TypeError("User not defined") + self.user = Worker.get_by_user(user) + if self.user is None: + raise TypeError("Worker not defined for: " + user.username) + super(ContactAttemptEditForm, self).__init__(*args, **kwargs) + self.fields['subject'].disabled = True + + class KitRequestForm(Form): start_date = forms.DateField(label="From date", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), diff --git a/smash/web/migrations/0048_auto_20170911_1504.py b/smash/web/migrations/0048_auto_20170911_1504.py new file mode 100644 index 0000000000000000000000000000000000000000..4c627d657a40fbabad6e031d701b2cfc9f317eab --- /dev/null +++ b/smash/web/migrations/0048_auto_20170911_1504.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-11 13:04 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0047_subject_flying_team_from_annotation'), + ] + + operations = [ + migrations.AlterField( + model_name='subject', + name='flying_team', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.FlyingTeam', verbose_name=b'Default flying team location (if applicable)'), + ), + ] diff --git a/smash/web/templates/contact_attempt/edit.html b/smash/web/templates/contact_attempt/edit.html new file mode 100644 index 0000000000000000000000000000000000000000..028c782b051c1730cd089956ca01eb16f02c959b --- /dev/null +++ b/smash/web/templates/contact_attempt/edit.html @@ -0,0 +1,81 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/> + + {% include "includes/datepicker.css.html" %} +{% endblock styles %} + +{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %} +{% block page_header %}Edit contact attempt{% endblock page_header %} +{% block page_description %}{% endblock page_description %} + +{% block title %}{{ block.super }} - Edit contact attempt{% endblock %} + +{% block breadcrumb %} + {% include "subjects/breadcrumb.html" %} +{% endblock breadcrumb %} + +{% block maincontent %} + + {% block content %} + <div class="row"> + <div class="col-md-12"> + <div class="box box-success"> + <div class="box-header with-border"> + <h3 class="box-title">Enter contact attempt details</h3> + </div> + + + <form method="post" action="" class="form-horizontal"> + {% csrf_token %} + + <div class="box-body"> + {% for field in form %} + <div class="form-group {% if field.errors %}has-error{% endif %}"> + <label class="col-sm-4 col-lg-offset-1 col-lg-2 control-label"> + {{ field.label }} + </label> + + <div class="col-sm-8 col-lg-4"> + {{ field|add_class:'form-control' }} + </div> + + {% if field.errors %} + <span class="help-block"> + {{ field.errors }} + </span> + {% endif %} + </div> + {% endfor %} + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-success">Save</button> + </div> + <div class="col-sm-6"> + <a href="{% url 'web.views.subject_edit' subject_id %}" + class="btn btn-block btn-default">Cancel</a> + </div> + </div><!-- /.box-footer --> + </form> + </div> + + </div> + </div> + + {% endblock %} + + +{% endblock maincontent %} + +{% block scripts %} + {{ block.super }} + + <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script> + + {% include "includes/datetimepicker.js.html" %} +{% endblock scripts %} diff --git a/smash/web/templates/includes/contact_attempts_box.html b/smash/web/templates/includes/contact_attempts_box.html index 68d1244495033cd88fcc5e82bde436240403c57f..61637ffc24ca8100366c7329b51727b0e50bdac6 100644 --- a/smash/web/templates/includes/contact_attempts_box.html +++ b/smash/web/templates/includes/contact_attempts_box.html @@ -5,6 +5,8 @@ <h3>Contact attempts <a title="add a new contact attempt" id="add-contact-attempt" href=" + + {% url 'web.views.contact_add' subject.id %}{% if appointment_id %}?from_appointment={{ appointment_id }}{% endif %}" class="text-primary" ><i class="fa fa-plus-circle text-success"></i></a></h3> @@ -19,6 +21,7 @@ <th class="text-center">Type</th> <th class="text-center">Success</th> <th class="text-center">Comment</th> + <th class="text-center">Edit</th> </tr> </thead> <tbody> @@ -31,6 +34,11 @@ <i class="fa {% if contact_attempt.success %}fa-check text-success{% else %}fa-times text-danger{% endif %}"></i> </td> <td>{{ contact_attempt.comment }}</td> + <td><a title="edit contact attempt" + href="{% url 'web.views.contact_edit' subject.id contact_attempt.id %}{% if appointment_id %}?from_appointment={{ appointment_id }}{% endif %}" + type="button" + class="btn btn-block btn-default" + >EDIT</a></td> </tr> {% endfor %} </tbody> diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py index 3f616e355472d30b1668f3ef5e42e2f627086db5..1918e847adc49fbdb271018bb25ed069f4645edc 100644 --- a/smash/web/tests/functions.py +++ b/smash/web/tests/functions.py @@ -4,8 +4,9 @@ import os from django.contrib.auth.models import User from web.models import Location, AppointmentType, Subject, Worker, Visit, Appointment, ConfigurationItem, Language, \ - FlyingTeam -from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL + ContactAttempt, FlyingTeam +from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, CONTACT_TYPES_PHONE + from web.views.notifications import get_today_midnight_date @@ -36,6 +37,21 @@ def create_appointment_type(): ) +def create_contact_attempt(subject=None, worker=None): + if subject is None: + subject = create_subject() + if worker is None: + worker = create_worker() + + return ContactAttempt.objects.create(subject=subject, + worker=worker, + type=CONTACT_TYPES_PHONE, + datetime_when=get_today_midnight_date(), + success=True, + comment="Successful contact attempt", + ) + + def create_subject(subject_id=1): return Subject.objects.create( first_name="Piotr", @@ -118,3 +134,10 @@ def create_language(name="French", locale="fr_FR"): def get_resource_path(filename): return os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', filename) + + +def format_form_field(value): + if isinstance(value, datetime.datetime): + return value.strftime('%Y-%m-%d %H:%M') + else: + return value diff --git a/smash/web/tests/test_view_appointments.py b/smash/web/tests/test_view_appointments.py index 5ea5c23a2029df526cc8beb3619bee59e59597eb..bf721ebe836316136b26bb85ed47ae8f030c091f 100644 --- a/smash/web/tests/test_view_appointments.py +++ b/smash/web/tests/test_view_appointments.py @@ -2,7 +2,8 @@ import datetime from django.urls import reverse -from functions import create_subject, create_visit, create_appointment, create_worker, create_flying_team +from functions import create_subject, create_visit, create_appointment, create_worker, create_flying_team, \ + format_form_field from web.forms import AppointmentEditForm, SubjectEditForm from web.models import Appointment, Subject from web.views.notifications import get_today_midnight_date @@ -91,15 +92,11 @@ class AppointmentsViewTests(LoggedInTestCase): form_subject = SubjectEditForm(instance=subject, prefix="subject") form_data = {} for key, value in form_appointment.initial.items(): - if isinstance(value, datetime.datetime): - form_data['appointment-{}'.format(key)] = value.strftime('%Y-%m-%d %H:%M') - elif value is not None: - form_data['appointment-{}'.format(key)] = value + if value is not None: + form_data['appointment-{}'.format(key)] = format_form_field(value) for key, value in form_subject.initial.items(): - if isinstance(value, datetime.datetime): - form_data['subject-{}'.format(key)] = value.strftime('%Y-%m-%d %H:%M') - elif value is not None: - form_data['subject-{}'.format(key)] = value + if value is not None: + form_data['subject-{}'.format(key)] = format_form_field(value) return form_data def test_subject_flying_team_location(self): diff --git a/smash/web/tests/test_view_contact_attempt.py b/smash/web/tests/test_view_contact_attempt.py index 760119e7466f20d39f8ef815805384927fffa229..48b09ac930c4c411d56b493c504b420979848a29 100644 --- a/smash/web/tests/test_view_contact_attempt.py +++ b/smash/web/tests/test_view_contact_attempt.py @@ -3,7 +3,8 @@ import datetime from django.urls import reverse from django.utils import timezone -from functions import create_subject +from web.forms import ContactAttemptEditForm +from functions import create_subject, create_contact_attempt, format_form_field from web.models import ContactAttempt from web.models.constants import CONTACT_TYPES_EMAIL from . import LoggedInWithWorkerTestCase @@ -51,3 +52,21 @@ class ContactAttemptViewTests(LoggedInWithWorkerTestCase): reverse('web.views.contact_add', kwargs={'subject_id': subject.id}), data=form_data) self.assertContains(response, "This field is required", 2) self.assertEqual(0, ContactAttempt.objects.filter(subject=subject).count()) + + def test_contact_attempt_edit_post(self): + contact_attempt = create_contact_attempt() + + form_subject = ContactAttemptEditForm(instance=contact_attempt, user=self.user) + form_data = {} + for key, value in form_subject.initial.items(): + if value is not None: + form_data[key] = format_form_field(value) + + response = self.client.post( + reverse('web.views.contact_edit', + kwargs={'subject_id': contact_attempt.subject.id, 'contact_attempt_id': contact_attempt.id}), + data=form_data) + + print response.content + + self.assertEqual(response.status_code, 302) diff --git a/smash/web/urls.py b/smash/web/urls.py index a2e1a0191019f89ae7f1db70d641c63c9e2fe171..6247a09449277a620defcd52f39d678115fcd1f6 100644 --- a/smash/web/urls.py +++ b/smash/web/urls.py @@ -82,6 +82,8 @@ urlpatterns = [ url(r'^subjects/(?P<subject_id>\d+)/contacts/add$', views.contact_attempt.contact_add, name='web.views.contact_add'), + url(r'^subjects/(?P<subject_id>\d+)/contacts/(?P<contact_attempt_id>\d+)/edit', views.contact_attempt.contact_edit, + name='web.views.contact_edit'), #################### # DOCTORS # diff --git a/smash/web/views/contact_attempt.py b/smash/web/views/contact_attempt.py index 439a2a025329c9de1aa3b5feaa17cc25da87bf18..6246cd03afc6fdea92f4e5f0bd9daea80cd8ed81 100644 --- a/smash/web/views/contact_attempt.py +++ b/smash/web/views/contact_attempt.py @@ -1,8 +1,8 @@ from django.shortcuts import redirect, get_object_or_404 from . import wrap_response -from ..forms import ContactAttemptForm -from ..models import Subject +from ..forms import ContactAttemptForm, ContactAttemptEditForm +from ..models import Subject, ContactAttempt def contact_add(request, subject_id): @@ -13,7 +13,7 @@ def contact_add(request, subject_id): if form.is_valid(): form.save() if 'from_appointment' in request.GET: - return redirect('web.views.appointment_edit', id=request.GET.get('from_appointment','')) + return redirect('web.views.appointment_edit', id=request.GET.get('from_appointment', '')) else: return redirect('web.views.subject_edit', id=subject_id) else: @@ -21,3 +21,19 @@ def contact_add(request, subject_id): return wrap_response(request, 'contact_attempt/add.html', {'form': form, 'subject_id': subject_id}) + + +def contact_edit(request, subject_id, contact_attempt_id): + contact_attempt = get_object_or_404(ContactAttempt, id=contact_attempt_id) + if request.method == 'POST': + form = ContactAttemptEditForm(request.POST, instance=contact_attempt, user=request.user, ) + if form.is_valid(): + form.save() + if 'from_appointment' in request.GET: + return redirect('web.views.appointment_edit', id=request.GET.get('from_appointment', '')) + else: + return redirect('web.views.subject_edit', id=contact_attempt.subject.id) + else: + form = ContactAttemptEditForm(instance=contact_attempt, user=request.user) + + return wrap_response(request, 'contact_attempt/edit.html', {'form': form, 'subject_id': subject_id})