From 1b70da09256cca74c7a2c5a1a085ea5c14dcae87 Mon Sep 17 00:00:00 2001
From: Carlos Vega <carlos.vega@uni.lu>
Date: Wed, 24 Oct 2018 20:45:42 +0200
Subject: [PATCH] pep8 format

---
 smash/create_dummy_data.py | 1319 ++++++++++++++++++------------------
 1 file changed, 675 insertions(+), 644 deletions(-)

diff --git a/smash/create_dummy_data.py b/smash/create_dummy_data.py
index 79ca1310..9379af36 100644
--- a/smash/create_dummy_data.py
+++ b/smash/create_dummy_data.py
@@ -9,14 +9,14 @@ import os
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smash.settings")
 django.setup()
 from django.contrib.auth.models import User
-#models (please add in both lines)
+# models (please add in both lines)
 from web.models import StudySubject, Availability, Visit, Appointment, AppointmentType, AppointmentTypeLink, Study, Subject, Worker, Location, Language, Country, WorkerStudyRole, Item, FlyingTeam, Room, MailTemplate
 from smash.local_settings import MEDIA_ROOT
 from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, REDCAP_BASE_URL_CONFIGURATION_TYPE, \
-	SEX_CHOICES_MALE, SEX_CHOICES_FEMALE, SUBJECT_TYPE_CHOICES_CONTROL, SUBJECT_TYPE_CHOICES_PATIENT, CONTACT_TYPES_PHONE, \
-	MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID, DEFAULT_LOCALE_NAME
+    SEX_CHOICES_MALE, SEX_CHOICES_FEMALE, SUBJECT_TYPE_CHOICES_CONTROL, SUBJECT_TYPE_CHOICES_PATIENT, CONTACT_TYPES_PHONE, \
+    MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID, DEFAULT_LOCALE_NAME
 from web.models.constants import MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VISIT, \
-	MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VOUCHER
+    MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VOUCHER
 from web.models.worker_study_role import ROLE_CHOICES_PROJECT_MANAGER, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_DOCTOR, WORKER_VOUCHER_PARTNER, ROLE_CHOICES_TECHNICIAN, ROLE_CHOICES_PSYCHOLOGIST, ROLE_CHOICES_NURSE
 from web.tests.functions import get_resource_path
 
@@ -28,657 +28,688 @@ from web.views.notifications import get_today_midnight_date
 from faker.providers import BaseProvider, color
 from numpy.random import choice
 from faker import Faker
-import platform, tempfile, unidecode
+import platform
+import tempfile
+import unidecode
 from shutil import copyfile
 
