From 8294cf1dd3cd212fa754d986abc254a5c7c8792c Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Tue, 10 Oct 2017 16:47:35 +0200
Subject: [PATCH] Add followup email + editable emails

---
 mails/forms.py                                | 55 +++++++++++++-----
 .../partners_followup_mail.json               |  7 +++
 .../mail_templates/partners_followup_mail.txt | 17 ++++++
 .../mail_templates/partners_initial_mail.json |  7 +++
 .../mail_templates/partners_initial_mail.txt  | 31 ++++++++++
 mails/views.py                                |  4 ++
 partners/forms.py                             | 20 -------
 .../partners/_prospective_partner_card.html   | 12 +++-
 partners/urls.py                              |  4 ++
 partners/views.py                             | 58 ++++++++++---------
 10 files changed, 150 insertions(+), 65 deletions(-)
 create mode 100644 mails/templates/mail_templates/partners_followup_mail.json
 create mode 100644 mails/templates/mail_templates/partners_followup_mail.txt
 create mode 100644 mails/templates/mail_templates/partners_initial_mail.json
 create mode 100644 mails/templates/mail_templates/partners_initial_mail.txt

diff --git a/mails/forms.py b/mails/forms.py
index 9e8b9fbeb..a034d1a75 100644
--- a/mails/forms.py
+++ b/mails/forms.py
@@ -17,6 +17,7 @@ class EmailTemplateForm(forms.Form):
 
     def __init__(self, *args, **kwargs):
         self.mail_code = kwargs.pop('mail_code')
+        self.mail_fields = None
         super().__init__(*args)
 
         # Gather data
@@ -27,19 +28,25 @@ class EmailTemplateForm(forms.Form):
         self.mail_data = json.loads(open(json_location).read())
 
         # Object
-        self.object = kwargs.get(self.mail_data.get('context_object'))
-        recipient = self.object
-        for attr in self.mail_data.get('to_address').split('.'):
-            recipient = getattr(recipient, attr)
-            if inspect.ismethod(recipient):
-                recipient = recipient()
-        self.recipient = recipient
+        self.object = kwargs.get(self.mail_data.get('context_object', ''), None)
+        self.recipient = None
+        if self.object:
+            recipient = self.object
+            for attr in self.mail_data.get('to_address').split('.'):
+                recipient = getattr(recipient, attr)
+                if inspect.ismethod(recipient):
+                    recipient = recipient()
+            self.recipient = recipient
+
+        if not self.recipient:
+            self.fields['extra_recipient'].label = "Send this email to"
+            self.fields['extra_recipient'].required = True
 
         # Set the data as initials
         self.fields['text'].initial = self.mail_template
         self.fields['subject'].initial = self.mail_data['subject']
 
-    def send(self):
+    def save_data(self):
         # Get text and html
         message = self.cleaned_data['text']
         html_template = loader.get_template('email/general.html')
@@ -47,7 +54,7 @@ class EmailTemplateForm(forms.Form):
 
         # Get recipients list. Try to send through BCC to prevent privacy issues!
         bcc_list = []
-        if self.mail_data.get('bcc_to'):
+        if self.mail_data.get('bcc_to') and self.object:
             bcc_to = self.object
             for attr in self.mail_data.get('bcc_to').split('.'):
                 bcc_to = getattr(bcc_to, attr)
@@ -57,8 +64,12 @@ class EmailTemplateForm(forms.Form):
             else:
                 bcc_list = bcc_to
 
-        if self.cleaned_data.get('extra_recipient'):
+        if self.cleaned_data.get('extra_recipient') and self.recipient:
             bcc_list.append(self.cleaned_data.get('extra_recipient'))
+        elif self.cleaned_data.get('extra_recipient') and not self.recipient:
+            self.recipient = [self.cleaned_data.get('extra_recipient')]
+        elif not self.recipient:
+            self.add_error('extra_recipient', 'Please fill the bcc field to send the mail.')
 
         # Check the send list
         if isinstance(self.recipient, list):
@@ -82,14 +93,28 @@ class EmailTemplateForm(forms.Form):
             elif isinstance(recipient, str):
                 _recipients.append(recipient)
 
