diff --git a/smash/web/templates/export/index.html b/smash/web/templates/export/index.html index fe8d952d03f0a8fc4ede565a05b3351dde977459..d7ff1b5de4bcda6e8ae0e4074d54eea62a318d60 100644 --- a/smash/web/templates/export/index.html +++ b/smash/web/templates/export/index.html @@ -68,10 +68,10 @@ </ul> </div> <ul> - <li><a onclick="addFields(this, 'subject_fields')" href="{% url 'web.views.export_to_excel' 'subjects' %}"><i class="fa fa-file-excel-o"></i> XLS - + <li><a onclick="addFields(this, 'subject_fields')" href="{% url 'web.views.export_to_excel' study_id 'subjects' %}"><i class="fa fa-file-excel-o"></i> XLS - Excel</a> </li> - <li><a onclick="addFields(this, 'subject_fields')" href="{% url 'web.views.export_to_csv' 'subjects' %}"><i class="fa fa-file-text-o"></i> CSV - + <li><a onclick="addFields(this, 'subject_fields')" href="{% url 'web.views.export_to_csv' study_id 'subjects' %}"><i class="fa fa-file-text-o"></i> CSV - Text based</a></li> </ul> <h3>Appointments</h3> @@ -87,9 +87,9 @@ </ul> </div> <ul> - <li><a onclick="addFields(this, 'appointment_fields')" href="{% url 'web.views.export_to_excel' 'appointments' %}"><i class="fa fa-file-excel-o"></i> XLS - + <li><a onclick="addFields(this, 'appointment_fields')" href="{% url 'web.views.export_to_excel' study_id 'appointments' %}"><i class="fa fa-file-excel-o"></i> XLS - Excel</a></li> - <li><a onclick="addFields(this, 'appointment_fields')" href="{% url 'web.views.export_to_csv' 'appointments' %}"><i class="fa fa-file-text-o"></i> CSV - + <li><a onclick="addFields(this, 'appointment_fields')" href="{% url 'web.views.export_to_csv' study_id 'appointments' %}"><i class="fa fa-file-text-o"></i> CSV - Text based</a></li> </ul> </div> diff --git a/smash/web/templates/sidebar.html b/smash/web/templates/sidebar.html index a575319957dc7bab0a8d2cf03b4204c9796d53b3..bea2f85b80f6a78b75564abe3becd7a04f0a7427 100644 --- a/smash/web/templates/sidebar.html +++ b/smash/web/templates/sidebar.html @@ -26,12 +26,12 @@ {% endif %} {% if "change_worker" in permissions %} - <li data-desc="workers"> - <a href="{% url 'web.views.workers' %}"> - <i class="fa fa-user-md"></i> - <span>Worker</span> - </a> - </li> + <li data-desc="workers"> + <a href="{% url 'web.views.workers' %}"> + <i class="fa fa-user-md"></i> + <span>Worker</span> + </a> + </li> {% endif %} {% if equipment_perms %} @@ -85,57 +85,59 @@ {% if "export_subjects" in permissions %} <li data-desc="export"> - <a href="{% url 'web.views.export' %}"> + <a href="{% url 'web.views.export' study_id %}"> <i class="fa fa-file-excel-o"></i> <span>Export</span> </a> </li> {% endif %} - {% if study.has_vouchers and "change_voucher" in permissions%} - <li data-desc="vouchers"> - <a href="{% url 'web.views.vouchers' %}"> - <i class="fa fa-user-md"></i> - <span>Vouchers</span> - </a> - </li> + {% if study.has_vouchers and "change_voucher" in permissions %} + <li data-desc="vouchers"> + <a href="{% url 'web.views.vouchers' %}"> + <i class="fa fa-user-md"></i> + <span>Vouchers</span> + </a> + </li> {% endif %} {% if conf_perms %} - <li data-desc="configuration" class="treeview"> - <a href="#"> - <i class="fa fa-wrench"></i> <span>Configuration</span> - <span class="pull-right-container"> + <li data-desc="configuration" class="treeview"> + <a href="#"> + <i class="fa fa-wrench"></i> <span>Configuration</span> + <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> - </a> - <ul class="treeview-menu"> - {% if "change_configurationitem" in permissions %} - <li data-desc="settings"><a href="{% url 'web.views.configuration' %}">General</a></li> - {% endif %} - - {% if "change_language" in permissions %} - <li data-desc="languages"><a href="{% url 'web.views.languages' %}">Languages</a></li> - {% endif %} - - {% if study.has_voucher_types and "change_vouchertype" in permissions %} - <li data-desc="voucher_types"><a href="{% url 'web.views.voucher_types' %}">Voucher types</a></li> - {% endif %} - - {% if study.has_vouchers and "change_worker" in permissions %} - <li data-desc="voucher_partner"><a href="{% url 'web.views.workers' 'VOUCHER_PARTNER' %}">Voucher partners</a></li> - {% endif %} - - {% if "change_worker" in permissions %} - <li data-desc="health_partner"><a href="{% url 'web.views.workers' 'HEALTH_PARTNER' %}">Health partners</a></li> - {% endif %} - - {% if "change_study" in permissions %} - <li data-desc="study_conf"><a href="{% url 'web.views.edit_study' study_id %}">Study</a></li> - {% endif %} - </ul> - </li> + </a> + <ul class="treeview-menu"> + {% if "change_configurationitem" in permissions %} + <li data-desc="settings"><a href="{% url 'web.views.configuration' %}">General</a></li> + {% endif %} + + {% if "change_language" in permissions %} + <li data-desc="languages"><a href="{% url 'web.views.languages' %}">Languages</a></li> + {% endif %} + + {% if study.has_voucher_types and "change_vouchertype" in permissions %} + <li data-desc="voucher_types"><a href="{% url 'web.views.voucher_types' %}">Voucher types</a></li> + {% endif %} + + {% if study.has_vouchers and "change_worker" in permissions %} + <li data-desc="voucher_partner"><a href="{% url 'web.views.workers' 'VOUCHER_PARTNER' %}">Voucher + partners</a></li> + {% endif %} + + {% if "change_worker" in permissions %} + <li data-desc="health_partner"><a href="{% url 'web.views.workers' 'HEALTH_PARTNER' %}">Health + partners</a></li> + {% endif %} + + {% if "change_study" in permissions %} + <li data-desc="study_conf"><a href="{% url 'web.views.edit_study' study_id %}">Study</a></li> + {% endif %} + </ul> + </li> {% endif %} diff --git a/smash/web/tests/view/test_export.py b/smash/web/tests/view/test_export.py index 93900de7d1f43b56006e4d6bfbc1d5bc483b1a44..c367eb1d2df89ee577b1d2eeb8ef302093e6d2ac 100644 --- a/smash/web/tests/view/test_export.py +++ b/smash/web/tests/view/test_export.py @@ -2,50 +2,59 @@ from django.urls import reverse from web.models import Appointment, AppointmentTypeLink +from web.models.constants import CUSTOM_FIELD_TYPE_TEXT +from web.models.custom_data import CustomStudySubjectField +from web.models.custom_data.custom_study_subject_field import get_study_subject_field_id from web.tests import LoggedInTestCase -from web.tests.functions import create_study_subject, create_appointment, create_visit, create_appointment_type -from web.views.export import subject_to_row_for_fields, DROP_OUT_FIELD +from web.tests.functions import create_study_subject, create_appointment, create_visit, create_appointment_type, \ + get_test_study +from web.views.export import subject_to_row_for_fields, DROP_OUT_FIELD, get_subjects_as_array class TestExportView(LoggedInTestCase): def test_export_subjects_to_csv(self): self.login_as_admin() create_study_subject() - response = self.client.get(reverse('web.views.export_to_csv', kwargs={'data_type': "subjects"})) + response = self.client.get( + reverse('web.views.export_to_csv', kwargs={'study_id': get_test_study().id, 'data_type': "subjects"})) self.assertEqual(response.status_code, 200) def test_export_subjects_to_csv_without_permission(self): self.client.get(reverse("web.views.mail_templates")) create_study_subject() - response = self.client.get(reverse('web.views.export_to_csv', kwargs={'data_type': "subjects"})) + response = self.client.get( + reverse('web.views.export_to_csv', kwargs={'study_id': get_test_study().id, 'data_type': "subjects"})) self.assertEqual(response.status_code, 302) def test_render_export(self): self.login_as_admin() create_study_subject() - response = self.client.get(reverse('web.views.export')) + response = self.client.get(reverse('web.views.export', kwargs={'study_id': get_test_study().id})) self.assertEqual(response.status_code, 200) def test_render_export_without_permission(self): create_study_subject() - response = self.client.get(reverse('web.views.export')) + response = self.client.get(reverse('web.views.export', kwargs={'study_id': get_test_study().id})) self.assertEqual(response.status_code, 302) def test_export_appointments_to_csv(self): self.login_as_admin() create_appointment() - response = self.client.get(reverse('web.views.export_to_csv', kwargs={'data_type': "appointments"})) + response = self.client.get( + reverse('web.views.export_to_csv', kwargs={'study_id': get_test_study().id, 'data_type': "appointments"})) self.assertEqual(response.status_code, 200) def test_export_subjects_to_excel(self): self.login_as_admin() create_study_subject() - response = self.client.get(reverse('web.views.export_to_excel', kwargs={'data_type': "subjects"})) + response = self.client.get( + reverse('web.views.export_to_excel', kwargs={'study_id': get_test_study().id, 'data_type': "subjects"})) self.assertEqual(response.status_code, 200) def test_export_subjects_to_excel_without_permission(self): create_study_subject() - response = self.client.get(reverse('web.views.export_to_excel', kwargs={'data_type': "subjects"})) + response = self.client.get( + reverse('web.views.export_to_excel', kwargs={'study_id': get_test_study().id, 'data_type': "subjects"})) self.assertEqual(response.status_code, 302) def test_export_appointments_to_excel(self): @@ -55,7 +64,8 @@ class TestExportView(LoggedInTestCase): appointment.save() AppointmentTypeLink.objects.create(appointment=appointment, appointment_type=create_appointment_type()) - response = self.client.get(reverse('web.views.export_to_excel', kwargs={'data_type': "appointments"})) + response = self.client.get( + reverse('web.views.export_to_excel', kwargs={'study_id': get_test_study().id, 'data_type': "appointments"})) self.assertEqual(response.status_code, 200) def test_subject_to_row_for_fields_when_not_resigned(self): @@ -86,3 +96,11 @@ class TestExportView(LoggedInTestCase): result = subject_to_row_for_fields(subject, [DROP_OUT_FIELD]) self.assertTrue(result[0]) + + def test_subject_with_custom_field(self): + subject = create_study_subject() + field = CustomStudySubjectField.objects.create(study=subject.study, name='HW', type=CUSTOM_FIELD_TYPE_TEXT) + subject.set_custom_data_value(field, 'bbb') + + subjects = get_subjects_as_array(get_test_study(), get_study_subject_field_id(field)) + self.assertEqual('bbb', subjects[1][0]) diff --git a/smash/web/urls.py b/smash/web/urls.py index 73b0e64f1b47a8671d1ed5ccfca44e83c077c88a..3bc27db6f6c72628fa7b27ee2ce37a1b47f906de 100644 --- a/smash/web/urls.py +++ b/smash/web/urls.py @@ -256,9 +256,9 @@ urlpatterns = [ # EXPORT # #################### - url(r'^export$', views.export.export, name='web.views.export'), - url(r'^export/csv/(?P<data_type>[A-z]+)$', views.export.export_to_csv, name='web.views.export_to_csv'), - url(r'^export/xls/(?P<data_type>[A-z]+)$', views.export.export_to_excel, name='web.views.export_to_excel'), + url(r'^study/(?P<study_id>\d+)export$', views.export.export, name='web.views.export'), + url(r'^study/(?P<study_id>\d+)export/csv/(?P<data_type>[A-z]+)$', views.export.export_to_csv, name='web.views.export_to_csv'), + url(r'^study/(?P<study_id>\d+)export/xls/(?P<data_type>[A-z]+)$', views.export.export_to_excel, name='web.views.export_to_excel'), #################### # CONFIGURATION # diff --git a/smash/web/views/export.py b/smash/web/views/export.py index 2c9d56f36ac2f5861e47bd6cc371a5c3725ebf15..39dc5ed10b5b2b30b324c1715d4f47b96c298207 100644 --- a/smash/web/views/export.py +++ b/smash/web/views/export.py @@ -5,10 +5,11 @@ from distutils.util import strtobool import django_excel as excel from django.http import HttpResponse +from django.shortcuts import get_object_or_404 from web.decorators import PermissionDecorator -from web.models import Subject, StudySubject, Appointment, ConfigurationItem -from web.models.constants import VISIT_SHOW_VISIT_NUMBER_FROM_ZERO, GLOBAL_STUDY_ID +from web.models import Subject, StudySubject, Appointment, ConfigurationItem, Study +from web.models.constants import VISIT_SHOW_VISIT_NUMBER_FROM_ZERO from web.models.custom_data import CustomStudySubjectField from web.models.custom_data.custom_study_subject_field import get_study_subject_field_id from web.templatetags.filters import display_visit_number @@ -17,7 +18,8 @@ from .notifications import get_today_midnight_date @PermissionDecorator('export_subjects', 'subject') -def export_to_csv(request, data_type="subjects"): +def export_to_csv(request, study_id, data_type="subjects"): + study = get_object_or_404(Study, id=study_id) # Create the HttpResponse object with the appropriate CSV header. selected_fields = request.GET.get('fields', None) response = HttpResponse(content_type='text/csv; charset=utf-8') @@ -25,7 +27,7 @@ def export_to_csv(request, data_type="subjects"): "%Y-%m-%d") + '.csv"' if data_type == "subjects": - data = get_subjects_as_array(selected_fields=selected_fields) + data = get_subjects_as_array(study, selected_fields=selected_fields) elif data_type == "appointments": data = get_appointments_as_array(selected_fields=selected_fields) else: @@ -38,11 +40,12 @@ def export_to_csv(request, data_type="subjects"): @PermissionDecorator('export_subjects', 'subject') -def export_to_excel(request, data_type="subjects"): +def export_to_excel(request, study_id, data_type="subjects"): + study = get_object_or_404(Study, id=study_id) selected_fields = request.GET.get('fields', None) filename = data_type + '-' + get_today_midnight_date().strftime("%Y-%m-%d") + ".xls" if data_type == "subjects": - data = get_subjects_as_array(selected_fields=selected_fields) + data = get_subjects_as_array(study, selected_fields=selected_fields) elif data_type == "appointments": data = get_appointments_as_array(selected_fields=selected_fields) else: @@ -94,7 +97,7 @@ def filter_fields_from_selected_fields(fields, selected_fields): return [field for field in fields if field.name in selected_fields] -def get_default_subject_fields(): +def get_default_subject_fields(study: Study): visit_from_zero = ConfigurationItem.objects.get(type=VISIT_SHOW_VISIT_NUMBER_FROM_ZERO).value visit_from_zero = strtobool(visit_from_zero) subject_fields = [] @@ -113,15 +116,15 @@ def get_default_subject_fields(): number = int(match.groups()[0]) field.verbose_name = 'Virus {} RT-PCR date'.format(display_visit_number(number)) subject_fields.append(field) - for custom_field in CustomStudySubjectField.objects.filter(study__id=GLOBAL_STUDY_ID).all(): + for custom_field in CustomStudySubjectField.objects.filter(study=study).all(): subject_fields.append( CustomField({'verbose_name': custom_field.name, 'name': get_study_subject_field_id(custom_field)})) return subject_fields -def get_subjects_as_array(selected_fields=None): +def get_subjects_as_array(study: Study, selected_fields: str = None): result = [] - subject_fields = get_default_subject_fields() + subject_fields = get_default_subject_fields(study) subject_fields = filter_fields_from_selected_fields(subject_fields, selected_fields) field_names = [field.verbose_name for field in subject_fields] # faster than loop @@ -136,7 +139,7 @@ def get_subjects_as_array(selected_fields=None): def subject_to_row_for_fields(study_subject: StudySubject, subject_fields): row = [] - custom_fields = CustomStudySubjectField.objects.filter(study__id=GLOBAL_STUDY_ID).all() + custom_fields = CustomStudySubjectField.objects.filter(study=study_subject.study).all() for field in subject_fields: cell = None @@ -223,8 +226,10 @@ def get_appointments_as_array(selected_fields=None): @PermissionDecorator('export_subjects', 'subject') -def export(request): +def export(request, study_id): + study = get_object_or_404(Study, id=study_id) return wrap_response(request, 'export/index.html', { - 'subject_fields': get_default_subject_fields(), - 'appointment_fields': get_appointment_fields()[0] + 'subject_fields': get_default_subject_fields(study), + 'appointment_fields': get_appointment_fields()[0], + 'study_id': study_id })