-class smashProvider(BaseProvider):
-
-	__provider__ = 'smash'
-	__lang__ = 'fr_FR'
-	fake = Faker()
-	fake.seed(4321)
-
-	specialists = ['Psychiatrist', 'Radiologist', 'Immunologist', 'Anesthesiologist', 'Surgeon', 'Pediatrician', 'Neurologist', 'Medical examiner'] 
-	units = ['LHI', 'PCR', 'LCSB', 'ACO', 'PLI', 'LRSU'] 
-	workerRoles = [ROLE_CHOICES_PROJECT_MANAGER, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_DOCTOR, ROLE_CHOICES_TECHNICIAN, ROLE_CHOICES_PSYCHOLOGIST, ROLE_CHOICES_NURSE]
-
-	#towns and cities
-	near_fr_towns = ['Metz', 'Audun-le-Tiche', 'Thionville']
-	near_de_towns = ['Trier']
-	near_be_towns = ['Aubange', 'Arlon'] 
-	luxtowns  = ['Luxembourg City', 'Esch-sur-Alzette', 'Differdange', 'Dudelange', 'Ettelbruck', 'Diekirch', 'Wiltz', 'Rumelange', 'Echternach', 'Grevenmacher', 'Remich', 'Vianden']
-
-	#if you add or remove cities, be careful and change the probabilities as well
-	#here the probs ensure the luxembourgish towns have 0.8 prob, and so on...
-	cities = luxtowns + near_fr_towns + near_de_towns + near_be_towns
-	city_prob = [0.8/len(luxtowns)]      *len(luxtowns) + \
-					[0.1/len(near_fr_towns)] *len(near_fr_towns) + \
-					[0.05/len(near_de_towns)]*len(near_de_towns) + \
-					[0.05/len(near_be_towns)]*len(near_be_towns)
-	
-	alreadyCreatedLocations = {}
-	#languages
-	language_base_dir = 'web/static/flags/'
-	language_flags = {
-		'French' : 'FR.png',
-		'English': 'GB.png',
-		'Spanish': 'ES.png',
-		'Portuguese': 'PT.png',
-		'Luxembourgish': 'LU.png',
-		'German': 'DE.png',
-		'Dutch' : 'NL.png'
-	}
-	language_locale = {
-		'French' : 'fr_FR',
-		'Luxembourgish' : 'lb_LU',
-		'Spanish' : 'es_ES',
-		'English' : 'en_GB',
-		'Portuguese': 'pt_PT',
-		'German' : 'de_DE',
-		'Dutch' : 'nl_NL'
-	}
-	languages = ['English', 'Luxembourgish', 'French', 'German', 'Portuguese', 'Spanish', 'Dutch']
-	languages_prob = [0.25, 0.2, 0.16, 0.16, 0.13, 0.05, 0.05]
-	alreadyCreatedLanguages = {}
-	#items
-	items = ['Saliva', 'Blood', 'Liquid Biopsy', 'X-Ray Examination', 'Urine', 'Tissue Biopsy', 'Skin sample']
-	alreadyCreatedItems = {}
-	#flying teams
-	places = ['Belval', 'Belvaux', 'Arlon', 'Metz']
-	alreadyCreatedFlyingTeams = {}
-	#countries
-	countries = ['France', 'Luxembourg', 'Germamny', 'Belgium']	
-	alreadyCreatedCountries = {}
-	#screening number
-	screening_number_ctrs = defaultdict(int)
-	#template file
-	template_file = get_resource_path('upcoming_appointment_FR.docx')
-	template_context = [MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VOUCHER, MAIL_TEMPLATE_CONTEXT_VISIT, MAIL_TEMPLATE_CONTEXT_SUBJECT]
-	#subjects
-	alreadyCreatedSubjects = []
-	alreadyCreatedStudySubjects = []
-	#appointment type
-	alreadyCreatedAppointmentTypes = []
-	#workers 
-	alreadyCreatedWorkers = []
-	#rooms
-	alreadyCreatedRooms = []
-	#nd_number_ctr
-	nd_number_ctr = 0
-
-	def getLuxembourgTown(self):
-		return self.fake.word(ext_word_list=self.luxtowns)
-
-	def getFrenchTown(self):
-		return self.fake.word(ext_word_list=self.near_fr_towns)
-
-	def getBelgiumTown(self):
-		return self.fake.word(ext_word_list=self.near_be_towns)
-
-	def getDeutschTown(self):
-		return self.fake.word(ext_word_list=self.near_de_towns)
-
-	def getWorkerRole(self):
-		return self.fake.word(ext_word_list=self.workerRoles) 
-
-	#availability
-	def createSmashAvailabilities(self):
-		for worker in self.alreadyCreatedWorkers:
-			for weekday in set(choice(range(1,6), 4)):
-				availability = self.createSmashAvailability(worker=worker, day_number=weekday)
-
-	def createSmashAvailability(self, worker=None, day_number=None, available_from=None, available_till=None):
-		if worker is None:
-			worker = choice(self.alreadyCreatedWorkers)
-		if day_number is None:
-			day_number = choice(range(1,6))
-		if available_from is None:
-			available_from = '{}:00'.format(choice(range(8,10)))
-		if available_till is None:
-			available_till = '{}:00'.format(choice(range(13,18)))
-
-		availability, _ = Availability.objects.update_or_create(person=worker,
-						   day_number=day_number,
-						   available_from=available_from,
-						   available_till=available_till)
-		return availability
-
-	#appointments
-	def createSmashAppointments(self):
-		today = timezone.now()
-		#create first visit, in between -2y and -1y from now and first appointment
-		for studySubject in self.alreadyCreatedStudySubjects:
-			#date_between does not support months so we use days
-			visit_start_date = fake.date_between(start_date='-1y', end_date='-334d') - datetime.timedelta(days=-31)
-			visit_end_date   = visit_start_date + datetime.timedelta(days=31)
-			visit = self.createSmashVisit(studySubject=studySubject, datetime_begin=visit_start_date, 
-				datetime_end=visit_end_date, is_finished=True)
-			appointment_types = self.getAlreadyCreatedAppointmentTypes()
-			visit.appointment_types.set(appointment_types)
-			#appointment
-			duration = sum([app.default_duration for app in appointment_types])
-			appointment_start_date = fake.date_time_between(start_date=visit_start_date, end_date=visit_end_date, 
-				tzinfo=today.tzinfo)
-			hour   = choice(range(9, 18))
-			minute = choice(range(0, 30, 5))
-			#ensure the time is between office hours
-			appointment_start_date = appointment_start_date.replace(hour=hour, minute=minute, tzinfo=today.tzinfo)
-
-			room = choice(self.alreadyCreatedRooms)
-			appointment = self.createSmashAppointment(visit=visit, datetime_when=appointment_start_date, 
-				length=duration, appointment_types=appointment_types, room=room, status=Appointment.APPOINTMENT_STATUS_FINISHED)
-
-	def createSmashAppointment(self, visit=None, datetime_when=None, location=None, length=30,
-		status=Appointment.APPOINTMENT_STATUS_SCHEDULED, appointment_types=None, room=None, worker_assigned=None):
-		if visit is None:
-			visit = self.createSmashVisit()
-		if datetime_when is None:
-			datetime_when = get_today_midnight_date()
-		if location is None:
-			location = self.getAlreadyCreatedSmashLocation()
-		if room is None:
-			room = choice(self.alreadyCreatedRooms)
-		if worker_assigned is None:
-			worker_assigned = choice(self.alreadyCreatedWorkers)
-
-		appointment, _ = Appointment.objects.update_or_create(
-			visit=visit, length=length, location=location, worker_assigned=worker_assigned,
-			status=status, datetime_when=datetime_when, room=room)
-
-		if appointment_types is None:
-			appointment_types = self.getAlreadyCreatedAppointmentTypes()
-
-		#create connection for each appointment type
-		when = datetime_when
-		for appointment_type in appointment_types:
-			worker=choice(self.alreadyCreatedWorkers)
-			when = when + datetime.timedelta(minutes=appointment_type.default_duration)
-			app_type_link = AppointmentTypeLink(appointment=appointment, date_when=when, 
-				appointment_type=appointment_type, worker=worker)
-
-		return appointment
-
-	#visit
-	def createSmashVisit(self, datetime_begin=None, datetime_end=None, studySubject=None, is_finished=False, visit_number=1):
-		if datetime_begin is None:
-			datetime_begin = get_today_midnight_date() + datetime.timedelta(days=-31)
-		if datetime_end is None:
-			datetime_end = get_today_midnight_date() + datetime.timedelta(days=31)
-		if studySubject is None:
-			studySubject = choice(self.alreadyCreatedStudySubjects)
-
-		visit, _ = Visit.objects.update_or_create(datetime_begin=datetime_begin, datetime_end=datetime_end,
-									   subject=studySubject, is_finished=is_finished, visit_number=visit_number)
-		return visit
-
-
-	#AppointmentTypes
-	def getAlreadyCreatedAppointmentTypes(self, n=3):
-		return set(choice(self.alreadyCreatedAppointmentTypes, n))
-
-	def createSmashAppointmentTypes(self, n_max=5):
-		return [self.createSmashAppointmentType() for _ in xrange(n_max)]
-
-	def createSmashAppointmentType(self, code=None, default_duration=10, rest_time=5, description=None):
-		if code is None:
-			code = self.fake.word(ext_word_list=['C', 'A', 'N', 'P'])
-		if description is None:
-			description = self.fake.word(ext_word_list=['Examination', 'Analysis', 'Questions', 'Test'])
-		equipment = self.getSmashAlreadyCreatedItems()
-		appointmentType, _ = AppointmentType.objects.update_or_create(code=code, rest_time=rest_time, 
-			default_duration=default_duration, description=description)
-
-		appointmentType.required_equipment.set(equipment)
-		appointmentType.required_worker = choice(['DOCTOR', 'NURSE', 'PSYCHOLOGIST', 'ANY'])
-		appointmentType.save()
-
-		self.alreadyCreatedAppointmentTypes.append(appointmentType)
-
-		return appointmentType
-
-	#mail template
-	def createSmashMailTemplates(self):
-		'''
-		Returns a list of template objects
-		'''
-		languages = self.getAlreadyCreatedSmashLanguages()
-		templates = []
-		for context in self.template_context:
-			for language in languages:
-				template = self.createSmashMailTemplate(language=language, context=context)
-				templates.append(template)
-		return templates
-
-	def createSmashMailTemplate(self, name=None, language=None, context=MAIL_TEMPLATE_CONTEXT_APPOINTMENT, template_file=None):
-		if language is None:
-			language = self.getAlreadyCreatedSmashLanguages()[0]
-		if name is None:
-			name = '{} Template'.format(language.name)
-		if template_file is None:
-			template_file = self.template_file
-			basename = os.path.basename(template_file)
-			dst = os.path.join(MEDIA_ROOT, basename)
-			copyfile(template_file, dst)
-		template, _ = MailTemplate.objects.update_or_create(name=name, language=language, context=context, template_file = dst)
-		return template
-
-	#flying teams
-	def createSmashFlyingTeams(self):
-		return [self.createSmashFlyingTeam(place=place) for place in self.places]
-
-	def createSmashFlyingTeam(self, place=None):
-		if place is None:
-			place = self.fake.word(ext_word_list=self.places)
-		flying_team, _ = FlyingTeam.objects.update_or_create(place=place)
-
-		self.alreadyCreatedFlyingTeams[place] = flying_team
-
-		return flying_team
-
-	#item
-	def createSmashItems(self):
-		'''
-		Returns a list of Item objects
-		'''
-		return [self.createSmashItem(name=item) for item in self.items]
-
-	def createSmashItem(self, name=None, is_fixed=None, disposable=None):
-		'''
-		Returns an Item object
-		'''
-		if name is None:
-			name = self.fake.word(ext_word_list=self.items)
-
-		if is_fixed is None:
-			is_fixed = self.fake.boolean(chance_of_getting_true=75)
-
-		if disposable is None:
-			disposable = self.fake.boolean(chance_of_getting_true=75)
-
-		item, _ = Item.objects.update_or_create(name=name, is_fixed=is_fixed, disposable=disposable)
-
-		self.alreadyCreatedItems[name] = item
-
-		return item
-
-	def getSmashAlreadyCreatedItems(self, max_n=3):
-		if len(self.alreadyCreatedItems.keys()) == 0:
-			self.createSmashItems()
-
-		keys = set(choice(self.alreadyCreatedItems.keys(), max_n))
-		return [self.alreadyCreatedItems[key] for key in keys]
-
-	#room
-	def createSmashRooms(self, n=4):
-		return [self.createSmashRoom() for _ in xrange(n)]
-
-	def createSmashRoom(self, equipment=None, owner=None, address=None, city=None, room_number=None, floor=None, is_vehicle=None):
-		'''
-		equipment: List of Item objects: 
-		owner: string: 
-		address: string: 
-		city: string: 
-		room_number: int: 
-		floor: int: 
-		is_vehicle: boolean: 
-		'''
-		if equipment is None:
-			item = self.fake.word(ext_word_list=self.alreadyCreatedItems.keys())
-			equipment = self.getSmashAlreadyCreatedItems()
-
-		if owner is None:
-			owner = self.fake.first_name()
-
-		if address is None:
-			address = '{}, {} {}'.format(self.fake.word(ext_word_list=self.cities), self.fake.random_digit_not_null_or_empty(), self.fake.street_name())
-			address = address.replace('\n', ' ')
-
-		if city is None:
-			city = self.fake.word(ext_word_list=self.cities)
-
-		if room_number is None:
-			room_number = choice(range(10), 1)[0] #choice returns a list
-
-		if floor is None:
-			floor = choice(range(10), 1)[0]
-
-		if is_vehicle is None:
-			is_vehicle = self.fake.boolean(chance_of_getting_true=25)
-
-		dicc = {'owner': owner, 'city': city, 'address': address,
-		 'floor': floor, 'room_number': room_number, 'is_vehicle': is_vehicle}
-		room, _ = Room.objects.update_or_create(**dicc)
-		room.equipment.set(equipment)
-		room.save()
-
-		self.alreadyCreatedRooms.append(room)
-
-		return room
-
-	#country
-	def getAlreadyCreatedSmashCountry(self):
-		if len(self.alreadyCreatedCountries) == 0:
-			self.createSmashCountries()
-
-		name = self.fake.word(ext_word_list=self.countries)
-		return self.alreadyCreatedCountries[name]
-
-	def createSmashCountries(self):
-		return [self.createSmashCountry(name=country) for country in self.countries]
 