+        self.mail_fields = {
+            'subject': self.cleaned_data['subject'],
+            'message': message,
+            'html_message': html_message,
+            'recipients': _recipients,
+            'bcc_list': bcc_list,
+        }
+
+    def clean(self):
+        data = super().clean()
+        self.save_data()
+        return data
+
+    def send(self):
         # Send the mail
         email = EmailMultiAlternatives(
-            self.cleaned_data['subject'],
-            message,
+            self.mail_fields['subject'],
+            self.mail_fields['message'],
             '%s <%s>' % (self.mail_data.get('from_address_name', 'SciPost'),
                          self.mail_data.get('from_address', 'no-reply@scipost.org')),  # From
-            _recipients,  # To
-            bcc=bcc_list,
+            self.mail_fields['recipients'],  # To
+            bcc=self.mail_fields['bcc_list'],
             reply_to=[self.mail_data.get('from_address', 'no-reply@scipost.org')])
-        email.attach_alternative(html_message, 'text/html')
+        email.attach_alternative(self.mail_fields['html_message'], 'text/html')
         email.send(fail_silently=False)
diff --git a/mails/templates/mail_templates/partners_followup_mail.json b/mails/templates/mail_templates/partners_followup_mail.json
new file mode 100644
index 000000000..efb95bbc8
--- /dev/null
+++ b/mails/templates/mail_templates/partners_followup_mail.json
@@ -0,0 +1,7 @@
+{
+    "subject": "SciPost: Supporting Partners Board",
+    "to_address": "email",
+    "from_address_name": "SciPost Supporting Partners",
+    "from_address": "partners@scipost.org",
+    "context_object": "contact"
+}
diff --git a/mails/templates/mail_templates/partners_followup_mail.txt b/mails/templates/mail_templates/partners_followup_mail.txt
new file mode 100644
index 000000000..136e2d335
--- /dev/null
+++ b/mails/templates/mail_templates/partners_followup_mail.txt
@@ -0,0 +1,17 @@
+Dear {{ contact.get_title_display }} {{ contact.last_name }},
+
+Recently we contacted you about the SciPost Supporting Partners Board. We would like to know if you and your institution are interested in joining the Supporting Partners Board.
+
+It is greatly appreciated if you could take a few minutes to read through this document and let us know whether your institution would consider joining.
+
+It would be a privilege to welcome you as members of our Supporting Partners Board. Support takes the form of a small financial commitment, collectively pooled to enable SciPost to perform all its publication-related activities, maintain its online portal and implement its long-term development plan.
+
+Your support at this time is crucially required to make our initiative sustainable, and to help make it possible for the community to reap all the benefits deriving form its viable implementation.
+
+I will be happy to provide any required further details. If you are interested, you can simply get in touch via this address (partners@scipost.org). I sincerely hope that SciPost will be able to count on your support.
+
+If you not the right person in your organization to contact about this topic, please let us know.
+
+On behalf of the SciPost Foundation,
+Prof. dr Jean-Sébastien Caux
+J.S.Caux@uva.nl
diff --git a/mails/templates/mail_templates/partners_initial_mail.json b/mails/templates/mail_templates/partners_initial_mail.json
new file mode 100644
index 000000000..efb95bbc8
--- /dev/null
+++ b/mails/templates/mail_templates/partners_initial_mail.json
@@ -0,0 +1,7 @@
+{
+    "subject": "SciPost: Supporting Partners Board",
+    "to_address": "email",
+    "from_address_name": "SciPost Supporting Partners",
+    "from_address": "partners@scipost.org",
+    "context_object": "contact"
+}
diff --git a/mails/templates/mail_templates/partners_initial_mail.txt b/mails/templates/mail_templates/partners_initial_mail.txt
new file mode 100644
index 000000000..739744c47
--- /dev/null
+++ b/mails/templates/mail_templates/partners_initial_mail.txt
@@ -0,0 +1,31 @@
+Dear {{ contact.get_title_display }} {{ contact.last_name }},
+
+You might by now have heard of SciPost, a recently-launched initiative aiming to bring disruptive change to current academic publishing practices.
+
+In summary, SciPost is a publication portal managed by professional scientists, offering (among others) high-quality Open Access journals with innovative forms of refereeing, and a means of commenting on all existing literature. SciPost is established as a not-for-profit foundation devoted to serving the interests of the international scientific community.
+The site is anchored at https://scipost.org. Many further details about SciPost, its principles, ideals and implementation can be found at https://scipost.org/about and https://scipost.org/FAQ.
+
+Crucially, as explained on our Partners page at https://scipost.org/partners, SciPost follows a completely different funding model than traditional publishers, and provides a cost-slashing alternative to existing platforms. SciPost charges neither subscription fees, nor article processing charges; its activities are instead to be collectively financed through a Supporting Partners Board, formed by a worldwide consortium of institutions and organizations which directly or indirectly benefit from SciPost’s activities.
+
+Support takes the form of a small financial commitment, collectively pooled to enable SciPost to perform all its publication-related activities, maintain its online portal and implement its long-term development plan.
+
+In the agreement template, which you can find online at https://scipost.org/static/scipost/SPB/SciPost_Supporting_Partner_Agreement.pdf, you will find many more specific details about our operations, requirements and funding strategy. I would greatly appreciate if you took a few minutes to read through this document.
+
+It would be a privilege to welcome you as members of our Supporting Partners Board. I am hereby contacting you to enquire whether your institution would consider joining. Your support at this time is crucially required to make our initiative sustainable, and to help make it possible for the community to reap all the benefits deriving form its viable implementation.
+
+I will be happy to provide any required further details. If you are interested, you can simply get in touch via this address (partners@scipost.org). I sincerely hope that SciPost will be able to count on your support.
+
+On behalf of the SciPost Foundation,
+Prof. dr Jean-Sébastien Caux
+J.S.Caux@uva.nl
+http://jscaux.org
+---------------------------------------------
+Institute for Theoretical Physics
+University of Amsterdam
+Science Park 904
+1098 XH  Amsterdam
+The Netherlands
+---------------------------------------------
+tel.: +31 (0)20 5255775
+fax: +31 (0)20 5255778
+---------------------------------------------
diff --git a/mails/views.py b/mails/views.py
index 04dce36dd..f7fedc01d 100644
--- a/mails/views.py
+++ b/mails/views.py
@@ -10,6 +10,10 @@ class MailEditingSubView(object):
         self.template_name = kwargs.get('template', 'mails/mail_form.html')
         self.mail_form = EmailTemplateForm(request.POST or None, mail_code=mail_code, **kwargs)
 
