From 636a941605f3327250555a840fbaf803f502e7b1 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Fri, 17 Apr 2020 09:46:47 +0200
Subject: [PATCH] list of finished appointments is exported

---
 smash/smash/settings.py                 |  3 +-
 smash/web/importer/__init__.py          |  7 ++--
 smash/web/importer/exporter.py          | 53 ++++++++++++++++++++++++-
 smash/web/importer/exporter_cron_job.py | 45 ++++++++++++++++++---
 4 files changed, 96 insertions(+), 12 deletions(-)

diff --git a/smash/smash/settings.py b/smash/smash/settings.py
index 7cd843ec..b443f110 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 f60887a0..7740b827 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/exporter.py b/smash/web/importer/exporter.py
index ebdf57df..6c44efbc 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 8ea23426..6491077e 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,
-- 
GitLab