diff --git a/CHANGELOG b/CHANGELOG index 88dca169f76a71f2a612d3afaacf89b134e9dd01..e25e8a531c51aff9cdc1ea889aef62ceccdd9007 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,9 @@ smasch (1.0.0~alpha.1-0) unstable; urgency=low + * improvement: added views to delete StudySubject and Subject (#354) * improvement: study subject can be configured to contain custom fields (#339) + * small improvement: "next of keen" renamed to "next of kin" (#362) * small improvement: django command for creating admin in application (#347) * small improvement: django admin panel contains usable data tables (#346) * small improvement: possibility to unfinish visit (#351) @@ -9,6 +11,7 @@ smasch (1.0.0~alpha.1-0) unstable; urgency=low (#285) * small improvement: all configuration options that are not obligatory are moved to configuration panel (#343) + * small improvement: 2FA can be configured to be required option (#358) -- Piotr Gawron <piotr.gawron@uni.lu> Tue, 10 Nov 2020 14:00:00 +0200 diff --git a/requirements.txt b/requirements.txt index de271e69e8936a045bb6bb0d6a95e0843f63f3f3..cadf381fc5f69e983f49178d7fe172f60ecdf0fe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -59,4 +59,5 @@ urllib3==1.26.2 whitenoise==5.2.0 xlrd==1.2.0 xlwt==1.3.0 +parameterized==0.7.4 setuptools==50.3.2 \ No newline at end of file diff --git a/smash/smash/local_settings.py.template b/smash/smash/local_settings.py.template index 79c90e5220130d1e6ea9467b312d3edf30beee9b..fb44fbe9517d7b10898b1f5ae955843bed55ef06 100644 --- a/smash/smash/local_settings.py.template +++ b/smash/smash/local_settings.py.template @@ -76,3 +76,7 @@ LOGGING = { } TWO_FACTOR_SMS_GATEWAY = "web.nexmo_gateway.Nexmo" + +# whether 2 steps authentication is mandatory to access the system + +FORCE_2FA = True diff --git a/smash/smash/middleware/__init__.py b/smash/smash/middleware/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..eea436a3790f7fd77b1cf18c6f5c5ae198e7dd6f --- /dev/null +++ b/smash/smash/middleware/__init__.py @@ -0,0 +1,3 @@ +import logging + +logger = logging.getLogger(__name__) diff --git a/smash/smash/middleware/force_2fa_middleware.py b/smash/smash/middleware/force_2fa_middleware.py new file mode 100644 index 0000000000000000000000000000000000000000..21de43603e166d84d043fa403840357b0a45922b --- /dev/null +++ b/smash/smash/middleware/force_2fa_middleware.py @@ -0,0 +1,27 @@ +import logging + +from django.contrib import messages +from django.shortcuts import redirect + +logger = logging.getLogger(__name__) + + +class Force2FAMiddleware: + """ + Middleware restricting access to users with 2 factors authentication enabled + Redirects to 2fa section if not enabled + """ + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + """ + If user is authenticated and user is not verified (2fa not enabled) and we are in one of the 2fa setting pages + we redirect to the 2fa profile page + """ + if request.user.is_authenticated and not request.user.is_verified() and 'two_factor' not in request.path: + messages.add_message(request, messages.WARNING, + '2 factors authentication must be enabled to use this system') + return redirect('two_factor:profile') + return self.get_response(request) diff --git a/smash/smash/settings.py b/smash/smash/settings.py index 15be4ea9c4cd68270d4226892658989016d80985..e147adf43a7ce463b52595802204d800ad3094ea 100644 --- a/smash/smash/settings.py +++ b/smash/smash/settings.py @@ -24,6 +24,9 @@ WSGI_APPLICATION = 'smash.wsgi.application' SERVE_STATIC = False +# whether 2 steps authentication is mandatory to access the system +FORCE_2FA = False + # Application definition INSTALLED_APPS = [ @@ -46,6 +49,7 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ + 'web.middleware.PrivacyNoticeMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', @@ -145,3 +149,5 @@ from .local_settings import * if not SERVE_STATIC: MIDDLEWARE.remove('whitenoise.middleware.WhiteNoiseMiddleware') +if FORCE_2FA: + MIDDLEWARE.append('smash.middleware.force_2fa_middleware.Force2FAMiddleware') diff --git a/smash/web/admin.py b/smash/web/admin.py index dceea27fc8d9814aacd3d8e90a8c0e5868d1b4a9..e1250f3ee86d1a97a1803fff5b48c124101dba3f 100644 --- a/smash/web/admin.py +++ b/smash/web/admin.py @@ -3,7 +3,7 @@ from django.utils.html import format_html from .models import StudySubject, Item, Room, AppointmentType, Language, Location, Worker, FlyingTeam, Availability, \ Holiday, Visit, Appointment, StudyColumns, StudySubjectList, StudyVisitList, VisitColumns, SubjectColumns, \ - Voucher, VoucherType, Provenance + Voucher, VoucherType, Provenance, Subject #good tutorial #https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Admin_site @@ -159,6 +159,7 @@ class ProvenanceAdmin(admin.ModelAdmin): # Register your models here. admin.site.register(StudySubject) +admin.site.register(Subject) admin.site.register(Visit, VisitAdmin) admin.site.register(Item) admin.site.register(Room) diff --git a/smash/web/api_urls.py b/smash/web/api_urls.py index 11a02b7b4c553ecb41c5a1272502ab437bf93e3d..a3baf7356589b4d8dc08a3a592fcad90467d458d 100644 --- a/smash/web/api_urls.py +++ b/smash/web/api_urls.py @@ -64,6 +64,7 @@ urlpatterns = [ url(r'^workers/add_extra_availability/(?P<worker_id>\d+)/(?P<start_str_date>\d{4}-\d{2}-\d{2}-\d{2}-\d{2})/(?P<end_str_date>\d{4}-\d{2}-\d{2}-\d{2}-\d{2})/$', worker.add_worker_extra_availability, name='web.api.workers.add_extra_availability'), + url(r'^worker/accept_privacy_notice/$', worker.accept_privacy_notice, name='web.api.workers.accept_privacy_notice'), # daily planning data url(r'^daily_planning/workers/$', worker.workers_for_daily_planning, name='web.api.workers.daily_planning'), diff --git a/smash/web/api_views/subject.py b/smash/web/api_views/subject.py index 7e3ce4e70a1baa14c8471139864cc64fc27c50de..8a3b3b30fb56e6afc7f9c747bd3545c8944b405a 100644 --- a/smash/web/api_views/subject.py +++ b/smash/web/api_views/subject.py @@ -77,9 +77,9 @@ def get_subject_columns(request, subject_list_type): add_column(result, "Resigned", "resigned", study_subject_columns, "yes_no_filter", study.columns) add_column(result, "Endpoint Reached", "endpoint_reached", study_subject_columns, "yes_no_filter", study.columns) add_column(result, "Postponed", "postponed", study_subject_columns, "yes_no_filter", study.columns) - add_column(result, "Next of keen", "next_of_keen_name", subject_columns, "string_filter") - add_column(result, "Next of keen phone", "next_of_keen_phone", subject_columns, "string_filter") - add_column(result, "Next of keen address", "next_of_keen_address", subject_columns, "string_filter") + add_column(result, "Next of kin", "next_of_kin_name", subject_columns, "string_filter") + add_column(result, "Next of kin phone", "next_of_kin_phone", subject_columns, "string_filter") + add_column(result, "Next of kin address", "next_of_kin_address", subject_columns, "string_filter") add_column(result, "Brain donation agreement", "brain_donation_agreement", study_subject_columns, "yes_no_filter", study.columns) add_column(result, "Excluded", "excluded", study_subject_columns, "yes_no_filter", study.columns) @@ -222,12 +222,12 @@ def get_subjects_order(subjects_to_be_ordered: QuerySet, order_column, order_dir result = subjects_to_be_ordered.order_by(order_direction + 'subject__last_name') elif order_column == "address": result = subjects_to_be_ordered.order_by(order_direction + 'subject__address') - elif order_column == "next_of_keen_name": - result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_keen_name') - elif order_column == "next_of_keen_phone": - result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_keen_phone') - elif order_column == "next_of_keen_address": - result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_keen_address') + elif order_column == "next_of_kin_name": + result = subjects_to_be_ordered.order_by(order_direction + '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') + elif order_column == "next_of_kin_address": + result = subjects_to_be_ordered.order_by(order_direction + 'subject__next_of_kin_address') elif order_column == "nd_number": result = subjects_to_be_ordered.order_by(order_direction + 'nd_number') elif order_column == "referral": @@ -378,12 +378,12 @@ def get_subjects_filtered(subjects_to_be_filtered: QuerySet, filters) -> QuerySe result = result.filter(subject__last_name__icontains=value) elif column == "address": result = result.filter(subject__address__icontains=value) - elif column == "next_of_keen_name": - result = result.filter(subject__next_of_keen_name__icontains=value) - elif column == "next_of_keen_phone": - result = result.filter(subject__next_of_keen_phone__icontains=value) - elif column == "next_of_keen_address": - result = result.filter(subject__next_of_keen_address__icontains=value) + elif column == "next_of_kin_name": + result = result.filter(subject__next_of_kin_name__icontains=value) + elif column == "next_of_kin_phone": + result = result.filter(subject__next_of_kin_phone__icontains=value) + elif column == "next_of_kin_address": + result = result.filter(subject__next_of_kin_address__icontains=value) elif column == "nd_number": result = result.filter(nd_number__icontains=value) elif column == "referral": @@ -593,9 +593,9 @@ def serialize_subject(study_subject): "first_name": study_subject.subject.first_name, "last_name": study_subject.subject.last_name, "address": study_subject.subject.pretty_address(), - "next_of_keen_name": study_subject.subject.next_of_keen_name, - "next_of_keen_phone": study_subject.subject.next_of_keen_phone, - "next_of_keen_address": study_subject.subject.next_of_keen_address, + "next_of_kin_name": study_subject.subject.next_of_kin_name, + "next_of_kin_phone": study_subject.subject.next_of_kin_phone, + "next_of_kin_address": study_subject.subject.next_of_kin_address, "date_born": study_subject.subject.date_born, "datetime_contact_reminder": contact_reminder, "last_contact_attempt": last_contact_attempt_string, diff --git a/smash/web/api_views/worker.py b/smash/web/api_views/worker.py index c956782d4377bb8d365a58dd892aaefcdf429ac0..2ecf1a00a7bb9090abb12a7e34c058bef1049802 100644 --- a/smash/web/api_views/worker.py +++ b/smash/web/api_views/worker.py @@ -26,6 +26,15 @@ def units(request): "units": [x[0] for x in workers] }) + +def accept_privacy_notice(request): + worker = Worker.get_by_user(request.user) + worker.privacy_notice_accepted = True + worker.save() + return JsonResponse({ + "status": 'ok' + }) + def workers_for_daily_planning(request): start_date = request.GET.get('start_date') workers = get_workers_for_daily_planning(request) diff --git a/smash/web/forms/__init__.py b/smash/web/forms/__init__.py index 698f27b4f65ea900c87815a3ffa6fb3b6f08697d..fe81e129a4d942bdb713f4e19f24ccf4a47d9191 100644 --- a/smash/web/forms/__init__.py +++ b/smash/web/forms/__init__.py @@ -1,5 +1,5 @@ from .study_forms import StudyEditForm, StudyNotificationParametersEditForm, StudyColumnsEditForm, StudyRedCapColumnsEditForm -from .worker_form import WorkerForm +from .worker_form import WorkerForm, WorkerAcceptPrivacyNoticeForm from .forms import VisitDetailForm, \ VisitAddForm, KitRequestForm, StatisticsForm, AvailabilityAddForm, \ AvailabilityEditForm, HolidayAddForm @@ -8,10 +8,11 @@ from .appointment_form import AppointmentDetailForm, AppointmentEditForm, Appoin from .study_subject_forms import StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm from .subject_forms import SubjectAddForm, SubjectEditForm, SubjectDetailForm from .voucher_forms import VoucherTypeForm, VoucherTypePriceForm, VoucherForm +from .privacy_notice import PrivacyNoticeForm __all__ = [StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm, WorkerForm, AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, VisitDetailForm, VisitAddForm, ContactAttemptAddForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm, AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm, VoucherTypeForm, VoucherTypePriceForm, VoucherForm, StudyEditForm, StudyNotificationParametersEditForm, StudyColumnsEditForm, - StudyRedCapColumnsEditForm] + StudyRedCapColumnsEditForm, PrivacyNoticeForm, WorkerAcceptPrivacyNoticeForm] diff --git a/smash/web/forms/privacy_notice.py b/smash/web/forms/privacy_notice.py new file mode 100644 index 0000000000000000000000000000000000000000..9394fe3687c142c54dbab9ef6d2b0e3c23ccf50e --- /dev/null +++ b/smash/web/forms/privacy_notice.py @@ -0,0 +1,15 @@ +from django import forms +from django.forms import ModelForm +from web.models import PrivacyNotice + +import logging +logger = logging.getLogger(__name__) + +class PrivacyNoticeForm(ModelForm): + class Meta: + model = PrivacyNotice + fields = '__all__' + + def clean(self): + cleaned_data = super().clean() + return cleaned_data \ No newline at end of file diff --git a/smash/web/forms/worker_form.py b/smash/web/forms/worker_form.py index 25c4cc8df80a06ff60c6da7db42bd03dc45d6ec4..f82362938e92ed58bce1c113ec206699a5de5a7a 100644 --- a/smash/web/forms/worker_form.py +++ b/smash/web/forms/worker_form.py @@ -14,6 +14,19 @@ from web.decorators import PermissionDecorator logger = logging.getLogger(__name__) +class WorkerAcceptPrivacyNoticeForm(ModelForm): + class Meta: + model = Worker + fields = ('privacy_notice_accepted', ) + + def __init__(self, *args, **kwargs): + super(WorkerAcceptPrivacyNoticeForm, self).__init__(*args, **kwargs) + self.fields['privacy_notice_accepted'].label = 'Do you accept the privacy notice?' + + def clean(self): + cleaned_data = super().clean() + cleaned_data['privacy_notice_accepted'] = True + return cleaned_data class WorkerForm(ModelForm): class Meta: @@ -63,7 +76,9 @@ class WorkerForm(ModelForm): self.fields['Superuser'].initial = instance.user.is_superuser del self.fields['voucher_types'] del self.fields['name'] + self.fields['privacy_notice_accepted'].widget.attrs['readonly'] = True else: + del self.fields['privacy_notice_accepted'] del self.fields['locations'] del self.fields['first_name'] del self.fields['last_name'] @@ -73,7 +88,7 @@ class WorkerForm(ModelForm): fields = OrderedDict() - if worker_type == WORKER_STAFF: + if worker_type == WORKER_STAFF: if instance is None or instance.pk is None: fields['login'] = forms.CharField(label='Login') fields['password'] = forms.CharField(label='Password', widget=forms.PasswordInput) diff --git a/smash/web/importer/csv_tns_subject_import_reader.py b/smash/web/importer/csv_tns_subject_import_reader.py index c20862be0a42ffc977bdf3d772d16079b32aabc4..3c27fe8e53a26160d4caf8ba31a0a70298a3e7c5 100644 --- a/smash/web/importer/csv_tns_subject_import_reader.py +++ b/smash/web/importer/csv_tns_subject_import_reader.py @@ -54,8 +54,8 @@ class TnsCsvSubjectImportReader(SubjectImportReader): study_subject.subject.phone_number = self.get_new_value(study_subject.subject.phone_number, column_name, value) elif column_name == "representative": - study_subject.subject.next_of_keen_name = self.get_new_value(study_subject.subject.next_of_keen_name, - column_name, value) + study_subject.subject.next_of_kin_name = self.get_new_value(study_subject.subject.next_of_kin_name, + column_name, value) elif column_name == "treatingphysician": if value is not None and value != "": value = "Treating physician: " + value diff --git a/smash/web/middleware.py b/smash/web/middleware.py new file mode 100644 index 0000000000000000000000000000000000000000..e094a84f09c91c120fb0634d2b2e196c4a6cedea --- /dev/null +++ b/smash/web/middleware.py @@ -0,0 +1,39 @@ +from django.contrib.auth.views import logout + +from web.models.constants import GLOBAL_STUDY_ID +from web.models import Worker, Study +from django.contrib import messages +from django.urls import reverse +from django.shortcuts import redirect +from django.utils.deprecation import MiddlewareMixin +from web.views.privacy_notice import privacy_notice_accept + +class PrivacyNoticeMiddleware(MiddlewareMixin): + #def __init__(self, get_response): + #self.get_response = get_response + # One-time configuration and initialization. + + def process_view(self, request, view_func, view_args, view_kwargs): + # Code to be executed for each request before + # the view (and later middleware) are called. + + #response = self.get_response(request) + if request.user.is_authenticated \ + and not view_func == privacy_notice_accept \ + and not request.user.is_superuser \ + and not view_func == logout: + study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] + worker = Worker.get_by_user(request.user) + if worker is None: + return None + if study.study_privacy_notice \ + and study.acceptance_of_study_privacy_notice_required \ + and not worker.privacy_notice_accepted\ + and study.study_privacy_notice.document.url != request.path: + messages.add_message(request, messages.WARNING, "You can't use the system until you accept the privacy notice.") + #return reverse_lazy('web.views.accept_privacy_notice', kwargs={'pk': study.study_privacy_notice}) + return redirect(reverse('web.views.accept_privacy_notice', kwargs={'pk': study.study_privacy_notice.id})) + + # Code to be executed for each request/response after + # the view is called. + return None \ No newline at end of file diff --git a/smash/web/migrations/0001_initial.py b/smash/web/migrations/0001_initial.py index 03eecd51456b2d21104465558f53285bca9f9355..7d3f9800878b0d32e9b1a011bd12d7e3a57bd432 100644 --- a/smash/web/migrations/0001_initial.py +++ b/smash/web/migrations/0001_initial.py @@ -74,7 +74,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=20)), - ('image', models.ImageField(upload_to=b'')), + ('image', models.ImageField(upload_to='')), ], ), migrations.CreateModel( diff --git a/smash/web/migrations/0022_auto_20170403_0904.py b/smash/web/migrations/0022_auto_20170403_0904.py index 95aee17872f28c119ae8b03ad436f4004ffd68e5..bde42f6c5487879a6f0f1857205ccb88a69cd459 100644 --- a/smash/web/migrations/0022_auto_20170403_0904.py +++ b/smash/web/migrations/0022_auto_20170403_0904.py @@ -20,31 +20,31 @@ class Migration(migrations.Migration): migrations.AddField( model_name='worker', name='screening_number_prefix', - field=models.CharField(blank=True, max_length=1, null=True, verbose_name=b'Default screening number prefix'), + field=models.CharField(blank=True, max_length=1, null=True, verbose_name='Default screening number prefix'), ), migrations.AlterField( model_name='appointment', name='status', - field=models.CharField(choices=[(b'SCHEDULED', b'Scheduled'), (b'CANCELLED', b'Cancelled'), (b'FINISHED', b'Finished'), (b'NO_SHOW', b'No Show')], default=b'SCHEDULED', max_length=20, verbose_name=b'Status'), + field=models.CharField(choices=[('SCHEDULED', 'Scheduled'), ('CANCELLED', 'Cancelled'), ('FINISHED', 'Finished'), ('NO_SHOW', 'No Show')], default='SCHEDULED', max_length=20, verbose_name='Status'), ), migrations.AlterField( model_name='appointment', name='visit', - field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Visit', verbose_name=b'Visit ID'), + field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Visit', verbose_name='Visit ID'), ), migrations.AlterField( model_name='subject', name='dead', - field=models.BooleanField(default=False, verbose_name=b'Deceased'), + field=models.BooleanField(default=False, verbose_name='Deceased'), ), migrations.AlterField( model_name='subject', name='resigned', - field=models.BooleanField(default=False, verbose_name=b'Resigned'), + field=models.BooleanField(default=False, verbose_name='Resigned'), ), migrations.AlterField( model_name='subject', name='type', - field=models.CharField(choices=[(b'P', b'PATIENT'), (b'C', b'CONTROL')], max_length=1, verbose_name=b'Type'), + field=models.CharField(choices=[('P', 'PATIENT'), ('C', 'CONTROL')], max_length=1, verbose_name='Type'), ), ] diff --git a/smash/web/migrations/0023_auto_20170404_1047.py b/smash/web/migrations/0023_auto_20170404_1047.py index d62117ae22cbb2ccff9b08488033a768bb117b81..8e5da3b0300a02610f5150979a3501c82b128011 100644 --- a/smash/web/migrations/0023_auto_20170404_1047.py +++ b/smash/web/migrations/0023_auto_20170404_1047.py @@ -17,23 +17,23 @@ class Migration(migrations.Migration): name='Availability', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('day_number', models.IntegerField(verbose_name=b'Day of the week')), - ('available_from', models.TimeField(verbose_name=b'Available since')), - ('available_till', models.TimeField(verbose_name=b'Available until')), - ('is_current', models.BooleanField(default=True, verbose_name=b'Is current?')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name=b'Worker')), + ('day_number', models.IntegerField(verbose_name='Day of the week')), + ('available_from', models.TimeField(verbose_name='Available since')), + ('available_till', models.TimeField(verbose_name='Available until')), + ('is_current', models.BooleanField(default=True, verbose_name='Is current?')), + ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name='Worker')), ], ), migrations.CreateModel( name='ContactAttempt', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[(b'E', b'Email'), (b'F', b'Face to face'), (b'X', b'Fax'), (b'P', b'Phone'), (b'S', b'SMS')], default=b'P', max_length=2)), - ('datetime_when', models.DateTimeField(help_text=b'When did the contact occurred?', verbose_name=b'Contact on')), + ('type', models.CharField(choices=[('E', 'Email'), ('F', 'Face to face'), ('X', 'Fax'), ('P', 'Phone'), ('S', 'SMS')], default='P', max_length=2)), + ('datetime_when', models.DateTimeField(help_text='When did the contact occurred?', verbose_name='Contact on')), ('success', models.BooleanField(default=False)), ('comment', models.TextField(blank=True, max_length=1024, null=True)), - ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name=b'Subject')), - ('worker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name=b'Worker')), + ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name='Subject')), + ('worker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name='Worker')), ], ), migrations.RemoveField( diff --git a/smash/web/migrations/0024_configurationitem.py b/smash/web/migrations/0024_configurationitem.py index d71473f90b24bfa489f22c2a826af8d0064b3a82..9ad06c81f61153b38fc8af6f35bb9fbb0201a39c 100644 --- a/smash/web/migrations/0024_configurationitem.py +++ b/smash/web/migrations/0024_configurationitem.py @@ -16,9 +16,9 @@ class Migration(migrations.Migration): name='ConfigurationItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(editable=False, max_length=50, verbose_name=b'Type')), - ('name', models.CharField(editable=False, max_length=50, verbose_name=b'Name')), - ('value', models.CharField(max_length=50, verbose_name=b'Value')), + ('type', models.CharField(editable=False, max_length=50, verbose_name='Type')), + ('name', models.CharField(editable=False, max_length=50, verbose_name='Name')), + ('value', models.CharField(max_length=50, verbose_name='Value')), ], ), ] diff --git a/smash/web/migrations/0026_location_color.py b/smash/web/migrations/0026_location_color.py index 675cd0a345428457e6b195f53f194829ef25e6d2..86ea8a9e73177c00cc1f36e0f8a615824ccb390f 100644 --- a/smash/web/migrations/0026_location_color.py +++ b/smash/web/migrations/0026_location_color.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='location', name='color', - field=models.CharField(blank=True, default=b'', max_length=20), + field=models.CharField(blank=True, default='', max_length=20), ), ] diff --git a/smash/web/migrations/0027_auto_20170404_1505.py b/smash/web/migrations/0027_auto_20170404_1505.py index c602732507708070c1b23f84bc4ee5c8de99a94b..0bc24c432df5dab6c7263c010a464f4c3743cca3 100644 --- a/smash/web/migrations/0027_auto_20170404_1505.py +++ b/smash/web/migrations/0027_auto_20170404_1505.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='location', name='color', - field=models.CharField(blank=True, default=b'', max_length=20, verbose_name=b'Calendar appointment color'), + field=models.CharField(blank=True, default='', max_length=20, verbose_name='Calendar appointment color'), ), ] diff --git a/smash/web/migrations/0029_auto_20170404_1616.py b/smash/web/migrations/0029_auto_20170404_1616.py index aaa9f0c7dbecc85d026787ac6493a344a83a3d63..f8daac9c44a79cdb033a4b2be104c5062fe35ca7 100644 --- a/smash/web/migrations/0029_auto_20170404_1616.py +++ b/smash/web/migrations/0029_auto_20170404_1616.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='subject', name='information_sent', - field=models.BooleanField(default=False, verbose_name=b'Information sent'), + field=models.BooleanField(default=False, verbose_name='Information sent'), ), migrations.AddField( model_name='subject', name='pd_in_family', - field=models.BooleanField(default=False, verbose_name=b'PD in family'), + field=models.BooleanField(default=False, verbose_name='PD in family'), ), ] diff --git a/smash/web/migrations/0031_appointment_post_mail_sent.py b/smash/web/migrations/0031_appointment_post_mail_sent.py index 173aa65ef70598333d50930c18494542eb70cf54..9284b69d2dad1bb684817a49cb0d62ffcb62fea4 100644 --- a/smash/web/migrations/0031_appointment_post_mail_sent.py +++ b/smash/web/migrations/0031_appointment_post_mail_sent.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='appointment', name='post_mail_sent', - field=models.BooleanField(default=False, verbose_name=b'Post mail sent'), + field=models.BooleanField(default=False, verbose_name='Post mail sent'), ), ] diff --git a/smash/web/migrations/0033_auto_20170406_1146.py b/smash/web/migrations/0033_auto_20170406_1146.py index c8b6295cdfc814542d0c766fbb55e5e4b98f390d..8145505320c8a2548132e1f0e721bd629e298225 100644 --- a/smash/web/migrations/0033_auto_20170406_1146.py +++ b/smash/web/migrations/0033_auto_20170406_1146.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='datetime_contact_reminder', - field=models.DateTimeField(blank=True, null=True, verbose_name=b'Contact on'), + field=models.DateTimeField(blank=True, null=True, verbose_name='Contact on'), ), ] diff --git a/smash/web/migrations/0034_mail_templates.py b/smash/web/migrations/0034_mail_templates.py index 4539c95200a252195284fd9c3cad005e364f6d50..9b6564ae17e078990db40fad235e9c7dda07e91c 100644 --- a/smash/web/migrations/0034_mail_templates.py +++ b/smash/web/migrations/0034_mail_templates.py @@ -47,9 +47,9 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=255)), - ('context', models.CharField(choices=[(b'A', b'Appointment'), (b'S', b'Subject'), (b'V', b'Visit')], + ('context', models.CharField(choices=[('A', 'Appointment'), ('S', 'Subject'), ('V', 'Visit')], max_length=1)), - ('template_file', models.FileField(upload_to=b'templates/')), + ('template_file', models.FileField(upload_to='templates/')), ], ), migrations.AlterModelOptions( @@ -60,59 +60,59 @@ class Migration(migrations.Migration): model_name='language', name='locale', field=models.CharField( - choices=[(b'af_ZA', b'af_ZA'), (b'am_ET', b'am_ET'), (b'ar_AE', b'ar_AE'), (b'ar_BH', b'ar_BH'), - (b'ar_DZ', b'ar_DZ'), (b'ar_EG', b'ar_EG'), (b'ar_IQ', b'ar_IQ'), (b'ar_JO', b'ar_JO'), - (b'ar_KW', b'ar_KW'), (b'ar_LB', b'ar_LB'), (b'ar_LY', b'ar_LY'), (b'ar_MA', b'ar_MA'), - (b'ar_OM', b'ar_OM'), (b'ar_QA', b'ar_QA'), (b'ar_SA', b'ar_SA'), (b'ar_SY', b'ar_SY'), - (b'ar_TN', b'ar_TN'), (b'ar_YE', b'ar_YE'), (b'arn_CL', b'arn_CL'), (b'as_IN', b'as_IN'), - (b'az_AZ', b'az_AZ'), (b'az_AZ', b'az_AZ'), (b'ba_RU', b'ba_RU'), (b'be_BY', b'be_BY'), - (b'bg_BG', b'bg_BG'), (b'bn_IN', b'bn_IN'), (b'bo_BT', b'bo_BT'), (b'bo_CN', b'bo_CN'), - (b'br_FR', b'br_FR'), (b'bs_BA', b'bs_BA'), (b'bs_BA', b'bs_BA'), (b'ca_ES', b'ca_ES'), - (b'co_FR', b'co_FR'), (b'cs_CZ', b'cs_CZ'), (b'cy_GB', b'cy_GB'), (b'da_DK', b'da_DK'), - (b'de_AT', b'de_AT'), (b'de_CH', b'de_CH'), (b'de_DE', b'de_DE'), (b'de_LI', b'de_LI'), - (b'de_LU', b'de_LU'), (b'div_MV', b'div_MV'), (b'dsb_DE', b'dsb_DE'), (b'el_GR', b'el_GR'), - (b'en_AU', b'en_AU'), (b'en_BZ', b'en_BZ'), (b'en_CA', b'en_CA'), (b'en_CB', b'en_CB'), - (b'en_GB', b'en_GB'), (b'en_IE', b'en_IE'), (b'en_IN', b'en_IN'), (b'en_IN', b'en_IN'), - (b'en_JA', b'en_JA'), (b'en_MY', b'en_MY'), (b'en_NZ', b'en_NZ'), (b'en_PH', b'en_PH'), - (b'en_TT', b'en_TT'), (b'en_US', b'en_US'), (b'en_ZA', b'en_ZA'), (b'en_ZW', b'en_ZW'), - (b'es_AR', b'es_AR'), (b'es_BO', b'es_BO'), (b'es_CL', b'es_CL'), (b'es_CO', b'es_CO'), - (b'es_CR', b'es_CR'), (b'es_DO', b'es_DO'), (b'es_EC', b'es_EC'), (b'es_ES', b'es_ES'), - (b'es_ES', b'es_ES'), (b'es_GT', b'es_GT'), (b'es_HN', b'es_HN'), (b'es_MX', b'es_MX'), - (b'es_NI', b'es_NI'), (b'es_PA', b'es_PA'), (b'es_PE', b'es_PE'), (b'es_PR', b'es_PR'), - (b'es_PY', b'es_PY'), (b'es_SV', b'es_SV'), (b'es_UR', b'es_UR'), (b'es_US', b'es_US'), - (b'es_VE', b'es_VE'), (b'et_EE', b'et_EE'), (b'eu_ES', b'eu_ES'), (b'fa_IR', b'fa_IR'), - (b'fi_FI', b'fi_FI'), (b'fil_PH', b'fil_PH'), (b'fo_FO', b'fo_FO'), (b'fr_BE', b'fr_BE'), - (b'fr_CA', b'fr_CA'), (b'fr_CH', b'fr_CH'), (b'fr_FR', b'fr_FR'), (b'fr_LU', b'fr_LU'), - (b'fr_MC', b'fr_MC'), (b'fy_NL', b'fy_NL'), (b'ga_IE', b'ga_IE'), (b'gbz_AF', b'gbz_AF'), - (b'gl_ES', b'gl_ES'), (b'gsw_FR', b'gsw_FR'), (b'gu_IN', b'gu_IN'), (b'ha_NG', b'ha_NG'), - (b'he_IL', b'he_IL'), (b'hi_IN', b'hi_IN'), (b'hr_BA', b'hr_BA'), (b'hr_HR', b'hr_HR'), - (b'hu_HU', b'hu_HU'), (b'hy_AM', b'hy_AM'), (b'id_ID', b'id_ID'), (b'ii_CN', b'ii_CN'), - (b'is_IS', b'is_IS'), (b'it_CH', b'it_CH'), (b'it_IT', b'it_IT'), (b'iu_CA', b'iu_CA'), - (b'iu_CA', b'iu_CA'), (b'ja_JP', b'ja_JP'), (b'ka_GE', b'ka_GE'), (b'kh_KH', b'kh_KH'), - (b'kk_KZ', b'kk_KZ'), (b'kl_GL', b'kl_GL'), (b'kn_IN', b'kn_IN'), (b'ko_KR', b'ko_KR'), - (b'kok_IN', b'kok_IN'), (b'ky_KG', b'ky_KG'), (b'lb_LU', b'lb_LU'), (b'lo_LA', b'lo_LA'), - (b'lt_LT', b'lt_LT'), (b'lv_LV', b'lv_LV'), (b'mi_NZ', b'mi_NZ'), (b'mk_MK', b'mk_MK'), - (b'ml_IN', b'ml_IN'), (b'mn_CN', b'mn_CN'), (b'mn_MN', b'mn_MN'), (b'moh_CA', b'moh_CA'), - (b'mr_IN', b'mr_IN'), (b'ms_BN', b'ms_BN'), (b'ms_MY', b'ms_MY'), (b'mt_MT', b'mt_MT'), - (b'nb_NO', b'nb_NO'), (b'ne_NP', b'ne_NP'), (b'nl_BE', b'nl_BE'), (b'nl_NL', b'nl_NL'), - (b'nn_NO', b'nn_NO'), (b'ns_ZA', b'ns_ZA'), (b'oc_FR', b'oc_FR'), (b'or_IN', b'or_IN'), - (b'pa_IN', b'pa_IN'), (b'pl_PL', b'pl_PL'), (b'ps_AF', b'ps_AF'), (b'pt_BR', b'pt_BR'), - (b'pt_PT', b'pt_PT'), (b'qut_GT', b'qut_GT'), (b'quz_BO', b'quz_BO'), (b'quz_EC', b'quz_EC'), - (b'quz_PE', b'quz_PE'), (b'rm_CH', b'rm_CH'), (b'ro_RO', b'ro_RO'), (b'ru_RU', b'ru_RU'), - (b'rw_RW', b'rw_RW'), (b'sa_IN', b'sa_IN'), (b'sah_RU', b'sah_RU'), (b'se_FI', b'se_FI'), - (b'se_NO', b'se_NO'), (b'se_SE', b'se_SE'), (b'si_LK', b'si_LK'), (b'sk_SK', b'sk_SK'), - (b'sl_SI', b'sl_SI'), (b'sma_NO', b'sma_NO'), (b'sma_SE', b'sma_SE'), (b'smj_NO', b'smj_NO'), - (b'smj_SE', b'smj_SE'), (b'smn_FI', b'smn_FI'), (b'sms_FI', b'sms_FI'), (b'sq_AL', b'sq_AL'), - (b'sr_BA', b'sr_BA'), (b'sr_BA', b'sr_BA'), (b'sr_SP', b'sr_SP'), (b'sr_SP', b'sr_SP'), - (b'sv_FI', b'sv_FI'), (b'sv_SE', b'sv_SE'), (b'sw_KE', b'sw_KE'), (b'syr_SY', b'syr_SY'), - (b'ta_IN', b'ta_IN'), (b'te_IN', b'te_IN'), (b'tg_TJ', b'tg_TJ'), (b'th_TH', b'th_TH'), - (b'tk_TM', b'tk_TM'), (b'tmz_DZ', b'tmz_DZ'), (b'tn_ZA', b'tn_ZA'), (b'tr_TR', b'tr_TR'), - (b'tt_RU', b'tt_RU'), (b'ug_CN', b'ug_CN'), (b'uk_UA', b'uk_UA'), (b'ur_IN', b'ur_IN'), - (b'ur_PK', b'ur_PK'), (b'uz_UZ', b'uz_UZ'), (b'uz_UZ', b'uz_UZ'), (b'vi_VN', b'vi_VN'), - (b'wen_DE', b'wen_DE'), (b'wo_SN', b'wo_SN'), (b'xh_ZA', b'xh_ZA'), (b'yo_NG', b'yo_NG'), - (b'zh_CHS', b'zh_CHS'), (b'zh_CHT', b'zh_CHT'), (b'zh_CN', b'zh_CN'), (b'zh_HK', b'zh_HK'), - (b'zh_MO', b'zh_MO'), (b'zh_SG', b'zh_SG'), (b'zh_TW', b'zh_TW'), (b'zu_ZA', b'zu_ZA')], - default=b'fr_FR', max_length=10), + choices=[('af_ZA', 'af_ZA'), ('am_ET', 'am_ET'), ('ar_AE', 'ar_AE'), ('ar_BH', 'ar_BH'), + ('ar_DZ', 'ar_DZ'), ('ar_EG', 'ar_EG'), ('ar_IQ', 'ar_IQ'), ('ar_JO', 'ar_JO'), + ('ar_KW', 'ar_KW'), ('ar_LB', 'ar_LB'), ('ar_LY', 'ar_LY'), ('ar_MA', 'ar_MA'), + ('ar_OM', 'ar_OM'), ('ar_QA', 'ar_QA'), ('ar_SA', 'ar_SA'), ('ar_SY', 'ar_SY'), + ('ar_TN', 'ar_TN'), ('ar_YE', 'ar_YE'), ('arn_CL', 'arn_CL'), ('as_IN', 'as_IN'), + ('az_AZ', 'az_AZ'), ('az_AZ', 'az_AZ'), ('ba_RU', 'ba_RU'), ('be_BY', 'be_BY'), + ('bg_BG', 'bg_BG'), ('bn_IN', 'bn_IN'), ('bo_BT', 'bo_BT'), ('bo_CN', 'bo_CN'), + ('br_FR', 'br_FR'), ('bs_BA', 'bs_BA'), ('bs_BA', 'bs_BA'), ('ca_ES', 'ca_ES'), + ('co_FR', 'co_FR'), ('cs_CZ', 'cs_CZ'), ('cy_GB', 'cy_GB'), ('da_DK', 'da_DK'), + ('de_AT', 'de_AT'), ('de_CH', 'de_CH'), ('de_DE', 'de_DE'), ('de_LI', 'de_LI'), + ('de_LU', 'de_LU'), ('div_MV', 'div_MV'), ('dsb_DE', 'dsb_DE'), ('el_GR', 'el_GR'), + ('en_AU', 'en_AU'), ('en_BZ', 'en_BZ'), ('en_CA', 'en_CA'), ('en_CB', 'en_CB'), + ('en_GB', 'en_GB'), ('en_IE', 'en_IE'), ('en_IN', 'en_IN'), ('en_IN', 'en_IN'), + ('en_JA', 'en_JA'), ('en_MY', 'en_MY'), ('en_NZ', 'en_NZ'), ('en_PH', 'en_PH'), + ('en_TT', 'en_TT'), ('en_US', 'en_US'), ('en_ZA', 'en_ZA'), ('en_ZW', 'en_ZW'), + ('es_AR', 'es_AR'), ('es_BO', 'es_BO'), ('es_CL', 'es_CL'), ('es_CO', 'es_CO'), + ('es_CR', 'es_CR'), ('es_DO', 'es_DO'), ('es_EC', 'es_EC'), ('es_ES', 'es_ES'), + ('es_ES', 'es_ES'), ('es_GT', 'es_GT'), ('es_HN', 'es_HN'), ('es_MX', 'es_MX'), + ('es_NI', 'es_NI'), ('es_PA', 'es_PA'), ('es_PE', 'es_PE'), ('es_PR', 'es_PR'), + ('es_PY', 'es_PY'), ('es_SV', 'es_SV'), ('es_UR', 'es_UR'), ('es_US', 'es_US'), + ('es_VE', 'es_VE'), ('et_EE', 'et_EE'), ('eu_ES', 'eu_ES'), ('fa_IR', 'fa_IR'), + ('fi_FI', 'fi_FI'), ('fil_PH', 'fil_PH'), ('fo_FO', 'fo_FO'), ('fr_BE', 'fr_BE'), + ('fr_CA', 'fr_CA'), ('fr_CH', 'fr_CH'), ('fr_FR', 'fr_FR'), ('fr_LU', 'fr_LU'), + ('fr_MC', 'fr_MC'), ('fy_NL', 'fy_NL'), ('ga_IE', 'ga_IE'), ('gbz_AF', 'gbz_AF'), + ('gl_ES', 'gl_ES'), ('gsw_FR', 'gsw_FR'), ('gu_IN', 'gu_IN'), ('ha_NG', 'ha_NG'), + ('he_IL', 'he_IL'), ('hi_IN', 'hi_IN'), ('hr_BA', 'hr_BA'), ('hr_HR', 'hr_HR'), + ('hu_HU', 'hu_HU'), ('hy_AM', 'hy_AM'), ('id_ID', 'id_ID'), ('ii_CN', 'ii_CN'), + ('is_IS', 'is_IS'), ('it_CH', 'it_CH'), ('it_IT', 'it_IT'), ('iu_CA', 'iu_CA'), + ('iu_CA', 'iu_CA'), ('ja_JP', 'ja_JP'), ('ka_GE', 'ka_GE'), ('kh_KH', 'kh_KH'), + ('kk_KZ', 'kk_KZ'), ('kl_GL', 'kl_GL'), ('kn_IN', 'kn_IN'), ('ko_KR', 'ko_KR'), + ('kok_IN', 'kok_IN'), ('ky_KG', 'ky_KG'), ('lb_LU', 'lb_LU'), ('lo_LA', 'lo_LA'), + ('lt_LT', 'lt_LT'), ('lv_LV', 'lv_LV'), ('mi_NZ', 'mi_NZ'), ('mk_MK', 'mk_MK'), + ('ml_IN', 'ml_IN'), ('mn_CN', 'mn_CN'), ('mn_MN', 'mn_MN'), ('moh_CA', 'moh_CA'), + ('mr_IN', 'mr_IN'), ('ms_BN', 'ms_BN'), ('ms_MY', 'ms_MY'), ('mt_MT', 'mt_MT'), + ('nb_NO', 'nb_NO'), ('ne_NP', 'ne_NP'), ('nl_BE', 'nl_BE'), ('nl_NL', 'nl_NL'), + ('nn_NO', 'nn_NO'), ('ns_ZA', 'ns_ZA'), ('oc_FR', 'oc_FR'), ('or_IN', 'or_IN'), + ('pa_IN', 'pa_IN'), ('pl_PL', 'pl_PL'), ('ps_AF', 'ps_AF'), ('pt_BR', 'pt_BR'), + ('pt_PT', 'pt_PT'), ('qut_GT', 'qut_GT'), ('quz_BO', 'quz_BO'), ('quz_EC', 'quz_EC'), + ('quz_PE', 'quz_PE'), ('rm_CH', 'rm_CH'), ('ro_RO', 'ro_RO'), ('ru_RU', 'ru_RU'), + ('rw_RW', 'rw_RW'), ('sa_IN', 'sa_IN'), ('sah_RU', 'sah_RU'), ('se_FI', 'se_FI'), + ('se_NO', 'se_NO'), ('se_SE', 'se_SE'), ('si_LK', 'si_LK'), ('sk_SK', 'sk_SK'), + ('sl_SI', 'sl_SI'), ('sma_NO', 'sma_NO'), ('sma_SE', 'sma_SE'), ('smj_NO', 'smj_NO'), + ('smj_SE', 'smj_SE'), ('smn_FI', 'smn_FI'), ('sms_FI', 'sms_FI'), ('sq_AL', 'sq_AL'), + ('sr_BA', 'sr_BA'), ('sr_BA', 'sr_BA'), ('sr_SP', 'sr_SP'), ('sr_SP', 'sr_SP'), + ('sv_FI', 'sv_FI'), ('sv_SE', 'sv_SE'), ('sw_KE', 'sw_KE'), ('syr_SY', 'syr_SY'), + ('ta_IN', 'ta_IN'), ('te_IN', 'te_IN'), ('tg_TJ', 'tg_TJ'), ('th_TH', 'th_TH'), + ('tk_TM', 'tk_TM'), ('tmz_DZ', 'tmz_DZ'), ('tn_ZA', 'tn_ZA'), ('tr_TR', 'tr_TR'), + ('tt_RU', 'tt_RU'), ('ug_CN', 'ug_CN'), ('uk_UA', 'uk_UA'), ('ur_IN', 'ur_IN'), + ('ur_PK', 'ur_PK'), ('uz_UZ', 'uz_UZ'), ('uz_UZ', 'uz_UZ'), ('vi_VN', 'vi_VN'), + ('wen_DE', 'wen_DE'), ('wo_SN', 'wo_SN'), ('xh_ZA', 'xh_ZA'), ('yo_NG', 'yo_NG'), + ('zh_CHS', 'zh_CHS'), ('zh_CHT', 'zh_CHT'), ('zh_CN', 'zh_CN'), ('zh_HK', 'zh_HK'), + ('zh_MO', 'zh_MO'), ('zh_SG', 'zh_SG'), ('zh_TW', 'zh_TW'), ('zu_ZA', 'zu_ZA')], + default='fr_FR', max_length=10), ), migrations.AddField( model_name='language', diff --git a/smash/web/migrations/0036_year_of_diagnosis_default.py b/smash/web/migrations/0036_year_of_diagnosis_default.py index 43d9d2bfa9a6fca0b0b4e1ae1cec4a24c582b87b..8ceadb773e793c2814f9a8f7440495cfea8310bd 100644 --- a/smash/web/migrations/0036_year_of_diagnosis_default.py +++ b/smash/web/migrations/0036_year_of_diagnosis_default.py @@ -14,7 +14,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='year_of_diagnosis', - field=models.IntegerField(blank=True, null=True, verbose_name=b'Year of diagnosis (YYYY)'), + field=models.IntegerField(blank=True, null=True, verbose_name='Year of diagnosis (YYYY)'), ), migrations.RunSQL( "UPDATE web_subject SET year_of_diagnosis=NULL WHERE year_of_diagnosis = 0;", diff --git a/smash/web/migrations/0038_subject_pd_family_allow_null.py b/smash/web/migrations/0038_subject_pd_family_allow_null.py index 84a908f2f12e149cf55ec8080681a07c3f2bdea6..4171c3f50412314c4a7ac3fcc9155d87bdfcedf8 100644 --- a/smash/web/migrations/0038_subject_pd_family_allow_null.py +++ b/smash/web/migrations/0038_subject_pd_family_allow_null.py @@ -14,11 +14,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='contactattempt', name='datetime_when', - field=models.DateTimeField(help_text=b'When did the contact occurred?', verbose_name=b'When'), + field=models.DateTimeField(help_text='When did the contact occurred?', verbose_name='When'), ), migrations.AlterField( model_name='subject', name='pd_in_family', - field=models.NullBooleanField(default=False, verbose_name=b'PD in family'), + field=models.NullBooleanField(default=False, verbose_name='PD in family'), ), ] diff --git a/smash/web/migrations/0039_pd_family_default_unknown.py b/smash/web/migrations/0039_pd_family_default_unknown.py index d8f27658ff2c7fb3e8db7906b489e5028e66201f..b2cba262b98247b7b6e288485a1d57297c81a4f3 100644 --- a/smash/web/migrations/0039_pd_family_default_unknown.py +++ b/smash/web/migrations/0039_pd_family_default_unknown.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='pd_in_family', - field=models.NullBooleanField(default=None, verbose_name=b'PD in family'), + field=models.NullBooleanField(default=None, verbose_name='PD in family'), )] if is_sqlite_db(): operations.append( diff --git a/smash/web/migrations/0040_daily_planning.py b/smash/web/migrations/0040_daily_planning.py index 13337273897a613b0c7c2e69bd22894c7f19c46d..ce59986f6286c0bed8bc0a19ef6e5f6f2b2f5f9b 100644 --- a/smash/web/migrations/0040_daily_planning.py +++ b/smash/web/migrations/0040_daily_planning.py @@ -35,7 +35,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='appointment', name='appointment_types_new', - field=models.ManyToManyField(blank=True, related_name='new_appointment', through='web.AppointmentTypeLink', to='web.AppointmentType', verbose_name=b'Appointment types'), + field=models.ManyToManyField(blank=True, related_name='new_appointment', through='web.AppointmentTypeLink', to='web.AppointmentType', verbose_name='Appointment types'), ), migrations.RunPython(convert_records), migrations.RunSQL( diff --git a/smash/web/migrations/0041_language_windows_locale_name.py b/smash/web/migrations/0041_language_windows_locale_name.py index 44f218ed1535d5a95cce436f568264b06f2500fe..1c7d7909b9426ef32d60b5c14be12f0f7fb24b65 100644 --- a/smash/web/migrations/0041_language_windows_locale_name.py +++ b/smash/web/migrations/0041_language_windows_locale_name.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='language', name='windows_locale_name', - field=models.CharField(choices=[(b'af_ZA', b'af_ZA'), (b'am_ET', b'am_ET'), (b'ar_AE', b'ar_AE'), (b'ar_BH', b'ar_BH'), (b'ar_DZ', b'ar_DZ'), (b'ar_EG', b'ar_EG'), (b'ar_IQ', b'ar_IQ'), (b'ar_JO', b'ar_JO'), (b'ar_KW', b'ar_KW'), (b'ar_LB', b'ar_LB'), (b'ar_LY', b'ar_LY'), (b'ar_MA', b'ar_MA'), (b'ar_OM', b'ar_OM'), (b'ar_QA', b'ar_QA'), (b'ar_SA', b'ar_SA'), (b'ar_SY', b'ar_SY'), (b'ar_TN', b'ar_TN'), (b'ar_YE', b'ar_YE'), (b'arn_CL', b'arn_CL'), (b'as_IN', b'as_IN'), (b'az_AZ', b'az_AZ'), (b'az_AZ', b'az_AZ'), (b'ba_RU', b'ba_RU'), (b'be_BY', b'be_BY'), (b'bg_BG', b'bg_BG'), (b'bn_IN', b'bn_IN'), (b'bo_BT', b'bo_BT'), (b'bo_CN', b'bo_CN'), (b'br_FR', b'br_FR'), (b'bs_BA', b'bs_BA'), (b'bs_BA', b'bs_BA'), (b'ca_ES', b'ca_ES'), (b'co_FR', b'co_FR'), (b'cs_CZ', b'cs_CZ'), (b'cy_GB', b'cy_GB'), (b'da_DK', b'da_DK'), (b'de_AT', b'de_AT'), (b'de_CH', b'de_CH'), (b'de_DE', b'de_DE'), (b'de_LI', b'de_LI'), (b'de_LU', b'de_LU'), (b'div_MV', b'div_MV'), (b'dsb_DE', b'dsb_DE'), (b'el_GR', b'el_GR'), (b'en_AU', b'en_AU'), (b'en_BZ', b'en_BZ'), (b'en_CA', b'en_CA'), (b'en_CB', b'en_CB'), (b'en_GB', b'en_GB'), (b'en_IE', b'en_IE'), (b'en_IN', b'en_IN'), (b'en_IN', b'en_IN'), (b'en_JA', b'en_JA'), (b'en_MY', b'en_MY'), (b'en_NZ', b'en_NZ'), (b'en_PH', b'en_PH'), (b'en_TT', b'en_TT'), (b'en_US', b'en_US'), (b'en_ZA', b'en_ZA'), (b'en_ZW', b'en_ZW'), (b'es_AR', b'es_AR'), (b'es_BO', b'es_BO'), (b'es_CL', b'es_CL'), (b'es_CO', b'es_CO'), (b'es_CR', b'es_CR'), (b'es_DO', b'es_DO'), (b'es_EC', b'es_EC'), (b'es_ES', b'es_ES'), (b'es_ES', b'es_ES'), (b'es_GT', b'es_GT'), (b'es_HN', b'es_HN'), (b'es_MX', b'es_MX'), (b'es_NI', b'es_NI'), (b'es_PA', b'es_PA'), (b'es_PE', b'es_PE'), (b'es_PR', b'es_PR'), (b'es_PY', b'es_PY'), (b'es_SV', b'es_SV'), (b'es_UR', b'es_UR'), (b'es_US', b'es_US'), (b'es_VE', b'es_VE'), (b'et_EE', b'et_EE'), (b'eu_ES', b'eu_ES'), (b'fa_IR', b'fa_IR'), (b'fi_FI', b'fi_FI'), (b'fil_PH', b'fil_PH'), (b'fo_FO', b'fo_FO'), (b'fr_BE', b'fr_BE'), (b'fr_CA', b'fr_CA'), (b'fr_CH', b'fr_CH'), (b'fr_FR', b'fr_FR'), (b'fr_LU', b'fr_LU'), (b'fr_MC', b'fr_MC'), (b'fy_NL', b'fy_NL'), (b'ga_IE', b'ga_IE'), (b'gbz_AF', b'gbz_AF'), (b'gl_ES', b'gl_ES'), (b'gsw_FR', b'gsw_FR'), (b'gu_IN', b'gu_IN'), (b'ha_NG', b'ha_NG'), (b'he_IL', b'he_IL'), (b'hi_IN', b'hi_IN'), (b'hr_BA', b'hr_BA'), (b'hr_HR', b'hr_HR'), (b'hu_HU', b'hu_HU'), (b'hy_AM', b'hy_AM'), (b'id_ID', b'id_ID'), (b'ii_CN', b'ii_CN'), (b'is_IS', b'is_IS'), (b'it_CH', b'it_CH'), (b'it_IT', b'it_IT'), (b'iu_CA', b'iu_CA'), (b'iu_CA', b'iu_CA'), (b'ja_JP', b'ja_JP'), (b'ka_GE', b'ka_GE'), (b'kh_KH', b'kh_KH'), (b'kk_KZ', b'kk_KZ'), (b'kl_GL', b'kl_GL'), (b'kn_IN', b'kn_IN'), (b'ko_KR', b'ko_KR'), (b'kok_IN', b'kok_IN'), (b'ky_KG', b'ky_KG'), (b'lb_LU', b'lb_LU'), (b'lo_LA', b'lo_LA'), (b'lt_LT', b'lt_LT'), (b'lv_LV', b'lv_LV'), (b'mi_NZ', b'mi_NZ'), (b'mk_MK', b'mk_MK'), (b'ml_IN', b'ml_IN'), (b'mn_CN', b'mn_CN'), (b'mn_MN', b'mn_MN'), (b'moh_CA', b'moh_CA'), (b'mr_IN', b'mr_IN'), (b'ms_BN', b'ms_BN'), (b'ms_MY', b'ms_MY'), (b'mt_MT', b'mt_MT'), (b'nb_NO', b'nb_NO'), (b'ne_NP', b'ne_NP'), (b'nl_BE', b'nl_BE'), (b'nl_NL', b'nl_NL'), (b'nn_NO', b'nn_NO'), (b'ns_ZA', b'ns_ZA'), (b'oc_FR', b'oc_FR'), (b'or_IN', b'or_IN'), (b'pa_IN', b'pa_IN'), (b'pl_PL', b'pl_PL'), (b'ps_AF', b'ps_AF'), (b'pt_BR', b'pt_BR'), (b'pt_PT', b'pt_PT'), (b'qut_GT', b'qut_GT'), (b'quz_BO', b'quz_BO'), (b'quz_EC', b'quz_EC'), (b'quz_PE', b'quz_PE'), (b'rm_CH', b'rm_CH'), (b'ro_RO', b'ro_RO'), (b'ru_RU', b'ru_RU'), (b'rw_RW', b'rw_RW'), (b'sa_IN', b'sa_IN'), (b'sah_RU', b'sah_RU'), (b'se_FI', b'se_FI'), (b'se_NO', b'se_NO'), (b'se_SE', b'se_SE'), (b'si_LK', b'si_LK'), (b'sk_SK', b'sk_SK'), (b'sl_SI', b'sl_SI'), (b'sma_NO', b'sma_NO'), (b'sma_SE', b'sma_SE'), (b'smj_NO', b'smj_NO'), (b'smj_SE', b'smj_SE'), (b'smn_FI', b'smn_FI'), (b'sms_FI', b'sms_FI'), (b'sq_AL', b'sq_AL'), (b'sr_BA', b'sr_BA'), (b'sr_BA', b'sr_BA'), (b'sr_SP', b'sr_SP'), (b'sr_SP', b'sr_SP'), (b'sv_FI', b'sv_FI'), (b'sv_SE', b'sv_SE'), (b'sw_KE', b'sw_KE'), (b'syr_SY', b'syr_SY'), (b'ta_IN', b'ta_IN'), (b'te_IN', b'te_IN'), (b'tg_TJ', b'tg_TJ'), (b'th_TH', b'th_TH'), (b'tk_TM', b'tk_TM'), (b'tmz_DZ', b'tmz_DZ'), (b'tn_ZA', b'tn_ZA'), (b'tr_TR', b'tr_TR'), (b'tt_RU', b'tt_RU'), (b'ug_CN', b'ug_CN'), (b'uk_UA', b'uk_UA'), (b'ur_IN', b'ur_IN'), (b'ur_PK', b'ur_PK'), (b'uz_UZ', b'uz_UZ'), (b'uz_UZ', b'uz_UZ'), (b'vi_VN', b'vi_VN'), (b'wen_DE', b'wen_DE'), (b'wo_SN', b'wo_SN'), (b'xh_ZA', b'xh_ZA'), (b'yo_NG', b'yo_NG'), (b'zh_CHS', b'zh_CHS'), (b'zh_CHT', b'zh_CHT'), (b'zh_CN', b'zh_CN'), (b'zh_HK', b'zh_HK'), (b'zh_MO', b'zh_MO'), (b'zh_SG', b'zh_SG'), (b'zh_TW', b'zh_TW'), (b'zu_ZA', b'zu_ZA')], default=b'fr_FR', max_length=10), + field=models.CharField(choices=[('af_ZA', 'af_ZA'), ('am_ET', 'am_ET'), ('ar_AE', 'ar_AE'), ('ar_BH', 'ar_BH'), ('ar_DZ', 'ar_DZ'), ('ar_EG', 'ar_EG'), ('ar_IQ', 'ar_IQ'), ('ar_JO', 'ar_JO'), ('ar_KW', 'ar_KW'), ('ar_LB', 'ar_LB'), ('ar_LY', 'ar_LY'), ('ar_MA', 'ar_MA'), ('ar_OM', 'ar_OM'), ('ar_QA', 'ar_QA'), ('ar_SA', 'ar_SA'), ('ar_SY', 'ar_SY'), ('ar_TN', 'ar_TN'), ('ar_YE', 'ar_YE'), ('arn_CL', 'arn_CL'), ('as_IN', 'as_IN'), ('az_AZ', 'az_AZ'), ('az_AZ', 'az_AZ'), ('ba_RU', 'ba_RU'), ('be_BY', 'be_BY'), ('bg_BG', 'bg_BG'), ('bn_IN', 'bn_IN'), ('bo_BT', 'bo_BT'), ('bo_CN', 'bo_CN'), ('br_FR', 'br_FR'), ('bs_BA', 'bs_BA'), ('bs_BA', 'bs_BA'), ('ca_ES', 'ca_ES'), ('co_FR', 'co_FR'), ('cs_CZ', 'cs_CZ'), ('cy_GB', 'cy_GB'), ('da_DK', 'da_DK'), ('de_AT', 'de_AT'), ('de_CH', 'de_CH'), ('de_DE', 'de_DE'), ('de_LI', 'de_LI'), ('de_LU', 'de_LU'), ('div_MV', 'div_MV'), ('dsb_DE', 'dsb_DE'), ('el_GR', 'el_GR'), ('en_AU', 'en_AU'), ('en_BZ', 'en_BZ'), ('en_CA', 'en_CA'), ('en_CB', 'en_CB'), ('en_GB', 'en_GB'), ('en_IE', 'en_IE'), ('en_IN', 'en_IN'), ('en_IN', 'en_IN'), ('en_JA', 'en_JA'), ('en_MY', 'en_MY'), ('en_NZ', 'en_NZ'), ('en_PH', 'en_PH'), ('en_TT', 'en_TT'), ('en_US', 'en_US'), ('en_ZA', 'en_ZA'), ('en_ZW', 'en_ZW'), ('es_AR', 'es_AR'), ('es_BO', 'es_BO'), ('es_CL', 'es_CL'), ('es_CO', 'es_CO'), ('es_CR', 'es_CR'), ('es_DO', 'es_DO'), ('es_EC', 'es_EC'), ('es_ES', 'es_ES'), ('es_ES', 'es_ES'), ('es_GT', 'es_GT'), ('es_HN', 'es_HN'), ('es_MX', 'es_MX'), ('es_NI', 'es_NI'), ('es_PA', 'es_PA'), ('es_PE', 'es_PE'), ('es_PR', 'es_PR'), ('es_PY', 'es_PY'), ('es_SV', 'es_SV'), ('es_UR', 'es_UR'), ('es_US', 'es_US'), ('es_VE', 'es_VE'), ('et_EE', 'et_EE'), ('eu_ES', 'eu_ES'), ('fa_IR', 'fa_IR'), ('fi_FI', 'fi_FI'), ('fil_PH', 'fil_PH'), ('fo_FO', 'fo_FO'), ('fr_BE', 'fr_BE'), ('fr_CA', 'fr_CA'), ('fr_CH', 'fr_CH'), ('fr_FR', 'fr_FR'), ('fr_LU', 'fr_LU'), ('fr_MC', 'fr_MC'), ('fy_NL', 'fy_NL'), ('ga_IE', 'ga_IE'), ('gbz_AF', 'gbz_AF'), ('gl_ES', 'gl_ES'), ('gsw_FR', 'gsw_FR'), ('gu_IN', 'gu_IN'), ('ha_NG', 'ha_NG'), ('he_IL', 'he_IL'), ('hi_IN', 'hi_IN'), ('hr_BA', 'hr_BA'), ('hr_HR', 'hr_HR'), ('hu_HU', 'hu_HU'), ('hy_AM', 'hy_AM'), ('id_ID', 'id_ID'), ('ii_CN', 'ii_CN'), ('is_IS', 'is_IS'), ('it_CH', 'it_CH'), ('it_IT', 'it_IT'), ('iu_CA', 'iu_CA'), ('iu_CA', 'iu_CA'), ('ja_JP', 'ja_JP'), ('ka_GE', 'ka_GE'), ('kh_KH', 'kh_KH'), ('kk_KZ', 'kk_KZ'), ('kl_GL', 'kl_GL'), ('kn_IN', 'kn_IN'), ('ko_KR', 'ko_KR'), ('kok_IN', 'kok_IN'), ('ky_KG', 'ky_KG'), ('lb_LU', 'lb_LU'), ('lo_LA', 'lo_LA'), ('lt_LT', 'lt_LT'), ('lv_LV', 'lv_LV'), ('mi_NZ', 'mi_NZ'), ('mk_MK', 'mk_MK'), ('ml_IN', 'ml_IN'), ('mn_CN', 'mn_CN'), ('mn_MN', 'mn_MN'), ('moh_CA', 'moh_CA'), ('mr_IN', 'mr_IN'), ('ms_BN', 'ms_BN'), ('ms_MY', 'ms_MY'), ('mt_MT', 'mt_MT'), ('nb_NO', 'nb_NO'), ('ne_NP', 'ne_NP'), ('nl_BE', 'nl_BE'), ('nl_NL', 'nl_NL'), ('nn_NO', 'nn_NO'), ('ns_ZA', 'ns_ZA'), ('oc_FR', 'oc_FR'), ('or_IN', 'or_IN'), ('pa_IN', 'pa_IN'), ('pl_PL', 'pl_PL'), ('ps_AF', 'ps_AF'), ('pt_BR', 'pt_BR'), ('pt_PT', 'pt_PT'), ('qut_GT', 'qut_GT'), ('quz_BO', 'quz_BO'), ('quz_EC', 'quz_EC'), ('quz_PE', 'quz_PE'), ('rm_CH', 'rm_CH'), ('ro_RO', 'ro_RO'), ('ru_RU', 'ru_RU'), ('rw_RW', 'rw_RW'), ('sa_IN', 'sa_IN'), ('sah_RU', 'sah_RU'), ('se_FI', 'se_FI'), ('se_NO', 'se_NO'), ('se_SE', 'se_SE'), ('si_LK', 'si_LK'), ('sk_SK', 'sk_SK'), ('sl_SI', 'sl_SI'), ('sma_NO', 'sma_NO'), ('sma_SE', 'sma_SE'), ('smj_NO', 'smj_NO'), ('smj_SE', 'smj_SE'), ('smn_FI', 'smn_FI'), ('sms_FI', 'sms_FI'), ('sq_AL', 'sq_AL'), ('sr_BA', 'sr_BA'), ('sr_BA', 'sr_BA'), ('sr_SP', 'sr_SP'), ('sr_SP', 'sr_SP'), ('sv_FI', 'sv_FI'), ('sv_SE', 'sv_SE'), ('sw_KE', 'sw_KE'), ('syr_SY', 'syr_SY'), ('ta_IN', 'ta_IN'), ('te_IN', 'te_IN'), ('tg_TJ', 'tg_TJ'), ('th_TH', 'th_TH'), ('tk_TM', 'tk_TM'), ('tmz_DZ', 'tmz_DZ'), ('tn_ZA', 'tn_ZA'), ('tr_TR', 'tr_TR'), ('tt_RU', 'tt_RU'), ('ug_CN', 'ug_CN'), ('uk_UA', 'uk_UA'), ('ur_IN', 'ur_IN'), ('ur_PK', 'ur_PK'), ('uz_UZ', 'uz_UZ'), ('uz_UZ', 'uz_UZ'), ('vi_VN', 'vi_VN'), ('wen_DE', 'wen_DE'), ('wo_SN', 'wo_SN'), ('xh_ZA', 'xh_ZA'), ('yo_NG', 'yo_NG'), ('zh_CHS', 'zh_CHS'), ('zh_CHT', 'zh_CHT'), ('zh_CN', 'zh_CN'), ('zh_HK', 'zh_HK'), ('zh_MO', 'zh_MO'), ('zh_SG', 'zh_SG'), ('zh_TW', 'zh_TW'), ('zu_ZA', 'zu_ZA')], default='fr_FR', max_length=10), ), ] diff --git a/smash/web/migrations/0042_auto_20170613_1634.py b/smash/web/migrations/0042_auto_20170613_1634.py index b338e9185339a0214e5391a39a722292498cac99..3276fe5a6f1b184645a0157aac050e13e6049371 100644 --- a/smash/web/migrations/0042_auto_20170613_1634.py +++ b/smash/web/migrations/0042_auto_20170613_1634.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='language', name='windows_locale_name', - field=models.CharField(choices=[(b'af_ZA', b'af_ZA'), (b'am_ET', b'am_ET'), (b'ar_AE', b'ar_AE'), (b'ar_BH', b'ar_BH'), (b'ar_DZ', b'ar_DZ'), (b'ar_EG', b'ar_EG'), (b'ar_IQ', b'ar_IQ'), (b'ar_JO', b'ar_JO'), (b'ar_KW', b'ar_KW'), (b'ar_LB', b'ar_LB'), (b'ar_LY', b'ar_LY'), (b'ar_MA', b'ar_MA'), (b'ar_OM', b'ar_OM'), (b'ar_QA', b'ar_QA'), (b'ar_SA', b'ar_SA'), (b'ar_SY', b'ar_SY'), (b'ar_TN', b'ar_TN'), (b'ar_YE', b'ar_YE'), (b'arn_CL', b'arn_CL'), (b'as_IN', b'as_IN'), (b'az_AZ', b'az_AZ'), (b'az_AZ', b'az_AZ'), (b'ba_RU', b'ba_RU'), (b'be_BY', b'be_BY'), (b'bg_BG', b'bg_BG'), (b'bn_IN', b'bn_IN'), (b'bo_BT', b'bo_BT'), (b'bo_CN', b'bo_CN'), (b'br_FR', b'br_FR'), (b'bs_BA', b'bs_BA'), (b'bs_BA', b'bs_BA'), (b'ca_ES', b'ca_ES'), (b'co_FR', b'co_FR'), (b'cs_CZ', b'cs_CZ'), (b'cy_GB', b'cy_GB'), (b'da_DK', b'da_DK'), (b'de_AT', b'de_AT'), (b'de_CH', b'de_CH'), (b'de_DE', b'de_DE'), (b'de_LI', b'de_LI'), (b'de_LU', b'de_LU'), (b'div_MV', b'div_MV'), (b'dsb_DE', b'dsb_DE'), (b'el_GR', b'el_GR'), (b'en_AU', b'en_AU'), (b'en_BZ', b'en_BZ'), (b'en_CA', b'en_CA'), (b'en_CB', b'en_CB'), (b'en_GB', b'en_GB'), (b'en_IE', b'en_IE'), (b'en_IN', b'en_IN'), (b'en_IN', b'en_IN'), (b'en_JA', b'en_JA'), (b'en_MY', b'en_MY'), (b'en_NZ', b'en_NZ'), (b'en_PH', b'en_PH'), (b'en_TT', b'en_TT'), (b'en_US', b'en_US'), (b'en_ZA', b'en_ZA'), (b'en_ZW', b'en_ZW'), (b'es_AR', b'es_AR'), (b'es_BO', b'es_BO'), (b'es_CL', b'es_CL'), (b'es_CO', b'es_CO'), (b'es_CR', b'es_CR'), (b'es_DO', b'es_DO'), (b'es_EC', b'es_EC'), (b'es_ES', b'es_ES'), (b'es_ES', b'es_ES'), (b'es_GT', b'es_GT'), (b'es_HN', b'es_HN'), (b'es_MX', b'es_MX'), (b'es_NI', b'es_NI'), (b'es_PA', b'es_PA'), (b'es_PE', b'es_PE'), (b'es_PR', b'es_PR'), (b'es_PY', b'es_PY'), (b'es_SV', b'es_SV'), (b'es_UR', b'es_UR'), (b'es_US', b'es_US'), (b'es_VE', b'es_VE'), (b'et_EE', b'et_EE'), (b'eu_ES', b'eu_ES'), (b'fa_IR', b'fa_IR'), (b'fi_FI', b'fi_FI'), (b'fil_PH', b'fil_PH'), (b'fo_FO', b'fo_FO'), (b'fr_BE', b'fr_BE'), (b'fr_CA', b'fr_CA'), (b'fr_CH', b'fr_CH'), (b'fr_FR', b'fr_FR'), (b'fr_LU', b'fr_LU'), (b'fr_MC', b'fr_MC'), (b'fy_NL', b'fy_NL'), (b'ga_IE', b'ga_IE'), (b'gbz_AF', b'gbz_AF'), (b'gl_ES', b'gl_ES'), (b'gsw_FR', b'gsw_FR'), (b'gu_IN', b'gu_IN'), (b'ha_NG', b'ha_NG'), (b'he_IL', b'he_IL'), (b'hi_IN', b'hi_IN'), (b'hr_BA', b'hr_BA'), (b'hr_HR', b'hr_HR'), (b'hu_HU', b'hu_HU'), (b'hy_AM', b'hy_AM'), (b'id_ID', b'id_ID'), (b'ii_CN', b'ii_CN'), (b'is_IS', b'is_IS'), (b'it_CH', b'it_CH'), (b'it_IT', b'it_IT'), (b'iu_CA', b'iu_CA'), (b'iu_CA', b'iu_CA'), (b'ja_JP', b'ja_JP'), (b'ka_GE', b'ka_GE'), (b'kh_KH', b'kh_KH'), (b'kk_KZ', b'kk_KZ'), (b'kl_GL', b'kl_GL'), (b'kn_IN', b'kn_IN'), (b'ko_KR', b'ko_KR'), (b'kok_IN', b'kok_IN'), (b'ky_KG', b'ky_KG'), (b'lb_LU', b'lb_LU'), (b'lo_LA', b'lo_LA'), (b'lt_LT', b'lt_LT'), (b'lv_LV', b'lv_LV'), (b'mi_NZ', b'mi_NZ'), (b'mk_MK', b'mk_MK'), (b'ml_IN', b'ml_IN'), (b'mn_CN', b'mn_CN'), (b'mn_MN', b'mn_MN'), (b'moh_CA', b'moh_CA'), (b'mr_IN', b'mr_IN'), (b'ms_BN', b'ms_BN'), (b'ms_MY', b'ms_MY'), (b'mt_MT', b'mt_MT'), (b'nb_NO', b'nb_NO'), (b'ne_NP', b'ne_NP'), (b'nl_BE', b'nl_BE'), (b'nl_NL', b'nl_NL'), (b'nn_NO', b'nn_NO'), (b'ns_ZA', b'ns_ZA'), (b'oc_FR', b'oc_FR'), (b'or_IN', b'or_IN'), (b'pa_IN', b'pa_IN'), (b'pl_PL', b'pl_PL'), (b'ps_AF', b'ps_AF'), (b'pt_BR', b'pt_BR'), (b'pt_PT', b'pt_PT'), (b'qut_GT', b'qut_GT'), (b'quz_BO', b'quz_BO'), (b'quz_EC', b'quz_EC'), (b'quz_PE', b'quz_PE'), (b'rm_CH', b'rm_CH'), (b'ro_RO', b'ro_RO'), (b'ru_RU', b'ru_RU'), (b'rw_RW', b'rw_RW'), (b'sa_IN', b'sa_IN'), (b'sah_RU', b'sah_RU'), (b'se_FI', b'se_FI'), (b'se_NO', b'se_NO'), (b'se_SE', b'se_SE'), (b'si_LK', b'si_LK'), (b'sk_SK', b'sk_SK'), (b'sl_SI', b'sl_SI'), (b'sma_NO', b'sma_NO'), (b'sma_SE', b'sma_SE'), (b'smj_NO', b'smj_NO'), (b'smj_SE', b'smj_SE'), (b'smn_FI', b'smn_FI'), (b'sms_FI', b'sms_FI'), (b'sq_AL', b'sq_AL'), (b'sr_BA', b'sr_BA'), (b'sr_BA', b'sr_BA'), (b'sr_SP', b'sr_SP'), (b'sr_SP', b'sr_SP'), (b'sv_FI', b'sv_FI'), (b'sv_SE', b'sv_SE'), (b'sw_KE', b'sw_KE'), (b'syr_SY', b'syr_SY'), (b'ta_IN', b'ta_IN'), (b'te_IN', b'te_IN'), (b'tg_TJ', b'tg_TJ'), (b'th_TH', b'th_TH'), (b'tk_TM', b'tk_TM'), (b'tmz_DZ', b'tmz_DZ'), (b'tn_ZA', b'tn_ZA'), (b'tr_TR', b'tr_TR'), (b'tt_RU', b'tt_RU'), (b'ug_CN', b'ug_CN'), (b'uk_UA', b'uk_UA'), (b'ur_IN', b'ur_IN'), (b'ur_PK', b'ur_PK'), (b'uz_UZ', b'uz_UZ'), (b'uz_UZ', b'uz_UZ'), (b'vi_VN', b'vi_VN'), (b'wen_DE', b'wen_DE'), (b'wo_SN', b'wo_SN'), (b'xh_ZA', b'xh_ZA'), (b'yo_NG', b'yo_NG'), (b'zh_CHS', b'zh_CHS'), (b'zh_CHT', b'zh_CHT'), (b'zh_CN', b'zh_CN'), (b'zh_HK', b'zh_HK'), (b'zh_MO', b'zh_MO'), (b'zh_SG', b'zh_SG'), (b'zh_TW', b'zh_TW'), (b'zu_ZA', b'zu_ZA')], default=b'French', max_length=10), + field=models.CharField(choices=[('af_ZA', 'af_ZA'), ('am_ET', 'am_ET'), ('ar_AE', 'ar_AE'), ('ar_BH', 'ar_BH'), ('ar_DZ', 'ar_DZ'), ('ar_EG', 'ar_EG'), ('ar_IQ', 'ar_IQ'), ('ar_JO', 'ar_JO'), ('ar_KW', 'ar_KW'), ('ar_LB', 'ar_LB'), ('ar_LY', 'ar_LY'), ('ar_MA', 'ar_MA'), ('ar_OM', 'ar_OM'), ('ar_QA', 'ar_QA'), ('ar_SA', 'ar_SA'), ('ar_SY', 'ar_SY'), ('ar_TN', 'ar_TN'), ('ar_YE', 'ar_YE'), ('arn_CL', 'arn_CL'), ('as_IN', 'as_IN'), ('az_AZ', 'az_AZ'), ('az_AZ', 'az_AZ'), ('ba_RU', 'ba_RU'), ('be_BY', 'be_BY'), ('bg_BG', 'bg_BG'), ('bn_IN', 'bn_IN'), ('bo_BT', 'bo_BT'), ('bo_CN', 'bo_CN'), ('br_FR', 'br_FR'), ('bs_BA', 'bs_BA'), ('bs_BA', 'bs_BA'), ('ca_ES', 'ca_ES'), ('co_FR', 'co_FR'), ('cs_CZ', 'cs_CZ'), ('cy_GB', 'cy_GB'), ('da_DK', 'da_DK'), ('de_AT', 'de_AT'), ('de_CH', 'de_CH'), ('de_DE', 'de_DE'), ('de_LI', 'de_LI'), ('de_LU', 'de_LU'), ('div_MV', 'div_MV'), ('dsb_DE', 'dsb_DE'), ('el_GR', 'el_GR'), ('en_AU', 'en_AU'), ('en_BZ', 'en_BZ'), ('en_CA', 'en_CA'), ('en_CB', 'en_CB'), ('en_GB', 'en_GB'), ('en_IE', 'en_IE'), ('en_IN', 'en_IN'), ('en_IN', 'en_IN'), ('en_JA', 'en_JA'), ('en_MY', 'en_MY'), ('en_NZ', 'en_NZ'), ('en_PH', 'en_PH'), ('en_TT', 'en_TT'), ('en_US', 'en_US'), ('en_ZA', 'en_ZA'), ('en_ZW', 'en_ZW'), ('es_AR', 'es_AR'), ('es_BO', 'es_BO'), ('es_CL', 'es_CL'), ('es_CO', 'es_CO'), ('es_CR', 'es_CR'), ('es_DO', 'es_DO'), ('es_EC', 'es_EC'), ('es_ES', 'es_ES'), ('es_ES', 'es_ES'), ('es_GT', 'es_GT'), ('es_HN', 'es_HN'), ('es_MX', 'es_MX'), ('es_NI', 'es_NI'), ('es_PA', 'es_PA'), ('es_PE', 'es_PE'), ('es_PR', 'es_PR'), ('es_PY', 'es_PY'), ('es_SV', 'es_SV'), ('es_UR', 'es_UR'), ('es_US', 'es_US'), ('es_VE', 'es_VE'), ('et_EE', 'et_EE'), ('eu_ES', 'eu_ES'), ('fa_IR', 'fa_IR'), ('fi_FI', 'fi_FI'), ('fil_PH', 'fil_PH'), ('fo_FO', 'fo_FO'), ('fr_BE', 'fr_BE'), ('fr_CA', 'fr_CA'), ('fr_CH', 'fr_CH'), ('fr_FR', 'fr_FR'), ('fr_LU', 'fr_LU'), ('fr_MC', 'fr_MC'), ('fy_NL', 'fy_NL'), ('ga_IE', 'ga_IE'), ('gbz_AF', 'gbz_AF'), ('gl_ES', 'gl_ES'), ('gsw_FR', 'gsw_FR'), ('gu_IN', 'gu_IN'), ('ha_NG', 'ha_NG'), ('he_IL', 'he_IL'), ('hi_IN', 'hi_IN'), ('hr_BA', 'hr_BA'), ('hr_HR', 'hr_HR'), ('hu_HU', 'hu_HU'), ('hy_AM', 'hy_AM'), ('id_ID', 'id_ID'), ('ii_CN', 'ii_CN'), ('is_IS', 'is_IS'), ('it_CH', 'it_CH'), ('it_IT', 'it_IT'), ('iu_CA', 'iu_CA'), ('iu_CA', 'iu_CA'), ('ja_JP', 'ja_JP'), ('ka_GE', 'ka_GE'), ('kh_KH', 'kh_KH'), ('kk_KZ', 'kk_KZ'), ('kl_GL', 'kl_GL'), ('kn_IN', 'kn_IN'), ('ko_KR', 'ko_KR'), ('kok_IN', 'kok_IN'), ('ky_KG', 'ky_KG'), ('lb_LU', 'lb_LU'), ('lo_LA', 'lo_LA'), ('lt_LT', 'lt_LT'), ('lv_LV', 'lv_LV'), ('mi_NZ', 'mi_NZ'), ('mk_MK', 'mk_MK'), ('ml_IN', 'ml_IN'), ('mn_CN', 'mn_CN'), ('mn_MN', 'mn_MN'), ('moh_CA', 'moh_CA'), ('mr_IN', 'mr_IN'), ('ms_BN', 'ms_BN'), ('ms_MY', 'ms_MY'), ('mt_MT', 'mt_MT'), ('nb_NO', 'nb_NO'), ('ne_NP', 'ne_NP'), ('nl_BE', 'nl_BE'), ('nl_NL', 'nl_NL'), ('nn_NO', 'nn_NO'), ('ns_ZA', 'ns_ZA'), ('oc_FR', 'oc_FR'), ('or_IN', 'or_IN'), ('pa_IN', 'pa_IN'), ('pl_PL', 'pl_PL'), ('ps_AF', 'ps_AF'), ('pt_BR', 'pt_BR'), ('pt_PT', 'pt_PT'), ('qut_GT', 'qut_GT'), ('quz_BO', 'quz_BO'), ('quz_EC', 'quz_EC'), ('quz_PE', 'quz_PE'), ('rm_CH', 'rm_CH'), ('ro_RO', 'ro_RO'), ('ru_RU', 'ru_RU'), ('rw_RW', 'rw_RW'), ('sa_IN', 'sa_IN'), ('sah_RU', 'sah_RU'), ('se_FI', 'se_FI'), ('se_NO', 'se_NO'), ('se_SE', 'se_SE'), ('si_LK', 'si_LK'), ('sk_SK', 'sk_SK'), ('sl_SI', 'sl_SI'), ('sma_NO', 'sma_NO'), ('sma_SE', 'sma_SE'), ('smj_NO', 'smj_NO'), ('smj_SE', 'smj_SE'), ('smn_FI', 'smn_FI'), ('sms_FI', 'sms_FI'), ('sq_AL', 'sq_AL'), ('sr_BA', 'sr_BA'), ('sr_BA', 'sr_BA'), ('sr_SP', 'sr_SP'), ('sr_SP', 'sr_SP'), ('sv_FI', 'sv_FI'), ('sv_SE', 'sv_SE'), ('sw_KE', 'sw_KE'), ('syr_SY', 'syr_SY'), ('ta_IN', 'ta_IN'), ('te_IN', 'te_IN'), ('tg_TJ', 'tg_TJ'), ('th_TH', 'th_TH'), ('tk_TM', 'tk_TM'), ('tmz_DZ', 'tmz_DZ'), ('tn_ZA', 'tn_ZA'), ('tr_TR', 'tr_TR'), ('tt_RU', 'tt_RU'), ('ug_CN', 'ug_CN'), ('uk_UA', 'uk_UA'), ('ur_IN', 'ur_IN'), ('ur_PK', 'ur_PK'), ('uz_UZ', 'uz_UZ'), ('uz_UZ', 'uz_UZ'), ('vi_VN', 'vi_VN'), ('wen_DE', 'wen_DE'), ('wo_SN', 'wo_SN'), ('xh_ZA', 'xh_ZA'), ('yo_NG', 'yo_NG'), ('zh_CHS', 'zh_CHS'), ('zh_CHT', 'zh_CHT'), ('zh_CN', 'zh_CN'), ('zh_HK', 'zh_HK'), ('zh_MO', 'zh_MO'), ('zh_SG', 'zh_SG'), ('zh_TW', 'zh_TW'), ('zu_ZA', 'zu_ZA')], default='French', max_length=10), ), ] diff --git a/smash/web/migrations/0043_auto_20170904_1240.py b/smash/web/migrations/0043_auto_20170904_1240.py index 6d34956b90a3717392c12430704faef155641ce8..878d593ede130fc28875e5ac46fba4116cdbac89 100644 --- a/smash/web/migrations/0043_auto_20170904_1240.py +++ b/smash/web/migrations/0043_auto_20170904_1240.py @@ -26,16 +26,16 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='availability', name='available_from', - field=models.TimeField(verbose_name=b'Available from'), + field=models.TimeField(verbose_name='Available from'), ), migrations.AlterField( model_name='availability', name='available_till', - field=models.TimeField(default=d, verbose_name=b'Available until'), + field=models.TimeField(default=d, verbose_name='Available until'), ), migrations.AlterField( model_name='availability', name='day_number', - field=models.IntegerField(choices=[(1, b'MONDAY'), (2, b'TUESDAY'), (3, b'WEDNESDAY'), (4, b'THURSDAY'), (5, b'FRIDAY'), (6, b'SATURDAY'), (7, b'SUNDAY')], verbose_name=b'Day of the week'), + field=models.IntegerField(choices=[(1, 'MONDAY'), (2, 'TUESDAY'), (3, 'WEDNESDAY'), (4, 'THURSDAY'), (5, 'FRIDAY'), (6, 'SATURDAY'), (7, 'SUNDAY')], verbose_name='Day of the week'), ), ] diff --git a/smash/web/migrations/0044_auto_20170904_1602.py b/smash/web/migrations/0044_auto_20170904_1602.py index 8f020d02de60b99bb4737165b85f8e10d8982f7f..8d7b72b248d7d6c64874344fe6ac640cea24a63e 100644 --- a/smash/web/migrations/0044_auto_20170904_1602.py +++ b/smash/web/migrations/0044_auto_20170904_1602.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='availability', name='available_till', - field=models.TimeField(verbose_name=b'Available until'), + field=models.TimeField(verbose_name='Available until'), ), ] diff --git a/smash/web/migrations/0045_holiday_info.py b/smash/web/migrations/0045_holiday_info.py index 523998c286b6c95355268646d032204e2d350a88..551c53b1c6e7204a76eb47676768adc6a34003ef 100644 --- a/smash/web/migrations/0045_holiday_info.py +++ b/smash/web/migrations/0045_holiday_info.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='holiday', name='info', - field=models.TextField(blank=True, max_length=2000, verbose_name=b'Comments'), + field=models.TextField(blank=True, max_length=2000, verbose_name='Comments'), ), ] diff --git a/smash/web/migrations/0046_subject_flying_team.py b/smash/web/migrations/0046_subject_flying_team.py index c8ba8a8e9cf3148d27dcab87293b91f1bf127cd4..200e52e536056d1b96415f86dd5d4fa827caf524 100644 --- a/smash/web/migrations/0046_subject_flying_team.py +++ b/smash/web/migrations/0046_subject_flying_team.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( 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'Flying team (if applicable)'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.FlyingTeam', verbose_name='Flying team (if applicable)'), ), ] diff --git a/smash/web/migrations/0048_auto_20170911_1504.py b/smash/web/migrations/0048_auto_20170911_1504.py index 34fcc07d0232574ecf11e5dffdf926196cacd67e..1d4f890a9162d7bbd0be23da1df5e3fab05591dd 100644 --- a/smash/web/migrations/0048_auto_20170911_1504.py +++ b/smash/web/migrations/0048_auto_20170911_1504.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): 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)'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.FlyingTeam', verbose_name='Default flying team location (if applicable)'), ), ] diff --git a/smash/web/migrations/0049_auto_20170912_1438.py b/smash/web/migrations/0049_auto_20170912_1438.py index f6c8c021383267d0e8c9f3c9843c3ada478a8971..17d2af0481ea7c67a3c17aad1aeee530b92b1b61 100644 --- a/smash/web/migrations/0049_auto_20170912_1438.py +++ b/smash/web/migrations/0049_auto_20170912_1438.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='configurationitem', name='name', - field=models.CharField(editable=False, max_length=255, verbose_name=b'Name'), + field=models.CharField(editable=False, max_length=255, verbose_name='Name'), ), ] diff --git a/smash/web/migrations/0051_missingsubject.py b/smash/web/migrations/0051_missingsubject.py index 1d443d1ec3392fe3de6709f640219124b1d55c3a..a00459a696e3d4cd0d086c17a91746661895e8d4 100644 --- a/smash/web/migrations/0051_missingsubject.py +++ b/smash/web/migrations/0051_missingsubject.py @@ -17,10 +17,10 @@ class Migration(migrations.Migration): name='MissingSubject', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('ignore', models.BooleanField(default=False, verbose_name=b'Ignore missing subject')), - ('redcap_id', models.CharField(blank=True, max_length=255, null=True, verbose_name=b'RED Cap id')), - ('redcap_url', models.CharField(blank=True, max_length=255, null=True, verbose_name=b'URL to RED Cap subject')), - ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name=b'Subject')), + ('ignore', models.BooleanField(default=False, verbose_name='Ignore missing subject')), + ('redcap_id', models.CharField(blank=True, max_length=255, null=True, verbose_name='RED Cap id')), + ('redcap_url', models.CharField(blank=True, max_length=255, null=True, verbose_name='URL to RED Cap subject')), + ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name='Subject')), ], ), ] diff --git a/smash/web/migrations/0052_auto_20170913_0943.py b/smash/web/migrations/0052_auto_20170913_0943.py index 0d15c41794e1f5ddc83937f152f91f800f4f666b..dcfd06d1d7005e74fa909522f84dfb1deb23c7e3 100644 --- a/smash/web/migrations/0052_auto_20170913_0943.py +++ b/smash/web/migrations/0052_auto_20170913_0943.py @@ -17,23 +17,23 @@ class Migration(migrations.Migration): name='InconsistentField', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, verbose_name=b'Field name')), - ('smash_value', models.CharField(max_length=255, verbose_name=b'Smash value')), - ('redcap_value', models.CharField(max_length=255, verbose_name=b'RED Cap value')), + ('name', models.CharField(max_length=255, verbose_name='Field name')), + ('smash_value', models.CharField(max_length=255, verbose_name='Smash value')), + ('redcap_value', models.CharField(max_length=255, verbose_name='RED Cap value')), ], ), migrations.CreateModel( name='InconsistentSubject', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('ignore', models.BooleanField(default=False, verbose_name=b'Ignore missing subject')), - ('redcap_url', models.CharField(blank=True, max_length=255, null=True, verbose_name=b'URL to RED Cap subject')), - ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name=b'Subject')), + ('ignore', models.BooleanField(default=False, verbose_name='Ignore missing subject')), + ('redcap_url', models.CharField(blank=True, max_length=255, null=True, verbose_name='URL to RED Cap subject')), + ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', verbose_name='Subject')), ], ), migrations.AddField( model_name='inconsistentfield', name='inconsistent_subject', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.InconsistentSubject', verbose_name=b'Invalid fields'), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.InconsistentSubject', verbose_name='Invalid fields'), ), ] diff --git a/smash/web/migrations/0053_auto_20170913_0948.py b/smash/web/migrations/0053_auto_20170913_0948.py index 710e47e5325a5d9ab8d224dbd9cc62ce963b0f0a..7bf812d5a3c66d61598f409b372628d001f9d86a 100644 --- a/smash/web/migrations/0053_auto_20170913_0948.py +++ b/smash/web/migrations/0053_auto_20170913_0948.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='nd_number', - field=models.CharField(blank=True, max_length=25, verbose_name=b'ND number'), + field=models.CharField(blank=True, max_length=25, verbose_name='ND number'), ), ] diff --git a/smash/web/migrations/0055_auto_20170925_0905.py b/smash/web/migrations/0055_auto_20170925_0905.py index c2859add2d03b808e960ea8ad1f9e0b87f1b534b..2620faabb713353ff00669bb0dba83d7618bfa64 100644 --- a/smash/web/migrations/0055_auto_20170925_0905.py +++ b/smash/web/migrations/0055_auto_20170925_0905.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='datetime_contact_reminder', - field=models.DateTimeField(blank=True, null=True, verbose_name=b'Please make a contact on'), + field=models.DateTimeField(blank=True, null=True, verbose_name='Please make a contact on'), ), ] diff --git a/smash/web/migrations/0056_visit_visit_number.py b/smash/web/migrations/0056_visit_visit_number.py index 4317c86bdc4868eec564911ccbbf5603ffe2fb20..9524a50871aaea057b9e025e69dad6d0ca90bbbc 100644 --- a/smash/web/migrations/0056_visit_visit_number.py +++ b/smash/web/migrations/0056_visit_visit_number.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='visit', name='visit_number', - field=models.IntegerField(default=1, verbose_name=b'Visit number'), + field=models.IntegerField(default=1, verbose_name='Visit number'), ), ] diff --git a/smash/web/migrations/0059_subject_country_2.py b/smash/web/migrations/0059_subject_country_2.py index 9b0e2190b1e2f30b8abf6ad2d5c30747ac0c0a8c..97d023bb4b7845fd94e4f6e1c7aeeb219b0d1028 100644 --- a/smash/web/migrations/0059_subject_country_2.py +++ b/smash/web/migrations/0059_subject_country_2.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='subject', name='country_2', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', verbose_name=b'Country'), + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', verbose_name='Country'), ), ] diff --git a/smash/web/migrations/0062_subject_resign_reason.py b/smash/web/migrations/0062_subject_resign_reason.py index 92635ff084cf32dbc0a1165a8f17126906dabcf5..0c61334c9ef404008ba6044a4dc078e7a2799308 100644 --- a/smash/web/migrations/0062_subject_resign_reason.py +++ b/smash/web/migrations/0062_subject_resign_reason.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='subject', name='resign_reason', - field=models.TextField(blank=True, max_length=2000, verbose_name=b'Resign reason'), + field=models.TextField(blank=True, max_length=2000, verbose_name='Resign reason'), ), ] diff --git a/smash/web/migrations/0063_auto_20171120_1429.py b/smash/web/migrations/0063_auto_20171120_1429.py index 7f3ba2473cfc9615285c90038a5cc78e68081710..258a40e72301fd940271dfdddab553fa9060fc4e 100644 --- a/smash/web/migrations/0063_auto_20171120_1429.py +++ b/smash/web/migrations/0063_auto_20171120_1429.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='nd_number', - field=models.CharField(blank=True, max_length=25, validators=[django.core.validators.RegexValidator(b'^(ND[0-9]{4}|)$', message=b'ND number should look as follows: NDxxxx')], verbose_name=b'ND number'), + field=models.CharField(blank=True, max_length=25, validators=[django.core.validators.RegexValidator('^(ND[0-9]{4}|)$', message='ND number should look as follows: NDxxxx')], verbose_name='ND number'), ), ] diff --git a/smash/web/migrations/0065_auto_20171127_0957.py b/smash/web/migrations/0065_auto_20171127_0957.py index 28713af2bda156ad00306eb7e2737f1c5ab13b1e..a8e28a6098b32dd8ee5ea44f8418c59b868f2ef8 100644 --- a/smash/web/migrations/0065_auto_20171127_0957.py +++ b/smash/web/migrations/0065_auto_20171127_0957.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubject', name='default_written_communication_language', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='studysubject_written_comunication', to='web.Language', verbose_name=b'Default language for document generation'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='studysubject_written_comunication', to='web.Language', verbose_name='Default language for document generation'), ), ] diff --git a/smash/web/migrations/0067_subject.py b/smash/web/migrations/0067_subject.py index 890b3572f02498e8d25b039f34374878494bd116..0ffc0d5d750f1255cf9f5d5468e43a5c5a0b09d1 100644 --- a/smash/web/migrations/0067_subject.py +++ b/smash/web/migrations/0067_subject.py @@ -29,27 +29,27 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('tmp_study_subject_id', models.IntegerField()), ('sex', - models.CharField(choices=[(b'M', b'Male'), (b'F', b'Female')], max_length=1, verbose_name=b'Sex')), - ('first_name', models.CharField(max_length=50, verbose_name=b'First name')), - ('last_name', models.CharField(max_length=50, verbose_name=b'Last name')), - ('phone_number', models.CharField(blank=True, max_length=20, null=True, verbose_name=b'Phone number')), + models.CharField(choices=[('M', 'Male'), ('F', 'Female')], max_length=1, verbose_name='Sex')), + ('first_name', models.CharField(max_length=50, verbose_name='First name')), + ('last_name', models.CharField(max_length=50, verbose_name='Last name')), + ('phone_number', models.CharField(blank=True, max_length=20, null=True, verbose_name='Phone number')), ('phone_number_2', - models.CharField(blank=True, max_length=20, null=True, verbose_name=b'Phone number 2')), + models.CharField(blank=True, max_length=20, null=True, verbose_name='Phone number 2')), ('phone_number_3', - models.CharField(blank=True, max_length=20, null=True, verbose_name=b'Phone number 3')), - ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name=b'E-mail')), - ('date_born', models.DateField(blank=True, null=True, verbose_name=b'Date of birth (YYYY-MM-DD)')), - ('address', models.CharField(blank=True, max_length=255, verbose_name=b'Address')), - ('postal_code', models.CharField(blank=True, max_length=7, verbose_name=b'Postal code')), - ('city', models.CharField(blank=True, max_length=50, verbose_name=b'City')), - ('dead', models.BooleanField(default=False, verbose_name=b'Deceased')), + models.CharField(blank=True, max_length=20, null=True, verbose_name='Phone number 3')), + ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-mail')), + ('date_born', models.DateField(blank=True, null=True, verbose_name='Date of birth (YYYY-MM-DD)')), + ('address', models.CharField(blank=True, max_length=255, verbose_name='Address')), + ('postal_code', models.CharField(blank=True, max_length=7, verbose_name='Postal code')), + ('city', models.CharField(blank=True, max_length=50, verbose_name='City')), + ('dead', models.BooleanField(default=False, verbose_name='Deceased')), ('country', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', - verbose_name=b'Country')), + verbose_name='Country')), ('default_written_communication_language', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subjects_written_communication', to='web.Language', - verbose_name=b'Default language for document generation')), - ('languages', models.ManyToManyField(blank=True, to='web.Language', verbose_name=b'Known languages')), + verbose_name='Default language for document generation')), + ('languages', models.ManyToManyField(blank=True, to='web.Language', verbose_name='Known languages')), ], ), migrations.RunSQL('insert into web_subject (tmp_study_subject_id, sex, first_name, last_name, phone_number, ' + @@ -62,7 +62,7 @@ class Migration(migrations.Migration): model_name='studysubject', name='subject', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', - verbose_name=b'Subject'), + verbose_name='Subject'), ), migrations.RunSQL('update web_studysubject set subject_id = ' + '(select id from web_subject where tmp_study_subject_id =web_studysubject.id);'), @@ -74,6 +74,6 @@ class Migration(migrations.Migration): model_name='studysubject', name='subject', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Subject', - verbose_name=b'Subject'), + verbose_name='Subject'), ), ] diff --git a/smash/web/migrations/0071_auto_20171130_1607.py b/smash/web/migrations/0071_auto_20171130_1607.py index 6915cb1026bd06500012b53b2b31302c77d20854..747a8ee91194cc6d97e820c8d5073fae17ba38ac 100644 --- a/smash/web/migrations/0071_auto_20171130_1607.py +++ b/smash/web/migrations/0071_auto_20171130_1607.py @@ -27,26 +27,26 @@ class Migration(migrations.Migration): name='Study', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, verbose_name=b'Name')), + ('name', models.CharField(max_length=255, verbose_name='Name')), ], ), migrations.AlterField( model_name='studysubject', name='subject', field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='web.Subject', - verbose_name=b'Subject'), + verbose_name='Subject'), ), migrations.AddField( model_name='studysubject', name='study', field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, - to='web.Study', verbose_name=b'Study'), + to='web.Study', verbose_name='Study'), ), migrations.RunPython(create_default_study), migrations.AlterField( model_name='studysubject', name='study', - field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='web.Study', verbose_name=b'Study'), + field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='web.Study', verbose_name='Study'), preserve_default=False, ), diff --git a/smash/web/migrations/0072_auto_20171201_1013.py b/smash/web/migrations/0072_auto_20171201_1013.py index 2067c07ef08d2b7a4eef85bbdff21ba0efbc9c8d..cd9e93f75611802739099576add58db8f1c3e979 100644 --- a/smash/web/migrations/0072_auto_20171201_1013.py +++ b/smash/web/migrations/0072_auto_20171201_1013.py @@ -27,22 +27,22 @@ class Migration(migrations.Migration): name='StudyColumns', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('postponed', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Postponed')), - ('datetime_contact_reminder', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Please make a contact on')), - ('type', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Type')), - ('default_location', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Default appointment location')), - ('flying_team', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Default flying team location (if applicable)')), - ('screening_number', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Screening number')), - ('nd_number', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'ND number')), - ('mpower_id', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'MPower ID')), - ('comments', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Comments')), - ('referral', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Referred by')), - ('diagnosis', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Diagnosis')), - ('year_of_diagnosis', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Year of diagnosis (YYYY)')), - ('information_sent', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Information sent')), - ('pd_in_family', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'PD in family')), - ('resigned', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Resigned')), - ('resign_reason', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Resign reason')), + ('postponed', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Postponed')), + ('datetime_contact_reminder', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Please make a contact on')), + ('type', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Type')), + ('default_location', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Default appointment location')), + ('flying_team', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Default flying team location (if applicable)')), + ('screening_number', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Screening number')), + ('nd_number', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='ND number')), + ('mpower_id', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='MPower ID')), + ('comments', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Comments')), + ('referral', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Referred by')), + ('diagnosis', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Diagnosis')), + ('year_of_diagnosis', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Year of diagnosis (YYYY)')), + ('information_sent', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Information sent')), + ('pd_in_family', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='PD in family')), + ('resigned', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Resigned')), + ('resign_reason', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Resign reason')), ], ), migrations.RunPython(create_default_study_columns), diff --git a/smash/web/migrations/0073_auto_20171201_1034.py b/smash/web/migrations/0073_auto_20171201_1034.py index dc18022247801fe5a4214c67c784fa7e4729cd14..59d5f473452acae08fee671bbfce578440ea8168 100644 --- a/smash/web/migrations/0073_auto_20171201_1034.py +++ b/smash/web/migrations/0073_auto_20171201_1034.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubject', name='default_location', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Location', verbose_name=b'Default appointment location'), + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Location', verbose_name='Default appointment location'), ), ] diff --git a/smash/web/migrations/0074_auto_20171201_1038.py b/smash/web/migrations/0074_auto_20171201_1038.py index 5705718368ed9bf1c0c274589a007b04e79ba466..5462aa1aa4a9bb3b32853df42b7392a1fbf159e8 100644 --- a/smash/web/migrations/0074_auto_20171201_1038.py +++ b/smash/web/migrations/0074_auto_20171201_1038.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubject', name='default_location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Location', verbose_name=b'Default appointment location'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Location', verbose_name='Default appointment location'), ), ] diff --git a/smash/web/migrations/0075_auto_20171201_1252.py b/smash/web/migrations/0075_auto_20171201_1252.py index ccc941c0e8aea164947e5d465b0c0936947d9473..535a61b27320d0a9d40acd9266a4ef603e61bb5c 100644 --- a/smash/web/migrations/0075_auto_20171201_1252.py +++ b/smash/web/migrations/0075_auto_20171201_1252.py @@ -15,16 +15,16 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubject', name='nd_number', - field=models.CharField(blank=True, max_length=25, verbose_name=b'ND number'), + field=models.CharField(blank=True, max_length=25, verbose_name='ND number'), ), migrations.AlterField( model_name='studysubject', name='screening_number', - field=models.CharField(blank=True, max_length=50, null=True, verbose_name=b'Screening number'), + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Screening number'), ), migrations.AlterField( model_name='studysubject', name='type', - field=models.CharField(blank=True, choices=[(b'P', b'PATIENT'), (b'C', b'CONTROL')], max_length=1, null=True, verbose_name=b'Type'), + field=models.CharField(blank=True, choices=[('P', 'PATIENT'), ('C', 'CONTROL')], max_length=1, null=True, verbose_name='Type'), ), ] diff --git a/smash/web/migrations/0076_studysubjectlist.py b/smash/web/migrations/0076_studysubjectlist.py index f812c31979b1b986217c9518eae1b928d7a53bfd..b03bd5c04303cf1986626236685ae47786c0d951 100644 --- a/smash/web/migrations/0076_studysubjectlist.py +++ b/smash/web/migrations/0076_studysubjectlist.py @@ -43,9 +43,9 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('type', models.CharField(blank=True, - choices=[(b'GENERIC', b'Generic'), (b'NO_VISIT', b'Subjects without visit'), - (b'REQUIRE_CONTACT', b'Subjects required contact')], max_length=50, - null=True, verbose_name=b'Type o list')), + choices=[('GENERIC', 'Generic'), ('NO_VISIT', 'Subjects without visit'), + ('REQUIRE_CONTACT', 'Subjects required contact')], max_length=50, + null=True, verbose_name='Type o list')), ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')), ('visible_columns', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.StudyColumns')), diff --git a/smash/web/migrations/0077_subjectcolumns.py b/smash/web/migrations/0077_subjectcolumns.py index 304dfe796e2fb420850048bec339b7b517ea4e32..fabac0d3d305f609b8b5e5db1e887d3db59fc1a7 100644 --- a/smash/web/migrations/0077_subjectcolumns.py +++ b/smash/web/migrations/0077_subjectcolumns.py @@ -27,21 +27,21 @@ class Migration(migrations.Migration): name='SubjectColumns', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sex', models.BooleanField(default=False, max_length=1, verbose_name=b'Sex')), - ('first_name', models.BooleanField(default=True, max_length=1, verbose_name=b'First name')), - ('last_name', models.BooleanField(default=True, max_length=1, verbose_name=b'Last name')), - ('languages', models.BooleanField(default=False, max_length=1, verbose_name=b'Known languages')), - ('default_written_communication_language', models.BooleanField(default=False, max_length=1, verbose_name=b'Default language for document generation')), - ('phone_number', models.BooleanField(default=False, max_length=1, verbose_name=b'Phone number')), - ('phone_number_2', models.BooleanField(default=False, max_length=1, verbose_name=b'Phone number 2')), - ('phone_number_3', models.BooleanField(default=False, max_length=1, verbose_name=b'Phone number 3')), - ('email', models.BooleanField(default=False, max_length=1, verbose_name=b'E-mail')), - ('date_born', models.BooleanField(default=False, max_length=1, verbose_name=b'Date of birth')), - ('address', models.BooleanField(default=False, max_length=1, verbose_name=b'Address')), - ('postal_code', models.BooleanField(default=False, max_length=1, verbose_name=b'Postal code')), - ('city', models.BooleanField(default=False, max_length=1, verbose_name=b'City')), - ('country', models.BooleanField(default=False, max_length=1, verbose_name=b'Country')), - ('dead', models.BooleanField(default=True, max_length=1, verbose_name=b'Deceased')), + ('sex', models.BooleanField(default=False, max_length=1, verbose_name='Sex')), + ('first_name', models.BooleanField(default=True, max_length=1, verbose_name='First name')), + ('last_name', models.BooleanField(default=True, max_length=1, verbose_name='Last name')), + ('languages', models.BooleanField(default=False, max_length=1, verbose_name='Known languages')), + ('default_written_communication_language', models.BooleanField(default=False, max_length=1, verbose_name='Default language for document generation')), + ('phone_number', models.BooleanField(default=False, max_length=1, verbose_name='Phone number')), + ('phone_number_2', models.BooleanField(default=False, max_length=1, verbose_name='Phone number 2')), + ('phone_number_3', models.BooleanField(default=False, max_length=1, verbose_name='Phone number 3')), + ('email', models.BooleanField(default=False, max_length=1, verbose_name='E-mail')), + ('date_born', models.BooleanField(default=False, max_length=1, verbose_name='Date of birth')), + ('address', models.BooleanField(default=False, max_length=1, verbose_name='Address')), + ('postal_code', models.BooleanField(default=False, max_length=1, verbose_name='Postal code')), + ('city', models.BooleanField(default=False, max_length=1, verbose_name='City')), + ('country', models.BooleanField(default=False, max_length=1, verbose_name='Country')), + ('dead', models.BooleanField(default=True, max_length=1, verbose_name='Deceased')), ], ), migrations.RunPython(create_default_subject_columns), diff --git a/smash/web/migrations/0078_auto_20171204_1040.py b/smash/web/migrations/0078_auto_20171204_1040.py index a7553622679b67bd8962cb0050f95f647a1f0eca..9f5caf5d2bfd01494f97c0eda3d12be49b45be9d 100644 --- a/smash/web/migrations/0078_auto_20171204_1040.py +++ b/smash/web/migrations/0078_auto_20171204_1040.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='subject', name='social_security_number', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Social security_number'), + field=models.CharField(blank=True, max_length=50, verbose_name='Social security_number'), ), migrations.AddField( model_name='subjectcolumns', name='social_security_number', - field=models.BooleanField(default=False, verbose_name=b'Social security_number'), + field=models.BooleanField(default=False, verbose_name='Social security_number'), ), ] diff --git a/smash/web/migrations/0079_auto_20171204_1235.py b/smash/web/migrations/0079_auto_20171204_1235.py index e8f0588c25c8530dcce06a6857fb04976f933373..e5cab49b1dcf8df741e2b1318bd10c5baadf6f1a 100644 --- a/smash/web/migrations/0079_auto_20171204_1235.py +++ b/smash/web/migrations/0079_auto_20171204_1235.py @@ -18,23 +18,23 @@ class Migration(migrations.Migration): name='StudyNotificationParameters', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('exceeded_visits_visible', models.BooleanField(default=True, verbose_name=b'exceeded visit time')), + ('exceeded_visits_visible', models.BooleanField(default=True, verbose_name='exceeded visit time')), ('missing_redcap_subject_visible', - models.BooleanField(default=True, verbose_name=b'missing RED Cap subject')), + models.BooleanField(default=True, verbose_name='missing RED Cap subject')), ('inconsistent_redcap_subject_visible', - models.BooleanField(default=True, verbose_name=b'inconsistent RED Cap subject')), + models.BooleanField(default=True, verbose_name='inconsistent RED Cap subject')), ('subject_require_contact_visible', - models.BooleanField(default=True, verbose_name=b'subject required contact')), - ('subject_no_visits_visible', models.BooleanField(default=True, verbose_name=b'subject without visit')), - ('unfinished_visits_visible', models.BooleanField(default=True, verbose_name=b'unfinished visits')), + models.BooleanField(default=True, verbose_name='subject required contact')), + ('subject_no_visits_visible', models.BooleanField(default=True, verbose_name='subject without visit')), + ('unfinished_visits_visible', models.BooleanField(default=True, verbose_name='unfinished visits')), ('visits_with_missing_appointments_visible', - models.BooleanField(default=True, verbose_name=b'visits with missing appointments')), + models.BooleanField(default=True, verbose_name='visits with missing appointments')), ('approaching_visits_without_appointments_visible', - models.BooleanField(default=True, verbose_name=b'approaching visits')), + models.BooleanField(default=True, verbose_name='approaching visits')), ('approaching_visits_for_mail_contact_visible', - models.BooleanField(default=True, verbose_name=b'post mail for approaching visits')), + models.BooleanField(default=True, verbose_name='post mail for approaching visits')), ('unfinished_appointments_visible', - models.BooleanField(default=True, verbose_name=b'unfinished appointments')), + models.BooleanField(default=True, verbose_name='unfinished appointments')), ], )] diff --git a/smash/web/migrations/0080_auto_20171204_1341.py b/smash/web/migrations/0080_auto_20171204_1341.py index 07c8ee1a842eac8c287934b55431bcb7dba6aa99..9ca2b1b987a1f34275f687823fd386a1776fe017 100644 --- a/smash/web/migrations/0080_auto_20171204_1341.py +++ b/smash/web/migrations/0080_auto_20171204_1341.py @@ -61,8 +61,8 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studycolumns', name='datetime_contact_reminder', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, - verbose_name=b'Last contact attempt'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, + verbose_name='Last contact attempt'), )] if is_sqlite_db(): operations.append(migrations.RunSQL('UPDATE web_studycolumns SET datetime_contact_reminder =0 WHERE ' + diff --git a/smash/web/migrations/0081_studysubjectlist_last_contact_attempt.py b/smash/web/migrations/0081_studysubjectlist_last_contact_attempt.py index c3f963b4872f1da250feabfd8eb6f0b227713abc..b4ea1f13f9eb9a3e1302af196aaef6fe7b96a54d 100644 --- a/smash/web/migrations/0081_studysubjectlist_last_contact_attempt.py +++ b/smash/web/migrations/0081_studysubjectlist_last_contact_attempt.py @@ -61,12 +61,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studysubjectlist', name='visits', - field=models.BooleanField(default=True, verbose_name=b'Visits summary'), + field=models.BooleanField(default=True, verbose_name='Visits summary'), ), migrations.AddField( model_name='studysubjectlist', name='last_contact_attempt', - field=models.BooleanField(default=False, verbose_name=b'Last contact attempt'), + field=models.BooleanField(default=False, verbose_name='Last contact attempt'), ), migrations.RunPython(create_default_columns_for_SUBJECT_LIST_NO_VISIT), ] diff --git a/smash/web/migrations/0083_auto_20171205_1251.py b/smash/web/migrations/0083_auto_20171205_1251.py index 051d9c7197f151c4514ad3c23089c94e2e82d769..8ce784e18fd0e6be22db55147b63471fc6d770e0 100644 --- a/smash/web/migrations/0083_auto_20171205_1251.py +++ b/smash/web/migrations/0083_auto_20171205_1251.py @@ -17,7 +17,7 @@ class Migration(migrations.Migration): name='StudyVisitList', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[(b'GENERIC', b'Generic')], max_length=50, verbose_name=b'Type o list')), + ('type', models.CharField(choices=[('GENERIC', 'Generic')], max_length=50, verbose_name='Type o list')), ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')), ('visible_subject_columns', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.SubjectColumns')), ], @@ -26,11 +26,11 @@ class Migration(migrations.Migration): name='VisitColumns', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('datetime_begin', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Visit starts date')), - ('datetime_end', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Visit ends date')), - ('is_finished', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Is finished')), - ('post_mail_sent', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Post mail sent')), - ('visit_number', models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Visit number')), + ('datetime_begin', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Visit starts date')), + ('datetime_end', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Visit ends date')), + ('is_finished', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Is finished')), + ('post_mail_sent', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Post mail sent')), + ('visit_number', models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Visit number')), ], ), migrations.AddField( diff --git a/smash/web/migrations/0084_auto_20171205_1640.py b/smash/web/migrations/0084_auto_20171205_1640.py index 9a23ca67535e5cf3fbe8228ced13be599729b376..f8546c48b3daed53261e5b958f7e5d917194b086 100644 --- a/smash/web/migrations/0084_auto_20171205_1640.py +++ b/smash/web/migrations/0084_auto_20171205_1640.py @@ -15,17 +15,17 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studyvisitlist', name='visible_appointment_types_done', - field=models.BooleanField(default=False, verbose_name=b'Done appointments'), + field=models.BooleanField(default=False, verbose_name='Done appointments'), ), migrations.AddField( model_name='studyvisitlist', name='visible_appointment_types_in_progress', - field=models.BooleanField(default=False, verbose_name=b'Appointments in progress'), + field=models.BooleanField(default=False, verbose_name='Appointments in progress'), ), migrations.AddField( model_name='studyvisitlist', name='visible_appointment_types_missing', - field=models.BooleanField(default=False, verbose_name=b'Missing appointments'), + field=models.BooleanField(default=False, verbose_name='Missing appointments'), ), migrations.AddField( model_name='studyvisitlist', @@ -36,17 +36,17 @@ class Migration(migrations.Migration): migrations.AddField( model_name='visitcolumns', name='visible_appointment_types', - field=models.BooleanField(default=False, verbose_name=b'All appointments'), + field=models.BooleanField(default=False, verbose_name='All appointments'), ), migrations.AlterField( model_name='studyvisitlist', name='type', - field=models.CharField(choices=[(b'UNFINISHED', b'unfinished visits'), - (b'APPROACHING_WITHOUT_APPOINTMENTS', b'approaching visits'), - (b'APPROACHING_FOR_MAIL_CONTACT', b'post mail for approaching visits'), - (b'GENERIC', b'Generic'), - (b'MISSING_APPOINTMENTS', b'visits with missing appointments'), - (b'EXCEEDED_TIME', b'exceeded visit time')], max_length=50, - verbose_name=b'Type of list'), + field=models.CharField(choices=[('UNFINISHED', 'unfinished visits'), + ('APPROACHING_WITHOUT_APPOINTMENTS', 'approaching visits'), + ('APPROACHING_FOR_MAIL_CONTACT', 'post mail for approaching visits'), + ('GENERIC', 'Generic'), + ('MISSING_APPOINTMENTS', 'visits with missing appointments'), + ('EXCEEDED_TIME', 'exceeded visit time')], max_length=50, + verbose_name='Type of list'), ), ] diff --git a/smash/web/migrations/0085_auto_20171205_1650.py b/smash/web/migrations/0085_auto_20171205_1650.py index d0d6190d59ba30c0d3118363c68d13cb55775baa..baa510575f49cc292f9e1f2e26fc104d3b72e70d 100644 --- a/smash/web/migrations/0085_auto_20171205_1650.py +++ b/smash/web/migrations/0085_auto_20171205_1650.py @@ -69,7 +69,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubjectlist', name='type', - field=models.CharField(blank=True, choices=[(b'GENERIC', b'Generic'), (b'NO_VISIT', b'Subjects without visit'), (b'REQUIRE_CONTACT', b'Subjects required contact')], max_length=50, null=True, verbose_name=b'Type of list'), + field=models.CharField(blank=True, choices=[('GENERIC', 'Generic'), ('NO_VISIT', 'Subjects without visit'), ('REQUIRE_CONTACT', 'Subjects required contact')], max_length=50, null=True, verbose_name='Type of list'), ), migrations.RunPython(create_default_columns_for_VISIT_LIST_EXCEEDED_TIME) ] diff --git a/smash/web/migrations/0088_appointmentcolumns_appointmentlist.py b/smash/web/migrations/0088_appointmentcolumns_appointmentlist.py index 129299f9a96f4cc3e8207689699f477a3b777f44..aef3951e92ef55edb9d9397e7ef6de8087bf84f9 100644 --- a/smash/web/migrations/0088_appointmentcolumns_appointmentlist.py +++ b/smash/web/migrations/0088_appointmentcolumns_appointmentlist.py @@ -17,23 +17,23 @@ class Migration(migrations.Migration): name='AppointmentColumns', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('flying_team', models.BooleanField(default=False, verbose_name=b'Flying team')), - ('worker_assigned', models.BooleanField(default=False, verbose_name=b'Worker conducting the assessment')), - ('appointment_types', models.BooleanField(default=True, verbose_name=b'Appointment types')), - ('room', models.BooleanField(default=False, verbose_name=b'Room')), - ('location', models.BooleanField(default=False, verbose_name=b'Location')), - ('comment', models.BooleanField(default=False, verbose_name=b'Comment')), - ('datetime_when', models.BooleanField(default=True, verbose_name=b'Comment')), - ('length', models.BooleanField(default=False, verbose_name=b'Appointment length')), - ('status', models.BooleanField(default=False, verbose_name=b'Status')), - ('post_mail_sent', models.BooleanField(default=False, verbose_name=b'Post mail sent')), + ('flying_team', models.BooleanField(default=False, verbose_name='Flying team')), + ('worker_assigned', models.BooleanField(default=False, verbose_name='Worker conducting the assessment')), + ('appointment_types', models.BooleanField(default=True, verbose_name='Appointment types')), + ('room', models.BooleanField(default=False, verbose_name='Room')), + ('location', models.BooleanField(default=False, verbose_name='Location')), + ('comment', models.BooleanField(default=False, verbose_name='Comment')), + ('datetime_when', models.BooleanField(default=True, verbose_name='Comment')), + ('length', models.BooleanField(default=False, verbose_name='Appointment length')), + ('status', models.BooleanField(default=False, verbose_name='Status')), + ('post_mail_sent', models.BooleanField(default=False, verbose_name='Post mail sent')), ], ), migrations.CreateModel( name='AppointmentList', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[(b'GENERIC', b'Generic'), (b'UNFINISHED', b'Unfinished'), (b'APPROACHING', b'Approaching')], max_length=50, verbose_name=b'Type of list')), + ('type', models.CharField(choices=[('GENERIC', 'Generic'), ('UNFINISHED', 'Unfinished'), ('APPROACHING', 'Approaching')], max_length=50, verbose_name='Type of list')), ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')), ('visible_appointment_columns', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.AppointmentColumns')), ('visible_study_subject_columns', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.StudyColumns')), diff --git a/smash/web/migrations/0090_vouchertype_vouchertypeprice.py b/smash/web/migrations/0090_vouchertype_vouchertypeprice.py index 6b76896e3f154746b813e1182720aa334f689073..57c52c5a706f8b5ac583e4367c799b8ed24b629b 100644 --- a/smash/web/migrations/0090_vouchertype_vouchertypeprice.py +++ b/smash/web/migrations/0090_vouchertype_vouchertypeprice.py @@ -17,8 +17,8 @@ class Migration(migrations.Migration): name='VoucherType', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('code', models.CharField(max_length=20, verbose_name=b'Code')), - ('description', models.CharField(blank=True, max_length=1024, verbose_name=b'Description')), + ('code', models.CharField(max_length=20, verbose_name='Code')), + ('description', models.CharField(blank=True, max_length=1024, verbose_name='Description')), ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')), ], ), @@ -26,9 +26,9 @@ class Migration(migrations.Migration): name='VoucherTypePrice', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('price', models.DecimalField(decimal_places=2, max_digits=6, verbose_name=b'Price')), - ('start_date', models.DateField(verbose_name=b'Start date')), - ('end_date', models.DateField(verbose_name=b'End date')), + ('price', models.DecimalField(decimal_places=2, max_digits=6, verbose_name='Price')), + ('start_date', models.DateField(verbose_name='Start date')), + ('end_date', models.DateField(verbose_name='End date')), ('voucher_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.VoucherType')), ], ), diff --git a/smash/web/migrations/0092_voucher.py b/smash/web/migrations/0092_voucher.py index 27cc0e2e16cfbcf3b1daabcb3d22b04fd322229c..64dfcc661822c80c3bed392cf8154729034c13c2 100644 --- a/smash/web/migrations/0092_voucher.py +++ b/smash/web/migrations/0092_voucher.py @@ -17,12 +17,12 @@ class Migration(migrations.Migration): name='Voucher', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('number', models.CharField(max_length=10, unique=True, verbose_name=b'Number')), - ('issue_date', models.DateField(verbose_name=b'Issue date')), - ('expiry_date', models.DateField(verbose_name=b'Expiry date')), - ('use_date', models.DateField(verbose_name=b'Use date')), - ('status', models.CharField(choices=[(b'NEW', b'New'), (b'USED', b'Used'), (b'EXPIRED', b'Expired')], default=b'NEW', max_length=20, verbose_name=b'Status')), - ('feedback', models.TextField(blank=True, max_length=2000, verbose_name=b'Feedback')), + ('number', models.CharField(max_length=10, unique=True, verbose_name='Number')), + ('issue_date', models.DateField(verbose_name='Issue date')), + ('expiry_date', models.DateField(verbose_name='Expiry date')), + ('use_date', models.DateField(verbose_name='Use date')), + ('status', models.CharField(choices=[('NEW', 'New'), ('USED', 'Used'), ('EXPIRED', 'Expired')], default='NEW', max_length=20, verbose_name='Status')), + ('feedback', models.TextField(blank=True, max_length=2000, verbose_name='Feedback')), ('study_subject', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='web.StudySubject')), ('usage_partner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker')), ('voucher_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.VoucherType')), diff --git a/smash/web/migrations/0095_auto_20171208_1509.py b/smash/web/migrations/0095_auto_20171208_1509.py index 7706528368ce05b9a6308f706ffedfd8e378394d..bccf23688a667d3196f93dd863d6caaf1c166406 100644 --- a/smash/web/migrations/0095_auto_20171208_1509.py +++ b/smash/web/migrations/0095_auto_20171208_1509.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='voucher', name='use_date', - field=models.DateField(null=True, verbose_name=b'Use date'), + field=models.DateField(null=True, verbose_name='Use date'), ), ] diff --git a/smash/web/migrations/0096_auto_20171208_1509.py b/smash/web/migrations/0096_auto_20171208_1509.py index a23e3ce370719e7124ef3d8d2d976b86bcfd763e..e71521537b866e9fbc9d7896d038981821b7067c 100644 --- a/smash/web/migrations/0096_auto_20171208_1509.py +++ b/smash/web/migrations/0096_auto_20171208_1509.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='voucher', name='use_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Use date'), + field=models.DateField(blank=True, null=True, verbose_name='Use date'), ), ] diff --git a/smash/web/migrations/0097_auto_20171211_1616.py b/smash/web/migrations/0097_auto_20171211_1616.py index 852359a8c7ae673043b269287a891513f07acccb..07c4be145196cfe62fe6e0c448e5cb2d94641353 100644 --- a/smash/web/migrations/0097_auto_20171211_1616.py +++ b/smash/web/migrations/0097_auto_20171211_1616.py @@ -17,77 +17,77 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='health_partner', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Health partner'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Health partner'), ), migrations.AddField( model_name='studycolumns', name='health_partner_feedback_agreement', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Agrees to give information to referral'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Agrees to give information to referral'), ), migrations.AddField( model_name='studycolumns', name='previously_in_study', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Previously in PDP study'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Previously in PDP study'), ), migrations.AddField( model_name='studycolumns', name='referral_letter', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Referral letter'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Referral letter'), ), migrations.AddField( model_name='studycolumns', name='screening', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Screening'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Screening'), ), migrations.AddField( model_name='studycolumns', name='voucher_types', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Voucher types'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Voucher types'), ), migrations.AddField( model_name='studycolumns', name='vouchers', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'Vouchers'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=False, verbose_name='Vouchers'), ), migrations.AddField( model_name='studysubject', name='health_partner', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name=b'Health partner'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name='Health partner'), ), migrations.AddField( model_name='studysubject', name='health_partner_feedback_agreement', - field=models.BooleanField(default=False, verbose_name=b'Agrees to give information to referral'), + field=models.BooleanField(default=False, verbose_name='Agrees to give information to referral'), ), migrations.AddField( model_name='studysubject', name='previously_in_study', - field=models.BooleanField(default=False, verbose_name=b'Previously in PDP study'), + field=models.BooleanField(default=False, verbose_name='Previously in PDP study'), ), migrations.AddField( model_name='studysubject', name='referral_letter', - field=models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location=b'uploads'), upload_to=b'referral_letters', verbose_name=b'Referral letter'), + field=models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='uploads'), upload_to='referral_letters', verbose_name='Referral letter'), ), migrations.AddField( model_name='studysubject', name='screening', - field=models.CharField(blank=True, max_length=1024, null=True, verbose_name=b'Screening'), + field=models.CharField(blank=True, max_length=1024, null=True, verbose_name='Screening'), ), migrations.AddField( model_name='studysubject', name='voucher_types', - field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name=b'Voucher types'), + field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name='Voucher types'), ), migrations.AlterField( model_name='studycolumns', name='datetime_contact_reminder', - field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True, verbose_name=b'Please make a contact on'), + field=models.BooleanField(choices=[(True, 'Yes'), (False, 'No')], default=True, verbose_name='Please make a contact on'), ), migrations.AlterField( model_name='studysubject', name='diagnosis', - field=models.CharField(blank=True, max_length=1024, null=True, verbose_name=b'Diagnosis'), + field=models.CharField(blank=True, max_length=1024, null=True, verbose_name='Diagnosis'), ), migrations.AlterField( model_name='voucher', diff --git a/smash/web/migrations/0098_workerstudyrole.py b/smash/web/migrations/0098_workerstudyrole.py index 1a205daeca67eaae6cafb6a65b0d5a6641298757..d93368266e326a2f1d9ca19126da6f40e5c9a484 100644 --- a/smash/web/migrations/0098_workerstudyrole.py +++ b/smash/web/migrations/0098_workerstudyrole.py @@ -17,7 +17,7 @@ class Migration(migrations.Migration): name='WorkerStudyRole', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('role', models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary')], max_length=20, verbose_name=b'Role')), + ('role', models.CharField(choices=[('DOCTOR', 'Doctor'), ('NURSE', 'Nurse'), ('PSYCHOLOGIST', 'Psychologist'), ('TECHNICIAN', 'Technician'), ('SECRETARY', 'Secretary')], max_length=20, verbose_name='Role')), ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')), ('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='web.Worker')), ], diff --git a/smash/web/migrations/0099_auto_20171213_1115.py b/smash/web/migrations/0099_auto_20171213_1115.py index 63b737a52b85276505f847e8659f48b78d72d916..f926a715094cf4b048e2f871c10c9b8a6fbd0aa8 100644 --- a/smash/web/migrations/0099_auto_20171213_1115.py +++ b/smash/web/migrations/0099_auto_20171213_1115.py @@ -15,26 +15,26 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='worker', name='languages', - field=models.ManyToManyField(blank=True, to='web.Language', verbose_name=b'Known languages'), + field=models.ManyToManyField(blank=True, to='web.Language', verbose_name='Known languages'), ), migrations.AlterField( model_name='worker', name='locations', - field=models.ManyToManyField(blank=True, to='web.Location', verbose_name=b'Locations'), + field=models.ManyToManyField(blank=True, to='web.Location', verbose_name='Locations'), ), migrations.AlterField( model_name='worker', name='phone_number', - field=models.CharField(blank=True, max_length=20, verbose_name=b'Phone number'), + field=models.CharField(blank=True, max_length=20, verbose_name='Phone number'), ), migrations.AlterField( model_name='worker', name='specialization', - field=models.CharField(blank=True, max_length=20, verbose_name=b'Specialization'), + field=models.CharField(blank=True, max_length=20, verbose_name='Specialization'), ), migrations.AlterField( model_name='worker', name='unit', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Unit'), + field=models.CharField(blank=True, max_length=50, verbose_name='Unit'), ), ] diff --git a/smash/web/migrations/0100_auto_20171213_1140.py b/smash/web/migrations/0100_auto_20171213_1140.py index 85a67f9fe0dc3249ed870d6e296d5fc1a75e84da..ae1249db86b339281851f305365d7ec6d5b27e1d 100644 --- a/smash/web/migrations/0100_auto_20171213_1140.py +++ b/smash/web/migrations/0100_auto_20171213_1140.py @@ -16,36 +16,36 @@ class Migration(migrations.Migration): migrations.AddField( model_name='worker', name='address', - field=models.CharField(blank=True, max_length=255, verbose_name=b'Address'), + field=models.CharField(blank=True, max_length=255, verbose_name='Address'), ), migrations.AddField( model_name='worker', name='city', - field=models.CharField(blank=True, max_length=50, verbose_name=b'City'), + field=models.CharField(blank=True, max_length=50, verbose_name='City'), ), migrations.AddField( model_name='worker', name='country', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', verbose_name=b'Country'), + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', verbose_name='Country'), ), migrations.AddField( model_name='worker', name='fax_number', - field=models.CharField(blank=True, max_length=20, verbose_name=b'Fax number'), + field=models.CharField(blank=True, max_length=20, verbose_name='Fax number'), ), migrations.AddField( model_name='worker', name='phone_number_2', - field=models.CharField(blank=True, max_length=20, verbose_name=b'Phone number 2'), + field=models.CharField(blank=True, max_length=20, verbose_name='Phone number 2'), ), migrations.AddField( model_name='worker', name='postal_code', - field=models.CharField(blank=True, max_length=7, verbose_name=b'Postal code'), + field=models.CharField(blank=True, max_length=7, verbose_name='Postal code'), ), migrations.AddField( model_name='worker', name='voucher_types', - field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name=b'Voucher types'), + field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name='Voucher types'), ), ] diff --git a/smash/web/migrations/0101_auto_20171214_1047.py b/smash/web/migrations/0101_auto_20171214_1047.py index 530b92c8fd3ecbb946c6a6bfabd4041d09b8baf0..f44dea27d35023b4c76a1f20c55e8b62196901cc 100644 --- a/smash/web/migrations/0101_auto_20171214_1047.py +++ b/smash/web/migrations/0101_auto_20171214_1047.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='auto_create_follow_up', - field=models.BooleanField(default=True, verbose_name=b'Auto create follow up visit'), + field=models.BooleanField(default=True, verbose_name='Auto create follow up visit'), ), migrations.AlterField( model_name='worker', name='email', - field=models.EmailField(blank=True, max_length=254, verbose_name=b'E-mail'), + field=models.EmailField(blank=True, max_length=254, verbose_name='E-mail'), ), ] diff --git a/smash/web/migrations/0102_studynotificationparameters_subject_voucher_expiry_visible.py b/smash/web/migrations/0102_studynotificationparameters_subject_voucher_expiry_visible.py index 1c7c1b1bfb7b6f575ae2ec365e9fe1b9dd06a6a4..9686646d24f137ff5fcbff5b3207fa7cb2c1c5a3 100644 --- a/smash/web/migrations/0102_studynotificationparameters_subject_voucher_expiry_visible.py +++ b/smash/web/migrations/0102_studynotificationparameters_subject_voucher_expiry_visible.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studynotificationparameters', name='subject_voucher_expiry_visible', - field=models.BooleanField(default=False, verbose_name=b'subject vouchers almost expired'), + field=models.BooleanField(default=False, verbose_name='subject vouchers almost expired'), ), ] diff --git a/smash/web/migrations/0103_auto_20180214_1026.py b/smash/web/migrations/0103_auto_20180214_1026.py index 41a714e889691da1a4b9bd322732a92aad1b6238..3c92908add9c60ea5143ed026774a0b8250b2614 100644 --- a/smash/web/migrations/0103_auto_20180214_1026.py +++ b/smash/web/migrations/0103_auto_20180214_1026.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubjectlist', name='type', - field=models.CharField(blank=True, choices=[(b'GENERIC', b'Generic'), (b'NO_VISIT', b'Subjects without visit'), (b'REQUIRE_CONTACT', b'Subjects required contact'), (b'VOUCHER_EXPIRY', b'Subject with vouchers to be expired soon')], max_length=50, null=True, verbose_name=b'Type of list'), + field=models.CharField(blank=True, choices=[('GENERIC', 'Generic'), ('NO_VISIT', 'Subjects without visit'), ('REQUIRE_CONTACT', 'Subjects required contact'), ('VOUCHER_EXPIRY', 'Subject with vouchers to be expired soon')], max_length=50, null=True, verbose_name='Type of list'), ), ] diff --git a/smash/web/migrations/0110_auto_20180601_0754.py b/smash/web/migrations/0110_auto_20180601_0754.py index 159f4492fe63777ad19c50960df45b0be70089c8..f20b1b9429a96cd4dcf46f9d4b7bae86e722c4f0 100644 --- a/smash/web/migrations/0110_auto_20180601_0754.py +++ b/smash/web/migrations/0110_auto_20180601_0754.py @@ -16,22 +16,22 @@ class Migration(migrations.Migration): migrations.AddField( model_name='worker', name='voucher_partner_code', - field=models.CharField(blank=True, max_length=10, verbose_name=b'Code'), + field=models.CharField(blank=True, max_length=10, verbose_name='Code'), ), migrations.AlterField( model_name='studysubjectlist', name='type', - field=models.CharField(blank=True, choices=[(b'GENERIC', b'Generic subject list'), (b'NO_VISIT', b'Subjects without visit'), (b'REQUIRE_CONTACT', b'Subjects required contact'), (b'VOUCHER_EXPIRY', b'Subject with vouchers to be expired soon')], max_length=50, null=True, verbose_name=b'Type of list'), + field=models.CharField(blank=True, choices=[('GENERIC', 'Generic subject list'), ('NO_VISIT', 'Subjects without visit'), ('REQUIRE_CONTACT', 'Subjects required contact'), ('VOUCHER_EXPIRY', 'Subject with vouchers to be expired soon')], max_length=50, null=True, verbose_name='Type of list'), ), migrations.AlterField( model_name='studyvisitlist', name='type', - field=models.CharField(choices=[(b'UNFINISHED', b'unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'visits with missing appointments'), (b'EXCEEDED_TIME', b'exceeded visit time')], max_length=50, verbose_name=b'Type of list'), + field=models.CharField(choices=[('UNFINISHED', 'unfinished visits'), ('APPROACHING_WITHOUT_APPOINTMENTS', 'approaching visits'), ('APPROACHING_FOR_MAIL_CONTACT', 'post mail for approaching visits'), ('GENERIC', 'Generic visit list'), ('MISSING_APPOINTMENTS', 'visits with missing appointments'), ('EXCEEDED_TIME', 'exceeded visit time')], max_length=50, verbose_name='Type of list'), ), migrations.AlterField( model_name='voucher', name='number', - field=models.CharField(max_length=50, unique=True, verbose_name=b'Number'), + field=models.CharField(max_length=50, unique=True, verbose_name='Number'), ), migrations.AlterField( model_name='voucher', diff --git a/smash/web/migrations/0111_auto_20180601_1318.py b/smash/web/migrations/0111_auto_20180601_1318.py index 2c8bc8bda7b7bf3399a320e02e25b7b289742fad..3605a90d86158bd94d1eca6b85e89670da965b0a 100644 --- a/smash/web/migrations/0111_auto_20180601_1318.py +++ b/smash/web/migrations/0111_auto_20180601_1318.py @@ -17,8 +17,8 @@ class Migration(migrations.Migration): name='VoucherPartnerSession', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('length', models.IntegerField(verbose_name=b'Length (minutes)')), - ('date', models.DateTimeField(verbose_name=b'Issue date')), + ('length', models.IntegerField(verbose_name='Length (minutes)')), + ('date', models.DateTimeField(verbose_name='Issue date')), ], ), migrations.RemoveField( @@ -28,12 +28,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='voucher', name='hours', - field=models.IntegerField(default=0, verbose_name=b'Hours'), + field=models.IntegerField(default=0, verbose_name='Hours'), ), migrations.AlterField( model_name='voucher', name='status', - field=models.CharField(choices=[(b'NEW', b'New'), (b'IN_USE', b'In use'), (b'USED', b'Used'), (b'EXPIRED', b'Expired')], default=b'NEW', max_length=20, verbose_name=b'Status'), + field=models.CharField(choices=[('NEW', 'New'), ('IN_USE', 'In use'), ('USED', 'Used'), ('EXPIRED', 'Expired')], default='NEW', max_length=20, verbose_name='Status'), ), migrations.AddField( model_name='voucherpartnersession', diff --git a/smash/web/migrations/0112_auto_20180604_1021.py b/smash/web/migrations/0112_auto_20180604_1021.py index f2a23b319195a274b8e9f21762de0b7553974a6f..30dc84cdbf1bdceee3ce39ad712dfdc2613a40e9 100644 --- a/smash/web/migrations/0112_auto_20180604_1021.py +++ b/smash/web/migrations/0112_auto_20180604_1021.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='mailtemplate', name='context', - field=models.CharField(choices=[(b'A', b'Appointment'), (b'S', b'Subject'), (b'V', b'Visit'), (b'C', b'Voucher')], max_length=1), + field=models.CharField(choices=[('A', 'Appointment'), ('S', 'Subject'), ('V', 'Visit'), ('C', 'Voucher')], max_length=1), ), migrations.AlterField( model_name='mailtemplate', diff --git a/smash/web/migrations/0115_auto_20180611_0950.py b/smash/web/migrations/0115_auto_20180611_0950.py index ec293acf2f506b534899449f36dcb9afb2f07ae2..3a32357d1c16599ad07d722ad47349bb65dad092 100644 --- a/smash/web/migrations/0115_auto_20180611_0950.py +++ b/smash/web/migrations/0115_auto_20180611_0950.py @@ -16,122 +16,122 @@ class Migration(migrations.Migration): model_name='voucher', name='issue_worker', field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, - related_name='issued_vouchers', to='web.Worker', verbose_name=b'Issued by'), + related_name='issued_vouchers', to='web.Worker', verbose_name='Issued by'), preserve_default=False, ), migrations.AlterField( model_name='studycolumns', name='comments', - field=models.BooleanField(default=True, verbose_name=b'Comments'), + field=models.BooleanField(default=True, verbose_name='Comments'), ), migrations.AlterField( model_name='studycolumns', name='datetime_contact_reminder', - field=models.BooleanField(default=True, verbose_name=b'Please make a contact on'), + field=models.BooleanField(default=True, verbose_name='Please make a contact on'), ), migrations.AlterField( model_name='studycolumns', name='default_location', - field=models.BooleanField(default=True, verbose_name=b'Default appointment location'), + field=models.BooleanField(default=True, verbose_name='Default appointment location'), ), migrations.AlterField( model_name='studycolumns', name='diagnosis', - field=models.BooleanField(default=True, verbose_name=b'Diagnosis'), + field=models.BooleanField(default=True, verbose_name='Diagnosis'), ), migrations.AlterField( model_name='studycolumns', name='flying_team', - field=models.BooleanField(default=True, verbose_name=b'Default flying team location (if applicable)'), + field=models.BooleanField(default=True, verbose_name='Default flying team location (if applicable)'), ), migrations.AlterField( model_name='studycolumns', name='health_partner', - field=models.BooleanField(default=False, verbose_name=b'Health partner'), + field=models.BooleanField(default=False, verbose_name='Health partner'), ), migrations.AlterField( model_name='studycolumns', name='health_partner_feedback_agreement', - field=models.BooleanField(default=False, verbose_name=b'Agrees to give information to referral'), + field=models.BooleanField(default=False, verbose_name='Agrees to give information to referral'), ), migrations.AlterField( model_name='studycolumns', name='information_sent', - field=models.BooleanField(default=True, verbose_name=b'Information sent'), + field=models.BooleanField(default=True, verbose_name='Information sent'), ), migrations.AlterField( model_name='studycolumns', name='mpower_id', - field=models.BooleanField(default=True, verbose_name=b'MPower ID'), + field=models.BooleanField(default=True, verbose_name='MPower ID'), ), migrations.AlterField( model_name='studycolumns', name='nd_number', - field=models.BooleanField(default=True, verbose_name=b'ND number'), + field=models.BooleanField(default=True, verbose_name='ND number'), ), migrations.AlterField( model_name='studycolumns', name='pd_in_family', - field=models.BooleanField(default=True, verbose_name=b'PD in family'), + field=models.BooleanField(default=True, verbose_name='PD in family'), ), migrations.AlterField( model_name='studycolumns', name='postponed', - field=models.BooleanField(default=True, verbose_name=b'Postponed'), + field=models.BooleanField(default=True, verbose_name='Postponed'), ), migrations.AlterField( model_name='studycolumns', name='previously_in_study', - field=models.BooleanField(default=False, verbose_name=b'Previously in PDP study'), + field=models.BooleanField(default=False, verbose_name='Previously in PDP study'), ), migrations.AlterField( model_name='studycolumns', name='referral', - field=models.BooleanField(default=True, verbose_name=b'Referred by'), + field=models.BooleanField(default=True, verbose_name='Referred by'), ), migrations.AlterField( model_name='studycolumns', name='referral_letter', - field=models.BooleanField(default=False, verbose_name=b'Referral letter'), + field=models.BooleanField(default=False, verbose_name='Referral letter'), ), migrations.AlterField( model_name='studycolumns', name='resign_reason', - field=models.BooleanField(default=True, verbose_name=b'Resign reason'), + field=models.BooleanField(default=True, verbose_name='Resign reason'), ), migrations.AlterField( model_name='studycolumns', name='resigned', - field=models.BooleanField(default=True, verbose_name=b'Resigned'), + field=models.BooleanField(default=True, verbose_name='Resigned'), ), migrations.AlterField( model_name='studycolumns', name='screening', - field=models.BooleanField(default=False, verbose_name=b'Screening'), + field=models.BooleanField(default=False, verbose_name='Screening'), ), migrations.AlterField( model_name='studycolumns', name='screening_number', - field=models.BooleanField(default=True, verbose_name=b'Screening number'), + field=models.BooleanField(default=True, verbose_name='Screening number'), ), migrations.AlterField( model_name='studycolumns', name='type', - field=models.BooleanField(default=True, verbose_name=b'Type'), + field=models.BooleanField(default=True, verbose_name='Type'), ), migrations.AlterField( model_name='studycolumns', name='voucher_types', - field=models.BooleanField(default=False, verbose_name=b'Voucher types'), + field=models.BooleanField(default=False, verbose_name='Voucher types'), ), migrations.AlterField( model_name='studycolumns', name='vouchers', - field=models.BooleanField(default=False, verbose_name=b'Vouchers'), + field=models.BooleanField(default=False, verbose_name='Vouchers'), ), migrations.AlterField( model_name='studycolumns', name='year_of_diagnosis', - field=models.BooleanField(default=True, verbose_name=b'Year of diagnosis (YYYY)'), + field=models.BooleanField(default=True, verbose_name='Year of diagnosis (YYYY)'), ), ] diff --git a/smash/web/migrations/0116_auto_20180611_1346.py b/smash/web/migrations/0116_auto_20180611_1346.py index 5859c5dda4302fa8521c4e4b5ec7b5869f003515..6308017346ac0b246ec270bbe3892e39dce4cdd4 100644 --- a/smash/web/migrations/0116_auto_20180611_1346.py +++ b/smash/web/migrations/0116_auto_20180611_1346.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studysubject', name='date_added', - field=models.DateField(auto_now_add=True, verbose_name=b'Added on'), + field=models.DateField(auto_now_add=True, verbose_name='Added on'), ), ] diff --git a/smash/web/migrations/0117_auto_20180717_1434.py b/smash/web/migrations/0117_auto_20180717_1434.py index c540dc823114e21f509803d1635f60b3df2dcfb6..cd5cae1a7795413bfb1e002d0f98ec26bbb0eec4 100644 --- a/smash/web/migrations/0117_auto_20180717_1434.py +++ b/smash/web/migrations/0117_auto_20180717_1434.py @@ -15,16 +15,16 @@ class Migration(migrations.Migration): migrations.AddField( model_name='worker', name='name', - field=models.CharField(blank=True, default=b'', max_length=50, verbose_name=b'Name'), + field=models.CharField(blank=True, default='', max_length=50, verbose_name='Name'), ), migrations.AlterField( model_name='worker', name='first_name', - field=models.CharField(blank=True, max_length=50, verbose_name=b'First name'), + field=models.CharField(blank=True, max_length=50, verbose_name='First name'), ), migrations.AlterField( model_name='worker', name='last_name', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Last name'), + field=models.CharField(blank=True, max_length=50, verbose_name='Last name'), ), ] diff --git a/smash/web/migrations/0118_voucher_activity_type.py b/smash/web/migrations/0118_voucher_activity_type.py index 06d10c168e7a02c64aa94203a3e03ff9aa62443c..4b2b5f02397775cc818f66d215b042a6404a7cc2 100644 --- a/smash/web/migrations/0118_voucher_activity_type.py +++ b/smash/web/migrations/0118_voucher_activity_type.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='voucher', name='activity_type', - field=models.CharField(blank=True, default=b'', max_length=40, verbose_name=b'Activity type'), + field=models.CharField(blank=True, default='', max_length=40, verbose_name='Activity type'), ), ] diff --git a/smash/web/migrations/0119_auto_20181002_0908.py b/smash/web/migrations/0119_auto_20181002_0908.py index e6426d4147cf6432ad1021531f13c18c0163ab1f..694519ec5d10e37ec794460e75782cefdaf85512 100644 --- a/smash/web/migrations/0119_auto_20181002_0908.py +++ b/smash/web/migrations/0119_auto_20181002_0908.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='workerstudyrole', name='role', - field=models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary'), (b'PROJECT MANAGER', b'Project Manager')], max_length=20, verbose_name=b'Role'), + field=models.CharField(choices=[('DOCTOR', 'Doctor'), ('NURSE', 'Nurse'), ('PSYCHOLOGIST', 'Psychologist'), ('TECHNICIAN', 'Technician'), ('SECRETARY', 'Secretary'), ('PROJECT MANAGER', 'Project Manager')], max_length=20, verbose_name='Role'), ), ] diff --git a/smash/web/migrations/0119_auto_20181015_1324.py b/smash/web/migrations/0119_auto_20181015_1324.py index 7ac5d1774e0e2ae1d0c221773fcd739180f1abe6..8a66f73d04df7ff72802d4e1f61c82aeb7aa3219 100644 --- a/smash/web/migrations/0119_auto_20181015_1324.py +++ b/smash/web/migrations/0119_auto_20181015_1324.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studyvisitlist', name='type', - field=models.CharField(choices=[(b'UNFINISHED', b'Unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'Approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'Post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'Visits with missing appointments'), (b'EXCEEDED_TIME', b'Exceeded visit time')], max_length=50, verbose_name=b'Type of list'), + field=models.CharField(choices=[('UNFINISHED', 'Unfinished visits'), ('APPROACHING_WITHOUT_APPOINTMENTS', 'Approaching visits'), ('APPROACHING_FOR_MAIL_CONTACT', 'Post mail for approaching visits'), ('GENERIC', 'Generic visit list'), ('MISSING_APPOINTMENTS', 'Visits with missing appointments'), ('EXCEEDED_TIME', 'Exceeded visit time')], max_length=50, verbose_name='Type of list'), ), migrations.AlterField( model_name='workerstudyrole', name='role', - field=models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary'), (b'PROJECT MANAGER', b'Project Manager')], max_length=20, verbose_name=b'Role'), + field=models.CharField(choices=[('DOCTOR', 'Doctor'), ('NURSE', 'Nurse'), ('PSYCHOLOGIST', 'Psychologist'), ('TECHNICIAN', 'Technician'), ('SECRETARY', 'Secretary'), ('PROJECT MANAGER', 'Project Manager')], max_length=20, verbose_name='Role'), ), ] diff --git a/smash/web/migrations/0119_auto_20181024_1158.py b/smash/web/migrations/0119_auto_20181024_1158.py index ff17f157a9869d7284d817e91d59202c66d4c882..1132667f7ce5b12b5eb9b4b9a6bf38dce5b458ec 100644 --- a/smash/web/migrations/0119_auto_20181024_1158.py +++ b/smash/web/migrations/0119_auto_20181024_1158.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studyvisitlist', name='type', - field=models.CharField(choices=[(b'UNFINISHED', b'Unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'Approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'Post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'Visits with missing appointments'), (b'EXCEEDED_TIME', b'Exceeded visit time')], max_length=50, verbose_name=b'Type of list'), + field=models.CharField(choices=[('UNFINISHED', 'Unfinished visits'), ('APPROACHING_WITHOUT_APPOINTMENTS', 'Approaching visits'), ('APPROACHING_FOR_MAIL_CONTACT', 'Post mail for approaching visits'), ('GENERIC', 'Generic visit list'), ('MISSING_APPOINTMENTS', 'Visits with missing appointments'), ('EXCEEDED_TIME', 'Exceeded visit time')], max_length=50, verbose_name='Type of list'), ), migrations.AlterField( model_name='workerstudyrole', name='role', - field=models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary'), (b'PROJECT MANAGER', b'Project Manager')], max_length=20, verbose_name=b'Role'), + field=models.CharField(choices=[('DOCTOR', 'Doctor'), ('NURSE', 'Nurse'), ('PSYCHOLOGIST', 'Psychologist'), ('TECHNICIAN', 'Technician'), ('SECRETARY', 'Secretary'), ('PROJECT MANAGER', 'Project Manager')], max_length=20, verbose_name='Role'), ), ] diff --git a/smash/web/migrations/0120_holiday_kind.py b/smash/web/migrations/0120_holiday_kind.py index cb66217c1bd3aa72465faa829094062955be7225..97e043dd7072db75fe6375a8c554a6ea7b1ebc6b 100644 --- a/smash/web/migrations/0120_holiday_kind.py +++ b/smash/web/migrations/0120_holiday_kind.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='holiday', name='kind', - field=models.CharField(choices=[(b'H', b'Holiday'), (b'X', b'Extra Availability')], default=b'H', max_length=16), + field=models.CharField(choices=[('H', 'Holiday'), ('X', 'Extra Availability')], default='H', max_length=16), ), ] diff --git a/smash/web/migrations/0120_study_nd_number_study_subject_regex.py b/smash/web/migrations/0120_study_nd_number_study_subject_regex.py index df7c895a0358cf6e52b748ce842a7d0cbb2e2039..5b15f27c2e17c5eee4067a3c3caae2d0deaff2dd 100644 --- a/smash/web/migrations/0120_study_nd_number_study_subject_regex.py +++ b/smash/web/migrations/0120_study_nd_number_study_subject_regex.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='nd_number_study_subject_regex', - field=models.CharField(default=b'^ND\\d{4}$', help_text=b'Defines the regex to check the identification number used for each study subject.', max_length=255, verbose_name=b'Study Subject ND Number Regex'), + field=models.CharField(default='^ND\\d{4}$', help_text='Defines the regex to check the identification number used for each study subject.', max_length=255, verbose_name='Study Subject ND Number Regex'), ), ] diff --git a/smash/web/migrations/0121_auto_20181003_1256.py b/smash/web/migrations/0121_auto_20181003_1256.py index c2018e15a7e3998169719eb1fddb618b488717e6..3f9b81340bd1c98d566742128ea21b1b2235d3f5 100644 --- a/smash/web/migrations/0121_auto_20181003_1256.py +++ b/smash/web/migrations/0121_auto_20181003_1256.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='holiday', name='kind', - field=models.CharField(choices=[(b'H', b'Holiday'), (b'X', b'Extra Availability')], default=b'H', help_text=b'Defines the kind of availability. Either Holiday or Extra Availability.', max_length=1), + field=models.CharField(choices=[('H', 'Holiday'), ('X', 'Extra Availability')], default='H', help_text='Defines the kind of availability. Either Holiday or Extra Availability.', max_length=1), ), ] diff --git a/smash/web/migrations/0121_auto_20181024_1859.py b/smash/web/migrations/0121_auto_20181024_1859.py index 9bb28cf07e705e74335e3498b27c9ecdab49fd38..e732ceaf89b76edfeb351231375f52faafe4b607 100644 --- a/smash/web/migrations/0121_auto_20181024_1859.py +++ b/smash/web/migrations/0121_auto_20181024_1859.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='study', name='nd_number_study_subject_regex', - field=models.CharField(default=b'^ND\\d{4}$', help_text=b'Defines the regex to check the ID used for each study subject. Keep in mind that this regex should be valid for all previous study subjects in the database.', max_length=255, verbose_name=b'Study Subject ND Number Regex'), + field=models.CharField(default='^ND\\d{4}$', help_text='Defines the regex to check the ID used for each study subject. Keep in mind that this regex should be valid for all previous study subjects in the database.', max_length=255, verbose_name='Study Subject ND Number Regex'), ), ] diff --git a/smash/web/migrations/0124_auto_20181017_1532.py b/smash/web/migrations/0124_auto_20181017_1532.py index 6b473d67079448875c076bfd4f5593fc94e86f7c..19b6a5c29f54d4eec206d6621d858b6a81a45a5f 100644 --- a/smash/web/migrations/0124_auto_20181017_1532.py +++ b/smash/web/migrations/0124_auto_20181017_1532.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studyvisitlist', name='type', - field=models.CharField(choices=[(b'UNFINISHED', b'unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'visits with missing appointments'), (b'EXCEEDED_TIME', b'exceeded visit time')], max_length=50, verbose_name=b'Type of list'), + field=models.CharField(choices=[('UNFINISHED', 'unfinished visits'), ('APPROACHING_WITHOUT_APPOINTMENTS', 'approaching visits'), ('APPROACHING_FOR_MAIL_CONTACT', 'post mail for approaching visits'), ('GENERIC', 'Generic visit list'), ('MISSING_APPOINTMENTS', 'visits with missing appointments'), ('EXCEEDED_TIME', 'exceeded visit time')], max_length=50, verbose_name='Type of list'), ), ] diff --git a/smash/web/migrations/0126_auto_20181030_1733.py b/smash/web/migrations/0126_auto_20181030_1733.py index 1674a5bc96a2c5d4e35b28a8356d8180f472e26f..d8333cf5af9127c58b529d19aedfc658645a7e85 100644 --- a/smash/web/migrations/0126_auto_20181030_1733.py +++ b/smash/web/migrations/0126_auto_20181030_1733.py @@ -15,16 +15,16 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subject', name='phone_number', - field=models.CharField(blank=True, max_length=64, null=True, verbose_name=b'Phone number'), + field=models.CharField(blank=True, max_length=64, null=True, verbose_name='Phone number'), ), migrations.AlterField( model_name='subject', name='phone_number_2', - field=models.CharField(blank=True, max_length=64, null=True, verbose_name=b'Phone number 2'), + field=models.CharField(blank=True, max_length=64, null=True, verbose_name='Phone number 2'), ), migrations.AlterField( model_name='subject', name='phone_number_3', - field=models.CharField(blank=True, max_length=64, null=True, verbose_name=b'Phone number 3'), + field=models.CharField(blank=True, max_length=64, null=True, verbose_name='Phone number 3'), ), ] diff --git a/smash/web/migrations/0127_auto_20181031_0959.py b/smash/web/migrations/0127_auto_20181031_0959.py index 4807157dc86828c4e3b2a9e92cb1e28f579d15a2..cee722cfda10f05a7d01fb291e89453623d28e2c 100644 --- a/smash/web/migrations/0127_auto_20181031_0959.py +++ b/smash/web/migrations/0127_auto_20181031_0959.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studysubject', name='exclude_reason', - field=models.TextField(blank=True, max_length=2000, verbose_name=b'Exclude reason'), + field=models.TextField(blank=True, max_length=2000, verbose_name='Exclude reason'), ), migrations.AddField( model_name='studysubject', name='excluded', - field=models.BooleanField(default=False, verbose_name=b'Excluded'), + field=models.BooleanField(default=False, verbose_name='Excluded'), ), ] diff --git a/smash/web/migrations/0128_studycolumns_excluded.py b/smash/web/migrations/0128_studycolumns_excluded.py index b7d9b7c67be13d2cd0ff0e33ec058f20d1a27cd0..2f0e1a52165bb43eadb2c9de302749274042a5d7 100644 --- a/smash/web/migrations/0128_studycolumns_excluded.py +++ b/smash/web/migrations/0128_studycolumns_excluded.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='excluded', - field=models.BooleanField(default=True, verbose_name=b'Excluded'), + field=models.BooleanField(default=True, verbose_name='Excluded'), ), ] diff --git a/smash/web/migrations/0129_auto_20181031_1348.py b/smash/web/migrations/0129_auto_20181031_1348.py index 1ef867f38c837787625bbf73217d28ee624cf2d1..b27a23132380eeb7386d0d4fc8f12bee0c1ee939 100644 --- a/smash/web/migrations/0129_auto_20181031_1348.py +++ b/smash/web/migrations/0129_auto_20181031_1348.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='studycolumns', name='excluded', - field=models.BooleanField(default=False, verbose_name=b'Excluded'), + field=models.BooleanField(default=False, verbose_name='Excluded'), ), ] diff --git a/smash/web/migrations/0130_study_visits_to_show_in_subject_list.py b/smash/web/migrations/0130_study_visits_to_show_in_subject_list.py index fe530019fb69ab330e28c521ddecf349085f58a1..513548edff75aa2abd19a46622fa69e1cabf932e 100644 --- a/smash/web/migrations/0130_study_visits_to_show_in_subject_list.py +++ b/smash/web/migrations/0130_study_visits_to_show_in_subject_list.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='visits_to_show_in_subject_list', - field=models.IntegerField(default=5, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(1)], verbose_name=b'Number of visits to show in the subject list'), + field=models.IntegerField(default=5, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(1)], verbose_name='Number of visits to show in the subject list'), ), ] diff --git a/smash/web/migrations/0131_study_default_voucher_expiration_in_months.py b/smash/web/migrations/0131_study_default_voucher_expiration_in_months.py index 2a3c7413085ce1a067a334b8b2551b9b4a15f0cb..7e1b0e97c6ed29ddfa3bb97113da85211575b7b0 100644 --- a/smash/web/migrations/0131_study_default_voucher_expiration_in_months.py +++ b/smash/web/migrations/0131_study_default_voucher_expiration_in_months.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='default_voucher_expiration_in_months', - field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Default duration of the vouchers in months'), + field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Default duration of the vouchers in months'), ), ] diff --git a/smash/web/migrations/0132_study_default_visit_duration_in_months.py b/smash/web/migrations/0132_study_default_visit_duration_in_months.py index 02efe4efbbcd94924db0bc8dc33894623542229e..de941d6fc215cc19e2b7e4367b5b12afc90ddbf0 100644 --- a/smash/web/migrations/0132_study_default_visit_duration_in_months.py +++ b/smash/web/migrations/0132_study_default_visit_duration_in_months.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='default_visit_duration_in_months', - field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Default duration of the visits in months'), + field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Default duration of the visits in months'), ), ] diff --git a/smash/web/migrations/0132_worker_comment.py b/smash/web/migrations/0132_worker_comment.py index e4429baf3e51f938c45d126d9857dc26b6ff80d6..cd6ca169a3f35aa7410db051b8a472364df4ac87 100644 --- a/smash/web/migrations/0132_worker_comment.py +++ b/smash/web/migrations/0132_worker_comment.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='worker', name='comment', - field=models.TextField(blank=True, max_length=1024, null=True, verbose_name=b'Comment'), + field=models.TextField(blank=True, max_length=1024, null=True, verbose_name='Comment'), ), ] diff --git a/smash/web/migrations/0132_workerstudyrole_permissions.py b/smash/web/migrations/0132_workerstudyrole_permissions.py index 4477be4d93ae9084f935a4c7727f4fe26476ffbb..2b429909d23574ba51cb6917b3b1ddfe4a29c7b4 100644 --- a/smash/web/migrations/0132_workerstudyrole_permissions.py +++ b/smash/web/migrations/0132_workerstudyrole_permissions.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='workerstudyrole', name='permissions', - field=models.ManyToManyField(blank=True, to='auth.Permission', verbose_name=b'Worker Study Permissions'), + field=models.ManyToManyField(blank=True, to='auth.Permission', verbose_name='Worker Study Permissions'), ), ] diff --git a/smash/web/migrations/0133_auto_20181113_1550.py b/smash/web/migrations/0133_auto_20181113_1550.py index 7771620ca0688bcd9cdc7ec2ebfa1af53df26027..45761ab806ceca3daf08d1493ea13007b68bbab2 100644 --- a/smash/web/migrations/0133_auto_20181113_1550.py +++ b/smash/web/migrations/0133_auto_20181113_1550.py @@ -16,26 +16,26 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='default_delta_time_for_control_follow_up', - field=models.IntegerField(default=4, help_text=b'Time difference between visits used to automatically create follow up visits', validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Time difference between control visits'), + field=models.IntegerField(default=4, help_text='Time difference between visits used to automatically create follow up visits', validators=[django.core.validators.MinValueValidator(1)], verbose_name='Time difference between control visits'), ), migrations.AddField( model_name='study', name='default_delta_time_for_follow_up_units', - field=models.CharField(choices=[(b'days', b'Days'), (b'years', b'Years')], default=b'years', help_text=b'Units for the number of days between visits for both patients and controls', max_length=10, verbose_name=b'Units for the follow up incrementals'), + field=models.CharField(choices=[('days', 'Days'), ('years', 'Years')], default='years', help_text='Units for the number of days between visits for both patients and controls', max_length=10, verbose_name='Units for the follow up incrementals'), ), migrations.AddField( model_name='study', name='default_delta_time_for_patient_follow_up', - field=models.IntegerField(default=1, help_text=b'Time difference between visits used to automatically create follow up visits', validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Time difference between patient visits'), + field=models.IntegerField(default=1, help_text='Time difference between visits used to automatically create follow up visits', validators=[django.core.validators.MinValueValidator(1)], verbose_name='Time difference between patient visits'), ), migrations.AlterField( model_name='study', name='default_visit_duration_in_months', - field=models.IntegerField(default=6, help_text=b'Duration of the visit, this is, the time interval, in months, when the appointments may take place', validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Duration of the visits in months'), + field=models.IntegerField(default=6, help_text='Duration of the visit, this is, the time interval, in months, when the appointments may take place', validators=[django.core.validators.MinValueValidator(1)], verbose_name='Duration of the visits in months'), ), migrations.AlterField( model_name='study', name='default_voucher_expiration_in_months', - field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Duration of the vouchers in months'), + field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Duration of the vouchers in months'), ), ] diff --git a/smash/web/migrations/0137_auto_20190321_1024.py b/smash/web/migrations/0137_auto_20190321_1024.py index 3efceba18d481bcfcab15942bf2a64bf89623cf0..0373645b67444b7c3788cf07f74df5f6a25ea988 100644 --- a/smash/web/migrations/0137_auto_20190321_1024.py +++ b/smash/web/migrations/0137_auto_20190321_1024.py @@ -15,21 +15,21 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='endpoint_reached', - field=models.BooleanField(default=True, verbose_name=b'Endpoint reached'), + field=models.BooleanField(default=True, verbose_name='Endpoint reached'), ), migrations.AddField( model_name='studysubject', name='endpoint_reached', - field=models.BooleanField(default=False, verbose_name=b'Endpoint Reached'), + field=models.BooleanField(default=False, verbose_name='Endpoint Reached'), ), migrations.AddField( model_name='studysubject', name='endpoint_reached_reason', - field=models.TextField(blank=True, max_length=2000, verbose_name=b'Endpoint reached comments'), + field=models.TextField(blank=True, max_length=2000, verbose_name='Endpoint reached comments'), ), migrations.AlterField( model_name='studycolumns', name='resign_reason', - field=models.BooleanField(default=True, verbose_name=b'Endpoint reached comments'), + field=models.BooleanField(default=True, verbose_name='Endpoint reached comments'), ), ] diff --git a/smash/web/migrations/0138_auto_20190321_1111.py b/smash/web/migrations/0138_auto_20190321_1111.py index d2fc222f913e366da4faff9d9d5cdecd8f1559c6..adf8428e431917d8c4e0e5357f56984983716e16 100644 --- a/smash/web/migrations/0138_auto_20190321_1111.py +++ b/smash/web/migrations/0138_auto_20190321_1111.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='voucher', name='status', - field=models.CharField(choices=[(b'NEW', b'New'), (b'IN_USE', b'In use'), (b'USED', b'Used'), (b'EXPIRED', b'Expired'), (b'REMOVED', b'Removed')], default=b'NEW', max_length=20, verbose_name=b'Status'), + field=models.CharField(choices=[('NEW', 'New'), ('IN_USE', 'In use'), ('USED', 'Used'), ('EXPIRED', 'Expired'), ('REMOVED', 'Removed')], default='NEW', max_length=20, verbose_name='Status'), ), ] diff --git a/smash/web/migrations/0140_auto_20190528_0953.py b/smash/web/migrations/0140_auto_20190528_0953.py index 2c7c1a1927e8b946a1e347dfe557ae6ce40ebfa6..9f2e65eccee7ad8d05caccf33b7d8290f21131fb 100644 --- a/smash/web/migrations/0140_auto_20190528_0953.py +++ b/smash/web/migrations/0140_auto_20190528_0953.py @@ -18,11 +18,11 @@ class Migration(migrations.Migration): name='StudyRedCapColumns', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sex', models.BooleanField(default=True, verbose_name=b'Sex')), - ('date_born', models.BooleanField(default=True, verbose_name=b'Date of birth')), - ('dead', models.BooleanField(default=True, verbose_name=b'Dead')), - ('mpower_id', models.BooleanField(default=True, verbose_name=b'MPower ID')), - ('languages', models.BooleanField(default=True, verbose_name=b'Languages')), + ('sex', models.BooleanField(default=True, verbose_name='Sex')), + ('date_born', models.BooleanField(default=True, verbose_name='Date of birth')), + ('dead', models.BooleanField(default=True, verbose_name='Dead')), + ('mpower_id', models.BooleanField(default=True, verbose_name='MPower ID')), + ('languages', models.BooleanField(default=True, verbose_name='Languages')), ], )] if is_sqlite_db(): diff --git a/smash/web/migrations/0141_auto_20200319_1040.py b/smash/web/migrations/0141_auto_20200319_1040.py index 5e2d11e0858a8858e7d09aee5abf28a907cf7cef..1ec81c4fa0c40d903297532068676e1b987c3ec2 100644 --- a/smash/web/migrations/0141_auto_20200319_1040.py +++ b/smash/web/migrations/0141_auto_20200319_1040.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='appointmenttype', name='calendar_font_color', - field=models.CharField(default=b'#00000', max_length=2000, verbose_name=b'Calendar font color'), + field=models.CharField(default='#00000', max_length=2000, verbose_name='Calendar font color'), ), ] diff --git a/smash/web/migrations/0142_provenance.py b/smash/web/migrations/0142_provenance.py index 99a9099f760d1098b3e2ee22c980ec0c21c365c6..2d770b2d7323fcac89307aba15f0dfcc61d6f5bd 100644 --- a/smash/web/migrations/0142_provenance.py +++ b/smash/web/migrations/0142_provenance.py @@ -17,13 +17,13 @@ class Migration(migrations.Migration): name='Provenance', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified_table', models.CharField(max_length=1024, verbose_name=b'Modified table')), - ('modified_table_id', models.CharField(max_length=1024, verbose_name=b'Modified table row')), - ('modification_date', models.DateTimeField(verbose_name=b'Modified on')), - ('previous_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name=b'Previous Value')), - ('new_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name=b'New Value')), - ('modification_description', models.CharField(max_length=2048, verbose_name=b'Description')), - ('modification_author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name=b'Worker who modified the row')), + ('modified_table', models.CharField(max_length=1024, verbose_name='Modified table')), + ('modified_table_id', models.CharField(max_length=1024, verbose_name='Modified table row')), + ('modification_date', models.DateTimeField(verbose_name='Modified on')), + ('previous_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Previous Value')), + ('new_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='New Value')), + ('modification_description', models.CharField(max_length=2048, verbose_name='Description')), + ('modification_author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name='Worker who modified the row')), ], ), ] diff --git a/smash/web/migrations/0143_auto_20200319_1121.py b/smash/web/migrations/0143_auto_20200319_1121.py index 4c651a39b1af26f32dfb25c14214273e9231a4b7..f9eaeb5189443a7ff327be98f835a2acb9b33fbd 100644 --- a/smash/web/migrations/0143_auto_20200319_1121.py +++ b/smash/web/migrations/0143_auto_20200319_1121.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='provenance', name='modification_date', - field=models.DateTimeField(auto_now_add=True, verbose_name=b'Modified on'), + field=models.DateTimeField(auto_now_add=True, verbose_name='Modified on'), ), ] diff --git a/smash/web/migrations/0144_auto_20200319_1221.py b/smash/web/migrations/0144_auto_20200319_1221.py index b4eab423f46407a84edb253c216077caa0c4ded8..e8b8c4bfdeb810ed9d57b6d3172d1098ab9cbc78 100644 --- a/smash/web/migrations/0144_auto_20200319_1221.py +++ b/smash/web/migrations/0144_auto_20200319_1221.py @@ -15,12 +15,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='provenance', name='modified_field', - field=models.CharField(default='', max_length=1024, verbose_name=b'Modified field'), + field=models.CharField(default='', max_length=1024, verbose_name='Modified field'), preserve_default=False, ), migrations.AlterField( model_name='provenance', name='modification_description', - field=models.CharField(max_length=20480, verbose_name=b'Description'), + field=models.CharField(max_length=20480, verbose_name='Description'), ), ] diff --git a/smash/web/migrations/0145_auto_20200319_1404.py b/smash/web/migrations/0145_auto_20200319_1404.py index 43b2724511c4b7a0818effbd98a3a70c38a7b973..21dfc1004facf6f15a6d8fdd4454cf275112825d 100644 --- a/smash/web/migrations/0145_auto_20200319_1404.py +++ b/smash/web/migrations/0145_auto_20200319_1404.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='provenance', name='modified_field', - field=models.CharField(blank=b'', max_length=1024, verbose_name=b'Modified field'), + field=models.CharField(blank='', max_length=1024, verbose_name='Modified field'), ), ] diff --git a/smash/web/migrations/0146_auto_20200319_1446.py b/smash/web/migrations/0146_auto_20200319_1446.py index 663d50247fe81ce09950865a8090bf7719edaa42..cfa59cf7e2775d5b461c2786a1b961ab9a544282 100644 --- a/smash/web/migrations/0146_auto_20200319_1446.py +++ b/smash/web/migrations/0146_auto_20200319_1446.py @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='provenance', name='modification_author', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name=b'Worker who modified the row'), + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker', verbose_name='Worker who modified the row'), ), ] diff --git a/smash/web/migrations/0147_auto_20200320_0931.py b/smash/web/migrations/0147_auto_20200320_0931.py index 39cf0185b00409aeab5fefae207ec674fbf29c2a..f39112b066594e3002e9b0aab4e396f70dd0f8dc 100644 --- a/smash/web/migrations/0147_auto_20200320_0931.py +++ b/smash/web/migrations/0147_auto_20200320_0931.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='provenance', name='modified_table_id', - field=models.IntegerField(default=0, verbose_name=b'Modified table row'), + field=models.IntegerField(default=0, verbose_name='Modified table row'), ), ] diff --git a/smash/web/migrations/0148_auto_20200319_1301.py b/smash/web/migrations/0148_auto_20200319_1301.py index 301a3d5eb3ca7a95f71c89c618b2655f07cef5dc..0d9ecd0e3b6720ee41082ba333d972cfbf0e312d 100644 --- a/smash/web/migrations/0148_auto_20200319_1301.py +++ b/smash/web/migrations/0148_auto_20200319_1301.py @@ -18,6 +18,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='appointmenttype', name='calendar_font_color', - field=models.CharField(default=b'#00000', max_length=2000, verbose_name=b'Calendar font color'), + field=models.CharField(default='#00000', max_length=2000, verbose_name='Calendar font color'), ), ] diff --git a/smash/web/migrations/0153_auto_20200320_0932.py b/smash/web/migrations/0153_auto_20200320_0932.py index f68d08e752c2353a01a4c527c7f5912a2e8cc4a4..af773236c8ccad0a5e91e36d26c15c5e0c9d9628 100644 --- a/smash/web/migrations/0153_auto_20200320_0932.py +++ b/smash/web/migrations/0153_auto_20200320_0932.py @@ -15,41 +15,41 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='brain_donation_agreement', - field=models.BooleanField(default=False, verbose_name=b'Brain donation agreement'), + field=models.BooleanField(default=False, verbose_name='Brain donation agreement'), ), migrations.AddField( model_name='studysubject', name='brain_donation_agreement', - field=models.BooleanField(default=False, verbose_name=b'Brain donation agreement'), + field=models.BooleanField(default=False, verbose_name='Brain donation agreement'), ), migrations.AddField( model_name='subject', name='next_of_keen_address', - field=models.TextField(blank=True, max_length=2000, verbose_name=b'Next of keen address'), + field=models.TextField(blank=True, max_length=2000, verbose_name='Next of keen address'), ), migrations.AddField( model_name='subject', name='next_of_keen_name', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Next of keen'), + field=models.CharField(blank=True, max_length=50, verbose_name='Next of keen'), ), migrations.AddField( model_name='subject', name='next_of_keen_phone', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Next of keen phone'), + field=models.CharField(blank=True, max_length=50, verbose_name='Next of keen phone'), ), migrations.AddField( model_name='subjectcolumns', name='next_of_keen_address', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of keen address'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of keen address'), ), migrations.AddField( model_name='subjectcolumns', name='next_of_keen_name', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of keen'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of keen'), ), migrations.AddField( model_name='subjectcolumns', name='next_of_keen_phone', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of keen phone'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of keen phone'), ), ] diff --git a/smash/web/migrations/0160_auto_20200415_1101.py b/smash/web/migrations/0160_auto_20200415_1101.py index aa1dfa9a90bc3d429a4e20df30647d613286c27e..af28df3fc089413c0051dd21dc45a2fc0cc9f738 100644 --- a/smash/web/migrations/0160_auto_20200415_1101.py +++ b/smash/web/migrations/0160_auto_20200415_1101.py @@ -15,101 +15,101 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='virus_test_1', - field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus results'), + field=models.BooleanField(default=False, verbose_name='Visit 1 virus results'), ), migrations.AddField( model_name='studycolumns', name='virus_test_1_updated', - field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus results date'), + field=models.BooleanField(default=False, verbose_name='Visit 1 virus results date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_2', - field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus results'), + field=models.BooleanField(default=False, verbose_name='Visit 2 virus results'), ), migrations.AddField( model_name='studycolumns', name='virus_test_2_updated', - field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus results date'), + field=models.BooleanField(default=False, verbose_name='Visit 2 virus results date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_3', - field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus results'), + field=models.BooleanField(default=False, verbose_name='Visit 3 virus results'), ), migrations.AddField( model_name='studycolumns', name='virus_test_3_updated', - field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus results date'), + field=models.BooleanField(default=False, verbose_name='Visit 3 virus results date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_4', - field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus results'), + field=models.BooleanField(default=False, verbose_name='Visit 4 virus results'), ), migrations.AddField( model_name='studycolumns', name='virus_test_4_updated', - field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus results date'), + field=models.BooleanField(default=False, verbose_name='Visit 4 virus results date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_5', - field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus results'), + field=models.BooleanField(default=False, verbose_name='Visit 5 virus results'), ), migrations.AddField( model_name='studycolumns', name='virus_test_5_updated', - field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus results date'), + field=models.BooleanField(default=False, verbose_name='Visit 5 virus results date'), ), migrations.AddField( model_name='studysubject', name='virus_test_1', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, editable=False, verbose_name=b'Visit 1 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, editable=False, verbose_name='Visit 1 virus result'), ), migrations.AddField( model_name='studysubject', name='virus_test_1_updated', - field=models.DateField(editable=False, null=True, verbose_name=b'Visit 1 virus result date'), + field=models.DateField(editable=False, null=True, verbose_name='Visit 1 virus result date'), ), migrations.AddField( model_name='studysubject', name='virus_test_2', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, editable=False, verbose_name=b'Visit 2 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, editable=False, verbose_name='Visit 2 virus result'), ), migrations.AddField( model_name='studysubject', name='virus_test_2_updated', - field=models.DateField(editable=False, null=True, verbose_name=b'Visit 2 virus result date'), + field=models.DateField(editable=False, null=True, verbose_name='Visit 2 virus result date'), ), migrations.AddField( model_name='studysubject', name='virus_test_3', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, editable=False, verbose_name=b'Visit 3 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, editable=False, verbose_name='Visit 3 virus result'), ), migrations.AddField( model_name='studysubject', name='virus_test_3_updated', - field=models.DateField(editable=False, null=True, verbose_name=b'Visit 3 virus result date'), + field=models.DateField(editable=False, null=True, verbose_name='Visit 3 virus result date'), ), migrations.AddField( model_name='studysubject', name='virus_test_4', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, editable=False, verbose_name=b'Visit 4 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, editable=False, verbose_name='Visit 4 virus result'), ), migrations.AddField( model_name='studysubject', name='virus_test_4_updated', - field=models.DateField(editable=False, null=True, verbose_name=b'Visit 4 virus result date'), + field=models.DateField(editable=False, null=True, verbose_name='Visit 4 virus result date'), ), migrations.AddField( model_name='studysubject', name='virus_test_5', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, editable=False, verbose_name=b'Visit 5 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, editable=False, verbose_name='Visit 5 virus result'), ), migrations.AddField( model_name='studysubject', name='virus_test_5_updated', - field=models.DateField(editable=False, null=True, verbose_name=b'Visit 5 virus result date'), + field=models.DateField(editable=False, null=True, verbose_name='Visit 5 virus result date'), ), ] diff --git a/smash/web/migrations/0161_auto_20200416_0736.py b/smash/web/migrations/0161_auto_20200416_0736.py index 187b6b703e1dc70959f10d729ae1032687d25669..f47b98109fba89724275000eecca39d9c9f94e8b 100644 --- a/smash/web/migrations/0161_auto_20200416_0736.py +++ b/smash/web/migrations/0161_auto_20200416_0736.py @@ -15,56 +15,56 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='sample_mail_statistics', - field=models.BooleanField(default=False, verbose_name=b'Email with sample collections should use statistics'), + field=models.BooleanField(default=False, verbose_name='Email with sample collections should use statistics'), ), migrations.AlterField( model_name='studysubject', name='virus_test_1', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, verbose_name=b'Visit 1 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, verbose_name='Visit 1 virus result'), ), migrations.AlterField( model_name='studysubject', name='virus_test_1_updated', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 1 virus result date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 1 virus result date'), ), migrations.AlterField( model_name='studysubject', name='virus_test_2', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, verbose_name=b'Visit 2 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, verbose_name='Visit 2 virus result'), ), migrations.AlterField( model_name='studysubject', name='virus_test_2_updated', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 2 virus result date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 2 virus result date'), ), migrations.AlterField( model_name='studysubject', name='virus_test_3', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, verbose_name=b'Visit 3 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, verbose_name='Visit 3 virus result'), ), migrations.AlterField( model_name='studysubject', name='virus_test_3_updated', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 3 virus result date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 3 virus result date'), ), migrations.AlterField( model_name='studysubject', name='virus_test_4', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, verbose_name=b'Visit 4 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, verbose_name='Visit 4 virus result'), ), migrations.AlterField( model_name='studysubject', name='virus_test_4_updated', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 4 virus result date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 4 virus result date'), ), migrations.AlterField( model_name='studysubject', name='virus_test_5', - field=models.NullBooleanField(choices=[(True, b'Yes'), (False, b'No'), (None, b'N/A')], default=None, verbose_name=b'Visit 5 virus result'), + field=models.NullBooleanField(choices=[(True, 'Yes'), (False, 'No'), (None, 'N/A')], default=None, verbose_name='Visit 5 virus result'), ), migrations.AlterField( model_name='studysubject', name='virus_test_5_updated', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 5 virus result date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 5 virus result date'), ), ] diff --git a/smash/web/migrations/0162_auto_20200416_1212.py b/smash/web/migrations/0162_auto_20200416_1212.py index 2e84b8fc427a1558944419b9aa87ed5d625eb550..231b4fa2e2530b832ac05af08ccb2e875e9e86dd 100644 --- a/smash/web/migrations/0162_auto_20200416_1212.py +++ b/smash/web/migrations/0162_auto_20200416_1212.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='configurationitem', name='value', - field=models.CharField(max_length=1024, verbose_name=b'Value'), + field=models.CharField(max_length=1024, verbose_name='Value'), ), migrations.AlterField( model_name='subject', name='next_of_keen_name', - field=models.CharField(blank=True, max_length=255, verbose_name=b'Next of keen'), + field=models.CharField(blank=True, max_length=255, verbose_name='Next of keen'), ), ] diff --git a/smash/web/migrations/0163_study_redcap_first_visit_number.py b/smash/web/migrations/0163_study_redcap_first_visit_number.py index 7a4884b6673a55d58299982930d5082eced5e1c1..2872762f2b6f78a4090201d96f00694fb174e699 100644 --- a/smash/web/migrations/0163_study_redcap_first_visit_number.py +++ b/smash/web/migrations/0163_study_redcap_first_visit_number.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='study', name='redcap_first_visit_number', - field=models.IntegerField(default=1, verbose_name=b'Number of the first visit in redcap system'), + field=models.IntegerField(default=1, verbose_name='Number of the first visit in redcap system'), ), ] diff --git a/smash/web/migrations/0167_auto_20200428_1110.py b/smash/web/migrations/0167_auto_20200428_1110.py index 442dff958a80bb28946618b391a57eb056d6964f..6f7382baefe225e3b170113ce6609b0fb6e512a8 100644 --- a/smash/web/migrations/0167_auto_20200428_1110.py +++ b/smash/web/migrations/0167_auto_20200428_1110.py @@ -15,21 +15,21 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='subjectcolumns', name='next_of_keen_address', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of kin address'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of kin address'), ), migrations.AlterField( model_name='subjectcolumns', name='next_of_keen_name', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of kin'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of kin'), ), migrations.AlterField( model_name='subjectcolumns', name='next_of_keen_phone', - field=models.BooleanField(default=False, max_length=1, verbose_name=b'Next of kin phone'), + field=models.BooleanField(default=False, max_length=1, verbose_name='Next of kin phone'), ), migrations.AlterField( model_name='subject', name='social_security_number', - field=models.CharField(blank=True, max_length=50, verbose_name=b'Social security number'), + field=models.CharField(blank=True, max_length=50, verbose_name='Social security number'), ), ] diff --git a/smash/web/migrations/0169_auto_20200525_1123.py b/smash/web/migrations/0169_auto_20200525_1123.py index c3a55bf4659061ca25067e42e74113ea5ab051e5..8d1136d10604da6c20721171524b9acab3f7a83b 100644 --- a/smash/web/migrations/0169_auto_20200525_1123.py +++ b/smash/web/migrations/0169_auto_20200525_1123.py @@ -15,26 +15,26 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studysubject', name='virus_test_1_collection_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 1 virus collection date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 1 virus collection date'), ), migrations.AddField( model_name='studysubject', name='virus_test_2_collection_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 2 virus collection date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 2 virus collection date'), ), migrations.AddField( model_name='studysubject', name='virus_test_3_collection_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 3 virus collection date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 3 virus collection date'), ), migrations.AddField( model_name='studysubject', name='virus_test_4_collection_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 4 virus collection date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 4 virus collection date'), ), migrations.AddField( model_name='studysubject', name='virus_test_5_collection_date', - field=models.DateField(blank=True, null=True, verbose_name=b'Visit 5 virus collection date'), + field=models.DateField(blank=True, null=True, verbose_name='Visit 5 virus collection date'), ), ] diff --git a/smash/web/migrations/0170_auto_20200525_1126.py b/smash/web/migrations/0170_auto_20200525_1126.py index 972aa79d4608648c06f76f3d28763add00dbf905..3885d2a1dfef9a780425a685b59c62c742e39159 100644 --- a/smash/web/migrations/0170_auto_20200525_1126.py +++ b/smash/web/migrations/0170_auto_20200525_1126.py @@ -15,26 +15,26 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='virus_test_1_collection_date', - field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus collection date'), + field=models.BooleanField(default=False, verbose_name='Visit 1 virus collection date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_2_collection_date', - field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus collection date'), + field=models.BooleanField(default=False, verbose_name='Visit 2 virus collection date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_3_collection_date', - field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus collection date'), + field=models.BooleanField(default=False, verbose_name='Visit 3 virus collection date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_4_collection_date', - field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus collection date'), + field=models.BooleanField(default=False, verbose_name='Visit 4 virus collection date'), ), migrations.AddField( model_name='studycolumns', name='virus_test_5_collection_date', - field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus collection date'), + field=models.BooleanField(default=False, verbose_name='Visit 5 virus collection date'), ), ] diff --git a/smash/web/migrations/0172_auto_20200525_1246.py b/smash/web/migrations/0172_auto_20200525_1246.py index 8f5e039a2f9cf7e225199377e1dd9515f823ff9f..b16499c9bcac4632d3822f65fb4dfddaf4f85633 100644 --- a/smash/web/migrations/0172_auto_20200525_1246.py +++ b/smash/web/migrations/0172_auto_20200525_1246.py @@ -15,101 +15,101 @@ class Migration(migrations.Migration): migrations.AddField( model_name='studycolumns', name='virus_test_1_iga_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus IgA status'), + field=models.BooleanField(default=False, verbose_name='Visit 1 virus IgA status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_1_igg_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus IgG status'), + field=models.BooleanField(default=False, verbose_name='Visit 1 virus IgG status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_2_iga_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus IgA status'), + field=models.BooleanField(default=False, verbose_name='Visit 2 virus IgA status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_2_igg_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus IgG status'), + field=models.BooleanField(default=False, verbose_name='Visit 2 virus IgG status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_3_iga_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus IgA status'), + field=models.BooleanField(default=False, verbose_name='Visit 3 virus IgA status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_3_igg_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus IgG status'), + field=models.BooleanField(default=False, verbose_name='Visit 3 virus IgG status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_4_iga_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus IgA status'), + field=models.BooleanField(default=False, verbose_name='Visit 4 virus IgA status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_4_igg_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus IgG status'), + field=models.BooleanField(default=False, verbose_name='Visit 4 virus IgG status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_5_iga_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus IgA status'), + field=models.BooleanField(default=False, verbose_name='Visit 5 virus IgA status'), ), migrations.AddField( model_name='studycolumns', name='virus_test_5_igg_status', - field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus IgG status'), + field=models.BooleanField(default=False, verbose_name='Visit 5 virus IgG status'), ), migrations.AddField( model_name='studysubject', name='virus_test_1_iga_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 1 IgA status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 1 IgA status'), ), migrations.AddField( model_name='studysubject', name='virus_test_1_igg_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 1 IgG status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 1 IgG status'), ), migrations.AddField( model_name='studysubject', name='virus_test_2_iga_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 2 IgA status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 2 IgA status'), ), migrations.AddField( model_name='studysubject', name='virus_test_2_igg_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 2 IgG status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 2 IgG status'), ), migrations.AddField( model_name='studysubject', name='virus_test_3_iga_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 3 IgA status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 3 IgA status'), ), migrations.AddField( model_name='studysubject', name='virus_test_3_igg_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 3 IgG status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 3 IgG status'), ), migrations.AddField( model_name='studysubject', name='virus_test_4_iga_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 4 IgA status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 4 IgA status'), ), migrations.AddField( model_name='studysubject', name='virus_test_4_igg_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 4 IgG status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 4 IgG status'), ), migrations.AddField( model_name='studysubject', name='virus_test_5_iga_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 5 IgA status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 5 IgA status'), ), migrations.AddField( model_name='studysubject', name='virus_test_5_igg_status', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 5 IgG status'), + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Visit 5 IgG status'), ), ] diff --git a/smash/web/migrations/0177_auto_20201116_1508.py b/smash/web/migrations/0177_auto_20201116_1508.py new file mode 100644 index 0000000000000000000000000000000000000000..969d1db84635e6c75d2604ae95110eea53085dd4 --- /dev/null +++ b/smash/web/migrations/0177_auto_20201116_1508.py @@ -0,0 +1,29 @@ +# Generated by Django 2.0.13 on 2020-11-16 15:08 + +import django.core.files.storage +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0176_configurationitem_local_setting_clean'), + ] + + operations = [ + migrations.CreateModel( + name='PrivacyNotice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('document', models.FileField(editable=False, upload_to='privacy_notices/', verbose_name='Study Privacy Notice file')), + ], + ), + migrations.AddField( + model_name='study', + name='study_privacy_notice', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='studies', to='web.PrivacyNotice', verbose_name='Study Privacy Note'), + ) + ] diff --git a/smash/web/migrations/0177_auto_20201116_1508_squashed_0180_auto_20201117_0838.py b/smash/web/migrations/0177_auto_20201116_1508_squashed_0180_auto_20201117_0838.py new file mode 100644 index 0000000000000000000000000000000000000000..0ea6aaa3e07eff90c830ec708ad47c730bdaf199 --- /dev/null +++ b/smash/web/migrations/0177_auto_20201116_1508_squashed_0180_auto_20201117_0838.py @@ -0,0 +1,31 @@ +# Generated by Django 2.0.13 on 2020-11-17 08:48 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + replaces = [('web', '0177_auto_20201116_1508'), ('web', '0178_auto_20201116_1513'), ('web', '0179_auto_20201116_1528'), ('web', '0180_auto_20201117_0838')] + + dependencies = [ + ('web', '0176_configurationitem_local_setting_clean'), + ] + + operations = [ + migrations.CreateModel( + name='PrivacyNotice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('document', models.FileField(editable=False, upload_to='privacy_notices/', verbose_name='Study Privacy Notice file')), + ('updated_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(default='', max_length=255, verbose_name='Name')), + ], + ), + migrations.AddField( + model_name='study', + name='study_privacy_notice', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='studies', to='web.PrivacyNotice', verbose_name='Study Privacy Note'), + ), + ] diff --git a/smash/web/migrations/0178_auto_20201116_1513.py b/smash/web/migrations/0178_auto_20201116_1513.py new file mode 100644 index 0000000000000000000000000000000000000000..c3c4c4cc683cd3adc24cb7dbcbdf5d9421d8e3d5 --- /dev/null +++ b/smash/web/migrations/0178_auto_20201116_1513.py @@ -0,0 +1,21 @@ +# Generated by Django 2.0.13 on 2020-11-16 15:13 + +import django.core.files.storage +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0177_auto_20201116_1508'), + ] + + operations = [ + migrations.AddField( + model_name='privacynotice', + name='study', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Study', verbose_name='Study'), + ) + ] diff --git a/smash/web/migrations/0179_auto_20201116_1528.py b/smash/web/migrations/0179_auto_20201116_1528.py new file mode 100644 index 0000000000000000000000000000000000000000..da1ab045b22d246df336c1123b8be7f21ade2382 --- /dev/null +++ b/smash/web/migrations/0179_auto_20201116_1528.py @@ -0,0 +1,21 @@ +# Generated by Django 2.0.13 on 2020-11-16 15:28 + +import django.core.files.storage +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0178_auto_20201116_1513'), + ] + + operations = [ + migrations.AddField( + model_name='privacynotice', + name='updated_at', + field=models.DateTimeField(auto_now=True), + ) + ] diff --git a/smash/web/migrations/0179_merge_20201117_1048.py b/smash/web/migrations/0179_merge_20201117_1048.py new file mode 100644 index 0000000000000000000000000000000000000000..036333dbf183e05258b8d8fd47f8e7b026452c96 --- /dev/null +++ b/smash/web/migrations/0179_merge_20201117_1048.py @@ -0,0 +1,14 @@ +# Generated by Django 2.0.13 on 2020-11-17 10:48 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0178_auto_20201116_1250'), + ('web', '0177_auto_20201116_1508_squashed_0180_auto_20201117_0838'), + ] + + operations = [ + ] diff --git a/smash/web/migrations/0180_auto_20201117_0838.py b/smash/web/migrations/0180_auto_20201117_0838.py new file mode 100644 index 0000000000000000000000000000000000000000..da010905fdfbc27df5f524ddf6c94a6f1106f91c --- /dev/null +++ b/smash/web/migrations/0180_auto_20201117_0838.py @@ -0,0 +1,31 @@ +# Generated by Django 2.0.13 on 2020-11-17 08:38 + +import django.core.files.storage +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0179_auto_20201116_1528'), + ] + + operations = [ + migrations.RemoveField( + model_name='privacynotice', + name='study', + ), + migrations.AddField( + model_name='privacynotice', + name='name', + field=models.CharField(default='', max_length=255, verbose_name='Name'), + preserve_default=False, + ), + migrations.AlterField( + model_name='study', + name='study_privacy_notice', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='studies', to='web.PrivacyNotice', verbose_name='Study Privacy Note'), + ) + ] diff --git a/smash/web/migrations/0180_auto_20201120_1554.py b/smash/web/migrations/0180_auto_20201120_1554.py new file mode 100644 index 0000000000000000000000000000000000000000..12474a8aebcbd8176fa2562489f2d82d17742dc9 --- /dev/null +++ b/smash/web/migrations/0180_auto_20201120_1554.py @@ -0,0 +1,50 @@ +# Generated by Django 2.0.13 on 2020-11-20 15:54 + +import django.core.files.storage +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0179_merge_20201117_1048'), + ] + + operations = [ + migrations.AddField( + model_name='privacynotice', + name='summary', + field=models.CharField(default='description', max_length=255, verbose_name='Summary'), + preserve_default=False, + ), + migrations.AddField( + model_name='study', + name='acceptance_of_study_privacy_notice_required', + field=models.BooleanField(default=False, verbose_name='Is privacy notice acceptance required?'), + ), + migrations.AlterField( + model_name='privacynotice', + name='created_at', + field=models.DateTimeField(auto_now_add=True, verbose_name='Created at'), + ), + migrations.AlterField( + model_name='privacynotice', + name='document', + field=models.FileField(upload_to='privacy_notices/', verbose_name='Study Privacy Notice file'), + ), + migrations.AlterField( + model_name='privacynotice', + name='name', + field=models.CharField(max_length=255, verbose_name='Name'), + ), + migrations.AlterField( + model_name='privacynotice', + name='updated_at', + field=models.DateTimeField(auto_now=True, verbose_name='Updated at'), + ), + migrations.AlterField( + model_name='studysubject', + name='referral_letter', + field=models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='/tmp/upload'), upload_to='referral_letters', verbose_name='Referral letter'), + ), + ] diff --git a/smash/web/migrations/0181_worker_privacy_notice_accepted.py b/smash/web/migrations/0181_worker_privacy_notice_accepted.py new file mode 100644 index 0000000000000000000000000000000000000000..3677558e321d5989c69eaf39163851c6e6fddc47 --- /dev/null +++ b/smash/web/migrations/0181_worker_privacy_notice_accepted.py @@ -0,0 +1,18 @@ +# Generated by Django 2.0.13 on 2020-11-20 15:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0180_auto_20201120_1554'), + ] + + operations = [ + migrations.AddField( + model_name='worker', + name='privacy_notice_accepted', + field=models.BooleanField(default=False, verbose_name='Has accepted privacy notice?'), + ), + ] diff --git a/smash/web/migrations/0182_auto_20201126_1154.py b/smash/web/migrations/0182_auto_20201126_1154.py new file mode 100644 index 0000000000000000000000000000000000000000..3c7e93752fa5a3e1da48bf20888ce871c967c238 --- /dev/null +++ b/smash/web/migrations/0182_auto_20201126_1154.py @@ -0,0 +1,59 @@ +# Generated by Django 2.0.13 on 2020-11-26 11:54 + +import django.core.files.storage +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0181_worker_privacy_notice_accepted'), + ] + + operations = [ + migrations.RenameField( + model_name='subjectcolumns', + old_name='next_of_keen_address', + new_name='next_of_kin_address', + ), + migrations.RenameField( + model_name='subjectcolumns', + old_name='next_of_keen_name', + new_name='next_of_kin_name', + ), + migrations.RenameField( + model_name='subjectcolumns', + old_name='next_of_keen_phone', + new_name='next_of_kin_phone', + ), + migrations.RenameField( + model_name='subject', + old_name='next_of_keen_address', + new_name='next_of_kin_address', + ), + migrations.RenameField( + model_name='subject', + old_name='next_of_keen_name', + new_name='next_of_kin_name', + ), + migrations.RenameField( + model_name='subject', + old_name='next_of_keen_phone', + new_name='next_of_kin_phone', + ), + migrations.AlterField( + model_name='subject', + name='next_of_kin_address', + field=models.TextField(blank=True, max_length=2000, verbose_name='Next of kin address'), + ), + migrations.AlterField( + model_name='subject', + name='next_of_kin_name', + field=models.CharField(blank=True, max_length=255, verbose_name='Next of kin'), + ), + migrations.AlterField( + model_name='subject', + name='next_of_kin_phone', + field=models.CharField(blank=True, max_length=50, verbose_name='Next of kin phone'), + ), + ] diff --git a/smash/web/models/__init__.py b/smash/web/models/__init__.py index 9c193eaa042b0662683c6f399f21b5053222e89d..46f20636c434b587773fe96e454b017f2248cb14 100644 --- a/smash/web/models/__init__.py +++ b/smash/web/models/__init__.py @@ -38,6 +38,7 @@ from .contact_attempt import ContactAttempt from .mail_template import MailTemplate from .missing_subject import MissingSubject from .inconsistent_subject import InconsistentSubject, InconsistentField +from .privacy_notice import PrivacyNotice __all__ = [Study, FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room, Subject, StudySubject, StudySubjectList, SubjectColumns, StudyNotificationParameters, diff --git a/smash/web/models/privacy_notice.py b/smash/web/models/privacy_notice.py new file mode 100644 index 0000000000000000000000000000000000000000..12c0696145f12c5b569a0595993c69e290532a98 --- /dev/null +++ b/smash/web/models/privacy_notice.py @@ -0,0 +1,21 @@ +# coding=utf-8 +import datetime + +from django.db import models +from web.templatetags.filters import basename + +class PrivacyNotice(models.Model): + name = models.CharField(max_length=255, verbose_name='Name') + created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created at') + updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated at') + summary = models.CharField(max_length=255, verbose_name='Summary', blank=False, null=False) + document = models.FileField(upload_to='privacy_notices/', + verbose_name='Study Privacy Notice file', + null=False, editable=True) + + def __str__(self): + return f'{self.name} ({basename(self.document.url)})' + + @property + def all_studies(self): + return self.studies.all() diff --git a/smash/web/models/study.py b/smash/web/models/study.py index 41006b1e335c42c217a35b925ed5b2db454ae741..83f438ebaa452e7a5ca9ae442b5ccb45b8d65b3e 100644 --- a/smash/web/models/study.py +++ b/smash/web/models/study.py @@ -94,6 +94,18 @@ class Study(models.Model): blank=False ) + study_privacy_notice = models.ForeignKey("web.PrivacyNotice", + verbose_name='Study Privacy Note', + editable=True, blank=True, + null=True, on_delete=models.SET_NULL, + related_name='studies' + ) + + acceptance_of_study_privacy_notice_required = models.BooleanField( + default=False, + verbose_name="Is privacy notice acceptance required?" + ) + def check_nd_number(self, nd_number): regex = re.compile(self.nd_number_study_subject_regex) return regex.match(nd_number) is not None diff --git a/smash/web/models/subject.py b/smash/web/models/subject.py index 160c2c41d1347a79271e22c4663ecec4df610eb0..f7660020b20a7137b5c0d92358bfdfea381b4e90 100644 --- a/smash/web/models/subject.py +++ b/smash/web/models/subject.py @@ -106,20 +106,20 @@ class Subject(models.Model): verbose_name='Country', on_delete=models.CASCADE ) - next_of_keen_name = models.CharField(max_length=255, + next_of_kin_name = models.CharField(max_length=255, + blank=True, + verbose_name='Next of kin' + ) + + next_of_kin_phone = models.CharField(max_length=50, blank=True, - verbose_name='Next of keen' + verbose_name='Next of kin phone' ) - next_of_keen_phone = models.CharField(max_length=50, - blank=True, - verbose_name='Next of keen phone' - ) - - next_of_keen_address = models.TextField(max_length=2000, - blank=True, - verbose_name='Next of keen address' - ) + next_of_kin_address = models.TextField(max_length=2000, + blank=True, + verbose_name='Next of kin address' + ) dead = models.BooleanField( verbose_name='Deceased', diff --git a/smash/web/models/subject_columns.py b/smash/web/models/subject_columns.py index 82c4bf3b20df029fcc8e03397f671ef3d303f3df..2572b7544ca554099a25190834d31f09325cb988 100644 --- a/smash/web/models/subject_columns.py +++ b/smash/web/models/subject_columns.py @@ -84,17 +84,17 @@ class SubjectColumns(models.Model): verbose_name='Deceased', ) - next_of_keen_name = models.BooleanField(max_length=1, + next_of_kin_name = models.BooleanField(max_length=1, + default=False, + verbose_name='Next of kin', + ) + + next_of_kin_phone = models.BooleanField(max_length=1, default=False, - verbose_name='Next of kin', + verbose_name='Next of kin phone', ) - next_of_keen_phone = models.BooleanField(max_length=1, - default=False, - verbose_name='Next of kin phone', - ) - - next_of_keen_address = models.BooleanField(max_length=1, - default=False, - verbose_name='Next of kin address', - ) + next_of_kin_address = models.BooleanField(max_length=1, + default=False, + verbose_name='Next of kin address', + ) diff --git a/smash/web/models/worker.py b/smash/web/models/worker.py index 83793ffd80514f25d2df2950b0caa38a6ce95caa..8de5a4258bacc945bcd73fb346c9b5cab0e8ed8f 100644 --- a/smash/web/models/worker.py +++ b/smash/web/models/worker.py @@ -154,6 +154,10 @@ class Worker(models.Model): blank=True ) + privacy_notice_accepted = models.BooleanField( + default=False, + verbose_name="Has accepted privacy notice?") + def is_on_leave(self): if len(self.holiday_set.filter(datetime_end__gt=timezone.now(), datetime_start__lt=timezone.now(), diff --git a/smash/web/templates/_base.html b/smash/web/templates/_base.html index b5ec2ee0002e84a2b0fdf164914f2742f5e1e8ea..688db99e33a405591cbaeaad32c84fca14fbd5bf 100644 --- a/smash/web/templates/_base.html +++ b/smash/web/templates/_base.html @@ -32,6 +32,8 @@ <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> + <script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js"></script> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css"> {% endblock styles %} </head> <!-- @@ -73,7 +75,7 @@ desired effect <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button"> <span class="sr-only">Toggle navigation</span> </a> - + <div class="col-xs-7 navbar-text" style="margin-left: 0px"> <div class="warning_ticker"> <div class="ticker_list"> @@ -388,7 +390,7 @@ desired effect mousePause: 1 }); }else if($('.ticker_list').children().length == 1){ - + }else{ $('.warning_ticker').css('display', 'none'); } @@ -397,12 +399,42 @@ desired effect var $e = $(".sidebar-menu li[data-desc='" + page_to_activate + "']"); $e.addClass("active"); if($($e).parents('li[data-desc]').length > 0){ //if there is a parent, it should also be active - $($e).parents('li[data-desc]').addClass("active"); + $($e).parents('li[data-desc]').addClass("active"); } - + }; activate({% block ui_active_tab %}{% endblock ui_active_tab %}); + if ("{{ show_notice }}".toLowerCase() === "true") { + window.cookieconsent.initialise({ + container: document.getElementById("content"), + content: { + header: 'Privacy notice!', + message: '{{ study.study_privacy_notice.summary}}', + href: '{{ study.study_privacy_notice.document.url }}', + dismiss: 'Got it!', + }, + palette: { + popup: {background: "#fff"}, + button: {background: "#aa0000"}, + }, + revokable: true, + onStatusChange: function (status) { + if (this.hasConsented()) { + $.ajax({ + url: "{% url 'web.api.workers.accept_privacy_notice' %}", + success: function (result) { + if (result.isOk === false) console.log(result.message); + }, + async: false + }); + } + }, + law: { + regionalLaw: false, + } + }); + } </script> {% comment "TODO: Check, and add if works %} diff --git a/smash/web/templates/privacy_notice/acceptance_study_privacy_notice.html b/smash/web/templates/privacy_notice/acceptance_study_privacy_notice.html new file mode 100644 index 0000000000000000000000000000000000000000..e2c1a1d6f58e1c446e3727aff344427f72b53773 --- /dev/null +++ b/smash/web/templates/privacy_notice/acceptance_study_privacy_notice.html @@ -0,0 +1,62 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} +{% endblock styles %} + +{% block ui_active_tab %}'workers'{% endblock ui_active_tab %} +{% block page_description %}{% endblock page_description %} + +{% 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">{% block form-title %}Check the privacy notice{% endblock %}</h3> + </div> + + + <form method="post" action="" class="form-horizontal" enctype="multipart/form-data"> + {% csrf_token %} + + <div class="box-body"> + <div class="form-group {% if field.errors %}has-error{% endif %}"> + <label class="col-sm-4 col-lg-offset-1 col-lg-2 control-label"> + <p >{{privacy_notice.summary}}. Read <a href="{{ privacy_notice.document.url }}">more</a></p> + </label> + </div> + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <a class="btn btn-block btn-info" href="{% url 'logout' %}"> + I do not agree + </a> + </div> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-success">{% block save-button %} + I agree{% endblock %}</button> + </div> + </div><!-- /.box-footer --> + </form> + </div> + + </div> + </div> + + {% endblock %} + + +{% endblock maincontent %} + +{% block scripts %} + {{ block.super }} + + <script type="text/javascript"> + + + </script> +{% endblock scripts %} \ No newline at end of file diff --git a/smash/web/templates/privacy_notice/add.html b/smash/web/templates/privacy_notice/add.html new file mode 100644 index 0000000000000000000000000000000000000000..6d4f87bf936db78ad7926b81338120374ef97eca --- /dev/null +++ b/smash/web/templates/privacy_notice/add.html @@ -0,0 +1,8 @@ +{% extends "privacy_notice/add_edit.html" %} + +{% block page_header %}New privacy notice{% endblock page_header %} + +{% block title %}{{ block.super }} - Add new privacy notice{% endblock %} + +{% block form-title %}Enter privacy notice details{% endblock %} +{% block save-button %}Add{% endblock %} \ No newline at end of file diff --git a/smash/web/templates/privacy_notice/add_edit.html b/smash/web/templates/privacy_notice/add_edit.html new file mode 100644 index 0000000000000000000000000000000000000000..17ad93d68448db002bc8e4c813749e38dacabfce --- /dev/null +++ b/smash/web/templates/privacy_notice/add_edit.html @@ -0,0 +1,83 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/> + <style type="text/css"> + .help_text{ + margin-left: 5px; + } + </style> +{% endblock styles %} + +{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %} +{% block page_description %}{% endblock page_description %} + +{% block breadcrumb %} + {% include "privacy_notice/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">{% block form-title %}Enter privacy notice details{% endblock %}</h3> + </div> + + + <form method="post" action="" class="form-horizontal" enctype="multipart/form-data"> + {% 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 }} + {% if field.help_text %} + <i class="fa fa-info-circle help_text" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="{{field.help_text}}"></i> + {% endif %} + </label> + + <div class="col-sm-8 col-lg-4"> + {{ field|add_class:'form-control' }} + {% if field.errors %} + <span class="help-block">{{ field.errors }}</span> + {% endif %} + </div> + + + </div> + {% endfor %} + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-success">{% block save-button %} + Add{% endblock %}</button> + </div> + <div class="col-sm-6"> + <a href="{% url 'web.views.privacy_notices' %}" + 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> + +{% endblock scripts %} \ No newline at end of file diff --git a/smash/web/templates/privacy_notice/breadcrumb.html b/smash/web/templates/privacy_notice/breadcrumb.html new file mode 100644 index 0000000000000000000000000000000000000000..3a3bdd23e7829eec33bf65d789fd90b566940f2b --- /dev/null +++ b/smash/web/templates/privacy_notice/breadcrumb.html @@ -0,0 +1,2 @@ +<li><a href="{% url 'web.views.appointments' %}"><i class="fa fa-dashboard"></i> Dashboard</a></li> +<li class="active"><a href="{% url 'web.views.privacy_notices' %}">Privacy Notices</a></li> \ No newline at end of file diff --git a/smash/web/templates/privacy_notice/confirm_delete.html b/smash/web/templates/privacy_notice/confirm_delete.html new file mode 100644 index 0000000000000000000000000000000000000000..8e618e11025dea0fff578d6dca8546038dadf85f --- /dev/null +++ b/smash/web/templates/privacy_notice/confirm_delete.html @@ -0,0 +1,62 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/> + +{% endblock styles %} + +{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %} +{% block page_header %}Delete privacy notice{% endblock page_header %} +{% block page_description %}{% endblock page_description %} + +{% block title %}{{ block.super }} - Delete privacy notice{% endblock %} + +{% block breadcrumb %} + {% include "privacy_notice/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">Confirm deletion</h3> + </div> + + <form action="" method="post" class="form-horizontal">{% csrf_token %} + <div class="box-body"> + <p>Are you sure you want to delete privacy notice "{{ object.document.url |Â basename }}" from Study "{{object.study}}"?</p> + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-danger">Delete</button> + </div> + <div class="col-sm-6"> + <a href="{% url 'web.views.privacy_notices' %}" + 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> + +{% endblock scripts %} + + diff --git a/smash/web/templates/privacy_notice/edit.html b/smash/web/templates/privacy_notice/edit.html new file mode 100644 index 0000000000000000000000000000000000000000..f1f0d651f3d94b4c6f27a7fcea64d0d4f86dcaf1 --- /dev/null +++ b/smash/web/templates/privacy_notice/edit.html @@ -0,0 +1,9 @@ +{% extends "privacy_notice/add_edit.html" %} + +{% block page_header %}Edit privacy notice "{{ privacy_notice.name }}"{% endblock page_header %} + +{% block title %}{{ block.super }} - Edit privacy notice "{{ privacy_notice.name }}"{% endblock %} + +{% block form-title %}Enter privacy notice details{% endblock %} + +{% block save-button %}Save{% endblock %} diff --git a/smash/web/templates/privacy_notice/list.html b/smash/web/templates/privacy_notice/list.html new file mode 100644 index 0000000000000000000000000000000000000000..f9a4ebe47515723a05a3d2082301265e6bbf9121 --- /dev/null +++ b/smash/web/templates/privacy_notice/list.html @@ -0,0 +1,92 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <!-- DataTables --> + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}"> +{% endblock styles %} + +{% block ui_active_tab %}'privacy_notices'{% endblock ui_active_tab %} +{% block page_header %}Privacy Notices{% endblock page_header %} +{% block page_description %}{% endblock page_description %} + +{% block breadcrumb %} + {% include "privacy_notice/breadcrumb.html" %} +{% endblock breadcrumb %} + +{% block maincontent %} + + + <div class="box box-success"> + <div class="box-header with-border"> + <h3 class="box-title">Privacy Notices</h3> + </div> + <div class="box-body"> + + <div> + <a class="btn btn-app" href="{% url 'web.views.privacy_notice_add' %}"> + <i class="fa fa-plus"></i> Add new privacy notice + </a> + </div> + <table id="table" class="table table-bordered table-striped"> + <thead> + <tr> + <th>No.</th> + <th>Name</th> + <th>Studies</th> + <th>Creation Date</th> + <th>Last Updated</th> + <th>Download</th> + <th>Edit</th> + <th>Delete</th> + </tr> + </thead> + <tbody> + {% for privacy_notice in privacy_notices %} + <tr> + <td>{{ forloop.counter }}</td> + <td>{{ privacy_notice.name }}</td> + <td> + <ul> + {% for study in privacy_notice.all_studies %} + <li>{{ study }}</li> + {% endfor %} + </ul> + </td> + <td>{{ privacy_notice.created_at }}</td> + <td>{{ privacy_notice.updated_at }}</td> + <td><a href="{{ privacy_notice.document.url }}"><i class="fa fa-download"></i></a> {{privacy_notice.document.url |Â basename}}</td> + <td><a href="{% url 'web.views.privacy_notice_edit' privacy_notice.id %}"><i + class="fa fa-edit"></i></a></td> + <td><a href="{% url 'web.views.privacy_notice_delete' privacy_notice.id %}"><i + class="fa fa-trash text-danger"></i></a></td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + +{% endblock maincontent %} + +{% block scripts %} + {{ block.super }} + + <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script> + <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script> + + <script> + $(function () { + $('#table').DataTable({ + "paging": true, + "lengthChange": false, + "searching": true, + "ordering": true, + "info": true, + "autoWidth": false + }); + }); + </script> +{% endblock scripts %} diff --git a/smash/web/templates/study/edit.html b/smash/web/templates/study/edit.html index 5808f33837a87adc20dda1b7ec7f9ca0d9591a0a..ef795d8879bb28bd13c90457bc743c9c00ca4b0c 100644 --- a/smash/web/templates/study/edit.html +++ b/smash/web/templates/study/edit.html @@ -6,14 +6,19 @@ {{ block.super }} <!-- DataTables --> <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}"> + {% include "includes/datepicker.css.html" %} + {% include "includes/datetimepicker.css.html" %} <style type="text/css"> .tooltip-inner { - max-width: 350px; - width: 350px; + max-width: 200px; + width: 200px; + } + .privacy-notice-buttons { + float: right; + padding: 0; + margin-top: 7px; } </style> - {% include "includes/datepicker.css.html" %} - {% include "includes/datetimepicker.css.html" %} {% endblock styles %} {% block ui_active_tab %}'study_conf'{% endblock ui_active_tab %} @@ -55,10 +60,29 @@ data-placement="bottom" title="{{ field.help_text }}"></i> {% endif %} </label> - - <div class="col-sm-8"> - {{ field|add_class:'form-control' }} - </div> + + {% if field.label == 'Study Privacy Note' %} + <div class="col-sm-7"> + {{ field|add_class:'form-control' }} + </div> + <div class="col-sm-1 privacy-notice-buttons"> + {% if privacy_notice %} + <a title="Edit selected privacy notice" href="{% url 'web.views.privacy_notice_edit' field.value %}"> + <i class="fa fa-edit"></i> + </a> + <a title="Download selected privacy notice" href="{{ privacy_notice.document.url }}"> + <i class="fa fa-download"></i> + </a> + {% endif %} + <a title="Add privacy notice" href="{% url 'web.views.privacy_notice_add' %}"> + <i class="fa fa-plus"></i> + </a> + </div> + {% else %} + <div class="col-sm-8"> + {{ field|add_class:'form-control' }} + </div> + {% endif %} {% if field.errors %} <span class="help-block"> {{ field.errors }} </span> @@ -178,4 +202,10 @@ {% include "includes/datepicker.js.html" %} {% include "includes/datetimepicker.js.html" %} + + <script> + $(function(){ + $('a[title]').tooltip({container: 'body'}) + }) + </script> {% endblock scripts %} diff --git a/smash/web/templates/subjects/confirm_delete.html b/smash/web/templates/subjects/confirm_delete.html new file mode 100644 index 0000000000000000000000000000000000000000..0cceb3e9550e58058c7106870efa24b68cc24cc9 --- /dev/null +++ b/smash/web/templates/subjects/confirm_delete.html @@ -0,0 +1,89 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/> + <style> + table, th, td { + border: 1px solid black; + border-collapse: collapse; + padding: 5px; + } + </style> +{% endblock styles %} + +{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %} +{% block page_header %}Delete subject{% endblock page_header %} +{% block page_description %}{% endblock page_description %} + +{% block title %}{{ block.super }} - Delete subject{% 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">Confirm deletion</h3> + </div> + + <form action="" method="post" class="form-horizontal">{% csrf_token %} + <div class="box-body"> + <p>Are you sure you want to delete subject "{{ object }}"?</p> + <p>Other related elements will be removed too</p> + + <h4>Deletion Summary</h4> + <table> + <tr> + <th>Name</th> + <th>Amount</th> + </tr> + {% for model_name, object_count in model_count %} + <tr> + <td>{{ model_name|capfirst }}</td> + <td>{{ object_count }}</td> + </tr> + {% endfor %} + </table> + <h4>Deletion Tree</h4> + <p> + <ul> + {{ deletable_objects|unordered_list }} + </ul> + </p> + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-danger">Delete</button> + </div> + <div class="col-sm-6"> + <a href="{% url 'web.views.subjects' %}" + 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> + +{% endblock scripts %} + + diff --git a/smash/web/templates/subjects/confirm_delete_study_subject.html b/smash/web/templates/subjects/confirm_delete_study_subject.html new file mode 100644 index 0000000000000000000000000000000000000000..927457de84334a0818ddffc007357dd32fc38375 --- /dev/null +++ b/smash/web/templates/subjects/confirm_delete_study_subject.html @@ -0,0 +1,89 @@ +{% extends "_base.html" %} +{% load static %} +{% load filters %} + +{% block styles %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/> + <style> + table, th, td { + border: 1px solid black; + border-collapse: collapse; + padding: 5px; + } + </style> +{% endblock styles %} + +{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %} +{% block page_header %}Delete study subject{% endblock page_header %} +{% block page_description %}{% endblock page_description %} + +{% block title %}{{ block.super }} - Delete study subject{% 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">Confirm deletion</h3> + </div> + + <form action="" method="post" class="form-horizontal">{% csrf_token %} + <div class="box-body"> + <p>Are you sure you want to delete study subject "{{ object }}" from study "{{object.study}}"?</p> + <p>Other related elements will be removed too</p> + + <h4>Deletion Summary</h4> + <table> + <tr> + <th>Name</th> + <th>Amount</th> + </tr> + {% for model_name, object_count in model_count %} + <tr> + <td>{{ model_name|capfirst }}</td> + <td>{{ object_count }}</td> + </tr> + {% endfor %} + </table> + <h4>Deletion Tree</h4> + <p> + <ul> + {{ deletable_objects|unordered_list }} + </ul> + </p> + </div><!-- /.box-body --> + <div class="box-footer"> + <div class="col-sm-6"> + <button type="submit" class="btn btn-block btn-danger">Delete</button> + </div> + <div class="col-sm-6"> + <a href="{% url 'web.views.subjects' %}" + 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> + +{% endblock scripts %} + + diff --git a/smash/web/templates/subjects/edit.html b/smash/web/templates/subjects/edit.html index 90400f575318339ac11927a1729b48bf8195b211..ad411c46a79cf3f44606a27bbd30781fa9f63bb8 100644 --- a/smash/web/templates/subjects/edit.html +++ b/smash/web/templates/subjects/edit.html @@ -61,9 +61,21 @@ {% endif %} </div> {% endfor %} - </div> + {% if "delete_subject" in permissions %} + <div class="col-md-9"></div> + <div class="col-md-2"> + <a href="{% url 'web.views.subject_delete' study_subject.subject.id %}" + class="btn btn-block btn-danger">Delete Subject</a> + </div> + <div class="col-md-1"></div> + {% endif %} </div><!-- /.box-body --> + + <div class="box-footer"> + + </div> + <div class="box-header with-border"> <h3>Subject's study details</h3> </div> @@ -84,11 +96,30 @@ {% endif %} </div> {% endfor %} - - </div> </div><!-- /.box-body --> + {% if "delete_studysubject" in permissions and n_studies > 1 %} + <div class="box-footer"> + <div class="col-sm-3"> + <button type="submit" class="btn btn-block btn-success">Save</button> + </div> + <div class="col-sm-3"> + <button id="save-and-continue" type="button" class="btn btn-block btn-success">Save and + Continue + </button> + </div> + <div class="col-sm-3"> + <a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default" + onclick="history.back()">Cancel</a> + </div> + <div class="col-md-3"> + <a href="{% url 'web.views.study_subject_delete' study_subject.id %}" + class="btn btn-block btn-danger">Delete Study Subject</a> + </div> + </div><!-- /.box-footer --> + + {% else %} <div class="box-footer"> <div class="col-sm-4"> @@ -103,7 +134,9 @@ <a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default" onclick="history.back()">Cancel</a> </div> + </div><!-- /.box-footer --> + {% endif %} </form> </div><!-- /.box --> </div><!-- /.col-md-12 --> diff --git a/smash/web/templatetags/filters.py b/smash/web/templatetags/filters.py index a7a63383cf825187fbac57307b97da48f68a0da0..6e2e122ef8c1ea1bc89c060ff220de717fc720be 100644 --- a/smash/web/templatetags/filters.py +++ b/smash/web/templatetags/filters.py @@ -2,7 +2,7 @@ from django import template from django.forms import CheckboxSelectMultiple, CheckboxInput from django.utils.safestring import mark_safe -import datetime +import datetime, os from web.models import ConfigurationItem from web.models.constants import VISIT_SHOW_VISIT_NUMBER_FROM_ZERO from distutils.util import strtobool @@ -59,4 +59,8 @@ def display_visit_number(visit_number): if strtobool(visit_from_zero): return (visit_number - 1) else: - return visit_number \ No newline at end of file + return visit_number + +@register.filter(name='basename') +def basename(path): + return os.path.basename(path) \ No newline at end of file diff --git a/smash/web/tests/models/test_visit.py b/smash/web/tests/models/test_visit.py index 48ba8358b7561ae6106eafb643c433ba0dff8154..1edc9e890fd8ec2ffe0ff68b5578b49fc74bfed6 100644 --- a/smash/web/tests/models/test_visit.py +++ b/smash/web/tests/models/test_visit.py @@ -1,13 +1,14 @@ import datetime +import logging + from dateutil.relativedelta import relativedelta from django.test import TestCase -from web.models import Visit -from web.models.constants import SUBJECT_TYPE_CHOICES_PATIENT +from web.models import Visit, Study +from web.models.constants import SUBJECT_TYPE_CHOICES_PATIENT, GLOBAL_STUDY_ID from web.tests.functions import create_study_subject, create_visit from web.utils import get_today_midnight_date -import logging logger = logging.getLogger(__name__) class VisitModelTests(TestCase): @@ -32,10 +33,10 @@ class VisitModelTests(TestCase): visit1.datetime_end = get_today_midnight_date() + datetime.timedelta(days=1) visit2.datetime_end = get_today_midnight_date() + datetime.timedelta(days=2) - + visit1.save() #post save will be raised visit2.save() #post save will be raised - + visit1.refresh_from_db() visit2.refresh_from_db() self.assertEqual(1, visit1.visit_number) @@ -54,7 +55,7 @@ class VisitModelTests(TestCase): def test_visit_numbers(self): subject = create_study_subject() Visit.objects.filter(subject=subject).all().delete() - visit1 = create_visit(subject=subject, + visit1 = create_visit(subject=subject, datetime_begin = get_today_midnight_date() - datetime.timedelta(days=15), datetime_end = get_today_midnight_date() - datetime.timedelta(days=14)) #post save will be raised visit2 = create_visit(subject=subject, @@ -94,9 +95,20 @@ class VisitModelTests(TestCase): visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() - self.assertEqual(3, visit1.visit_number) #<= change + self.assertEqual(3, visit1.visit_number) #<= change self.assertEqual(2, visit2.visit_number) #<= change - self.assertEqual(1, visit3.visit_number) #<= change + self.assertEqual(1, visit3.visit_number) #<= change + + def test_mark_as_finished_for_global_study(self): + subject = create_study_subject() + visit = create_visit(subject) + + subject.study = Study.objects.get(pk=GLOBAL_STUDY_ID) + subject.save() + visit.mark_as_finished() + + visit_count = Visit.objects.filter(subject=subject).count() + self.assertEqual(2, visit_count) def test_mark_as_finished(self): subject = create_study_subject() @@ -205,7 +217,7 @@ class VisitModelTests(TestCase): # check if follow up date is based on the first visit date study = visit.subject.study args = {study.default_delta_time_for_follow_up_units: study.default_delta_time_for_patient_follow_up} #patient - + time_to_next_visit = relativedelta(**args) * (visit_number - 1) #calculated from first visit self.assertTrue(visit.datetime_begin + time_to_next_visit - datetime.timedelta(days=1) < new_follow_up.datetime_begin) diff --git a/smash/web/tests/test_enforce_2fa.py b/smash/web/tests/test_enforce_2fa.py new file mode 100644 index 0000000000000000000000000000000000000000..0affc9b1708b360feb079b12e3e0c09718260e01 --- /dev/null +++ b/smash/web/tests/test_enforce_2fa.py @@ -0,0 +1,55 @@ +# coding=utf-8 +from unittest.mock import Mock + +from django.http import HttpResponseRedirect +from django.test import TestCase + +from smash.middleware.force_2fa_middleware import Force2FAMiddleware + +NOT_REDIRECTED = "Not redirected" + + +class TestForce2FAMiddleware(TestCase): + + def setUp(self): + self.middleware = Force2FAMiddleware(lambda x: NOT_REDIRECTED) + + def test_verified(self): + """ + if user verified and we don't redirect + """ + request = Mock() + request.session = {} + request.user = Mock() + request.path = 'subjects' + request.user.is_authenticated = True + request.user.is_verified = lambda: True + result = self.middleware(request) + self.assertEqual(result, NOT_REDIRECTED) + + def test_not_verified(self): + """ + if user not verified and not in 2fa section, we redirect to 2fa section + """ + request = Mock() + request.session = {} + request.user = Mock() + request.path = 'subjects' + request.user.is_authenticated = True + request.user.is_verified = lambda: False + result = self.middleware(request) + self.assertTrue(isinstance(result, HttpResponseRedirect)) + self.assertEqual(result.url, '/account/two_factor/') + + def test_not_verified_2fa_section(self): + """ + if user not verified but in 2fa section, we don't redirect + """ + request = Mock() + request.session = {} + request.user = Mock() + request.path = 'two_factor' + request.user.is_authenticated = True + request.user.is_verified = lambda: False + result = self.middleware(request) + self.assertEqual(result, NOT_REDIRECTED) diff --git a/smash/web/tests/view/test_privacy_notice.py b/smash/web/tests/view/test_privacy_notice.py new file mode 100644 index 0000000000000000000000000000000000000000..609d46b55efc863445b80abf758a195bb08642aa --- /dev/null +++ b/smash/web/tests/view/test_privacy_notice.py @@ -0,0 +1,126 @@ +from web.tests.functions import get_resource_path, get_test_study +from web.models import PrivacyNotice, Study, Worker +from web.forms import PrivacyNoticeForm, WorkerAcceptPrivacyNoticeForm +from web.tests import LoggedInTestCase +from django.urls import reverse +from django.core.files.uploadedfile import SimpleUploadedFile +from django.contrib.messages import get_messages +from web.models.constants import GLOBAL_STUDY_ID + +class PrivacyNoticeTests(LoggedInTestCase): + def test_add_privacy_notice(self): + self.assertEqual(0, PrivacyNotice.objects.count()) + self.login_as_admin() + + form_data = dict( + name='example', + summary='example summary' + ) + + file_data = dict( + document=SimpleUploadedFile('file.txt', b"file_content") + ) + + form = PrivacyNoticeForm(form_data, file_data) + self.assertTrue(form.is_valid()) + + page = reverse('web.views.privacy_notice_add') + response = self.client.post(page, data={**form_data, **file_data}) + self.assertEqual(response.status_code, 302) + self.assertEqual(1, PrivacyNotice.objects.count()) + + def test_edit_privacy_notice(self): + self.test_add_privacy_notice() + self.assertEqual(1, PrivacyNotice.objects.count()) + pn = PrivacyNotice.objects.all()[0] + form_data = dict( + name='example2', + summary=pn.summary + ) + + file_data = dict( + document=SimpleUploadedFile('file.txt', b"file_content") + ) + + form = PrivacyNoticeForm(form_data, file_data, instance=pn) + self.assertTrue(form.is_valid()) + + page = reverse('web.views.privacy_notice_edit', kwargs={'pk': pn.id}) + response = self.client.post(page, data={**form_data, **file_data}) + self.assertEqual(response.status_code, 302) + pn = PrivacyNotice.objects.all()[0] + self.assertEqual(pn.name, 'example2') + + def test_delete_privacy_notice(self): + self.test_add_privacy_notice() + self.assertEqual(1, PrivacyNotice.objects.count()) + pn = PrivacyNotice.objects.all()[0] + page = reverse('web.views.privacy_notice_delete', kwargs={'pk': pn.id}) + response = self.client.post(page) + self.assertEqual(response.status_code, 302) + self.assertEqual(0, PrivacyNotice.objects.count()) + + def test_privacy_notice_middleware_superuser(self): + self.test_add_privacy_notice() + + self.login_as_admin() + #assign privacy notice + pn = PrivacyNotice.objects.all()[0] + study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] + study.acceptance_of_study_privacy_notice_required = True + study.study_privacy_notice = pn + study.save() + + study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] + self.assertEqual(study.acceptance_of_study_privacy_notice_required, True) + self.assertEqual(study.study_privacy_notice.id, pn.id) + + self.login_as_super() + self.assertEqual(self.staff_worker.privacy_notice_accepted, False) + page = reverse('web.views.appointments') + response = self.client.get(page) + self.assertEqual(response.status_code, 200) + messages = list(get_messages(response.wsgi_request)) + self.assertEqual(len(messages), 0) + + def test_privacy_notice_middleware(self): + self.test_add_privacy_notice() + + self.login_as_admin() + #assign privacy notice + pn = PrivacyNotice.objects.all()[0] + study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] + study.acceptance_of_study_privacy_notice_required = True + study.study_privacy_notice = pn + study.save() + + study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] + self.assertEqual(study.acceptance_of_study_privacy_notice_required, True) + self.assertEqual(study.study_privacy_notice.id, pn.id) + + self.login_as_staff() + self.assertEqual(self.staff_worker.privacy_notice_accepted, False) + page = reverse('web.views.appointments') + response = self.client.get(page) + self.assertEqual(response.status_code, 302) + messages = list(get_messages(response.wsgi_request)) + self.assertEqual(len(messages), 1) + self.assertEqual(str(messages[0]), "You can't use the system until you accept the privacy notice.") + #accept privacy notice + form_data = dict(privacy_notice_accepted=True) + form = WorkerAcceptPrivacyNoticeForm(form_data) + self.assertTrue(form.is_valid()) + page = reverse('web.views.accept_privacy_notice', kwargs={'pk': pn.id}) + response = self.client.post(page, data={**form_data}) + self.assertEqual(response.status_code, 302) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertIn("Privacy notice accepted", messages) + #check acceptance + worker = Worker.objects.filter(id=self.staff_worker.id).first() + self.assertEqual(worker.privacy_notice_accepted, True) + page = reverse('web.views.appointments') + response = self.client.get(page) + self.assertEqual(response.status_code, 200) + messages = list(get_messages(response.wsgi_request)) + worker = Worker.get_by_user(response.wsgi_request.user) + self.assertEqual(worker.privacy_notice_accepted, True) diff --git a/smash/web/tests/view/test_subjects.py b/smash/web/tests/view/test_subjects.py index 516423687daeebce37554ae137a83f793076cb6f..9551f3e7ed64921324fd712cca08a5634e9b06b1 100644 --- a/smash/web/tests/view/test_subjects.py +++ b/smash/web/tests/view/test_subjects.py @@ -6,7 +6,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse from web.forms import SubjectAddForm, SubjectEditForm, StudySubjectAddForm, StudySubjectEditForm -from web.models import MailTemplate, StudySubject, StudyColumns, Visit, Provenance +from web.models import MailTemplate, StudySubject, StudyColumns, Visit, Provenance, Subject from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, SUBJECT_TYPE_CHOICES_PATIENT, \ COUNTRY_AFGHANISTAN_ID, COUNTRY_OTHER_ID, MAIL_TEMPLATE_CONTEXT_SUBJECT, CUSTOM_FIELD_TYPE_FILE from web.models.custom_data import CustomStudySubjectField @@ -140,6 +140,30 @@ class SubjectsViewTests(LoggedInWithWorkerTestCase): self.assertEqual(response.status_code, 302) self.assertTrue("edit" in response.url) + def test_delete_subject(self): + self.login_as_super() + study_subject = create_study_subject() + subject = study_subject.subject + self.assertEqual(1, Subject.objects.filter(id=subject.id).count()) + self.assertEqual(1, StudySubject.objects.filter(id=study_subject.id).count()) + url = reverse('web.views.subject_delete', kwargs={'pk': subject.id}) + response = self.client.post(url) + self.assertEqual(response.status_code, 302) + self.assertEqual(0, Subject.objects.filter(id=subject.id).count()) + self.assertEqual(0, StudySubject.objects.filter(id=study_subject.id).count()) + + def test_delete_study_subject(self): + self.login_as_super() + study_subject = create_study_subject() + subject = study_subject.subject + self.assertEqual(1, Subject.objects.filter(id=subject.id).count()) + self.assertEqual(1, StudySubject.objects.filter(id=study_subject.id).count()) + url = reverse('web.views.study_subject_delete', kwargs={'pk': study_subject.id}) + response = self.client.post(url) + self.assertEqual(response.status_code, 302) + self.assertEqual(1, Subject.objects.filter(id=subject.id).count()) + self.assertEqual(0, StudySubject.objects.filter(id=study_subject.id).count()) + def create_edit_form_data_for_study_subject(self, instance: StudySubject = None): if instance is None: instance = self.study_subject diff --git a/smash/web/urls.py b/smash/web/urls.py index 4b14ff39155df4f2e6d68caf1603bec93b9447ed..e83509bdf62f8768125463c107384c5dff9a9e5e 100644 --- a/smash/web/urls.py +++ b/smash/web/urls.py @@ -90,6 +90,11 @@ urlpatterns = [ url(r'^subjects/subject_visit_details/(?P<id>\d+)$', views.subject.subject_visit_details, 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/(?P<pk>\d+)/delete$', views.subject.SubjectDeleteView.as_view(), + name='web.views.subject_delete'), + + url(r'^studysubjects/(?P<pk>\d+)/delete$', views.subject.StudySubjectDeleteView.as_view(), + name='web.views.study_subject_delete'), ######################### # RED CAP NOTIFICATIONS # @@ -164,6 +169,19 @@ urlpatterns = [ url(r'^equipment_and_rooms/rooms/delete/(?P<room_id>\d+)$', views.rooms.rooms_delete, name='web.views.equipment_and_rooms.rooms_delete'), + #################### + # PRIVACY NOTICE # + #################### + + url(r'^privacy_notices$', views.privacy_notice.PrivacyNoticeListView.as_view(), name='web.views.privacy_notices'), + + url(r'^accept_privacy_notice/(?P<pk>\d+)$', views.privacy_notice.privacy_notice_accept, name='web.views.accept_privacy_notice'), + + url(r'^privacy_notices/add$', views.privacy_notice.privacy_notice_add, name='web.views.privacy_notice_add'), + url(r'^privacy_notices/(?P<pk>\d+)/edit$', views.privacy_notice.privacy_notice_edit, name='web.views.privacy_notice_edit'), + + url(r'^privacy_notices/(?P<pk>\d+)/delete$', views.privacy_notice.PrivacyNoticeDeleteView.as_view(), name='web.views.privacy_notice_delete'), + #################### # MAIL # #################### diff --git a/smash/web/utils.py b/smash/web/utils.py index 54666468190a5c15bf1562b333687f7fb192c510..170f1d13e0464b33aac56bd1fada890a69716bee 100644 --- a/smash/web/utils.py +++ b/smash/web/utils.py @@ -5,6 +5,28 @@ from datetime import timedelta from web.algorithm import VerhoeffAlgorithm, LuhnAlgorithm +from django.db import models +from django.contrib.admin.utils import NestedObjects +from django.utils.text import capfirst +from django.utils.encoding import force_text +from typing import List + +def get_deleted_objects(objs: List[models.Model]): + collector = NestedObjects(using='default') + collector.collect(objs) + # + def format_callback(obj): + opts = obj._meta + no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), + force_text(obj)) + return no_edit_link + # + to_delete = collector.nested(format_callback) + protected = [format_callback(obj) for obj in collector.protected] + model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()} + # + return to_delete, model_count, protected + def get_client_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py index 90f254227fb955480ca1425d8a6a4764dd004ca6..779ba85535665619709884c836ee7480316f1aea 100644 --- a/smash/web/views/__init__.py +++ b/smash/web/views/__init__.py @@ -1,5 +1,6 @@ # coding=utf-8 from django.conf import settings +from django.http import HttpRequest from django.shortcuts import redirect, render from django.views.generic.base import ContextMixin @@ -41,13 +42,16 @@ def wrap_response(request, template, params): return render(request, template, final_params) -def extend_context(params, request): +def extend_context(params, request: HttpRequest): study = Study.get_by_id(GLOBAL_STUDY_ID) person = Worker.get_by_user(request.user) # None if AnonymousUser or no Worker associated permissions = set() + show_notice = True if person is not None: role = person.role permissions = person.get_permissions(study) + show_notice = study.study_privacy_notice \ + and not person.privacy_notice_accepted person = str(person) else: #use full name if available, username otherwise @@ -56,6 +60,8 @@ def extend_context(params, request): else: person = request.user.get_username() role = '<No worker information>' + if request.resolver_match is not None and request.resolver_match.url_name == 'web.views.accept_privacy_notice': + show_notice = False notifications = get_notifications(request.user) final_params = params.copy() final_params.update({ @@ -65,6 +71,7 @@ def extend_context(params, request): 'person': person, 'role': role, 'notifications': notifications, + 'show_notice' : show_notice, 'study_id': GLOBAL_STUDY_ID, 'study' : study }) @@ -105,4 +112,5 @@ from . import uploaded_files from . import study from . import password from . import appointment_type -from . import provenance \ No newline at end of file +from . import provenance +from . import privacy_notice \ No newline at end of file diff --git a/smash/web/views/privacy_notice.py b/smash/web/views/privacy_notice.py new file mode 100644 index 0000000000000000000000000000000000000000..dc44ade1a75b40d399528b4d13bedff39e38125c --- /dev/null +++ b/smash/web/views/privacy_notice.py @@ -0,0 +1,108 @@ +# coding=utf-8 +import io +from wsgiref.util import FileWrapper + +from django.contrib import messages +from django.http import HttpResponse +from django.shortcuts import redirect, get_object_or_404 +from django.urls import reverse_lazy +from django.views.generic import DeleteView +from django.views.generic import ListView + +from web.decorators import PermissionDecorator +from . import WrappedView +from . import wrap_response +from ..forms.privacy_notice import PrivacyNoticeForm +from ..forms.worker_form import WorkerAcceptPrivacyNoticeForm +from ..models import PrivacyNotice, Worker + + +class PrivacyNoticeListView(ListView, WrappedView): + model = PrivacyNotice + context_object_name = "privacy_notices" + template_name = 'privacy_notice/list.html' + + @PermissionDecorator('change_privacynotice', 'privacynotice') + def dispatch(self, *args, **kwargs): + return super(PrivacyNoticeListView, self).dispatch(*args, **kwargs) + + +@PermissionDecorator('change_privacynotice', 'privacynotice') +def privacy_notice_add(request): + if request.method == 'POST': + form = PrivacyNoticeForm(request.POST, request.FILES) + if form.is_valid(): + try: + form.save() + except: + messages.add_message(request, messages.ERROR, 'There was a problem when saving privacy notice. ' + 'Contact system administrator.') + return redirect('web.views.privacy_notices') + else: + form = PrivacyNoticeForm() + + return wrap_response(request, 'privacy_notice/add.html', {'form': form}) + + +@PermissionDecorator('change_privacynotice', 'privacynotice') +def privacy_notice_edit(request, pk): + privacy_notice = get_object_or_404(PrivacyNotice, pk=pk) + if request.method == 'POST': + form = PrivacyNoticeForm(request.POST, request.FILES, instance=privacy_notice) + if form.is_valid(): + try: + form.save() + return redirect('web.views.privacy_notices') + except: + messages.add_message(request, messages.ERROR, 'There was a problem when updating the privacy notice.' + 'Contact system administrator.') + return wrap_response(request, 'privacy_notice/edit.html', + {'form': form, 'privacy_notice': privacy_notice}) + else: + form = PrivacyNoticeForm(instance=privacy_notice) + + return wrap_response(request, 'privacy_notice/edit.html', {'form': form, 'privacy_notice': privacy_notice}) + + +class PrivacyNoticeDeleteView(DeleteView, WrappedView): + model = PrivacyNotice + success_url = reverse_lazy('web.views.privacy_notices') + template_name = 'privacy_notice/confirm_delete.html' + + @PermissionDecorator('change_privacynotice', 'privacynotice') + def delete(self, request, *args, **kwargs): + messages.success(request, "Privacy Notice deleted") + # try: + return super(PrivacyNoticeDeleteView, self).delete(request, *args, **kwargs) + # except: + # messages.add_message(request, messages.ERROR, 'There was a problem when deleting privacy notice. ' + # 'Contact system administrator.') + return redirect('web.views.privacy_notices') + + +def privacy_notice_accept(request, pk): + privacy_notice = get_object_or_404(PrivacyNotice, pk=pk) + worker = Worker.get_by_user(request.user) + if request.method == 'POST': + form = WorkerAcceptPrivacyNoticeForm(request.POST, instance=worker) + if form.is_valid(): + # noinspection PyBroadException + try: + form.save() + if form.cleaned_data['privacy_notice_accepted']: + messages.add_message(request, messages.SUCCESS, 'Privacy notice accepted') + if request.POST.get('next'): + return redirect(request.POST.get('next')) + return redirect('web.views.appointments') + else: + return redirect('logout') + except BaseException: + messages.add_message(request, messages.ERROR, 'There was a problem when updating the privacy notice.' + 'Contact system administrator.') + return wrap_response(request, 'privacy_notice/acceptance_study_privacy_notice.html', + {'form': form, 'privacy_notice': privacy_notice}) + else: + form = WorkerAcceptPrivacyNoticeForm(instance=worker) + + return wrap_response(request, 'privacy_notice/acceptance_study_privacy_notice.html', + {'form': form, 'privacy_notice': privacy_notice}) diff --git a/smash/web/views/study.py b/smash/web/views/study.py index 8d8bc07de6ef171d55ed5b4a21065e5af95bca72..7060a98284ba20e9b8f99b9795c0a31591d2311f 100644 --- a/smash/web/views/study.py +++ b/smash/web/views/study.py @@ -53,6 +53,7 @@ def study_edit(request, study_id): return wrap_response(request, 'study/edit.html', { 'study_form': study_form, + 'privacy_notice': study.study_privacy_notice, 'notifications_form': notifications_form, 'study_columns_form': study_columns_form, 'redcap_columns_form': redcap_columns_form diff --git a/smash/web/views/subject.py b/smash/web/views/subject.py index 2b0ddce56b84551a39bbfca87ad2d4bcc067c5e3..8151f21cab8a581af671f62ddb2a48c9a52e99cc 100644 --- a/smash/web/views/subject.py +++ b/smash/web/views/subject.py @@ -1,12 +1,17 @@ # coding=utf-8 import logging +from web.utils import get_deleted_objects +from django.db.models.deletion import Collector from django.contrib import messages from django.shortcuts import redirect, get_object_or_404 from ..utils import get_client_ip from web.decorators import PermissionDecorator from web.models.custom_data import CustomStudySubjectField from . import wrap_response +from django.views.generic import DeleteView +from . import WrappedView +from django.urls import reverse_lazy from ..forms import VisitDetailForm, SubjectAddForm, SubjectEditForm, StudySubjectAddForm, StudySubjectEditForm from ..models import StudySubject, MailTemplate, Worker, Study, Provenance, Subject from ..models.constants import GLOBAL_STUDY_ID, SUBJECT_TYPE_CHOICES, FILE_STORAGE @@ -54,6 +59,53 @@ def subject_add(request, study_id): return wrap_response(request, 'subjects/add.html', {'study_subject_form': study_subject_form, 'subject_form': subject_form}) +#delete subject (from all studies!) +class SubjectDeleteView(DeleteView, WrappedView): + model = Subject + success_url = reverse_lazy('web.views.subjects') + template_name = 'subjects/confirm_delete.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + deletable_objects, model_count, protected = get_deleted_objects([self.object]) + context['deletable_objects'] = deletable_objects + context['model_count'] = dict(model_count).items() + context['protected'] = protected + return context + + @PermissionDecorator('delete_subject', 'subject') + def delete(self, request, *args, **kwargs): + messages.success(request, "Subject deleted") + try: + return super(SubjectDeleteView, self).delete(request, *args, **kwargs) + except: + messages.add_message(request, messages.ERROR, 'There was a problem when deleting the subject. ' + 'Contact system administrator.') + return redirect('web.views.subjects') + +#delete subject from study +class StudySubjectDeleteView(DeleteView, WrappedView): + model = StudySubject + success_url = reverse_lazy('web.views.subjects') + template_name = 'subjects/confirm_delete_study_subject.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + deletable_objects, model_count, protected = get_deleted_objects([self.object]) + context['deletable_objects'] = deletable_objects + context['model_count'] = dict(model_count).items() + context['protected'] = protected + return context + + @PermissionDecorator('delete_studysubject', 'studysubject') + def delete(self, request, *args, **kwargs): + messages.success(request, "Study Subject deleted") + try: + return super(StudySubjectDeleteView, self).delete(request, *args, **kwargs) + except: + messages.add_message(request, messages.ERROR, 'There was a problem when deleting the Study Subject. ' + 'Contact system administrator.') + return redirect('web.views.subjects') def subject_no_visits(request): return subject_list(request, SUBJECT_LIST_NO_VISIT) @@ -150,6 +202,7 @@ def subject_edit(request, id): languages.extend(study_subject.subject.languages.all()) return wrap_response(request, 'subjects/edit.html', { + 'n_studies': Study.objects.count(), 'study_subject_form': study_subject_form, 'subject_form': subject_form, 'study_subject': study_subject,