+    @property
+    def recipients_string(self):
+        return ', '.join(getattr(self.mail_form, 'mail_fields', {}).get('recipients', ['']))
+
     def is_valid(self):
         return self.mail_form.is_valid()
 
diff --git a/partners/forms.py b/partners/forms.py
index 87322b2d6..18a2df781 100644
--- a/partners/forms.py
+++ b/partners/forms.py
@@ -458,26 +458,6 @@ class ProspectiveContactForm(forms.ModelForm):
         widgets = {'prospartner': forms.HiddenInput()}
 
 
-class EmailProspectivePartnerContactForm(forms.Form):
-    email_subject = forms.CharField(widget=forms.Textarea(),
-                                    initial='Supporting Partners Board')
-    message = forms.CharField(widget=forms.Textarea(), required=False)
-    include_SPB_summary = forms.BooleanField(
-        required=False, initial=True,
-        label='include SPB summary with message')
-
-    def __init__(self, *args, **kwargs):
-        super(EmailProspectivePartnerContactForm, self).__init__(*args, **kwargs)
-        self.fields['email_subject'].widget.attrs.update(
-            {'rows': 1})
-        self.fields['message'].widget.attrs.update(
-            {'placeholder': 'Write your message in this box (optional).'})
-
-
-class EmailProspectivePartnerGenericForm(EmailProspectivePartnerContactForm):
-    email = forms.EmailField(label='Generic address for emailing')
-
-
 class ProspectivePartnerEventForm(forms.ModelForm):
     class Meta:
         model = ProspectivePartnerEvent
diff --git a/partners/templates/partners/_prospective_partner_card.html b/partners/templates/partners/_prospective_partner_card.html
index 28f587665..5ab2d85a1 100644
--- a/partners/templates/partners/_prospective_partner_card.html
+++ b/partners/templates/partners/_prospective_partner_card.html
@@ -15,7 +15,10 @@
       <p>{{ pp.get_status_display }}</p>
     </div>
     <div class="col-md-7">