-	def createSmashCountry(self, name=None, order=0):
-		if name is None:
-			name = self.fake.word(ext_word_list=self.countries)
-		country, _ = Country.objects.update_or_create(name=name, order=order)
-		self.alreadyCreatedCountries[name] = country
-		return country
-
-	def createSmashScreeningNumber(self, prefix):
-		self.screening_number_ctrs[prefix]+=1
-		return '{}-{:03}'.format(prefix, self.screening_number_ctrs[prefix])
-
-	#subject
-	def createSmashStudySubjects(self, n=30):
-		'''
-		Returns a list of tuples (subject, study_subject)
-		'''
-		study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
-		return [self.createSmashStudySubject(study=study) for _ in xrange(n)]
-
-	def createSmashStudySubject(self, nd_number=None, subject=None, study=None, postponed=None,
-		datetime_contact_reminder=None, type=None, default_location=None, flying_team=None,
-		screening_number=None): # complete code and args...
-
-		if nd_number is None:
-			nd_number = 'nd{:05}'.format(self.nd_number_ctr)
-			self.nd_number_ctr+=1
-
-		if subject is None:
-			subject = self.createSmashSubject()
-
-		if study is None:
-			study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
-
-		if type is None:
-			type = choice([SUBJECT_TYPE_CHOICES_CONTROL, SUBJECT_TYPE_CHOICES_PATIENT], 1, p=[0.2, 0.8])
-			type = type[0]
-
-		if default_location is None:
-			default_location = self.getAlreadyCreatedSmashLocation()
-
-		if screening_number is None:
-			screening_number = self.createSmashScreeningNumber(default_location.prefix)
-
-		study_subject, _ = StudySubject.objects.update_or_create(subject=subject, 
-			defaults={'default_location':default_location, 'type':type, 
-			'screening_number': screening_number, 'study':study})
-
-		self.alreadyCreatedStudySubjects.append(study_subject)
-
-		return study_subject
-
-	def createSmashSubject(self, first_name=None, last_name=None, languages=None, 
-		default_written_communication_language=None, phone_number=None, social_security_number=None,
-		sex=None, country_id=None, date_born=None, address=None,
-		postal_code=None, city=None, country=None, dead=None):
-
-		if first_name is None:
-			first_name = self.fake.first_name()
-
-		if last_name is None:
-			last_name  = self.fake.last_name()
-
-		if languages is None:
-			languages = self.getAlreadyCreatedSmashLanguages()
-
-		if default_written_communication_language is None:
-			getAlreadyCreatedSmashLanguages = languages[0]
-
-		if phone_number is None:
-			phone_number = self.fake.phone_number()
-
-		if social_security_number is None:
-			social_security_number = self.fake.ean(length=8)
-
-		if sex is None:
-			sex = self.fake.word(ext_word_list=[SEX_CHOICES_MALE, SEX_CHOICES_FEMALE])
-
-		if country_id is None:
-			country_id = COUNTRY_AFGHANISTAN_ID
-
-		if date_born is None:
-			date_born = self.fake.date_of_birth(minimum_age=50, maximum_age=105).strftime('%Y-%m-%d')
-		if address is None:
-			address = self.fake.address()
-		if postal_code is None:
-			postal_code = self.fake.postcode()
-		if city is None:
-			city = self.fake.word(ext_word_list=self.cities)
-		if country is None:
-			country = self.getAlreadyCreatedSmashCountry()
-		if dead is None:
-			dead = self.fake.boolean(chance_of_getting_true=1)
-
-		dicc = {'first_name': first_name, 'last_name': last_name,
-		'default_written_communication_language': default_written_communication_language, 
-		'phone_number': phone_number, 'social_security_number': social_security_number,
-		'sex': sex, 'country_id': country_id, 'date_born': date_born, 'address': address, 
-		'postal_code': postal_code, 'city': city, 'country': country, 'dead': dead}
-
-		subject, _ = Subject.objects.update_or_create(**dicc)
-		subject.languages.set(languages)
-		subject.save()
-
-		self.alreadyCreatedSubjects.append(subject)
-
-		return subject
-
-	#user
-	def createSmashUser(self, username=None, email=None, password='smashtest007'):
-		'''
-		username: string: Sets the username. By default None. Random values are generated unless other value is provided.
-		email: string: Sets the email. By default None. Random values are generated unless other value is provided.
-		password: string: Sets the password. By default password1234 unless other value is provided.
-		Returns a user
-		'''
-		first_name = self.fake.first_name().lower()
-		last_name  = self.fake.last_name().lower()
-		if username is None:
-			username = u'{}_{}'.format(first_name, last_name)
-		username = unidecode.unidecode(username).lower().replace(' ', '_')
-
-		if email is None:
-			email = u'{}.{}@smash.lu'.format(first_name, last_name)
-		email = unidecode.unidecode(email)
-		#create user
-		defaults = {'email':email, 'password': password}
-		user, _ = User.objects.update_or_create(username=username, defaults=defaults)
-		user.set_password(password)
-		user.save()
-		return user
-
-	#worker
-	def createSmashWorkers(self, n=10):
-		'''
-		:n int: number of workers to create
-		
-		Returns a list of tuples (user, worker, workerStuyRole)
-		'''
-		logger.info('creating Smash Worker...')
-		return [self.createSmashWorker() for _ in xrange(n)]
-
-	def createSmashWorker(self, first_name=None, last_name=None, username=None, email=None, 
-		specialization=None, unit=None, phone_number=None, password='password1234', role=None,
-		locations=None, languages=None):
-		'''
-		first_name: string: Sets the first_name. By default None. Random values are generated. Provide a value to overwrite random generation
-		last_name: string: Sets the last_name. By default None. Random values are generated. Provide a value to overwrite random generation
-		username: string: Sets the username. By default None. Random values are generated. Provide a value to overwrite random generation
-		email: string: Sets the email. By default None. Random values are generated. Provide a value to overwrite random generation
-		specialization: string: Sets the specialization. By default None. Random values are generated. Provide a value to overwrite random generation
-		unit: string: Sets the unit. By default None. Random values are generated. Provide a value to overwrite random generation
-		phone_number: string: Sets the phone_number. By default None. Random values are generated. Provide a value to overwrite random generation
-		password: string: Sets the password. By default None. Random values are generated. Provide a value to overwrite random generation
-		role: string: Sets the role. By default None. Random values are generated. Provide a value to overwrite random generation
-		locations: list: Sets the worker locations. By default None. Random values are generated. Provide a value to overwrite random generation
-		languages: list: Sets the worker languages. By default None. Random values are generated. Provide a value to overwrite random generation
-		Returns a tuple with (user, worker, workerStuyRole)
-		'''
-		if first_name is None:
-			first_name = self.fake.first_name()
-
-		if last_name is None:
-			last_name  = self.fake.last_name()
-
-		if username is None:
-			username = u'{}_{}'.format(first_name, last_name).lower().replace(' ', '_')
-
-		if email is None:
-			email = u'{}.{}@smash.lu'.format(first_name, last_name)
-
-		if specialization is None:
-			specialization = self.getSmashSpecialization()
-
-		if unit is None:
-			unit = self.getSmashUnit()
-
-		if phone_number is None:
-			phone_number = self.fake.phone_number()
-
-		if role is None:
-			role = self.getWorkerRole()
-
-		#create user
-		user = self.createSmashUser(username=username, email=email, password=password)
-
-		#create worker
-		defaults = {'first_name': first_name, 'last_name': last_name, 
-		'email': email, 'unit':unit, 'specialization': specialization,
-		'phone_number': phone_number, 'user': user}
-		worker, _ = Worker.objects.update_or_create(first_name=first_name, 
-			last_name=last_name, defaults=defaults)
-
-		if locations is None:
-			locations = [self.getAlreadyCreatedSmashLocation()]
-		worker.locations.set(locations)
-		if languages is None:
-			languages = self.getAlreadyCreatedSmashLanguages()
-		worker.languages.set(languages)
-		worker.save()
-
-		self.alreadyCreatedWorkers.append(worker)
-
-		#create workerStudyRole
-		workerStudyRole, _ = WorkerStudyRole.objects.update_or_create(worker=worker, 
-			study_id=GLOBAL_STUDY_ID, role=role)
-
-	#unit
-	def getSmashUnit(self):
-		return self.fake.word(ext_word_list=self.units)
-
-	#specialization
-	def getSmashSpecialization(self):
-		return self.fake.word(ext_word_list=self.specialists)
-
-	#languages
-	def createSmashLanguages(self):
-		'''
-		Returns a list of Language objects
-		'''
-		logger.info('creating Smash Languages...')
-		return [self.createSmashLanguage(name=name) for name in self.languages]
-
-	def createSmashLanguage(self, name=None, locale=None):
-		'''
-		Returns a Language object
-		'''
-		if name is None:
-			name = self.fake.word(ext_word_list=self.languages)
-
-		if locale is None:
-			if name in self.language_locale:
-				locale = self.language_locale[name]
-			else:
-				locale = DEFAULT_LOCALE_NAME
-
-		language, _ = Language.objects.update_or_create(name=name, locale=locale)
-		self.alreadyCreatedLanguages[name] = language
-
-		if name in self.language_flags:
-			src = os.path.join(self.language_base_dir, self.language_flags[name])
-			basename = os.path.basename(src)
-			dst = os.path.join(MEDIA_ROOT, basename)
-			copyfile(src, dst)
-			language.image = basename #.save(basename, File(open(dst, 'rb'))) #SimpleUploadedFile(name=path, content=open(path, 'rb').read(), content_type='image/png')
-			language.save()
-
-		return language
-
-	def getAlreadyCreatedSmashLanguages(self, max_n=3):
-		'''
-		Returns a list of Languages from the already created languages, 
-		if no languages are created, then the list is generated.
-
-		max_n: int: maximum number of languages to return
-
-		Returns a list of Language objects.
-		'''
-		if len(self.alreadyCreatedLanguages.keys()) == 0:
-			self.createSmashLanguages()
-
-		languages = choice(self.languages, max_n, p=self.languages_prob)
-		keys = set(languages) #unique
-		return [self.alreadyCreatedLanguages[key] for key in keys]
+class smashProvider(BaseProvider):
 
