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

Merge branch '330-mail-about-virus-test-results' into 'master'

Resolve "mail about virus test results"

Closes #330

See merge request NCER-PD/scheduling-system!245
parents bf4ee83d 20a24be6
No related branches found
No related tags found
1 merge request!245Resolve "mail about virus test results"
Pipeline #25471 passed
......@@ -74,6 +74,7 @@ TEMPLATES = [
CRON_CLASSES = [
'web.views.kit.KitRequestEmailSendJob',
'web.views.virus_mail.KitRequestEmailSendJob',
'web.redcap_connector.RedCapRefreshJob',
'web.views.voucher.ExpireVouchersJob',
'web.importer.exporter_cron_job.SubjectExporterCronJob',
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2017-04-04 09:43
from __future__ import unicode_literals
from django.db import migrations
from web.models.constants import VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE
def create_item(apps, type, value, name):
# We can't import the ConfigurationItem model directly as it may be a newer
# version than this migration expects. We use the historical version.
ConfigurationItem = apps.get_model("web", "ConfigurationItem")
item = ConfigurationItem.objects.create()
item.type = type
item.value = value
item.name = name
item.save()
def configuration_items(apps, schema_editor):
create_item(apps, VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE, "",
"At what time a day email with updates about virus tests should be sent")
class Migration(migrations.Migration):
dependencies = [
('web', '0164_configurationitem_email_items_for_redcap'),
]
operations = [
migrations.RunPython(configuration_items),
]
......@@ -51,6 +51,7 @@ KIT_EMAIL_HOUR_CONFIGURATION_TYPE = "KIT_DAILY_EMAIL_HOUR_CONFIGURATION_TYPE"
KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE = "KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE"
KIT_DAILY_EMAIL_DAYS_PERIOD_TYPE = "KIT_DAILY_EMAIL_DAYS_PERIOD_TYPE"
KIT_DAILY_EMAIL_TIME_FORMAT_TYPE = "KIT_DAILY_EMAIL_TIME_FORMAT_TYPE"
VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE = "VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE"
RED_CAP_LANGUAGE_4_FIELD_TYPE = 'RED_CAP_LANGUAGE_4_FIELD_TYPE'
RED_CAP_LANGUAGE_3_FIELD_TYPE = 'RED_CAP_LANGUAGE_3_FIELD_TYPE'
......@@ -64,6 +65,7 @@ RED_CAP_ND_NUMBER_FIELD_TYPE = 'RED_CAP_ND_NUMBER_FIELD_TYPE'
RED_CAP_VIRUS_FIELD_TYPE = 'RED_CAP_VIRUS_FIELD_TYPE'
RED_CAP_SAMPLE_DATE_FIELD_TYPE = "RED_CAP_SAMPLE_DATE_FIELD_TYPE"
MAIL_TEMPLATE_CONTEXT_SUBJECT = 'S'
MAIL_TEMPLATE_CONTEXT_APPOINTMENT = 'A'
MAIL_TEMPLATE_CONTEXT_VISIT = 'V'
......
......@@ -43,6 +43,7 @@ class RedcapSubject(object):
class RedcapVisit(object):
virus = None
virus_inconclusive = False
visit_number = 0
......@@ -218,6 +219,21 @@ class RedcapConnector(object):
subject.virus_test_5 = visit.virus
subject.virus_test_5_updated = datetime.datetime.now()
subject.save()
if visit.visit_number == 1 and subject.virus_test_1_updated is None and visit.virus_inconclusive:
subject.virus_test_1_updated = datetime.datetime.now()
subject.save()
if visit.visit_number == 2 and subject.virus_test_2_updated is None and visit.virus_inconclusive:
subject.virus_test_2_updated = datetime.datetime.now()
subject.save()
if visit.visit_number == 3 and subject.virus_test_3_updated is None and visit.virus_inconclusive:
subject.virus_test_3_updated = datetime.datetime.now()
subject.save()
if visit.visit_number == 4 and subject.virus_test_4_updated is None and visit.virus_inconclusive:
subject.virus_test_4_updated = datetime.datetime.now()
subject.save()
if visit.visit_number == 5 and subject.virus_test_5_updated is None and visit.virus_inconclusive:
subject.virus_test_5_updated = datetime.datetime.now()
subject.save()
return result
......@@ -330,6 +346,8 @@ class RedcapConnector(object):
visit.virus = False
elif row.get(self.virus_field) == "Positive":
visit.virus = True
elif row.get(self.virus_field) == "Inconclusive":
visit.virus_inconclusive = True
if self.sample_date_field != "":
if row.get(self.sample_date_field) != "":
redcap_subject.visits.append(visit)
......
# coding=utf-8
import datetime
import logging
import timeout_decorator
from django_cron import CronJobBase, Schedule
from web.models import ConfigurationItem
from web.models.constants import VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE, \
CRON_JOB_TIMEOUT
from ..models import StudySubject, Worker
from ..smash_email import EmailSender
logger = logging.getLogger(__name__)
def get_subject_statistics():
date_from = datetime.datetime.now() - datetime.timedelta(days=1)
subjects_positive_count = StudySubject.objects.filter(virus_test_1_updated__gt=date_from, virus_test_1=True).count()
subjects_positive_count += StudySubject.objects.filter(virus_test_2_updated__gt=date_from,
virus_test_2=True).count()
subjects_positive_count += StudySubject.objects.filter(virus_test_3_updated__gt=date_from,
virus_test_3=True).count()
subjects_positive_count += StudySubject.objects.filter(virus_test_4_updated__gt=date_from,
virus_test_4=True).count()
subjects_positive_count += StudySubject.objects.filter(virus_test_5_updated__gt=date_from,
virus_test_5=True).count()
subjects_negative_count = StudySubject.objects.filter(virus_test_1_updated__gt=date_from,
virus_test_1=False).count()
subjects_negative_count += StudySubject.objects.filter(virus_test_2_updated__gt=date_from,
virus_test_2=False).count()
subjects_negative_count += StudySubject.objects.filter(virus_test_3_updated__gt=date_from,
virus_test_3=False).count()
subjects_negative_count += StudySubject.objects.filter(virus_test_4_updated__gt=date_from,
virus_test_4=False).count()
subjects_negative_count += StudySubject.objects.filter(virus_test_5_updated__gt=date_from,
virus_test_5=False).count()
subjects_inconclusive_count = StudySubject.objects.filter(virus_test_1_updated__gt=date_from,
virus_test_1__isnull=True).count()
subjects_inconclusive_count += StudySubject.objects.filter(virus_test_2_updated__gt=date_from,
virus_test_2__isnull=True).count()
subjects_inconclusive_count += StudySubject.objects.filter(virus_test_3_updated__gt=date_from,
virus_test_3__isnull=True).count()
subjects_inconclusive_count += StudySubject.objects.filter(virus_test_4_updated__gt=date_from,
virus_test_4__isnull=True).count()
subjects_inconclusive_count += StudySubject.objects.filter(virus_test_5_updated__gt=date_from,
virus_test_5__isnull=True).count()
return {"Positive": subjects_positive_count, "Negative": subjects_negative_count,
"Inconclusive": subjects_inconclusive_count,
"total": subjects_positive_count + subjects_negative_count + subjects_inconclusive_count}
def create_statistic_email_content(data, title):
email_body = "<h1>" + title + "</h1>"
email_body += "In the past 24 hours " + str(data["total"]) + " donors were tested</br></br>"
for status in data:
if status != "total":
email_body += str(data[status]) + ' number of donors were tested ' + status + "</br>"
return email_body
def send_mail(data):
title = "Virus test statistics"
email_body = create_statistic_email_content(data, title)
recipients = []
workers = Worker.objects.all()
for worker in workers:
if worker.user is not None:
if worker.user.is_active:
if worker.email is not None and worker.email != "":
recipients.append(worker.email)
cc_recipients = []
logger.warn('Calling to send email')
EmailSender().send_email(title, email_body, ";".join(recipients), cc_recipients)
class KitRequestEmailSendJob(CronJobBase):
RUN_AT = []
try:
times = ConfigurationItem.objects.get(
type=VIRUS_EMAIL_HOUR_CONFIGURATION_TYPE).value.split(";")
for entry in times:
# TODO it's a hack assuming that we are in CEST
text = str((int(entry.split(":")[0]) + 22) % 24) + ":" + entry.split(":")[1]
RUN_AT.append(text)
except:
logger.error("Cannot fetch data about email hour")
schedule = Schedule(run_at_times=RUN_AT)
code = 'web.virus_daily_email' # a unique code
@timeout_decorator.timeout(CRON_JOB_TIMEOUT)
def do(self):
data = get_subject_statistics()
send_mail(data)
return "mail sent"
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