-      <a href="{% url 'partners:email_prospartner_generic' prospartner_id=pp.id %}">Compose email to a generic address</a>
+        <ul>
+          <li><a href="{% url 'partners:email_prospartner_generic' prospartner_id=pp.id %}">Compose email to a generic address</a></li>
+          <li><a href="{% url 'partners:email_prospartner_generic' prospartner_id=pp.id mail='followup' %}">Compose follow-up email to a generic address</a></li>
+        </ul>
       <h3>Contacts:</h3>
       <a class="d-inline-block mb-2" href="{% url 'partners:add_prospartner_contact' prospartner_id=pp.id %}">Add a contact</a>
       <table class="table">
@@ -31,7 +34,12 @@
             <td>{{ contact.role }}</td>
             <td>{{ contact.get_title_display }} {{ contact.first_name }} {{ contact.last_name }}</td>
             <td>{{ contact.email }}</td>
-	    <td><a href="{% url 'partners:email_prospartner_contact' contact_id=contact.id %}">Compose email</a></td>
+	    <td>
+            <ul>
+                <li><a href="{% url 'partners:email_prospartner_contact' contact_id=contact.id %}">Compose email</a>
+                <li><a href="{% url 'partners:email_prospartner_contact' contact_id=contact.id mail='followup' %}">Compose follow-up email</a>
+            </ul>
+        </td>
 	  </tr>
           {% empty %}
           <tr>
diff --git a/partners/urls.py b/partners/urls.py
index f376c8de2..b7d4e8638 100644
--- a/partners/urls.py
+++ b/partners/urls.py
@@ -13,6 +13,8 @@ urlpatterns = [
         name='add_prospective_partner'),
     url(r'^prospects/contacts/(?P<contact_id>[0-9]+)/email$',
         views.email_prospartner_contact, name='email_prospartner_contact'),
+    url(r'^prospects/contacts/(?P<contact_id>[0-9]+)/email/(?P<mail>followup)$',
+        views.email_prospartner_contact, name='email_prospartner_contact'),
 
     url(r'^prospects/(?P<prospartner_id>[0-9]+)/contacts/add$',
         views.add_prospartner_contact, name='add_prospartner_contact'),
@@ -20,6 +22,8 @@ urlpatterns = [
         views.promote_prospartner, name='promote_prospartner'),
     url(r'^prospects/(?P<prospartner_id>[0-9]+)/email_generic',
         views.email_prospartner_generic, name='email_prospartner_generic'),
+    url(r'^prospects/(?P<prospartner_id>[0-9]+)/email_generic/(?P<mail>followup)',
+        views.email_prospartner_generic, name='email_prospartner_generic'),
     url(r'^prospects/(?P<prospartner_id>[0-9]+)/events/add$',
         views.add_prospartner_event, name='add_prospartner_event'),
 
diff --git a/partners/views.py b/partners/views.py
index 1a94818df..0acab83ef 100644
--- a/partners/views.py
+++ b/partners/views.py
@@ -10,6 +10,8 @@ from django.utils import timezone
 
 from guardian.decorators import permission_required
 
+from mails.views import MailEditingSubView
+
 from .constants import PROSPECTIVE_PARTNER_REQUESTED,\
     PROSPECTIVE_PARTNER_APPROACHED, PROSPECTIVE_PARTNER_ADDED,\
     PROSPECTIVE_PARTNER_EVENT_REQUESTED, PROSPECTIVE_PARTNER_EVENT_EMAIL_SENT
@@ -17,13 +19,12 @@ from .models import Partner, ProspectivePartner, ProspectiveContact, ContactRequ
                     ProspectivePartnerEvent, MembershipAgreement, Contact, Institution,\
                     PartnersAttachment
 from .forms import ProspectivePartnerForm, ProspectiveContactForm,\
-                   EmailProspectivePartnerContactForm, PromoteToPartnerForm,\
+                   PromoteToPartnerForm,\
                    ProspectivePartnerEventForm, MembershipQueryForm,\
                    PartnerForm, ContactForm, ContactFormset, ContactModelFormset,\
                    NewContactForm, InstitutionForm, ActivationForm, PartnerEventForm,\
                    MembershipAgreementForm, RequestContactForm, RequestContactFormSet,\