-	#locations
-	def getAlreadyCreatedSmashLocation(self):
-		return self.random_element(self.alreadyCreatedLocations.values())
+    __provider__ = 'smash'
+    __lang__ = 'fr_FR'
+    fake = Faker()
+    fake.seed(4321)
+
+    specialists = ['Psychiatrist', 'Radiologist', 'Immunologist', 'Anesthesiologist',
+                   'Surgeon', 'Pediatrician', 'Neurologist', 'Medical examiner']
+    units = ['LHI', 'PCR', 'LCSB', 'ACO', 'PLI', 'LRSU']
+    workerRoles = [ROLE_CHOICES_PROJECT_MANAGER, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_DOCTOR,
+                   ROLE_CHOICES_TECHNICIAN, ROLE_CHOICES_PSYCHOLOGIST, ROLE_CHOICES_NURSE]
+
+    #towns and cities
+    near_fr_towns = ['Metz', 'Audun-le-Tiche', 'Thionville']
+    near_de_towns = ['Trier']
+    near_be_towns = ['Aubange', 'Arlon']
+    luxtowns = ['Luxembourg City', 'Esch-sur-Alzette', 'Differdange', 'Dudelange', 'Ettelbruck',
+                'Diekirch', 'Wiltz', 'Rumelange', 'Echternach', 'Grevenmacher', 'Remich', 'Vianden']
+
+    # if you add or remove cities, be careful and change the probabilities as well
+    # here the probs ensure the luxembourgish towns have 0.8 prob, and so on...
+    cities = luxtowns + near_fr_towns + near_de_towns + near_be_towns
+    city_prob = [0.8 / len(luxtowns)]      * len(luxtowns) + \
+        [0.1 / len(near_fr_towns)] * len(near_fr_towns) + \
+        [0.05 / len(near_de_towns)] * len(near_de_towns) + \
+        [0.05 / len(near_be_towns)] * len(near_be_towns)
+
+    alreadyCreatedLocations = {}
+    # languages
+    language_base_dir = 'web/static/flags/'
+    language_flags = {
+        'French': 'FR.png',
+        'English': 'GB.png',
+        'Spanish': 'ES.png',
+        'Portuguese': 'PT.png',
+        'Luxembourgish': 'LU.png',
+        'German': 'DE.png',
+        'Dutch': 'NL.png'
+    }
+    language_locale = {
+        'French': 'fr_FR',
+        'Luxembourgish': 'lb_LU',
+        'Spanish': 'es_ES',
+        'English': 'en_GB',
+        'Portuguese': 'pt_PT',
+        'German': 'de_DE',
+        'Dutch': 'nl_NL'
+    }
+    languages = ['English', 'Luxembourgish', 'French',
+                 'German', 'Portuguese', 'Spanish', 'Dutch']
+    languages_prob = [0.25, 0.2, 0.16, 0.16, 0.13, 0.05, 0.05]
+    alreadyCreatedLanguages = {}
+    # items
+    items = ['Saliva', 'Blood', 'Liquid Biopsy',
+             'X-Ray Examination', 'Urine', 'Tissue Biopsy', 'Skin sample']
+    alreadyCreatedItems = {}
+    # flying teams
+    places = ['Belval', 'Belvaux', 'Arlon', 'Metz']
+    alreadyCreatedFlyingTeams = {}
+    # countries
+    countries = ['France', 'Luxembourg', 'Germamny', 'Belgium']
+    alreadyCreatedCountries = {}
+    # screening number
+    screening_number_ctrs = defaultdict(int)
+    # template file
+    template_file = get_resource_path('upcoming_appointment_FR.docx')
+    template_context = [MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VOUCHER,
+                        MAIL_TEMPLATE_CONTEXT_VISIT, MAIL_TEMPLATE_CONTEXT_SUBJECT]
+    # subjects
+    alreadyCreatedSubjects = []
+    alreadyCreatedStudySubjects = []
+    # appointment type
+    alreadyCreatedAppointmentTypes = []
+    # workers
+    alreadyCreatedWorkers = []
+    # rooms
+    alreadyCreatedRooms = []
+    # nd_number_ctr
+    nd_number_ctr = 0
+
+    def getLuxembourgTown(self):
+        return self.fake.word(ext_word_list=self.luxtowns)
+
+    def getFrenchTown(self):
+        return self.fake.word(ext_word_list=self.near_fr_towns)
+
+    def getBelgiumTown(self):
+        return self.fake.word(ext_word_list=self.near_be_towns)
+
+    def getDeutschTown(self):
+        return self.fake.word(ext_word_list=self.near_de_towns)
+
+    def getWorkerRole(self):
+        return self.fake.word(ext_word_list=self.workerRoles)
+
+    # availability
+    def createSmashAvailabilities(self):
+        for worker in self.alreadyCreatedWorkers:
+            for weekday in set(choice(range(1, 6), 4)):
+                availability = self.createSmashAvailability(
+                    worker=worker, day_number=weekday)
+
+    def createSmashAvailability(self, worker=None, day_number=None, available_from=None, available_till=None):
+        if worker is None:
+            worker = choice(self.alreadyCreatedWorkers)
+        if day_number is None:
+            day_number = choice(range(1, 6))
+        if available_from is None:
+            available_from = '{}:00'.format(choice(range(8, 10)))
+        if available_till is None:
+            available_till = '{}:00'.format(choice(range(13, 18)))
+
+        availability, _ = Availability.objects.update_or_create(person=worker,
+                                                                day_number=day_number,
+                                                                available_from=available_from,
+                                                                available_till=available_till)
+        return availability
+
+    # appointments
+    def createSmashAppointments(self):
+        today = timezone.now()
+        # create first visit, in between -2y and -1y from now and first
+        # appointment
+        for studySubject in self.alreadyCreatedStudySubjects:
+            # date_between does not support months so we use days
+            visit_start_date = fake.date_between(
+                start_date='-1y', end_date='-334d') - datetime.timedelta(days=-31)
+            visit_end_date = visit_start_date + datetime.timedelta(days=31)
+            visit = self.createSmashVisit(studySubject=studySubject, datetime_begin=visit_start_date,
+                                          datetime_end=visit_end_date, is_finished=True)
+            appointment_types = self.getAlreadyCreatedAppointmentTypes()
+            visit.appointment_types.set(appointment_types)
+            # appointment
+            duration = sum([app.default_duration for app in appointment_types])
+            appointment_start_date = fake.date_time_between(start_date=visit_start_date, end_date=visit_end_date,
+                                                            tzinfo=today.tzinfo)
+            hour = choice(range(9, 18))
+            minute = choice(range(0, 30, 5))
+            # ensure the time is between office hours
+            appointment_start_date = appointment_start_date.replace(
+                hour=hour, minute=minute, tzinfo=today.tzinfo)
+
+            room = choice(self.alreadyCreatedRooms)
+            appointment = self.createSmashAppointment(visit=visit, datetime_when=appointment_start_date,
+                                                      length=duration, appointment_types=appointment_types, room=room, status=Appointment.APPOINTMENT_STATUS_FINISHED)
+
+    def createSmashAppointment(self, visit=None, datetime_when=None, location=None, length=30,
+                               status=Appointment.APPOINTMENT_STATUS_SCHEDULED, appointment_types=None, room=None, worker_assigned=None):
+        if visit is None:
+            visit = self.createSmashVisit()
+        if datetime_when is None:
+            datetime_when = get_today_midnight_date()
+        if location is None:
+            location = self.getAlreadyCreatedSmashLocation()
+        if room is None:
+            room = choice(self.alreadyCreatedRooms)
+        if worker_assigned is None:
+            worker_assigned = choice(self.alreadyCreatedWorkers)
+
+        appointment, _ = Appointment.objects.update_or_create(
+            visit=visit, length=length, location=location, worker_assigned=worker_assigned,
+            status=status, datetime_when=datetime_when, room=room)
+
+        if appointment_types is None:
+            appointment_types = self.getAlreadyCreatedAppointmentTypes()
+
+        # create connection for each appointment type
+        when = datetime_when
+        for appointment_type in appointment_types:
+            worker = choice(self.alreadyCreatedWorkers)
+            when = when + \
+                datetime.timedelta(minutes=appointment_type.default_duration)
+            app_type_link = AppointmentTypeLink(appointment=appointment, date_when=when,
+                                                appointment_type=appointment_type, worker=worker)
+
+        return appointment
+
+    # visit
+    def createSmashVisit(self, datetime_begin=None, datetime_end=None, studySubject=None, is_finished=False, visit_number=1):
+        if datetime_begin is None:
+            datetime_begin = get_today_midnight_date() + datetime.timedelta(days=-31)
+        if datetime_end is None:
+            datetime_end = get_today_midnight_date() + datetime.timedelta(days=31)
+        if studySubject is None:
+            studySubject = choice(self.alreadyCreatedStudySubjects)
+
+        visit, _ = Visit.objects.update_or_create(datetime_begin=datetime_begin, datetime_end=datetime_end,
+                                                  subject=studySubject, is_finished=is_finished, visit_number=visit_number)
+        return visit
+
+    # AppointmentTypes
+    def getAlreadyCreatedAppointmentTypes(self, n=3):
+        return set(choice(self.alreadyCreatedAppointmentTypes, n))
+
+    def createSmashAppointmentTypes(self, n_max=5):
+        return [self.createSmashAppointmentType() for _ in xrange(n_max)]
+
+    def createSmashAppointmentType(self, code=None, default_duration=10, rest_time=5, description=None):
+        if code is None:
+            code = self.fake.word(ext_word_list=['C', 'A', 'N', 'P'])
+        if description is None:
+            description = self.fake.word(
+                ext_word_list=['Examination', 'Analysis', 'Questions', 'Test'])
+        equipment = self.getSmashAlreadyCreatedItems()
+        appointmentType, _ = AppointmentType.objects.update_or_create(code=code, rest_time=rest_time,
+                                                                      default_duration=default_duration, description=description)
+
+        appointmentType.required_equipment.set(equipment)
+        appointmentType.required_worker = choice(
+            ['DOCTOR', 'NURSE', 'PSYCHOLOGIST', 'ANY'])
+        appointmentType.save()
+
+        self.alreadyCreatedAppointmentTypes.append(appointmentType)
+
+        return appointmentType
+
+    # mail template
+    def createSmashMailTemplates(self):
+        '''
+        Returns a list of template objects
+        '''
+        languages = self.getAlreadyCreatedSmashLanguages()
+        templates = []
+        for context in self.template_context:
+            for language in languages:
+                template = self.createSmashMailTemplate(
+                    language=language, context=context)
+                templates.append(template)
+        return templates
+
+    def createSmashMailTemplate(self, name=None, language=None, context=MAIL_TEMPLATE_CONTEXT_APPOINTMENT, template_file=None):
+        if language is None:
+            language = self.getAlreadyCreatedSmashLanguages()[0]
+        if name is None:
+            name = '{} Template'.format(language.name)
+        if template_file is None:
+            template_file = self.template_file
+            basename = os.path.basename(template_file)
+            dst = os.path.join(MEDIA_ROOT, basename)
+            copyfile(template_file, dst)
+        template, _ = MailTemplate.objects.update_or_create(
+            name=name, language=language, context=context, template_file=dst)
+        return template
+
+    # flying teams
+    def createSmashFlyingTeams(self):
+        return [self.createSmashFlyingTeam(place=place) for place in self.places]
+
+    def createSmashFlyingTeam(self, place=None):
+        if place is None:
+            place = self.fake.word(ext_word_list=self.places)
+        flying_team, _ = FlyingTeam.objects.update_or_create(place=place)
+
+        self.alreadyCreatedFlyingTeams[place] = flying_team
+
+        return flying_team
+
+    # item
+    def createSmashItems(self):
+        '''
+        Returns a list of Item objects
+        '''
+        return [self.createSmashItem(name=item) for item in self.items]
+
+    def createSmashItem(self, name=None, is_fixed=None, disposable=None):
+        '''
+        Returns an Item object
+        '''
+        if name is None:
+            name = self.fake.word(ext_word_list=self.items)
+
+        if is_fixed is None:
+            is_fixed = self.fake.boolean(chance_of_getting_true=75)
+
+        if disposable is None:
+            disposable = self.fake.boolean(chance_of_getting_true=75)
+
+        item, _ = Item.objects.update_or_create(
+            name=name, is_fixed=is_fixed, disposable=disposable)
+
+        self.alreadyCreatedItems[name] = item
+
+        return item
+
+    def getSmashAlreadyCreatedItems(self, max_n=3):
+        if len(self.alreadyCreatedItems.keys()) == 0:
+            self.createSmashItems()
+
+        keys = set(choice(self.alreadyCreatedItems.keys(), max_n))
+        return [self.alreadyCreatedItems[key] for key in keys]
+
+    # room
+    def createSmashRooms(self, n=4):
+        return [self.createSmashRoom() for _ in xrange(n)]
+
+    def createSmashRoom(self, equipment=None, owner=None, address=None, city=None, room_number=None, floor=None, is_vehicle=None):
+        '''
+        equipment: List of Item objects: 
+        owner: string: 
+        address: string: 
+        city: string: 
+        room_number: int: 
+        floor: int: 
+        is_vehicle: boolean: 
+        '''
+        if equipment is None:
+            item = self.fake.word(
+                ext_word_list=self.alreadyCreatedItems.keys())
+            equipment = self.getSmashAlreadyCreatedItems()
+
+        if owner is None:
+            owner = self.fake.first_name()
+
+        if address is None:
+            address = '{}, {} {}'.format(self.fake.word(
+                ext_word_list=self.cities), self.fake.random_digit_not_null_or_empty(), self.fake.street_name())
+            address = address.replace('\n', ' ')
+
+        if city is None:
+            city = self.fake.word(ext_word_list=self.cities)
+
+        if room_number is None:
+            room_number = choice(range(10), 1)[0]  # choice returns a list
+
+        if floor is None:
+            floor = choice(range(10), 1)[0]
+
+        if is_vehicle is None:
+            is_vehicle = self.fake.boolean(chance_of_getting_true=25)
+
+        dicc = {'owner': owner, 'city': city, 'address': address,
+                'floor': floor, 'room_number': room_number, 'is_vehicle': is_vehicle}
+        room, _ = Room.objects.update_or_create(**dicc)
+        room.equipment.set(equipment)
+        room.save()
 
