# coding=utf-8 import io from wsgiref.util import FileWrapper from django.contrib import messages from django.http import HttpResponse from django.shortcuts import redirect, get_object_or_404 from django.urls import reverse_lazy from django.views.generic import DeleteView from django.views.generic import ListView from web.decorators import PermissionDecorator from web.docx_helper import merge_files from . import WrappedView from . import wrap_response from ..forms.mail_template import MailTemplateForm 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_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 } class MailTemplatesListView(ListView, WrappedView): model = MailTemplate context_object_name = "mail_templates" template_name = 'mail_templates/list.html' @PermissionDecorator('change_mailtemplate', 'mailtemplate') def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) def get_context_data(self, *args, **kwargs): context = super().get_context_data() MailTemplate.update_tags() 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 @PermissionDecorator('change_mailtemplate', 'mailtemplate') def mail_template_add(request): if request.method == 'POST': form = MailTemplateForm(request.POST, request.FILES) if form.is_valid(): try: form.save() except: messages.add_message(request, messages.ERROR, 'There was a problem when saving template. ' 'Contact system administrator.') return redirect('web.views.mail_templates') else: form = MailTemplateForm() return wrap_response(request, 'mail_templates/add.html', {'form': form}) @PermissionDecorator('change_mailtemplate', 'mailtemplate') def mail_template_edit(request, pk): template = get_object_or_404(MailTemplate, pk=pk) if request.method == 'POST': form = MailTemplateForm(request.POST, request.FILES, instance=template) if form.is_valid(): try: form.save() return redirect('web.views.mail_templates') except: messages.add_message(request, messages.ERROR, 'There was a problem when updating template. ' 'Contact system administrator.') return wrap_response(request, 'mail_templates/edit.html', {'form': form, 'mail_template': template}) else: form = MailTemplateForm(instance=template) return wrap_response(request, 'mail_templates/edit.html', {'form': form, 'mail_template': template}) class MailTemplatesDeleteView(DeleteView, WrappedView): model = MailTemplate success_url = reverse_lazy('web.views.mail_templates') template_name = 'mail_templates/confirm_delete.html' @PermissionDecorator('change_mailtemplate', 'mailtemplate') def delete(self, request, *args, **kwargs): messages.success(request, "Template deleted") try: return super().delete(request, *args, **kwargs) except: messages.add_message(request, messages.ERROR, 'There was a problem when deleting template. ' 'Contact system administrator.') return redirect('web.views.mail_templates') def generate(request, mail_template_id, instance_id): mail_template = get_object_or_404(MailTemplate, id=mail_template_id) instance = get_object_or_404(CONTEXT_TYPES_MAPPING[mail_template.context], id=instance_id) stream = io.BytesIO() stream = mail_template.apply(instance, request.user, stream) file_size = stream.tell() stream.seek(0) response = HttpResponse(FileWrapper(stream), content_type=MIMETYPE_DOCX) response['Content-Length'] = file_size response['Content-Disposition'] = 'attachment; filename={}.docx'.format(mail_template.name) return response def generate_for_vouchers(request): ids = request.GET.get('voucher_id', '').split(',') vouchers = [] for voucher_id in ids: if voucher_id.isdigit(): vouchers.append(Voucher.objects.get(pk=int(voucher_id))) templates = MailTemplate.get_voucher_mail_templates([])[0] if len(templates) == 0: messages.add_message(request, messages.WARNING, 'There are no voucher mail templates. Please add one in order to print vouchers.') return redirect(request.META.get('HTTP_REFERER', 'web.views.subjects')) output_stream = io.BytesIO() inputs = [] for template in templates: for voucher in vouchers: input_stream = io.BytesIO() input_stream = template.apply(voucher, request.user, input_stream) input_stream.seek(0) inputs.append(input_stream) if len(inputs) == 0: return redirect(request.META.get('HTTP_REFERER', 'web.views.subjects')) merge_files(inputs, output_stream) file_size = output_stream.tell() output_stream.seek(0) response = HttpResponse(FileWrapper(output_stream), content_type=MIMETYPE_DOCX) response['Content-Length'] = file_size response['Content-Disposition'] = 'attachment; filename=vouchers.docx' return response