-                   ProcessRequestContactForm, PartnersAttachmentFormSet, PartnersAttachmentForm,\
-                   EmailProspectivePartnerGenericForm
+                   ProcessRequestContactForm, PartnersAttachmentFormSet, PartnersAttachmentForm
 from .utils import PartnerUtils
 
 
@@ -261,10 +262,15 @@ def add_prospartner_contact(request, prospartner_id):
 
 @permission_required('scipost.can_email_prospartner_contact', return_403=True)
 @transaction.atomic
-def email_prospartner_contact(request, contact_id):
+def email_prospartner_contact(request, contact_id, mail=None):
     contact = get_object_or_404(ProspectiveContact, pk=contact_id)
-    form = EmailProspectivePartnerContactForm(request.POST or None)
-    if form.is_valid():
+
+    if mail == 'followup':
+        code = 'partners_followup_mail'
+    else:
+        code = 'partners_initial_mail'
+    mail_request = MailEditingSubView(request, mail_code=code, contact=contact)
+    if mail_request.is_valid():
         comments = 'Email sent to %s.' % str(contact)
         prospartnerevent = ProspectivePartnerEvent(
             prospartner=contact.prospartner,
@@ -277,25 +283,26 @@ def email_prospartner_contact(request, contact_id):
                                           PROSPECTIVE_PARTNER_ADDED]:
             contact.prospartner.status = PROSPECTIVE_PARTNER_APPROACHED
             contact.prospartner.save()
-        PartnerUtils.load({'contact': contact,
-                           'email_subject': form.cleaned_data['email_subject'],
-                           'message': form.cleaned_data['message'],
-                           'include_SPB_summary': form.cleaned_data['include_SPB_summary']})
 
-        PartnerUtils.email_prospartner_contact()
-        messages.success(request, 'Email successfully sent')
+        messages.success(request, 'Email successfully sent.')
+        mail_request.send()
         return redirect(reverse('partners:dashboard'))
-    context = {'contact': contact, 'form': form}
-    return render(request, 'partners/email_prospartner_contact.html', context)
+    else:
+        return mail_request.return_render()
 
 
 @permission_required('scipost.can_email_prospartner_contact', return_403=True)
 @transaction.atomic
-def email_prospartner_generic(request, prospartner_id):
+def email_prospartner_generic(request, prospartner_id, mail=None):
     prospartner = get_object_or_404(ProspectivePartner, pk=prospartner_id)
-    form = EmailProspectivePartnerGenericForm(request.POST or None)
-    if form.is_valid():
-        comments = 'Email sent to %s.' % form.cleaned_data['email']
+
+    if mail == 'followup':
+        code = 'partners_followup_mail'
+    else:
+        code = 'partners_initial_mail'
+    mail_request = MailEditingSubView(request, mail_code=code)
+    if mail_request.is_valid():
+        comments = 'Email sent to %s.' % str(mail_request.recipients_string)
         prospartnerevent = ProspectivePartnerEvent(
             prospartner=prospartner,
             event=PROSPECTIVE_PARTNER_EVENT_EMAIL_SENT,
@@ -307,17 +314,12 @@ def email_prospartner_generic(request, prospartner_id):
                                   PROSPECTIVE_PARTNER_ADDED]:
             prospartner.status = PROSPECTIVE_PARTNER_APPROACHED
             prospartner.save()
-        PartnerUtils.load({'institution_name': prospartner.institution_name,
-                           'email': form.cleaned_data['email'],
-                           'email_subject': form.cleaned_data['email_subject'],
-                           'message': form.cleaned_data['message'],
-                           'include_SPB_summary': form.cleaned_data['include_SPB_summary']})
-
-        PartnerUtils.email_prospartner_generic()
-        messages.success(request, 'Email successfully sent')
+
+        messages.success(request, 'Email successfully sent.')
+        mail_request.send()
         return redirect(reverse('partners:dashboard'))
-    context = {'prospartner': prospartner, 'form': form}
-    return render(request, 'partners/email_prospartner_generic.html', context)
+    else:
+        return mail_request.return_render()
 
 
 @permission_required('scipost.can_manage_SPB', return_403=True)
-- 
GitLab