-	def createSmashLocations(self, n=5):
-		logger.info('creating Smash Locations...')
-		return [self.createSmashLocation() for _ in xrange(n)]
+        self.alreadyCreatedRooms.append(room)
 
-	def createSmashLocation(self, city=None, color=None, prefix=None):
-		if city is None:
-			city = choice(self.cities, 1, p=self.city_prob)[0]
+        return room
 
-		if color is None:
-			color = self.fake.hex_color()
+    # country
+    def getAlreadyCreatedSmashCountry(self):
+        if len(self.alreadyCreatedCountries) == 0:
+            self.createSmashCountries()
+
+        name = self.fake.word(ext_word_list=self.countries)
+        return self.alreadyCreatedCountries[name]
 
-		if prefix is None:
-			prefix = city[:1]
+    def createSmashCountries(self):
+        return [self.createSmashCountry(name=country) for country in self.countries]
+
+    def createSmashCountry(self, name=None, order=0):
+        if name is None:
+            name = self.fake.word(ext_word_list=self.countries)
+        country, _ = Country.objects.update_or_create(name=name, order=order)
+        self.alreadyCreatedCountries[name] = country
+        return country
+
+    def createSmashScreeningNumber(self, prefix):
+        self.screening_number_ctrs[prefix] += 1
+        return '{}-{:03}'.format(prefix, self.screening_number_ctrs[prefix])
 
