diff --git a/smash/create_dummy_data.py b/smash/create_dummy_data.py
index 00123ca144d7c33a55e85aa07888b3c8d8fce745..8adbda03fd8d14c3b12fe9f3a665e336dabc4462 100644
--- a/smash/create_dummy_data.py
+++ b/smash/create_dummy_data.py
@@ -1,16 +1,23 @@
 from django.conf import settings
+from django.core.files import File  # you need this somewhere
+import urllib
+from django.core.files.uploadedfile import SimpleUploadedFile
 import django
+import datetime
+from django.utils import timezone
 import os
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smash.settings")
 django.setup()
 from django.contrib.auth.models import User
-from web.models import StudySubject, Availability, Appointment, AppointmentType, Study, Subject, Worker, Location, Language, Country, WorkerStudyRole, Item, FlyingTeam, Room, MailTemplate
+#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
 from web.models.constants import MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VISIT, \
 	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
+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
 
 from collections import defaultdict
@@ -21,7 +28,8 @@ 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 unidecode
+import platform, tempfile, unidecode
+from shutil import copyfile
 
 class smashProvider(BaseProvider):
 
@@ -32,7 +40,7 @@ class smashProvider(BaseProvider):
 
 	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_DOCTOR]
+	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']
@@ -50,7 +58,7 @@ class smashProvider(BaseProvider):
 	
 	alreadyCreatedLocations = {}
 	#languages
-	language_base_dir = './smash/web/static/flags/'
+	language_base_dir = 'web/static/flags/'
 	language_flags = {
 		'French' : 'FR.png',
 		'English': 'GB.png',
@@ -60,11 +68,20 @@ class smashProvider(BaseProvider):
 		'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 = ['Ambulance', 'Bandages', 'Examination Table', 'X-Ray Machine', 'Lab Coat', 'Needle', 'Stretcher', 'Vial', 'Wheelchair']
+	items = ['Saliva', 'Blood', 'Liquid Biopsy', 'X-Ray Examination', 'Urine', 'Tissue Biopsy', 'Skin sample']
 	alreadyCreatedItems = {}
 	#flying teams
 	places = ['Belval', 'Belvaux', 'Arlon', 'Metz']
@@ -84,6 +101,8 @@ class smashProvider(BaseProvider):
 	alreadyCreatedAppointmentTypes = []
 	#workers 
 	alreadyCreatedWorkers = []
+	#rooms
+	alreadyCreatedRooms = []
 
 	def getLuxembourgTown(self):
 		return self.fake.word(ext_word_list=self.luxtowns)
@@ -112,9 +131,9 @@ class smashProvider(BaseProvider):
 		if day_number is None:
 			day_number = choice(range(1,6))
 		if available_from is None:
-			available_from = '8:00'
+			available_from = '{}:00'.format(choice(range(8,10)))
 		if available_till is None:
-			available_till = '18:00'
+			available_till = '{}:00'.format(choice(range(13,18)))
 
 		availability, _ = Availability.objects.update_or_create(person=worker,
 						   day_number=day_number,
@@ -124,44 +143,76 @@ class smashProvider(BaseProvider):
 
 	#appointments
 	def createSmashAppointments(self):
-		for subject in self.alreadyCreatedSubjects:
-			visit = self.createSmashVisit(subject=subject)
-			appointment = self.createSmashAppointment(visit=visit)
-
-	def createSmashAppointment(self, visit=None, datetime_when=None, location=None, length=30, status=Appointment.APPOINTMENT_STATUS_SCHEDULED):
+		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,
-			status=status, datetime_when=datetime_when)
+			visit=visit, length=length, location=location, worker_assigned=worker_assigned,
+			status=status, datetime_when=datetime_when, room=room)
 
