diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py index 0ef157f4b99f0f009eec4f5de0cca8f20a651305..865f10ccf3c1c1e17f102a0cdca273c34cdc1014 100644 --- a/smash/web/models/constants.py +++ b/smash/web/models/constants.py @@ -48,14 +48,18 @@ KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE = "KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_ MAIL_TEMPLATE_CONTEXT_SUBJECT = 'S' MAIL_TEMPLATE_CONTEXT_APPOINTMENT = 'A' MAIL_TEMPLATE_CONTEXT_VISIT = 'V' +MAIL_TEMPLATE_CONTEXT_VOUCHER = 'C' MAIL_TEMPLATE_CONTEXT_CHOICES = ( (MAIL_TEMPLATE_CONTEXT_APPOINTMENT, 'Appointment'), (MAIL_TEMPLATE_CONTEXT_SUBJECT, 'Subject'), (MAIL_TEMPLATE_CONTEXT_VISIT, 'Visit'), + (MAIL_TEMPLATE_CONTEXT_VOUCHER, 'Voucher'), ) LOCALE_CHOICES = [(value, value) for value in sorted(locale.windows_locale.values())] +DEFAULT_LOCALE_NAME = "fr_FR" + MONDAY_AS_DAY_OF_WEEK = 1 TUESDAY_AS_DAY_OF_WEEK = 2 WEDNESDAY_AS_DAY_OF_WEEK = 3 diff --git a/smash/web/models/language.py b/smash/web/models/language.py index 8db4cd2733ebc47242c4bad1e82408e11b45f1b1..5848ace6180745d33749f3140e618803dffcce02 100644 --- a/smash/web/models/language.py +++ b/smash/web/models/language.py @@ -2,7 +2,7 @@ from django.db import models -from .constants import LOCALE_CHOICES +from .constants import LOCALE_CHOICES, DEFAULT_LOCALE_NAME class Language(models.Model): @@ -13,7 +13,8 @@ class Language(models.Model): name = models.CharField(max_length=20) image = models.ImageField() order = models.IntegerField(default=0) - locale = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False, default="fr_FR") + locale = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False, + default=DEFAULT_LOCALE_NAME) windows_locale_name = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False, default="French") diff --git a/smash/web/models/mail_template.py b/smash/web/models/mail_template.py index d4f72d1867a4de358b55957fbf9cb3686f40b960..729015253713c0724797cc82f43a1879e533ad68 100644 --- a/smash/web/models/mail_template.py +++ b/smash/web/models/mail_template.py @@ -7,9 +7,9 @@ from contextlib import contextmanager from django.db import models from .constants import MAIL_TEMPLATE_CONTEXT_CHOICES, MAIL_TEMPLATE_CONTEXT_APPOINTMENT, \ - MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT + MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT, MAIL_TEMPLATE_CONTEXT_VOUCHER, DEFAULT_LOCALE_NAME from ..docx_helper import process_file -from ..models import Appointment, Visit, StudySubject, Worker +from ..models import Appointment, Visit, StudySubject, Worker, Voucher DATE_FORMAT_FULL = "%A %d %B %Y" @@ -99,9 +99,26 @@ class MailTemplate(models.Model): ("##A_TYPES##", "Appointment's types", "comma separated"), ] + MAILS_TEMPLATE_VOUCHER_TAGS = [ + ("##C_NUMBER##", "Number", ''), + ("##C_PATIENT_NAME##", "Voucher Partner name", ''), + ("##C_VOUCHER_TYPE##", "Voucher type", ''), + + ("##C_ISSUE_DATE_SHORT##", "Issue date", get_formatted_time(DATE_FORMAT_SHORT)), + ("##C_EXPIRY_START_SHORT##", "Expiry date", get_formatted_time(DATE_FORMAT_SHORT)), + + ("##C_PARTNER_NAME##", "Voucher Partner name", ''), + ("##C_PARTNER_ADDRESS##", "Voucher Partner address", ''), + ("##C_PARTNER_CITY##", "Voucher Partner city", ''), + ("##C_PARTNER_POSTAL_CODE##", "Voucher Partner postal code", ''), + ("##C_PARTNER_COUNTRY##", "Voucher Partner country", ''), + ("##C_PARTNER_PHONE##", "Voucher Partner phone", ''), + ("##C_HOURS##", "Hours", ''), + ] + name = models.CharField(max_length=255) context = models.CharField(max_length=1, choices=MAIL_TEMPLATE_CONTEXT_CHOICES) - language = models.ForeignKey("web.Language", on_delete=models.CASCADE) + language = models.ForeignKey("web.Language", on_delete=models.CASCADE, null=True) template_file = models.FileField(upload_to='templates/') @staticmethod @@ -112,6 +129,10 @@ class MailTemplate(models.Model): def get_subject_mail_templates(languages): return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_SUBJECT) + @staticmethod + def get_voucher_mail_templates(languages): + return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_VOUCHER) + @staticmethod def get_visit_mail_templates(languages): return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_VISIT) @@ -134,6 +155,7 @@ class MailTemplate(models.Model): appointment = None visit = None study_subject = None + voucher = None if isinstance(instance, Appointment): appointment = instance visit = instance.visit @@ -143,19 +165,29 @@ class MailTemplate(models.Model): study_subject = visit.subject elif isinstance(instance, StudySubject): study_subject = instance + elif isinstance(instance, Voucher): + voucher = instance # set locale to get correct date format - locale_name = self.language.locale - if platform.system() == 'Windows': - locale_name = self.language.windows_locale_name + locale_name = self.get_locale_name() with setlocale(locale_name.encode('utf8')): replacements = {} self._add_generic_replacements(replacements, Worker.get_by_user(user)) self._add_appointment_replacements(replacements, appointment) self._add_visit_replacements(replacements, visit) self._add_subject_replacements(replacements, study_subject) + self._add_voucher_replacements(replacements, voucher) process_file(self.template_file.path, stream, replacements) return stream + def get_locale_name(self): + if self.language is None: + locale_name = DEFAULT_LOCALE_NAME + else: + locale_name = self.language.locale + if platform.system() == 'Windows': + locale_name = self.language.windows_locale_name + return locale_name + def _add_generic_replacements(self, replacements, worker): current_datetime = datetime.datetime.now() replacements.update({ @@ -237,3 +269,21 @@ class MailTemplate(models.Model): '##S_MAIL_LANGUAGE##': str(study_subject.subject.default_written_communication_language), '##S_KNOWN_LANGUAGES##': ", ".join([l.name for l in study_subject.subject.languages.all()]) }) + + def _add_voucher_replacements(self, replacements, voucher): + if voucher is not None: + replacements.update({ + "##C_NUMBER##": voucher.number, + "##C_PATIENT_NAME##": voucher.study_subject.subject.first_name + ' ' + voucher.study_subject.subject.last_name, + "##C_VOUCHER_TYPE##": voucher.voucher_type.description, + "##C_ISSUE_DATE_SHORT##": voucher.issue_date.strftime(DATE_FORMAT_SHORT).decode(date_format_encoding()), + "##C_EXPIRY_START_SHORT##": voucher.expiry_date.strftime(DATE_FORMAT_SHORT).decode( + date_format_encoding()), + "##C_PARTNER_NAME##": voucher.usage_partner.first_name + ' ' + voucher.usage_partner.last_name, + "##C_PARTNER_ADDRESS##": voucher.usage_partner.address, + "##C_PARTNER_POSTAL_CODE##": voucher.usage_partner.postal_code, + "##C_PARTNER_CITY##": voucher.usage_partner.city, + "##C_PARTNER_COUNTRY##": unicode(voucher.usage_partner.country), + "##C_PARTNER_PHONE##": voucher.usage_partner.phone_number, + "##C_HOURS##": str(voucher.hours), + }) diff --git a/smash/web/tests/data/voucher_test.docx b/smash/web/tests/data/voucher_test.docx new file mode 100644 index 0000000000000000000000000000000000000000..8f263326ba270ab7bfe216c812631225bb1fd105 Binary files /dev/null and b/smash/web/tests/data/voucher_test.docx differ diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py index f7da4add1364911a0e51a2015cfe53842f754b06..0164230b3ae50aa50a93cc8979135df6c938670b 100644 --- a/smash/web/tests/functions.py +++ b/smash/web/tests/functions.py @@ -9,7 +9,7 @@ from web.models import Location, AppointmentType, StudySubject, Worker, Visit, A VoucherType, VoucherTypePrice, Voucher, Room, Item, WorkerStudyRole from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, REDCAP_BASE_URL_CONFIGURATION_TYPE, \ SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, CONTACT_TYPES_PHONE, \ - MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID + MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID, DEFAULT_LOCALE_NAME from web.models.worker_study_role import ROLE_CHOICES_DOCTOR, WORKER_VOUCHER_PARTNER from web.redcap_connector import RedcapSubject from web.views.notifications import get_today_midnight_date @@ -311,7 +311,7 @@ def create_room(owner='Test owner', city='Test city', return room -def create_language(name="French", locale="fr_FR"): +def create_language(name="French", locale=DEFAULT_LOCALE_NAME): language = Language(name=name, locale=locale) language.save() return language diff --git a/smash/web/tests/models/test_mail_template.py b/smash/web/tests/models/test_mail_template.py index 49c84a13962049a563cd007c6a2b819575e33361..27d5dcca3781292acee3934d4c4a89b0ca235b29 100644 --- a/smash/web/tests/models/test_mail_template.py +++ b/smash/web/tests/models/test_mail_template.py @@ -5,11 +5,11 @@ from docx import Document from web.models import MailTemplate from web.models.constants import MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VISIT, \ - MAIL_TEMPLATE_CONTEXT_SUBJECT + MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VOUCHER from web.models.mail_template import DATE_FORMAT_SHORT from web.tests.functions import create_language, get_resource_path, create_appointment, create_user, \ create_study_subject, \ - create_visit + create_visit, create_voucher class MailTemplateModelTests(TestCase): @@ -34,6 +34,11 @@ class MailTemplateModelTests(TestCase): function_to_test = MailTemplate.get_subject_mail_templates self.check_get_mail_templates(context, function_to_test) + def test_get_voucher_mail_templates(self): + context = MAIL_TEMPLATE_CONTEXT_VOUCHER + function_to_test = MailTemplate.get_voucher_mail_templates + self.check_get_mail_templates(context, function_to_test) + def check_get_mail_templates(self, context, function_to_test): # create french template template_name_french = "test_fr" @@ -93,6 +98,23 @@ class MailTemplateModelTests(TestCase): self.check_doc_contains(doc, [worker_name, str(subject), str(subject.subject.country), subject.nd_number, subject.get_type_display()]) + def test_apply_voucher(self): + template_name_french = "test_without_language" + subject = create_study_subject() + subject_template_french = MailTemplate(name=template_name_french, language=None, + context=MAIL_TEMPLATE_CONTEXT_VOUCHER, + template_file="voucher_test.docx") + voucher = create_voucher(study_subject=subject) + stream = StringIO.StringIO() + subject_template_french.apply(voucher, self.user, stream) + doc = Document(stream) + worker_name = str(self.user.worker) + + self.check_doc_contains(doc, [worker_name, str(subject), voucher.number, voucher.usage_partner.address, + voucher.expiry_date.strftime(DATE_FORMAT_SHORT), + voucher.issue_date.strftime(DATE_FORMAT_SHORT) + ]) + def test_apply_visit(self): template_name_french = "test_fr" visit = create_visit() diff --git a/smash/web/views/mails.py b/smash/web/views/mails.py index 1fc450b3a55b695190667cf55c5eea8b30749df0..53b8557e8b0aa12887b9e8137cfa2d7e7054bfc7 100644 --- a/smash/web/views/mails.py +++ b/smash/web/views/mails.py @@ -12,15 +12,16 @@ from django.views.generic import ListView from django.views.generic import UpdateView from . import WrappedView -from ..models import StudySubject, Visit, Appointment, MailTemplate +from ..models import StudySubject, Visit, Appointment, MailTemplate, Voucher from ..models.constants import MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT, \ - MAIL_TEMPLATE_CONTEXT_APPOINTMENT + MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VOUCHER MIMETYPE_DOCX = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' CONTEXT_TYPES_MAPPING = { MAIL_TEMPLATE_CONTEXT_SUBJECT: StudySubject, MAIL_TEMPLATE_CONTEXT_VISIT: Visit, + MAIL_TEMPLATE_CONTEXT_VOUCHER: Voucher, MAIL_TEMPLATE_CONTEXT_APPOINTMENT: Appointment } @@ -35,6 +36,7 @@ class MailTemplatesListView(ListView, WrappedView): context['explanations'] = {"generic": MailTemplate.MAILS_TEMPLATE_GENERIC_TAGS, "subject": MailTemplate.MAILS_TEMPLATE_SUBJECT_TAGS, "visit": MailTemplate.MAILS_TEMPLATE_VISIT_TAGS, + "voucher": MailTemplate.MAILS_TEMPLATE_VOUCHER_TAGS, "appointment": MailTemplate.MAILS_TEMPLATE_APPOINTMENT_TAGS, } return context