-		location, _ = Location.objects.update_or_create(name=city, color=color, prefix=prefix)
+    # subject
+    def createSmashStudySubjects(self, n=30):
+        '''
+        Returns a list of tuples (subject, study_subject)
+        '''
+        study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
+        return [self.createSmashStudySubject(study=study) for _ in xrange(n)]
+
+    def createSmashStudySubject(self, nd_number=None, subject=None, study=None, postponed=None,
+                                datetime_contact_reminder=None, type=None, default_location=None, flying_team=None,
+                                screening_number=None):  # complete code and args...
+
+        if nd_number is None:
+            nd_number = 'ND{:04}'.format(self.nd_number_ctr)
+            self.nd_number_ctr += 1
+
+        if subject is None:
+            subject = self.createSmashSubject()
+
+        if study is None:
+            study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
+
+        if type is None:
+            type = choice([SUBJECT_TYPE_CHOICES_CONTROL,
+                           SUBJECT_TYPE_CHOICES_PATIENT], 1, p=[0.2, 0.8])
+            type = type[0]
+
+        if default_location is None:
+            default_location = self.getAlreadyCreatedSmashLocation()
+
+        if screening_number is None:
+            screening_number = self.createSmashScreeningNumber(
+                default_location.prefix)
+
+        study_subject, _ = StudySubject.objects.update_or_create(nd_number=nd_number, subject=subject,
+                                                                 defaults={'default_location': default_location, 'type': type,
+                                                                           'screening_number': screening_number, 'study': study})
+
+        self.alreadyCreatedStudySubjects.append(study_subject)
+
+        return study_subject
+
+    def createSmashSubject(self, first_name=None, last_name=None, languages=None,
+                           default_written_communication_language=None, phone_number=None, social_security_number=None,
+                           sex=None, country_id=None, date_born=None, address=None,
+                           postal_code=None, city=None, country=None, dead=None):
+
+        if first_name is None:
+            first_name = self.fake.first_name()
+
+        if last_name is None:
+            last_name = self.fake.last_name()
+
+        if languages is None:
+            languages = self.getAlreadyCreatedSmashLanguages()
+
+        if default_written_communication_language is None:
+            getAlreadyCreatedSmashLanguages = languages[0]
+
+        if phone_number is None:
+            phone_number = self.fake.phone_number()
+
+        if social_security_number is None:
+            social_security_number = self.fake.ean(length=8)
+
+        if sex is None:
+            sex = self.fake.word(
+                ext_word_list=[SEX_CHOICES_MALE, SEX_CHOICES_FEMALE])
+
+        if country_id is None:
+            country_id = COUNTRY_AFGHANISTAN_ID
+
+        if date_born is None:
+            date_born = self.fake.date_of_birth(
+                minimum_age=50, maximum_age=105).strftime('%Y-%m-%d')
+        if address is None:
+            address = self.fake.address()
+        if postal_code is None:
+            postal_code = self.fake.postcode()
+        if city is None:
+            city = self.fake.word(ext_word_list=self.cities)
+        if country is None:
+            country = self.getAlreadyCreatedSmashCountry()
+        if dead is None:
+            dead = self.fake.boolean(chance_of_getting_true=1)
+
+        dicc = {'first_name': first_name, 'last_name': last_name,
+                'default_written_communication_language': default_written_communication_language,
+                'phone_number': phone_number, 'social_security_number': social_security_number,
+                'sex': sex, 'country_id': country_id, 'date_born': date_born, 'address': address,
+                'postal_code': postal_code, 'city': city, 'country': country, 'dead': dead}
+
+        subject, _ = Subject.objects.update_or_create(**dicc)
+        subject.languages.set(languages)
+        subject.save()
+
+        self.alreadyCreatedSubjects.append(subject)
+
+        return subject
+
+    # user
+    def createSmashUser(self, username=None, email=None, password='smashtest007'):
+        '''
+        username: string: Sets the username. By default None. Random values are generated unless other value is provided.
+        email: string: Sets the email. By default None. Random values are generated unless other value is provided.
+        password: string: Sets the password. By default password1234 unless other value is provided.
+        Returns a user
+        '''
+        first_name = self.fake.first_name().lower()
+        last_name = self.fake.last_name().lower()
+        if username is None:
+            username = u'{}_{}'.format(first_name, last_name)
+        username = unidecode.unidecode(username).lower().replace(' ', '_')
+
+        if email is None:
+            email = u'{}.{}@smash.lu'.format(first_name, last_name)
+        email = unidecode.unidecode(email)
+        # create user
+        defaults = {'email': email, 'password': password}
+        user, _ = User.objects.update_or_create(
+            username=username, defaults=defaults)
+        user.set_password(password)
+        user.save()
+        return user
+
+    # worker
+    def createSmashWorkers(self, n=10):
+        '''
+        :n int: number of workers to create
+
+        Returns a list of tuples (user, worker, workerStuyRole)
+        '''
+        logger.info('creating Smash Worker...')
+        return [self.createSmashWorker() for _ in xrange(n)]
+
+    def createSmashWorker(self, first_name=None, last_name=None, username=None, email=None,
+                          specialization=None, unit=None, phone_number=None, password='password1234', role=None,
+                          locations=None, languages=None):
+        '''
+        first_name: string: Sets the first_name. By default None. Random values are generated. Provide a value to overwrite random generation
+        last_name: string: Sets the last_name. By default None. Random values are generated. Provide a value to overwrite random generation
+        username: string: Sets the username. By default None. Random values are generated. Provide a value to overwrite random generation
+        email: string: Sets the email. By default None. Random values are generated. Provide a value to overwrite random generation
+        specialization: string: Sets the specialization. By default None. Random values are generated. Provide a value to overwrite random generation
+        unit: string: Sets the unit. By default None. Random values are generated. Provide a value to overwrite random generation
+        phone_number: string: Sets the phone_number. By default None. Random values are generated. Provide a value to overwrite random generation
+        password: string: Sets the password. By default None. Random values are generated. Provide a value to overwrite random generation
+        role: string: Sets the role. By default None. Random values are generated. Provide a value to overwrite random generation
+        locations: list: Sets the worker locations. By default None. Random values are generated. Provide a value to overwrite random generation
+        languages: list: Sets the worker languages. By default None. Random values are generated. Provide a value to overwrite random generation
+        Returns a tuple with (user, worker, workerStuyRole)
+        '''
+        if first_name is None:
+            first_name = self.fake.first_name()
+
+        if last_name is None:
+            last_name = self.fake.last_name()
+
+        if username is None:
+            username = u'{}_{}'.format(
+                first_name, last_name).lower().replace(' ', '_')
+
+        if email is None:
+            email = u'{}.{}@smash.lu'.format(first_name, last_name)
+
+        if specialization is None:
+            specialization = self.getSmashSpecialization()
+
+        if unit is None:
+            unit = self.getSmashUnit()
+
+        if phone_number is None:
+            phone_number = self.fake.phone_number()
+
+        if role is None:
+            role = self.getWorkerRole()
+
+        # create user
+        user = self.createSmashUser(
+            username=username, email=email, password=password)
+
+        # create worker
+        defaults = {'first_name': first_name, 'last_name': last_name,
+                    'email': email, 'unit': unit, 'specialization': specialization,
+                    'phone_number': phone_number, 'user': user}
+        worker, _ = Worker.objects.update_or_create(first_name=first_name,
+                                                    last_name=last_name, defaults=defaults)
+
+        if locations is None:
+            locations = [self.getAlreadyCreatedSmashLocation()]
+        worker.locations.set(locations)
+        if languages is None:
+            languages = self.getAlreadyCreatedSmashLanguages()
+        worker.languages.set(languages)
+        worker.save()
+
+        self.alreadyCreatedWorkers.append(worker)
+
+        # create workerStudyRole
+        workerStudyRole, _ = WorkerStudyRole.objects.update_or_create(worker=worker,
+                                                                      study_id=GLOBAL_STUDY_ID, role=role)
+
+    # unit
+    def getSmashUnit(self):
+        return self.fake.word(ext_word_list=self.units)
+
+    # specialization
+    def getSmashSpecialization(self):
+        return self.fake.word(ext_word_list=self.specialists)
+
+    # languages
+    def createSmashLanguages(self):
+        '''
+        Returns a list of Language objects
+        '''
+        logger.info('creating Smash Languages...')
+        return [self.createSmashLanguage(name=name) for name in self.languages]
+
+    def createSmashLanguage(self, name=None, locale=None):
+        '''
+        Returns a Language object
+        '''
+        if name is None:
+            name = self.fake.word(ext_word_list=self.languages)
+
+        if locale is None:
+            if name in self.language_locale:
+                locale = self.language_locale[name]
+            else:
+                locale = DEFAULT_LOCALE_NAME
+
+        language, _ = Language.objects.update_or_create(
+            name=name, locale=locale)
+        self.alreadyCreatedLanguages[name] = language
+
+        if name in self.language_flags:
+            src = os.path.join(self.language_base_dir,
+                               self.language_flags[name])
+            basename = os.path.basename(src)
+            dst = os.path.join(MEDIA_ROOT, basename)
+            copyfile(src, dst)
+            # .save(basename, File(open(dst, 'rb'))) #SimpleUploadedFile(name=path, content=open(path, 'rb').read(), content_type='image/png')
+            language.image = basename
+            language.save()
+
+        return language
+
+    def getAlreadyCreatedSmashLanguages(self, max_n=3):
+        '''
+        Returns a list of Languages from the already created languages, 
+        if no languages are created, then the list is generated.
 
-		self.alreadyCreatedLocations[city] = location
-
-		return location
+        max_n: int: maximum number of languages to return
 
-	def getAllCreatedLocations(self):
-		return self.alreadyCreatedLocations.values()
+        Returns a list of Language objects.
+        '''
+        if len(self.alreadyCreatedLanguages.keys()) == 0:
+            self.createSmashLanguages()
+
+        languages = choice(self.languages, max_n, p=self.languages_prob)
+        keys = set(languages)  # unique
+        return [self.alreadyCreatedLanguages[key] for key in keys]
+
+    # locations
+    def getAlreadyCreatedSmashLocation(self):
+        return self.random_element(self.alreadyCreatedLocations.values())
+
+    def createSmashLocations(self, n=5):
+        logger.info('creating Smash Locations...')
+        return [self.createSmashLocation() for _ in xrange(n)]
+
+    def createSmashLocation(self, city=None, color=None, prefix=None):
+        if city is None:
+            city = choice(self.cities, 1, p=self.city_prob)[0]
+
+        if color is None:
+            color = self.fake.hex_color()
+
+        if prefix is None:
+            prefix = city[:1]
+
+        location, _ = Location.objects.update_or_create(
+            name=city, color=color, prefix=prefix)
+
+        self.alreadyCreatedLocations[city] = location
+
+        return location
 
