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

Merge branch 'hotfix/import_file' into 'master'

Hotfix/import file

Closes #263, #262, and #264

See merge request NCER-PD/scheduling-system!181
parents 7536a235 32dd9347
No related branches found
No related tags found
1 merge request!181Hotfix/import file
Pipeline #7292 passed
# coding=utf-8 # coding=utf-8
import os import os
import getpass
import django import django
from django.conf import settings from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smash.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smash.settings")
...@@ -13,18 +14,35 @@ from operator import itemgetter ...@@ -13,18 +14,35 @@ from operator import itemgetter
from collections import OrderedDict, defaultdict from collections import OrderedDict, defaultdict
import sys import sys
import string import string
from django.contrib.auth.models import User
from web.models.constants import VOUCHER_STATUS_IN_USE, SUBJECT_TYPE_CHOICES_PATIENT, GLOBAL_STUDY_ID, SEX_CHOICES, SEX_CHOICES_MALE, SEX_CHOICES_FEMALE from web.models.constants import VOUCHER_STATUS_IN_USE, SUBJECT_TYPE_CHOICES_PATIENT, GLOBAL_STUDY_ID, SEX_CHOICES, SEX_CHOICES_MALE, SEX_CHOICES_FEMALE
from web.algorithm import VerhoeffAlgorithm, LuhnAlgorithm from web.algorithm import VerhoeffAlgorithm, LuhnAlgorithm
from web.utils import is_valid_social_security_number from web.utils import is_valid_social_security_number
from web.models import VoucherType, Voucher, Country, AppointmentTypeLink, AppointmentType, Study, Worker, Language, Subject, WorkerStudyRole, StudySubject, Location, FlyingTeam, Visit, Appointment, AppointmentType from web.models import VoucherType, Voucher, Country, AppointmentTypeLink, AppointmentType, Study, Worker, Language, Subject, WorkerStudyRole, StudySubject, Location, FlyingTeam, Visit, Appointment, AppointmentType
from web.models.worker_study_role import WORKER_STAFF, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_HEALTH_PARTNER, \ from web.models.worker_study_role import ROLE_CHOICES_TECHNICIAN, WORKER_STAFF, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_HEALTH_PARTNER, \
WORKER_HEALTH_PARTNER, ROLE_CHOICES_VOUCHER_PARTNER, WORKER_VOUCHER_PARTNER WORKER_HEALTH_PARTNER, ROLE_CHOICES_VOUCHER_PARTNER, WORKER_VOUCHER_PARTNER
DEFAULT_LOCATION = 'CHL' DEFAULT_LOCATION = 'CHL'
DEFAULT_LOCATION_PREFIX = 'P'
date_regex = re.compile(r'\d{1,2}\.\d{1,2}\.\d{4}') date_regex = re.compile(r'\d{1,2}\.\d{1,2}\.\d{4}')
def get_new_screening_number(screening_number_prefix):
result_number = 0
subjects = StudySubject.objects.filter(screening_number__contains=screening_number_prefix)
for subject in subjects:
screening_numbers = subject.screening_number.split(";")
for screening_number in screening_numbers:
screening_number = screening_number.strip()
if screening_number.startswith(screening_number_prefix):
number = screening_number[len(screening_number_prefix)+1:]
try:
result_number = max(result_number, int(number))
except ValueError:
pass
return screening_number_prefix + '-' + str(result_number + 1).zfill(3)
def itembetter(items, lst): def itembetter(items, lst):
if len(items) == 1: if len(items) == 1:
...@@ -161,6 +179,19 @@ language_table = { ...@@ -161,6 +179,19 @@ language_table = {
'FIN': 'Finnish' 'FIN': 'Finnish'
} }
locale_table = {
'Luxembourgish': ('lb_LU', 'LU'),
'Lithuanian': ('lt_LT', 'LT'),
'Italian': ('it_IT', 'IT'),
'French': ('fr_FR', 'FR'),
'German': ('de_DE', 'DE'),
'English': ('en_GB', 'GB'),
'Portuguese': ('pt_PT', 'PT'),
'Arabic': ('ar_sa', None),
'Spanish': ('es_ES', 'ES') ,
'Finnish': ('fi_FI', 'FI')
}
language_translation_table = { language_translation_table = {
# deletions # deletions
ord(u')'): None, ord(u')'): None,
...@@ -233,6 +264,7 @@ voucher_partners = {} ...@@ -233,6 +264,7 @@ voucher_partners = {}
voucher_partners['ZIT'] = 'Zitha' voucher_partners['ZIT'] = 'Zitha'
def add_subject_vouchers(voucher_reference, referral, voucher_types): def add_subject_vouchers(voucher_reference, referral, voucher_types):
nd_number, date, voucher_partner, voucher_type, num = voucher_reference.split('-') nd_number, date, voucher_partner, voucher_type, num = voucher_reference.split('-')
nd_number = nd_number.upper().replace('ND', 'PDP')
issue_date = datetime.datetime.strptime(date, '%Y%m%d') issue_date = datetime.datetime.strptime(date, '%Y%m%d')
expiry_date = issue_date + datetime.timedelta(days=365) expiry_date = issue_date + datetime.timedelta(days=365)
usage_partner, created = Worker.objects.update_or_create( usage_partner, created = Worker.objects.update_or_create(
...@@ -290,14 +322,15 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -290,14 +322,15 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
languages = [] languages = []
for language in row['LANGUAGES']: for language in row['LANGUAGES']:
lang, created = Language.objects.get_or_create( lang, created = Language.objects.get_or_create(
name=language) name=language, locale=locale_table.get(language,(None, None))[0])
languages.append(lang) languages.append(lang)
if created: if created:
logging.warn('New Language added: {}'.format(language)) logging.warn('New Language added: {}'.format(language))
lang.save() lang.save()
for language in row['PREFERED WRITEN LANGUAGE'][:1]: for language in row['PREFERED WRITEN LANGUAGE'][:1]:
pref_lang, created = Language.objects.get_or_create(name=language) pref_lang, created = Language.objects.get_or_create(name=language
,locale=locale_table.get(language,(None, None))[0])
if created: if created:
logging.warn( logging.warn(
'New Language (from Prefered) added: {}'.format(language)) 'New Language (from Prefered) added: {}'.format(language))
...@@ -314,15 +347,18 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -314,15 +347,18 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
# If no FT, then default location is CHL # If no FT, then default location is CHL
ft = None ft = None
location = None location = None
prefix = None
if not row['FLYING TEAM (FT)']: if not row['FLYING TEAM (FT)']:
prefix = DEFAULT_LOCATION_PREFIX
location, created = Location.objects.get_or_create( location, created = Location.objects.get_or_create(
name=DEFAULT_LOCATION) name=DEFAULT_LOCATION, prefix=prefix)
if created: if created:
logging.warn('New location added: {}'.format(DEFAULT_LOCATION)) logging.warn('New location added: {}'.format(DEFAULT_LOCATION))
location.save() location.save()
else: else:
prefix = 'F'
location, created = Location.objects.get_or_create( location, created = Location.objects.get_or_create(
name='Flying Team') name='Flying Team', prefix=prefix)
if created: if created:
logging.warn('New location added: Flying Team') logging.warn('New location added: Flying Team')
location.save() location.save()
...@@ -373,13 +409,13 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -373,13 +409,13 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
# StudySubject # StudySubject
study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
nd_number = row['ND NUMBER'].upper().replace('ND', 'PDP')
studySubject, created = StudySubject.objects.get_or_create(subject=subject, nd_number=row['ND NUMBER'], studySubject, created = StudySubject.objects.get_or_create(subject=subject, nd_number=nd_number,
defaults={ defaults={
'subject': subject, 'subject': subject,
'study': study, 'study': study,
'postponed': row['POSTPONED'], 'postponed': row['POSTPONED'],
'nd_number': row['ND NUMBER'], 'nd_number': nd_number,
'resigned': row['RESIGNED'], 'resigned': row['RESIGNED'],
'resign_reason': row['REASON'], 'resign_reason': row['REASON'],
'type': SUBJECT_TYPE_CHOICES_PATIENT, 'type': SUBJECT_TYPE_CHOICES_PATIENT,
...@@ -389,6 +425,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -389,6 +425,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
'comments': row['COMMENT'], 'comments': row['COMMENT'],
'default_location': location, 'default_location': location,
'flying_team': ft, 'flying_team': ft,
'screening_number': get_new_screening_number(prefix),
'date_added': parse_column_date_of_birth(row['DATE ADDED (V1)']) 'date_added': parse_column_date_of_birth(row['DATE ADDED (V1)'])
}) })
...@@ -397,7 +434,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -397,7 +434,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
studySubject.save() studySubject.save()
if created: if created:
logging.warn('New StudySubject added with ND number: {}'.format(row['ND NUMBER'])) logging.warn('New StudySubject added with ND number: {}'.format(nd_number))
#VOUCHERS #VOUCHERS
voucher_references = row['VOUCHER REFERENCE'] voucher_references = row['VOUCHER REFERENCE']
...@@ -427,7 +464,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -427,7 +464,7 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
'is_finished': True}) 'is_finished': True})
if created: if created:
logging.warn('New Visit added for ND number {} starting on {}'.format( logging.warn('New Visit added for ND number {} starting on {}'.format(
row['ND NUMBER'], datetime_begin)) nd_number, datetime_begin))
appointment_types = appointmentTypes[:len(set(visit_dates))] #in this case appointment types are incremental appointment_types = appointmentTypes[:len(set(visit_dates))] #in this case appointment types are incremental
visit.appointment_types.set(appointment_types) visit.appointment_types.set(appointment_types)
...@@ -459,6 +496,38 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types): ...@@ -459,6 +496,38 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
appointment_type=appointment_type) appointment_type=appointment_type)
date_when += datetime.timedelta( date_when += datetime.timedelta(
minutes=appointment_type.default_duration) minutes=appointment_type.default_duration)
app_type_link.save()
def createWorker(password, email='', username='admin', first_name='LCSB', last_name='Admin',
specialization='Technician', unit='LCSB'):
# create user
defaults = {'email': email, 'password': password}
user, _ = User.objects.update_or_create(username=username, defaults=defaults)
user.set_password(password)
user.is_superuser = True
user.is_staff = True
user.is_admin = True
user.save()
# create worker
defaults = {'first_name': first_name, 'last_name': last_name,
'email': email, 'unit': unit, 'specialization': specialization
, 'user': user}
worker, _ = Worker.objects.update_or_create(first_name=first_name,
last_name=last_name, defaults=defaults)
locations = Location.objects.all()
worker.locations.set(locations)
languages = Language.objects.all()
worker.languages.set(languages)
worker.save()
# create workerStudyRole
workerStudyRole, _ = WorkerStudyRole.objects.update_or_create(worker=worker,
study_id=GLOBAL_STUDY_ID, role=ROLE_CHOICES_TECHNICIAN)
logging.info('SuperUser and Worker {} created'.format(username))
if __name__ == '__main__': if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
...@@ -483,6 +552,7 @@ if __name__ == '__main__': ...@@ -483,6 +552,7 @@ if __name__ == '__main__':
#enable vouchers #enable vouchers
study.columns.voucher_types = True study.columns.voucher_types = True
study.columns.vouchers = True study.columns.vouchers = True
study.nd_number_study_subject_regex = r'^PDP\d{4}$'
study.columns.save() study.columns.save()
study.save() study.save()
# #
...@@ -500,3 +570,12 @@ if __name__ == '__main__': ...@@ -500,3 +570,12 @@ if __name__ == '__main__':
# process each row # process each row
for index, row in df.iterrows(): for index, row in df.iterrows():
parse_row(index, row, visit_columns, appointmentTypes, voucher_types) parse_row(index, row, visit_columns, appointmentTypes, voucher_types)
#create worker and super user
pass1 = ''
pass2 = None
while pass1 != pass2:
pass1 = getpass.getpass('Please type a password for the Admin user: ')
pass2 = getpass.getpass('Please type your password again: ')
if pass1 != pass2:
print 'Password mismatch, please try again'
createWorker(pass1)
\ No newline at end of file
...@@ -71,7 +71,7 @@ def get_subject_columns(request, subject_list_type): ...@@ -71,7 +71,7 @@ def get_subject_columns(request, subject_list_type):
add_column(result, "Info sent", "information_sent", study_subject_columns, "yes_no_filter", study.columns) add_column(result, "Info sent", "information_sent", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Type", "type", study_subject_columns, "type_filter", study.columns) add_column(result, "Type", "type", study_subject_columns, "type_filter", study.columns)
add_column(result, "Edit", "edit", None, None, sortable=False) add_column(result, "Edit", "edit", None, None, sortable=False)
for visit_number in range(1, 9): for visit_number in range(1, study.visits_to_show_in_subject_list+1):
visit_key = "visit_" + str(visit_number) visit_key = "visit_" + str(visit_number)
add_column(result, "Visit " + str(visit_number), visit_key, None, "visit_filter", add_column(result, "Visit " + str(visit_number), visit_key, None, "visit_filter",
visible_param=study_subject_list.visits) visible_param=study_subject_list.visits)
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2018-11-06 15:37
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0129_auto_20181031_1348'),
]
operations = [
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'),
),
]
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
from django.db import models from django.db import models
from web.models import StudyColumns, StudyNotificationParameters from web.models import StudyColumns, StudyNotificationParameters
from django.core.validators import MaxValueValidator, MinValueValidator
import re import re
...@@ -31,6 +32,12 @@ class Study(models.Model): ...@@ -31,6 +32,12 @@ class Study(models.Model):
verbose_name="Auto create follow up visit" verbose_name="Auto create follow up visit"
) )
visits_to_show_in_subject_list = models.IntegerField(
verbose_name='Number of visits to show in the subject list',
default=5,
validators=[MaxValueValidator(100), MinValueValidator(1)]
)
def check_nd_number(self, nd_number): def check_nd_number(self, nd_number):
regex = re.compile(self.nd_number_study_subject_regex) regex = re.compile(self.nd_number_study_subject_regex)
return regex.match(nd_number) is not None return regex.match(nd_number) is not None
......
...@@ -179,23 +179,26 @@ class StudySubject(models.Model): ...@@ -179,23 +179,26 @@ class StudySubject(models.Model):
) )
def sort_matched_screening_first(self, pattern, reverse=False): def sort_matched_screening_first(self, pattern, reverse=False):
parts = self.screening_number.split(';') if self.screening_number is None:
matches, reminder = [], [] return None
for part in parts:
chunks = part.strip().split('-') parts = self.screening_number.split(';')
if len(chunks) == 2: matches, reminder = [], []
letter, number = chunks for part in parts:
tupl = (letter, int(number)) chunks = part.strip().split('-')
else: if len(chunks) == 2:
logger.warn('There are {} chunks in some parts of this screening_number: |{}|.'.format( letter, number = chunks
len(chunks), self.screening_number)) tupl = (letter, int(number))
tupl = (part.strip(), None) else:
if pattern is not None and pattern in part: logger.warn('There are {} chunks in some parts of this screening_number: |{}|.'.format(
matches.append(tupl) len(chunks), self.screening_number))
else: tupl = (part.strip(), None)
reminder.append(tupl) if pattern is not None and pattern in part:
matches.append(tupl)
return matches + sorted(reminder, reverse=reverse) else:
reminder.append(tupl)
return matches + sorted(reminder, reverse=reverse)
@staticmethod @staticmethod
def check_nd_number_regex(regex_str): def check_nd_number_regex(regex_str):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment