diff --git a/smash/smash/settings.py b/smash/smash/settings.py
index 7cd843ec0ac63af7806278d35bb724be47864c62..b443f11026c2192d8bcfe0138e6027aed8272d5a 100644
--- a/smash/smash/settings.py
+++ b/smash/smash/settings.py
@@ -76,7 +76,8 @@ CRON_CLASSES = [
     'web.views.kit.KitRequestEmailSendJob',
     'web.redcap_connector.RedCapRefreshJob',
     'web.views.voucher.ExpireVouchersJob',
-    'web.importer.exporter_cron_job.ExporterCronJob',
+    'web.importer.exporter_cron_job.SubjectExporterCronJob',
+    'web.importer.exporter_cron_job.VisitExporterCronJob',
     'web.importer.importer_cron_job.SubjectImporterCronJob',
     'web.importer.importer_cron_job.VisitImporterCronJob'
 ]
diff --git a/smash/web/importer/__init__.py b/smash/web/importer/__init__.py
index f60887a0d48238dced793d829f0dd82eaabb9cb8..7740b827d19252769483d1a62ee8e8be2c9648d5 100644
--- a/smash/web/importer/__init__.py
+++ b/smash/web/importer/__init__.py
@@ -1,12 +1,13 @@
 from csv_subject_import_reader import CsvSubjectImportReader
 from csv_tns_subject_import_reader import TnsCsvSubjectImportReader
 from csv_tns_visit_import_reader import TnsCsvVisitImportReader
-from exporter import Exporter
-from exporter_cron_job import ExporterCronJob
+from exporter import SubjectExporter, VisitExporter
+from exporter_cron_job import SubjectExporterCronJob, VisitExporterCronJob
 from importer import Importer
 from importer_cron_job import SubjectImporterCronJob, VisitImporterCronJob
 from subject_import_reader import SubjectImportReader
 from warning_counter import MsgCounterHandler
 
 __all__ = [Importer, SubjectImportReader, CsvSubjectImportReader, SubjectImporterCronJob, VisitImporterCronJob,
-           Exporter, ExporterCronJob, TnsCsvSubjectImportReader, TnsCsvVisitImportReader, MsgCounterHandler]
+           SubjectExporter, VisitExporter, SubjectExporterCronJob, VisitExporterCronJob, TnsCsvSubjectImportReader,
+           TnsCsvVisitImportReader, MsgCounterHandler]
diff --git a/smash/web/importer/csv_tns_visit_import_reader.py b/smash/web/importer/csv_tns_visit_import_reader.py
index c8b46e742fdba3f74483e5293d6245baa23659bb..9032daf276924f715ec5692f904225ac2853d19f 100644
--- a/smash/web/importer/csv_tns_visit_import_reader.py
+++ b/smash/web/importer/csv_tns_visit_import_reader.py
@@ -1,10 +1,10 @@
 # coding=utf-8
+import codecs
 import csv
 import datetime
 import logging
 import sys
 import traceback
-import codecs
 
 import pytz
 from django.conf import settings
@@ -100,9 +100,9 @@ class TnsCsvVisitImportReader:
                     else:
                         appointment = Appointment.objects.create(visit=visit, length=60, datetime_when=date,
                                                                  location=location)
-                    if self.appointment_type is not None:
-                        AppointmentTypeLink.objects.create(appointment_id=appointment.id,
-                                                           appointment_type=self.appointment_type)
+                        if self.appointment_type is not None:
+                            AppointmentTypeLink.objects.create(appointment_id=appointment.id,
+                                                               appointment_type=self.appointment_type)
                     self.processed_count += 1
                 except:
                     self.problematic_count += 1
diff --git a/smash/web/importer/exporter.py b/smash/web/importer/exporter.py
index ebdf57df450478390716dc09161814b57f30c882..6c44efbc7b3478f22f9e89830b88dcf010cf50ee 100644
--- a/smash/web/importer/exporter.py
+++ b/smash/web/importer/exporter.py
@@ -1,14 +1,16 @@
 # coding=utf-8
 import csv
 import logging
+import sys
+import traceback
 
 from warning_counter import MsgCounterHandler
-from web.models import StudySubject
+from web.models import StudySubject, Appointment
 
 logger = logging.getLogger(__name__)
 
 
-class Exporter(object):
+class SubjectExporter(object):
     def __init__(self, filename):
         # type: (str) -> None
         self.filename = filename
@@ -48,3 +50,50 @@ class Exporter(object):
         for study_subject in study_subjects:
             result.append([study_subject.nd_number])
         return result
+
+
+class VisitExporter(object):
+    def __init__(self, filename):
+        # type: (str) -> None
+        self.filename = filename
+        self.exported_count = 0
+        self.warning_count = 0
+
+    def execute(self):
+        self.exported_count = 0
+        self.warning_count = 0
+
+        warning_counter = MsgCounterHandler()
+        logging.getLogger('').addHandler(warning_counter)
+
+        with open(self.filename, 'w') as csv_file:
+            data = self.get_appointments_as_array()
+            writer = csv.writer(csv_file, quotechar=str(u'"'))
+            for row in data:
+                writer.writerow([s.encode("utf-8") for s in row])
+                self.exported_count += 1
+
+        if "WARNING" in warning_counter.level2count:
+            self.warning_count = warning_counter.level2count["WARNING"]
+        logging.getLogger('').removeHandler(warning_counter)
+
+    def get_summary(self):
+        result = "<p>Number of entries: <b>" + str(self.exported_count) + "</b></p>"
+        style = ''
+        if self.warning_count > 0:
+            style = ' color="brown" '
+        result += "<p><font " + style + ">Number of raised warnings: <b>" + str(self.warning_count) + "</b></font></p>"
+
+        return result
+
+    def get_appointments_as_array(self):
+        result = []
+        appointments = Appointment.objects.filter(status=Appointment.APPOINTMENT_STATUS_FINISHED)
+        for appointment in appointments:
+            try:
+                if appointment.visit is not None:
+                    result.append([appointment.visit.subject.nd_number, str(appointment.visit.visit_number - 1)])
+            except:
+                traceback.print_exc(file=sys.stdout)
+                logger.warn("Problem with exporting appointment: " + str(appointment.id))
+        return result
diff --git a/smash/web/importer/exporter_cron_job.py b/smash/web/importer/exporter_cron_job.py
index 8ea234262ecb5c312a78a33316f35345d902843b..6491077e57dbf4b7b371f7dba78787c04e3a34f5 100644
--- a/smash/web/importer/exporter_cron_job.py
+++ b/smash/web/importer/exporter_cron_job.py
@@ -6,21 +6,21 @@ import timeout_decorator
 from django.conf import settings
 from django_cron import CronJobBase, Schedule
 
-from exporter import Exporter
+from exporter import SubjectExporter, VisitExporter
 from web.models.constants import CRON_JOB_TIMEOUT
 from ..smash_email import EmailSender
 
 logger = logging.getLogger(__name__)
 
 
-class ExporterCronJob(CronJobBase):
+class SubjectExporterCronJob(CronJobBase):
     RUN_AT_TIMES = getattr(settings, "EXPORT_RUN_AT", ['23:55'])
     schedule = Schedule(run_at_times=RUN_AT_TIMES)
-    code = 'web.import_daily_job'  # a unique code
+    code = 'web.export_subject_daily_job'  # a unique code
 
     @timeout_decorator.timeout(CRON_JOB_TIMEOUT)
     def do(self):
-        email_title = "Daily export"
+        email_title = "Daily subject export"
         email_recipients = getattr(settings, "DEFAULT_FROM_EMAIL", None)
 
         filename = getattr(settings, "DAILY_SUBJECT_EXPORT_FILE", None)
@@ -28,9 +28,42 @@ class ExporterCronJob(CronJobBase):
         if filename is None:
             logger.info("Exporting subjects skipped. File not defined ")
             return "export file not defined"
-        logger.info("Exporting subjects from file: " + filename)
+        logger.info("Exporting subjects to file: " + filename)
         try:
-            exporter = Exporter(settings.DAILY_SUBJECT_EXPORT_FILE)
+            exporter = SubjectExporter(filename)
+            exporter.execute()
+            email_body = exporter.get_summary()
+            EmailSender().send_email(email_title,
+                                     "<h3>Data was successfully exported to file: " + filename + "</h3>" + email_body,
+                                     email_recipients)
+            return "export is successful"
+
+        except:
+            tb = traceback.format_exc()
+            EmailSender().send_email(email_title,
+                                     "<h3><font color='red'>There was a problem with exporting data to file: " + filename + "</font></h3><pre>" + tb + "</pre>",
+                                     email_recipients)
+            return "export crashed"
+
+
+class VisitExporterCronJob(CronJobBase):
+    RUN_AT_TIMES = getattr(settings, "EXPORT_RUN_AT", ['23:55'])
+    schedule = Schedule(run_at_times=RUN_AT_TIMES)
+    code = 'web.export_visit_daily_job'  # a unique code
+
+    @timeout_decorator.timeout(CRON_JOB_TIMEOUT)
+    def do(self):
+        email_title = "Daily visit export"
+        email_recipients = getattr(settings, "DEFAULT_FROM_EMAIL", None)
+
+        filename = getattr(settings, "DAILY_VISIT_EXPORT_FILE", None)
+
+        if filename is None:
+            logger.info("Exporting visit skipped. File not defined ")
+            return "export file not defined"
+        logger.info("Exporting visits to file: " + filename)
+        try:
+            exporter = VisitExporter(filename)
             exporter.execute()
             email_body = exporter.get_summary()
             EmailSender().send_email(email_title,
diff --git a/smash/web/tests/importer/test_exporter.py b/smash/web/tests/importer/test_exporter.py
index 3a552443b9ba73818783f213a5af0ced1b50a890..91eb81a9baf7925acd3195231dbdc8a604d57a88 100644
--- a/smash/web/tests/importer/test_exporter.py
+++ b/smash/web/tests/importer/test_exporter.py
@@ -6,7 +6,7 @@ import logging
 from django.test import TestCase
 
 from web.tests.functions import create_study_subject
-from web.importer import Exporter
+from web.importer import SubjectExporter
 from web.models import Subject, StudySubject, Study, Provenance
 from web.models.constants import GLOBAL_STUDY_ID
 
@@ -21,7 +21,7 @@ class TestExporter(TestCase):
     def test_export_not_excluded(self):
         create_study_subject()
 
-        exporter = Exporter(filename="empty.csv")
+        exporter = SubjectExporter(filename="empty.csv")
         exporter.execute()
 
         self.assertEqual(0, exporter.exported_count)
@@ -32,7 +32,7 @@ class TestExporter(TestCase):
         subject.excluded=True
         subject.save()
 
-        exporter = Exporter(filename="empty.csv")
+        exporter = SubjectExporter(filename="empty.csv")
         exporter.execute()
 
         self.assertEqual(1, exporter.exported_count)
diff --git a/smash/web/tests/importer/test_exporter_cron_job.py b/smash/web/tests/importer/test_exporter_cron_job.py
index 95c0925304cec92b2d7dbd3e2c138fac2712caff..7bb15fc9e5924e97912e7a19d65f9e6c1e7dd67a 100644
--- a/smash/web/tests/importer/test_exporter_cron_job.py
+++ b/smash/web/tests/importer/test_exporter_cron_job.py
@@ -6,7 +6,7 @@ import tempfile
 from django.conf import settings
 from django.test import TestCase
 
-from web.importer import ExporterCronJob
+from web.importer import SubjectExporterCronJob
 
 logger = logging.getLogger(__name__)
 from django.core import mail
@@ -24,7 +24,7 @@ class TestCronJobExporter(TestCase):
     def test_import_without_configuration(self):
         CronJobLog.objects.all().delete()
 
-        job = ExporterCronJob()
+        job = SubjectExporterCronJob()
 
         status = job.do()
 
@@ -37,7 +37,7 @@ class TestCronJobExporter(TestCase):
         setattr(settings, "DAILY_SUBJECT_EXPORT_FILE", tmp)
         CronJobLog.objects.all().delete()
 
-        job = ExporterCronJob()
+        job = SubjectExporterCronJob()
 
         status = job.do()
 
diff --git a/smash/web/tests/importer/test_tns_csv_visit_import_reader.py b/smash/web/tests/importer/test_tns_csv_visit_import_reader.py
index f8ee5ce7db59a87c6a50a68b5b37af1efbbad8b5..c154055775a70a2c50451d482cbceaa5eb42fa28 100644
--- a/smash/web/tests/importer/test_tns_csv_visit_import_reader.py
+++ b/smash/web/tests/importer/test_tns_csv_visit_import_reader.py
@@ -151,6 +151,16 @@ class TestTnsCsvVisitReader(TestCase):
 
         self.assertEquals(3, self.get_warnings_count())
 
+    def test_dont_add_links_for_existing_appointments(self):
+        filename = get_resource_path('tns_vouchers_import.csv')
+        TnsCsvVisitImportReader().load_data(filename)
+        links = AppointmentTypeLink.objects.all().count()
+
+        TnsCsvVisitImportReader().load_data(filename)
+        self.assertEquals(links, AppointmentTypeLink.objects.all().count())
+
+        self.assertEquals(0, self.get_warnings_count())
+
     def get_warnings_count(self):
         if "WARNING" in self.warning_counter.level2count:
             return self.warning_counter.level2count["WARNING"]