-		appointment.types.set(self.getAlreadyCreatedAppointmentTypes())
-		appointment.save()
+		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, subject=None, is_finished=False):
+	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 subject is None:
-			subject = choice(self.alreadyCreatedSubjects, 1)[0]
+		if studySubject is None:
+			studySubject = choice(self.alreadyCreatedStudySubjects)
 
 		visit, _ = Visit.objects.update_or_create(datetime_begin=datetime_begin, datetime_end=datetime_end,
-									   subject=subject, is_finished=is_finished)
+									   subject=studySubject, is_finished=is_finished, visit_number=visit_number)
 		return visit
 
 
 	#AppointmentTypes
 	def getAlreadyCreatedAppointmentTypes(self, n=3):
-		return choice(self.alreadyCreatedAppointmentTypes, n)
+		return set(choice(self.alreadyCreatedAppointmentTypes, n))
 
 	def createSmashAppointmentTypes(self, n_max=5):
 		return [self.createSmashAppointmentType() for _ in xrange(n_max)]
@@ -203,7 +254,10 @@ class smashProvider(BaseProvider):
 			name = '{} Template'.format(language.name)
 		if template_file is None:
 			template_file = self.template_file
-		template, _ = MailTemplate.objects.update_or_create(name=name, language=language, context=context, template_file = 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
@@ -295,6 +349,8 @@ class smashProvider(BaseProvider):
 		room.equipment.set(equipment)
 		room.save()
 
+		self.alreadyCreatedRooms.append(room)
+
 		return room
 
 	#country
@@ -419,11 +475,11 @@ class smashProvider(BaseProvider):
 		password: string: Sets the password. By default password1234 unless other value is provided.
 		Returns a user
 		'''
-		first_name = self.fake.first_name().lower().replace('_', '')
-		last_name  = self.fake.last_name().lower().replace('_', '')
+		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)
+		username = unidecode.unidecode(username).lower().replace(' ', '_')
 
 		if email is None:
 			email = u'{}.{}@smash.lu'.format(first_name, last_name)
@@ -445,7 +501,9 @@ class smashProvider(BaseProvider):
 		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):
+	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
@@ -456,6 +514,8 @@ class smashProvider(BaseProvider):
 		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:
@@ -465,7 +525,7 @@ class smashProvider(BaseProvider):
 			last_name  = self.fake.last_name()
 
 		if username is None:
-			username = u'{}_{}'.format(first_name, last_name)
+			username = u'{}_{}'.format(first_name, last_name).lower().replace(' ', '_')
 
 		if email is None:
 			email = u'{}.{}@smash.lu'.format(first_name, last_name)
@@ -492,8 +552,12 @@ class smashProvider(BaseProvider):
 		worker, _ = Worker.objects.update_or_create(first_name=first_name, 
 			last_name=last_name, defaults=defaults)
 
-		worker.locations.set([self.getAlreadyCreatedSmashLocation()])
-		worker.languages.set(self.getAlreadyCreatedSmashLanguages())
+		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)
@@ -518,15 +582,30 @@ class smashProvider(BaseProvider):
 		logger.info('creating Smash Languages...')
 		return [self.createSmashLanguage(name=name) for name in self.languages]
 
-	def createSmashLanguage(self, name=None, locale=DEFAULT_LOCALE_NAME):
+	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):
@@ -569,11 +648,16 @@ class smashProvider(BaseProvider):
 
 		return location
 
+	def getAllCreatedLocations(self):
+		return self.alreadyCreatedLocations.values()
+
+	def getAllCreatedLanguages(self):
+		return self.alreadyCreatedLanguages.values()
+
 if __name__ == "__main__":
 	fake = Faker()
 	fake.seed(4321)
 	fake.add_provider(smashProvider)
-
 	fake.createSmashFlyingTeams()
 	fake.createSmashItems()
 	fake.createSmashAppointmentTypes()
@@ -586,7 +670,10 @@ if __name__ == "__main__":
 	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,
+		locations=fake.getAllCreatedLocations(), languages=fake.getAllCreatedLanguages())
 	# flying_teams = add_flying_teams()
 	# items = add_items()
 	# add_rooms(items)