-	def getAllCreatedLanguages(self):
-		return self.alreadyCreatedLanguages.values()
+    def getAllCreatedLocations(self):
+        return self.alreadyCreatedLocations.values()
+
+    def getAllCreatedLanguages(self):
+        return self.alreadyCreatedLanguages.values()
 
 if __name__ == "__main__":
-	if not os.path.exists(MEDIA_ROOT):
-		os.makedirs(MEDIA_ROOT)
-	fake = Faker()
-	fake.seed(4321)
-	fake.add_provider(smashProvider)
-	fake.createSmashFlyingTeams()
-	fake.createSmashItems()
-	fake.createSmashAppointmentTypes()
-	fake.createSmashRooms()
-	fake.createSmashLocations()
-	fake.createSmashLanguages()
-	fake.createSmashMailTemplates()
-	fake.createSmashCountries()
-
-	fake.createSmashWorkers()
-	fake.createSmashAvailabilities()
-	fake.createSmashStudySubjects()
-	fake.createSmashAppointments()
-	fake.createSmashWorker(first_name=u'System', last_name=u'Admin', 
-		email=u'carlos.vega@uni.lu', role=ROLE_CHOICES_TECHNICIAN, password='smashtest007',
-		locations=fake.getAllCreatedLocations(), languages=fake.getAllCreatedLanguages())
\ No newline at end of file
+    if not os.path.exists(MEDIA_ROOT):
+        os.makedirs(MEDIA_ROOT)
+    fake = Faker()
+    fake.seed(4321)
+    fake.add_provider(smashProvider)
+    fake.createSmashFlyingTeams()
+    fake.createSmashItems()
+    fake.createSmashAppointmentTypes()
+    fake.createSmashRooms()
+    fake.createSmashLocations()
+    fake.createSmashLanguages()
+    fake.createSmashMailTemplates()
+    fake.createSmashCountries()
+
+    fake.createSmashWorkers()
+    fake.createSmashAvailabilities()
+    fake.createSmashStudySubjects()
+    fake.createSmashAppointments()
+    fake.createSmashWorker(first_name=u'System', last_name=u'Admin',
+                           email=u'carlos.vega@uni.lu', role=ROLE_CHOICES_TECHNICIAN, password='smashtest007',
+                           locations=fake.getAllCreatedLocations(), languages=fake.getAllCreatedLanguages())
-- 
GitLab