Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • smasch/scheduling-system
1 result
Show changes
Commits on Source (22)
Showing
with 489 additions and 33 deletions
......@@ -4,6 +4,10 @@ env/*
# Folder with db statics (dev mode)
smash/~/
# files uploaded and hosted by django
smash/uploads/
smash/smash/uploads/
# Disable python bytecode
*.pyc
#vim swap files
......
from luhn_algorithm import LuhnAlgorithm
from verhoeff_alogirthm import VerhoeffAlgorithm
__all__ = [VerhoeffAlgorithm, LuhnAlgorithm]
class LuhnAlgorithm(object):
def __init__(self):
pass
@staticmethod
def luhn_checksum(card_number):
def digits_of(n):
return [int(d) for d in str(n)]
digits = digits_of(card_number)
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
checksum = 0
checksum += sum(odd_digits)
for d in even_digits:
checksum += sum(digits_of(d * 2))
return checksum % 10
@staticmethod
def is_luhn_valid(card_number):
return LuhnAlgorithm.luhn_checksum(card_number) == 0
verhoeff_multiplication_table = (
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(1, 2, 3, 4, 0, 6, 7, 8, 9, 5),
(2, 3, 4, 0, 1, 7, 8, 9, 5, 6),
(3, 4, 0, 1, 2, 8, 9, 5, 6, 7),
(4, 0, 1, 2, 3, 9, 5, 6, 7, 8),
(5, 9, 8, 7, 6, 0, 4, 3, 2, 1),
(6, 5, 9, 8, 7, 1, 0, 4, 3, 2),
(7, 6, 5, 9, 8, 2, 1, 0, 4, 3),
(8, 7, 6, 5, 9, 3, 2, 1, 0, 4),
(9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
verhoeff_permutation_table = (
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(1, 5, 7, 6, 2, 8, 3, 0, 9, 4),
(5, 8, 0, 3, 7, 9, 6, 1, 4, 2),
(8, 9, 1, 6, 0, 4, 3, 5, 2, 7),
(9, 4, 5, 3, 1, 2, 6, 8, 7, 0),
(4, 2, 8, 6, 5, 7, 3, 9, 0, 1),
(2, 7, 9, 3, 8, 0, 6, 4, 1, 5),
(7, 0, 4, 6, 9, 1, 3, 2, 5, 8))
class VerhoeffAlgorithm(object):
def __init__(self):
pass
@staticmethod
def verhoeff_checksum(number):
"""Calculate the Verhoeff checksum over the provided number. The checksum
is returned as an int. Valid numbers should have a checksum of 0."""
# transform number list
number = tuple(int(n) for n in reversed(str(number)))
# calculate checksum
check = 0
for i, n in enumerate(number):
check = verhoeff_multiplication_table[check][verhoeff_permutation_table[i % 8][n]]
return check
@staticmethod
def is_valid_verhoeff(number):
return VerhoeffAlgorithm.verhoeff_checksum(number) == 0
@staticmethod
def calculate_verhoeff_check_sum(number):
return str(verhoeff_multiplication_table[VerhoeffAlgorithm.verhoeff_checksum(str(number) + '0')].index(0))
......@@ -41,8 +41,8 @@ def serialize_datetime(date):
def add_column(result, name, field_name, column_list, param, columns_used_in_study=None, visible_param=None,
sortable=True):
add = True
sortable=True, add_param=True):
add = add_param
if columns_used_in_study:
add = getattr(columns_used_in_study, field_name)
if add:
......
......@@ -17,6 +17,7 @@ from web.views.notifications import get_subjects_with_no_visit, get_subjects_wit
logger = logging.getLogger(__name__)
# noinspection PyUnusedLocal
@login_required
def cities(request):
result_subjects = Subject.objects.filter(city__isnull=False).values_list('city').distinct()
......@@ -25,6 +26,7 @@ def cities(request):
})
# noinspection PyUnusedLocal
@login_required
def referrals(request):
result_subjects = StudySubject.objects.filter(referral__isnull=False).values_list('referral').distinct()
......@@ -51,10 +53,17 @@ def get_subject_columns(request, subject_list_type):
add_column(result, "Screening", "screening_number", study_subject_columns, "string_filter", study.columns)
add_column(result, "First name", "first_name", subject_columns, "string_filter")
add_column(result, "Last name", "last_name", subject_columns, "string_filter")
add_column(result, "Social Security Number", "social_security_number", subject_columns, "string_filter")
add_column(result, "Date of birth", "date_born", subject_columns, None)
add_column(result, "Contact on", "datetime_contact_reminder", study_subject_columns, None, study.columns)
add_column(result, "Last contact attempt", "last_contact_attempt", study_subject_list, None)
add_column(result, "Referred by", "referral", study_subject_columns, "string_filter", study.columns)
add_column(result, "Health partner name", "health_partner_first_name", None, "string_filter",
add_param=study.columns.health_partner,
visible_param=study_subject_columns.health_partner)
add_column(result, "Health partner last name", "health_partner_last_name", None, "string_filter",
add_param=study.columns.health_partner,
visible_param=study_subject_columns.health_partner)
add_column(result, "Location", "default_location", study_subject_columns, "location_filter", study.columns)
add_column(result, "Flying team location", "flying_team", study_subject_columns, "flying_team_filter",
study.columns)
......@@ -116,6 +125,12 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
result = subjects_to_be_ordered.order_by(order_direction + 'resigned')
elif order_column == "information_sent":
result = subjects_to_be_ordered.order_by(order_direction + 'information_sent')
elif order_column == "health_partner_first_name":
result = subjects_to_be_ordered.order_by(order_direction + 'health_partner__first_name')
elif order_column == "health_partner_last_name":
result = subjects_to_be_ordered.order_by(order_direction + 'health_partner__last_name')
elif order_column == "social_security_number":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__social_security_number')
elif order_column == "postponed":
result = subjects_to_be_ordered.order_by(order_direction + 'postponed')
elif order_column == "type":
......@@ -226,6 +241,12 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
result = result.filter(postponed=(value == "true"))
elif column == "information_sent":
result = result.filter(information_sent=(value == "true"))
elif column == "health_partner_first_name":
result = result.filter(health_partner__first_name__icontains=value)
elif column == "health_partner_last_name":
result = result.filter(health_partner__last_name__icontains=value)
elif column == "social_security_number":
result = result.filter(subject__social_security_number__icontains=value)
elif column == "default_location":
result = result.filter(default_location=value)
elif column == "flying_team":
......@@ -244,7 +265,6 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
else:
message += str(column)
logger.warn(message)
return result
......@@ -289,6 +309,7 @@ def subjects(request, type):
return e500_error(request)
# noinspection PyUnusedLocal
@login_required
def types(request):
data = [{"id": subject_type_id, "name": subject_type_name} for subject_type_id, subject_type_name in
......@@ -338,6 +359,12 @@ def serialize_subject(study_subject):
else:
last_contact_attempt_string = ""
health_partner_first_name = ""
if study_subject.health_partner:
health_partner_first_name = study_subject.health_partner.first_name
health_partner_last_name = ""
if study_subject.health_partner:
health_partner_last_name = study_subject.health_partner.last_name
result = {
"first_name": study_subject.subject.first_name,
"last_name": study_subject.subject.last_name,
......@@ -353,6 +380,9 @@ def serialize_subject(study_subject):
"resigned": bool_to_yes_no(study_subject.resigned),
"postponed": bool_to_yes_no(study_subject.postponed),
"information_sent": bool_to_yes_no(study_subject.information_sent),
"health_partner_first_name": health_partner_first_name,
"health_partner_last_name": health_partner_last_name,
"social_security_number": study_subject.subject.social_security_number,
"type": study_subject.get_type_display(),
"id": study_subject.id,
"visits": serialized_visits,
......
......@@ -4,8 +4,10 @@ from forms import WorkerAddForm, \
AvailabilityEditForm, HolidayAddForm
from study_subject_forms import StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm
from subject_forms import SubjectAddForm, SubjectEditForm, SubjectDetailForm
from voucher_forms import VoucherTypeForm, VoucherTypePriceForm, VoucherForm
__all__ = [StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm, WorkerAddForm, WorkerEditForm,
AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, VisitDetailForm, VisitAddForm,
ContactAttemptForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm,
AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm]
AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm, VoucherTypeForm,
VoucherTypePriceForm, VoucherForm]
......@@ -7,7 +7,7 @@ from django.forms import ModelForm, Form
from django.utils.dates import MONTHS
from web.models import StudySubject, Worker, Appointment, Visit, AppointmentType, ContactAttempt, AppointmentTypeLink, \
Availability, Holiday, VoucherType, VoucherTypePrice
Availability, Holiday
from web.models.constants import SUBJECT_TYPE_CHOICES
from web.views.notifications import get_filter_locations
......@@ -387,20 +387,3 @@ class HolidayAddForm(ModelForm):
validate_availability_conflict(self, self.cleaned_data, availability)
class VoucherTypeForm(ModelForm):
class Meta:
model = VoucherType
exclude = ['study']
class VoucherTypePriceForm(ModelForm):
start_date = forms.DateField(label="Start date",
widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
)
end_date = forms.DateField(label="End date",
widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
)
class Meta:
model = VoucherTypePrice
exclude = ['voucher_type']
......@@ -5,18 +5,31 @@ from django import forms
from django.forms import ModelForm
from web.forms.forms import DATETIMEPICKER_DATE_ATTRS, get_worker_from_args
from web.models import StudySubject, Study, StudyColumns
from web.models import StudySubject, Study, StudyColumns, VoucherType
from web.models.constants import SCREENING_NUMBER_PREFIXES_FOR_TYPE
from web.widgets.secure_file_widget import SecuredFileWidget
logger = logging.getLogger(__name__)
class StudySubjectAddForm(ModelForm):
class StudySubjectForm(ModelForm):
datetime_contact_reminder = forms.DateTimeField(label="Contact on",
widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
required=False
)
referral_letter = forms.FileField(label='Select a file', widget=SecuredFileWidget(), required=False)
voucher_types = forms.ModelMultipleChoiceField(required=False,
widget=forms.CheckboxSelectMultiple,
queryset=VoucherType.objects.all(),
)
def __init__(self, *args, **kwargs):
super(StudySubjectForm, self).__init__(*args, **kwargs)
class StudySubjectAddForm(StudySubjectForm):
class Meta:
model = StudySubject
fields = '__all__'
......@@ -26,12 +39,12 @@ class StudySubjectAddForm(ModelForm):
self.user = get_worker_from_args(kwargs)
self.study = get_study_from_args(kwargs)
super(ModelForm, self).__init__(*args, **kwargs)
super(StudySubjectAddForm, self).__init__(*args, **kwargs)
prepare_study_subject_fields(fields=self.fields, study=self.study)
def save(self, commit=True):
self.instance.study_id = self.study.id
return super(ModelForm, self).save(commit)
return super(StudySubjectAddForm, self).save(commit)
def build_screening_number(self, cleaned_data):
screening_number = cleaned_data.get('screening_number', None)
......@@ -83,7 +96,7 @@ def get_new_screening_number(screening_number_prefix):
return screening_number_prefix + str(result_number + 1).zfill(3)
class StudySubjectDetailForm(ModelForm):
class StudySubjectDetailForm(StudySubjectForm):
class Meta:
model = StudySubject
fields = '__all__'
......@@ -104,11 +117,7 @@ def get_study_from_study_subject_instance(study_subject):
return Study(columns=StudyColumns())
class StudySubjectEditForm(ModelForm):
datetime_contact_reminder = forms.DateTimeField(label="Contact on",
widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
required=False
)
class StudySubjectEditForm(StudySubjectForm):
def __init__(self, *args, **kwargs):
was_resigned = kwargs.get('was_resigned', False)
......@@ -166,6 +175,12 @@ def prepare_study_subject_fields(fields, study):
prepare_field(fields, study.columns, 'pd_in_family')
prepare_field(fields, study.columns, 'resigned')
prepare_field(fields, study.columns, 'resign_reason')
prepare_field(fields, study.columns, 'referral_letter')
prepare_field(fields, study.columns, 'health_partner')
prepare_field(fields, study.columns, 'health_partner_feedback_agreement')
prepare_field(fields, study.columns, 'screening')
prepare_field(fields, study.columns, 'previously_in_study')
prepare_field(fields, study.columns, 'voucher_types')
def validate_subject_screening_number(self, cleaned_data):
......
import logging
from django import forms
from django.forms import ModelForm
from web.algorithm import VerhoeffAlgorithm, LuhnAlgorithm
from web.forms.forms import DATEPICKER_DATE_ATTRS
from web.models import Subject
from web.models.constants import COUNTRY_OTHER_ID
logger = logging.getLogger(__name__)
def validate_subject_country(self, cleaned_data):
if cleaned_data['country'].id == COUNTRY_OTHER_ID:
self.add_error('country', "Select valid country")
def validate_social_security_number(self, number):
if not is_valid_social_security_number(number):
self.add_error('social_security_number', "Social security number is invalid")
def is_valid_social_security_number(number):
if number is not None and number != '':
if len(number) != 13:
return False
if not number.isdigit():
return False
if not LuhnAlgorithm.is_luhn_valid(number[:12]):
return False
if not VerhoeffAlgorithm.is_valid_verhoeff(number[:11] + number[12]):
return False
return True
FIELD_ORDER = ["first_name", "last_name", "sex", "date_born", "social_security_number",
"default_written_communication_language", "languages", "phone_number", "phone_number_2",
"phone_number_3", "address", "city", "postal_code", "country"]
......@@ -32,6 +56,7 @@ class SubjectAddForm(ModelForm):
def clean(self):
cleaned_data = super(SubjectAddForm, self).clean()
validate_subject_country(self, cleaned_data)
validate_social_security_number(self, cleaned_data["social_security_number"])
return cleaned_data
......@@ -53,6 +78,7 @@ class SubjectEditForm(ModelForm):
def clean(self):
validate_subject_country(self, self.cleaned_data)
validate_social_security_number(self, self.cleaned_data["social_security_number"])
class Meta:
model = Subject
......
import datetime
import logging
from django import forms
from django.forms import ModelForm
from django.utils import timezone
from web.algorithm import VerhoeffAlgorithm
from web.forms.forms import DATEPICKER_DATE_ATTRS
from web.models import VoucherType, VoucherTypePrice, Voucher
from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED
logger = logging.getLogger(__name__)
class VoucherTypeForm(ModelForm):
class Meta:
model = VoucherType
exclude = ['study']
class VoucherTypePriceForm(ModelForm):
start_date = forms.DateField(label="Start date",
widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
)
end_date = forms.DateField(label="End date",
widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
)
class Meta:
model = VoucherTypePrice
exclude = ['voucher_type']
class VoucherForm(ModelForm):
class Meta:
model = Voucher
fields = '__all__'
def __init__(self, *args, **kwargs):
voucher_types = kwargs.pop('voucher_types', VoucherType.objects.all())
super(VoucherForm, self).__init__(*args, **kwargs)
self.fields['voucher_type'].queryset = voucher_types
self.fields['number'].widget.attrs['readonly'] = True
self.fields['number'].required = False
self.fields['issue_date'].widget.attrs['readonly'] = True
self.fields['issue_date'].required = False
self.fields['expiry_date'].widget.attrs['readonly'] = True
self.fields['expiry_date'].required = False
self.fields['use_date'].widget.attrs['readonly'] = True
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['voucher_type'].widget.attrs['readonly'] = True
if instance.status != VOUCHER_STATUS_NEW:
self.fields['status'].widget.attrs['readonly'] = True
self.fields['feedback'].widget.attrs['readonly'] = True
self.fields['usage_partner'].widget.attrs['readonly'] = True
def clean(self):
if self.cleaned_data["status"] == VOUCHER_STATUS_USED and not self.cleaned_data["usage_partner"]:
self.add_error('usage_partner', "Partner must be defined for used voucher")
if self.cleaned_data["status"] != VOUCHER_STATUS_USED and self.cleaned_data["usage_partner"]:
self.add_error('status', "Status must be used for voucher with defined partner")
def save(self, commit=True):
instance = super(VoucherForm, self).save(commit=False)
if not instance.id:
instance.issue_date = timezone.now()
instance.expiry_date = instance.issue_date + datetime.timedelta(days=92)
max_id = str(0).zfill(5)
if Voucher.objects.all().count() > 0:
max_id = str(Voucher.objects.latest('id').id).zfill(5)
instance.number = max_id + VerhoeffAlgorithm.calculate_verhoeff_check_sum(max_id)
if instance.status == VOUCHER_STATUS_USED and not instance.use_date:
instance.use_date = timezone.now()
if commit:
instance.save()
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 13:12
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0090_vouchertype_vouchertypeprice'),
]
operations = [
migrations.AlterField(
model_name='vouchertypeprice',
name='voucher_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prices', to='web.VoucherType'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 15:00
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0091_auto_20171208_1312'),
]
operations = [
migrations.CreateModel(
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')),
('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')),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0092_voucher'),
]
operations = [
migrations.AlterField(
model_name='voucher',
name='usage_partner',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 15:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0093_auto_20171208_1508'),
]
operations = [
migrations.AlterField(
model_name='voucher',
name='usage_partner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Worker'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 15:09
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0094_auto_20171208_1508'),
]
operations = [
migrations.AlterField(
model_name='voucher',
name='use_date',
field=models.DateField(null=True, verbose_name=b'Use date'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-08 15:09
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0095_auto_20171208_1509'),
]
operations = [
migrations.AlterField(
model_name='voucher',
name='use_date',
field=models.DateField(blank=True, null=True, verbose_name=b'Use date'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-11 16:16
from __future__ import unicode_literals
import django.core.files.storage
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0096_auto_20171208_1509'),
]
operations = [
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'),
),
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'),
),
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'),
),
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'),
),
migrations.AddField(
model_name='studycolumns',
name='screening',
field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'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'),
),
migrations.AddField(
model_name='studycolumns',
name='vouchers',
field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=False, verbose_name=b'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'),
),
migrations.AddField(
model_name='studysubject',
name='health_partner_feedback_agreement',
field=models.BooleanField(default=False, verbose_name=b'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'),
),
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'),
),
migrations.AddField(
model_name='studysubject',
name='screening',
field=models.CharField(blank=True, max_length=1024, null=True, verbose_name=b'Screening'),
),
migrations.AddField(
model_name='studysubject',
name='voucher_types',
field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name=b'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'),
),
migrations.AlterField(
model_name='studysubject',
name='diagnosis',
field=models.CharField(blank=True, max_length=1024, null=True, verbose_name=b'Diagnosis'),
),
migrations.AlterField(
model_name='voucher',
name='study_subject',
field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='vouchers', to='web.StudySubject'),
),
]
......@@ -27,6 +27,7 @@ from item import Item
from language import Language
from subject import Subject
from study_subject import StudySubject
from voucher import Voucher
from study_subject_list import StudySubjectList
from study_visit_list import StudyVisitList
from appointment_list import AppointmentList
......@@ -38,5 +39,5 @@ from inconsistent_subject import InconsistentSubject, InconsistentField
__all__ = [Study, FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room,
Subject, StudySubject, StudySubjectList, SubjectColumns, StudyNotificationParameters,
AppointmentList, AppointmentColumns, Visit, Worker, ContactAttempt, ConfigurationItem, MailTemplate,
AppointmentTypeLink, VoucherType, VoucherTypePrice,
AppointmentTypeLink, VoucherType, VoucherTypePrice, Voucher,
MissingSubject, InconsistentSubject, InconsistentField, Country, StudyColumns, VisitColumns, StudyVisitList]
# coding=utf-8
import locale
from django.core.files.storage import FileSystemStorage
BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
SEX_CHOICES_MALE = 'M'
SEX_CHOICES_FEMALE = 'F'
......@@ -81,3 +83,14 @@ COUNTRY_AFGHANISTAN_ID = 2
# id of the singleton Study,
# TODO remove after allowing many studies per Smasch instance
GLOBAL_STUDY_ID = 1
VOUCHER_STATUS_NEW = "NEW"
VOUCHER_STATUS_USED = "USED"
VOUCHER_STATUS_EXPIRED = "EXPIRED"
VOUCHER_STATUS_CHOICES = (
(VOUCHER_STATUS_NEW, 'New'),
(VOUCHER_STATUS_USED, 'Used'),
(VOUCHER_STATUS_EXPIRED, 'Expired'),
)
FILE_STORAGE = FileSystemStorage(location='uploads')