Skip to content
Snippets Groups Projects
Commit 634b8b65 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge remote-tracking branch 'origin/master' into rpm-package

parents 560aefa5 e3c3c4ef
No related branches found
No related tags found
1 merge request!425rpm package
Pipeline #57933 failed
smasch (1.2.0~alpha.1-1) unstable; urgency=low
smasch (1.2.0-1) unstable; urgency=low
* small improvement: rpm package is available
-- Piotr Gawron <piotr.gawron@uni.lu> Thu, 12 May 2022 15:00:00 +0200
smasch (1.2.0~alpha.0-1) unstable; urgency=low
* small improvement: add possibility to include column
default_written_communication_language in the subject list as visible
column (#511)
* small improvement: export of subjects contains languages field (#507)
-- Piotr Gawron <piotr.gawron@uni.lu> Wed, 31 Mar 2022 12:00:00 +0200
-- Carlos Vega <carlos.vega@uni.lu> Thu, 16 Jun 2022 15:00:00 +0200
smasch (1.1.1-1) stable; urgency=medium
......
......@@ -16,7 +16,7 @@ Including another URLconf
from django.conf.urls import url
from web.api_views import worker, location, subject, appointment_type, appointment, configuration, daily_planning, \
redcap, flying_team, visit, voucher, voucher_type, provenance
redcap, flying_team, visit, voucher, voucher_type, provenance, language
urlpatterns = [
# appointments
......@@ -27,6 +27,9 @@ urlpatterns = [
# appointment types
url(r'^appointment_types$', appointment_type.appointment_types, name='web.api.appointment_types'),
# languages
url(r'^languages$', language.languages, name='web.api.languages'),
# configuration items
url(r'^configuration_items$', configuration.configuration_items, name='web.api.configuration_items'),
url(r'^configuration_items/update$', configuration.update_configuration_item,
......
......@@ -4,3 +4,4 @@ from . import appointment_type
from . import location
from . import subject
from . import worker
from . import language
from django.http import JsonResponse
from web.models import Language
def languages(request):
langs = Language.objects.all().order_by('name')
result = []
for lang in langs:
result.append({
"id": lang.id,
"name": lang.name,
"image": lang.image.url if lang.image else "",
"locale": lang.locale,
"order": lang.order,
"windows_locale_name": lang.windows_locale_name
})
return JsonResponse({
"languages": result
})
from django.db.models import F
import logging
import re
from distutils.util import strtobool
......@@ -83,6 +84,8 @@ def get_subject_columns(request: HttpRequest, subject_list_type: str) -> JsonRes
add_column(result, "Next of kin address", "next_of_kin_address", subject_columns, "string_filter")
add_column(result, "Excluded", "excluded", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Info sent", "information_sent", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Default Written Communication Language",
"default_written_communication_language", subject_columns, "language_filter")
visit_from_zero = ConfigurationItem.objects.get(type=VISIT_SHOW_VISIT_NUMBER_FROM_ZERO).value
# True values are y, yes, t, true, on and 1; false values are n, no, f, false, off and 0.
......@@ -171,10 +174,10 @@ def get_subjects(request, list_type):
raise TypeError("Unknown query type: " + list_type)
def order_by_visit(subjects_to_be_ordered, order_direction, visit_number):
def order_by_visit(subjects_to_be_ordered, order_f, visit_number):
return subjects_to_be_ordered.annotate(
sort_visit_date=Min(Case(When(visit__visit_number=visit_number, then='visit__datetime_begin')))).order_by(
order_direction + 'sort_visit_date')
sort_visit_date=Min(Case(When(visit__visit_number=visit_number,
then='visit__datetime_begin')))).order_by(order_f('sort_visit_date'))
def get_subjects_order(subjects_to_be_ordered: QuerySet, order_column, order_direction, column_filters=None):
......@@ -182,78 +185,82 @@ def get_subjects_order(subjects_to_be_ordered: QuerySet, order_column, order_dir
column_filters = {}
result = subjects_to_be_ordered
if order_direction == "asc":
order_direction = ""
def order_f(x):
return F(x).asc(nulls_first=True)
else:
order_direction = "-"
def order_f(x):
return F(x).desc(nulls_last=True)
if order_column is None:
logger.warning("Column cannot be null")
elif order_column == "first_name":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__first_name')
result = subjects_to_be_ordered.order_by(order_f('subject__first_name'))
elif order_column == "last_name":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__last_name')
result = subjects_to_be_ordered.order_by(order_f('subject__last_name'))
elif order_column == "address":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__address')
result = subjects_to_be_ordered.order_by(order_f('subject__address'))
elif order_column == "next_of_kin_name":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_kin_name')
result = subjects_to_be_ordered.order_by(order_f('subject__next_of_kin_name'))
elif order_column == "next_of_kin_phone":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_kin_phone')
result = subjects_to_be_ordered.order_by(order_f('subject__next_of_kin_phone'))
elif order_column == "next_of_kin_address":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_kin_address')
result = subjects_to_be_ordered.order_by(order_f('subject__next_of_kin_address'))
elif order_column == "nd_number":
result = subjects_to_be_ordered.order_by(order_direction + 'nd_number')
result = subjects_to_be_ordered.order_by(order_f('nd_number'))
elif order_column == "referral":
result = subjects_to_be_ordered.order_by(order_direction + 'referral')
result = subjects_to_be_ordered.order_by(order_f('referral'))
elif order_column == "default_written_communication_language":
result = subjects_to_be_ordered.order_by(order_f('subject__default_written_communication_language__name'))
elif order_column == "screening_number":
if 'screening_number' not in column_filters:
pattern = None
else:
pattern = column_filters['screening_number']
result = subjects_to_be_ordered.all()
result = sorted(result, key=lambda t: t.sort_matched_screening_first(pattern, reverse=order_direction == '-'),
reverse=order_direction == '-')
result = sorted(result, key=lambda t: t.sort_matched_screening_first(pattern, reverse=order_direction != 'asc'),
reverse=order_direction != 'asc')
elif order_column == "default_location":
result = subjects_to_be_ordered.order_by(order_direction + 'default_location')
result = subjects_to_be_ordered.order_by(order_f('default_location__name'))
elif order_column == "flying_team":
result = subjects_to_be_ordered.order_by(order_direction + 'flying_team')
result = subjects_to_be_ordered.order_by(order_f('flying_team'))
elif order_column == "dead":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__dead')
result = subjects_to_be_ordered.order_by(order_f('subject__dead'))
elif order_column == "resigned":
result = subjects_to_be_ordered.order_by(order_direction + 'resigned')
result = subjects_to_be_ordered.order_by(order_f('resigned'))
elif order_column == "endpoint_reached":
result = subjects_to_be_ordered.order_by(order_direction + 'endpoint_reached')
result = subjects_to_be_ordered.order_by(order_f('endpoint_reached'))
elif order_column == "information_sent":
result = subjects_to_be_ordered.order_by(order_direction + 'information_sent')
result = subjects_to_be_ordered.order_by(order_f('information_sent'))
elif order_column == "health_partner_first_name":
result = subjects_to_be_ordered.order_by(order_direction + 'health_partner__first_name')
result = subjects_to_be_ordered.order_by(order_f('health_partner__first_name'))
elif order_column == "health_partner_last_name":
result = subjects_to_be_ordered.order_by(order_direction + 'health_partner__last_name')
result = subjects_to_be_ordered.order_by(order_f('health_partner__last_name'))
elif order_column == "social_security_number":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__social_security_number')
result = subjects_to_be_ordered.order_by(order_f('subject__social_security_number'))
elif order_column == "postponed":
result = subjects_to_be_ordered.order_by(order_direction + 'postponed')
result = subjects_to_be_ordered.order_by(order_f('postponed'))
elif order_column == "excluded":
result = subjects_to_be_ordered.order_by(order_direction + 'excluded')
result = subjects_to_be_ordered.order_by(order_f('excluded'))
elif order_column == "type":
result = subjects_to_be_ordered.order_by(order_direction + 'type__name')
result = subjects_to_be_ordered.order_by(order_f('type__name'))
elif order_column == "id":
result = subjects_to_be_ordered.order_by(order_direction + 'id')
result = subjects_to_be_ordered.order_by(order_f('id'))
elif order_column == "date_born":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__date_born')
result = subjects_to_be_ordered.order_by(order_f('subject__date_born'))
elif order_column == "datetime_contact_reminder":
result = subjects_to_be_ordered.order_by(order_direction + 'datetime_contact_reminder')
result = subjects_to_be_ordered.order_by(order_f('datetime_contact_reminder'))
elif order_column == "last_contact_attempt":
# noinspection SpellCheckingInspection
result = subjects_to_be_ordered.annotate(sort_contact_attempt=Max("contactattempt__datetime_when")).order_by(
order_direction + 'sort_contact_attempt')
result = subjects_to_be_ordered.annotate(sort_contact_attempt=Max(
"contactattempt__datetime_when")).order_by(order_f('sort_contact_attempt'))
elif str(order_column).startswith("visit_"):
visit_number = get_visit_number_from_visit_x_string(order_column)
result = order_by_visit(subjects_to_be_ordered, order_direction, visit_number)
result = order_by_visit(subjects_to_be_ordered, order_f, visit_number)
elif re.search(r'^custom_field-[0-9]+$', order_column):
field_id = int(order_column.replace("custom_field-", ""))
result = subjects_to_be_ordered.annotate(
custom_field_value=Min(Case(When(customstudysubjectvalue__study_subject_field__id=field_id,
then='customstudysubjectvalue__value')))).order_by(
order_direction + 'custom_field_value')
then='customstudysubjectvalue__value')))). \
order_by(order_f('custom_field_value'))
else:
logger.warning("Unknown sort column: %s", str(order_column))
return result
......@@ -348,6 +355,8 @@ def get_subjects_filtered(subjects_to_be_filtered: QuerySet, filters) -> QuerySe
result = result.filter(nd_number__icontains=value)
elif column == "referral":
result = result.filter(referral__icontains=value)
elif column == "default_written_communication_language":
result = result.filter(subject__default_written_communication_language__id=value)
elif column == "screening_number":
result = result.filter(screening_number__icontains=value)
elif column == "dead":
......@@ -536,6 +545,10 @@ def serialize_subject(study_subject: StudySubject):
health_partner_last_name = ""
if study_subject.health_partner:
health_partner_last_name = study_subject.health_partner.last_name
default_written_communication_language = ""
if study_subject.subject.default_written_communication_language:
default_written_communication_language = study_subject.subject.default_written_communication_language.name
result = {
"first_name": study_subject.subject.first_name,
"last_name": study_subject.subject.last_name,
......@@ -563,6 +576,7 @@ def serialize_subject(study_subject: StudySubject):
"type": study_subject.type.name,
"id": study_subject.id,
"visits": serialized_visits,
"default_written_communication_language": default_written_communication_language
}
for field_value in study_subject.custom_data_values:
......
......@@ -17,7 +17,7 @@ class StudySubjectListEditForm(ModelForm):
class SubjectColumnsEditForm(ModelForm):
class Meta:
model = SubjectColumns
exclude = ['sex', 'phone_number', 'phone_number_2', 'phone_number_3', 'default_written_communication_language',
exclude = ['sex', 'phone_number', 'phone_number_2', 'phone_number_3',
'postal_code', 'city', 'country', 'email', 'languages']
def __init__(self, *args, **kwargs):
......
......@@ -288,6 +288,7 @@ function createTable(params) {
}
var subject_types_url = params.subject_types_url;
var locations_url = params.locations_url;
var languages_url = params.languages_url;
var flying_teams_url = params.flying_teams_url;
var appointment_types_url = params.appointment_types_url;
var subjects_url = params.subjects_url;
......@@ -385,6 +386,17 @@ function createTable(params) {
});
});
$(tableElement).find('tfoot div[name="language_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
var select = $('select', obj);
$.get(languages_url, function (data) {
$.each(data.languages, function (index, language) {
select.append('<option value="' + language.id + '">' + language.name + '</option>');
});
});
});
$(tableElement).find('tfoot div[name="voucher_type_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
......
......@@ -113,6 +113,7 @@
worker_locations: worker_locations,
subject_types_url: "{% url 'web.api.subject_types' %}",
locations_url: "{% url 'web.api.locations' %}",
languages_url: "{% url 'web.api.languages' %}",
subjects_url: "{% url 'web.api.subjects' list_type %}",
flying_teams_url: "{% url 'web.api.flying_teams' %}",
tableElement: document.getElementById("table"),
......
# coding=utf-8
import json
from django.urls import reverse
from web.tests import LoggedInTestCase
from web.models import StudySubject, Language
from web.tests.functions import create_study_subject, create_language
from web.api_views.subject import get_subjects_filtered, get_subjects_order
class TestLanguagesApi(LoggedInTestCase):
def test_languages(self):
lang_name = "French"
response = self.client.get(reverse('web.api.locations'))
self.assertEqual(response.status_code, 200)
create_language(lang_name)
response = self.client.get(reverse('web.api.languages'))
languages = json.loads(response.content)['languages']
found = False
for lang in languages:
if lang['name'] == lang_name:
found = True
self.assertTrue(found)
def test_default_written_communication_language_filter(self):
lang_name = "French"
create_language(lang_name)
language_fr = Language.objects.filter(name=lang_name)[0]
study_subject_a = create_study_subject()
study_subject_a.subject.default_written_communication_language = language_fr
study_subject_a.subject.save()
create_study_subject()
create_study_subject()
subjects = StudySubject.objects.all()
self.assertEqual(len(subjects), 3)
subjects_fr = StudySubject.objects.filter(
subject__default_written_communication_language__id=language_fr.id)
self.assertEqual(len(subjects_fr), 1)
filtered_subjects = get_subjects_filtered(
subjects, [('default_written_communication_language', language_fr.id)])
self.assertEqual(len(filtered_subjects), 1)
self.assertEqual(filtered_subjects[0].subject.default_written_communication_language.name, lang_name)
def test_default_written_communication_language_null_order(self):
lang_name = "French"
create_language(lang_name)
language_fr = Language.objects.filter(name=lang_name)[0]
study_subject_a = create_study_subject()
study_subject_a.subject.default_written_communication_language = language_fr
study_subject_a.subject.save()
create_study_subject()
create_study_subject()
subjects = StudySubject.objects.all()
self.assertEqual(len(subjects), 3)
ordered_subjects = get_subjects_order(
subjects, 'default_written_communication_language', "asc")
self.assertEqual(len(ordered_subjects), 3)
self.assertEqual(ordered_subjects[0].subject.default_written_communication_language, None)
self.assertEqual(ordered_subjects[1].subject.default_written_communication_language, None)
self.assertEqual(ordered_subjects[2].subject.default_written_communication_language.name, lang_name)
ordered_subjects = get_subjects_order(
subjects, 'default_written_communication_language', "-")
self.assertEqual(len(ordered_subjects), 3)
self.assertEqual(ordered_subjects[0].subject.default_written_communication_language.name, lang_name)
self.assertEqual(ordered_subjects[1].subject.default_written_communication_language, None)
self.assertEqual(ordered_subjects[2].subject.default_written_communication_language, None)
import logging
from django.core.files.images import ImageFile
from django.test import TestCase
from web.models import Language
from web.tests.functions import get_resource_path, create_language
logger = logging.getLogger(__name__)
class LanguageTests(TestCase):
def test_image_img(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment