From d2248cb02426954eda42e5ecefe4613afe3355fd Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Wed, 20 Feb 2019 18:34:39 +0100
Subject: [PATCH] Create Contact, ContactRole (draft)

---
 organizations/forms.py                        | 26 ++++++++++-----
 .../organizations/_organization_card.html     | 16 +++++----
 .../organization_add_contact.html             | 33 +++++++++++++++++++
 organizations/urls.py                         |  5 +++
 organizations/views.py                        | 18 +++++++---
 .../email_contact_for_activation.html         | 20 +++++++++++
 .../email_contact_for_activation.json         |  8 +++++
 7 files changed, 107 insertions(+), 19 deletions(-)
 create mode 100644 organizations/templates/organizations/organization_add_contact.html
 create mode 100644 templates/email/org_contacts/email_contact_for_activation.html
 create mode 100644 templates/email/org_contacts/email_contact_for_activation.json

diff --git a/organizations/forms.py b/organizations/forms.py
index 079d77fd8..522bf1691 100644
--- a/organizations/forms.py
+++ b/organizations/forms.py
@@ -2,15 +2,18 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import datetime
+
 from django import forms
 
 from django.contrib.auth.models import User
 from django.contrib.auth.password_validation import validate_password
 from django.core.exceptions import ValidationError
 from django.db import transaction
+from django.utils import timezone
 
-from .constants import ROLE_KINDS
-from .models import Contact
+from .constants import ROLE_GENERAL
+from .models import Contact, ContactRole
 
 from scipost.constants import TITLE_CHOICES
 
@@ -21,6 +24,7 @@ class ContactForm(forms.ModelForm):
     """
     class Meta:
         model = Contact
+        fields = ['title', 'key_expires']
 
 
 class NewContactForm(ContactForm):
@@ -66,18 +70,16 @@ class NewContactForm(ContactForm):
         If existing user is found, link it to the Organization.
         """
         if self.existing_user and self.data.get('confirm_use_existing', '') == 'on':
-            # Do not create new Contact
+            # Create new Contact if it doesn't already exist
             try:
                 # Link Contact to new Organization
                 contact = self.existing_user.org_contact
-                contact.organizations.add(self.organization)
             except Contact.DoesNotExist:
                 # Not yet a 'Contact-User'
                 contact = super().save(commit=False)
                 contact.title = self.existing_user.org_contact.title
                 contact.user = self.existing_user
                 contact.save()
-                contact.organizations.add(self.organization)
             return contact
 
         # Create complete new Account (User + Contact)
@@ -95,11 +97,17 @@ class NewContactForm(ContactForm):
         )
         contact.generate_key()
         contact.save()
-        contact.organizations.add(self.organization)
 
-        # TODOdeprecPartners Send email for activation
-        # PartnerUtils.load({'contact': contact})
-        # PartnerUtils.email_contact_new_for_activation(current_user=current_user)
+        # Create the role with to-be-updated info
+        contactrole = ContactRole(
+            contact=contact,
+            organization=self.organization,
+            kind=[ROLE_GENERAL,],
+            date_from=timezone.now(),
+            date_until=timezone.now() + datetime.timedelta(days=3650)
+        )
+        contactrole.save()
+
         return contact
 
 
diff --git a/organizations/templates/organizations/_organization_card.html b/organizations/templates/organizations/_organization_card.html
index 3f7c7df31..3b33311f2 100644
--- a/organizations/templates/organizations/_organization_card.html
+++ b/organizations/templates/organizations/_organization_card.html
@@ -186,9 +186,12 @@ $(document).ready(function($) {
 	</div>
 	{% endif %}
 
+	{% if perms.scipost.can_manage_organizations %}
 	<div class="tab-pane pt-4" id="contacts-{{ org.id }}" role="tabpanel" aria-labelledby="contacts-{{ org.id }}-tab">
-	  {% if perms.scipost.can_manage_organizations %}
 	  <h3>Contacts (with explicit role)</h3>
+	  <ul>
+	    <li><a href="{% url 'organizations:add_contact' organization_id=org.id %}">Add a new Contact</a></li>
+	  </ul>
 	  <table class="table">
 	    <tr>
 	      <th>Name</th>
@@ -220,11 +223,11 @@ $(document).ready(function($) {
 	    </tr>
 	    {% endfor %}
 	  </table>
-	  {% endif %}
 	</div>
+	{% endif %}
 
+	{% if perms.scipost.can_manage_organizations %}
 	<div class="tab-pane pt-4" id="events-{{ org.id }}" role="tabpanel" aria-labelledby="events-{{ org.id }}-tab">
-	  {% if perms.scipost.can_manage_organizations %}
 	  <h3>Events</h3>
 	  <ul>
 	    {% for event in org.organizationevent_set.all %}
@@ -233,19 +236,20 @@ $(document).ready(function($) {
 	    <li>No event found</li>
 	    {% endfor %}
 	  </ul>
-	  {% endif %}
 	</div>
+	{% endif %}
 
+	{% if perms.scipost.can_manage_organizations %}
 	<div class="tab-pane pt-4" id="manage-{{ org.id }}" role="tabpanel" aria-labelledby="manage-{{ org.id }}-tab">
-	  {% if perms.scipost.can_manage_organizations %}
 	  <h3>Manage this organization:</h3>
 	  <ul>
 	    <li><a href="{% url 'organizations:organization_update' pk=org.id %}">Update</a></li>
 	    <li><a href="{% url 'organizations:organization_delete' pk=org.id %}">Delete</a></li>
 	  </ul>
 	  <hr/>
-	  {% endif %}
 	</div>
+	{% endif %}
+
       </div>
     </div>
   </div>
diff --git a/organizations/templates/organizations/organization_add_contact.html b/organizations/templates/organizations/organization_add_contact.html
new file mode 100644
index 000000000..061b24c32
--- /dev/null
+++ b/organizations/templates/organizations/organization_add_contact.html
@@ -0,0 +1,33 @@
+{% extends 'scipost/base.html' %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Add Contact</span>
+{% endblock %}
+
+{% block pagetitle %}{{block.super}} Add Contact{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Add Contact for Organization {{ organization }}</h1>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+      <form method="post">
+        {% csrf_token %}
+        <div class="mb-5">
+            {{ form|bootstrap }}
+        </div>
+
+        <input class="btn btn-primary" type="submit" value="Submit"/>
+      </form>
+    </div>
+</div>
+
+{% endblock content %}
diff --git a/organizations/urls.py b/organizations/urls.py
index 158caa757..ea491532d 100644
--- a/organizations/urls.py
+++ b/organizations/urls.py
@@ -32,6 +32,11 @@ urlpatterns = [
         views.OrganizationDetailView.as_view(),
         name='organization_details'
     ),
+    url(
+        r'^add_contact/(?P<organization_id>[0-9]+)/$',
+        views.organization_add_contact,
+        name='add_contact'
+    ),
     url(
         r'^activate/(?P<activation_key>.+)$',
         views.activate_account,
diff --git a/organizations/views.py b/organizations/views.py
index 4fdb9c6c7..fd59d8c11 100644
--- a/organizations/views.py
+++ b/organizations/views.py
@@ -15,10 +15,11 @@ from django.views.generic.list import ListView
 from guardian.decorators import permission_required
 
 from .constants import ORGTYPE_PRIVATE_BENEFACTOR
-from .forms import ContactActivationForm
+from .forms import NewContactForm, ContactActivationForm
 from .models import Organization, Contact
 
 from funders.models import Funder
+from mails.views import MailEditingSubView
 from organizations.decorators import has_contact
 from partners.models import ProspectivePartner, Partner
 
@@ -108,9 +109,18 @@ def organization_add_contact(request, organization_id):
     form = NewContactForm(request.POST or None, organization=organization)
     if form.is_valid():
         contact = form.save(current_user=request.user)
-        messages.success(request, '<h3>Created contact: %s</h3>Email has been sent.'
-                                  % str(contact))
-        return redirect(reverse('organizations:dashboard'))
+        mail_request = MailEditingSubView(
+            request,
+            mail_code='org_contacts/email_contact_for_activation',
+            contact=contact)
+        if mail_request.is_valid():
+            mail_request.send()
+            messages.success(request, '<h3>Created contact: %s</h3>Email has been sent.'
+                             % str(contact))
+        else:
+            messages.warning(request, 'The mail request was not valid.')
+        return redirect(reverse('organizations:organization_details',
+                                kwargs={'pk': organization.id}))
     context = {
         'organization': organization,
         'form': form
diff --git a/templates/email/org_contacts/email_contact_for_activation.html b/templates/email/org_contacts/email_contact_for_activation.html
new file mode 100644
index 000000000..2419eb779
--- /dev/null
+++ b/templates/email/org_contacts/email_contact_for_activation.html
@@ -0,0 +1,20 @@
+<p>Dear {{contact.get_title_display}} {{contact.user.first_name}} {{contact.user.last_name}},</p>
+
+<p>
+    Many thanks for sponsoring SciPost. We have now created a personal account for you on scipost.org, which will allow you to access all relevant information and functionalities related to sponsoring.
+</p>
+<p>
+    In order to activate your account, please navigate to <a href="https://scipost.org{% url 'organizations:activate_account' contact.activation_key %}?email={{contact.user.email}}">this link</a>. You will be asked to choose a password, after which you will be able to login.
+</p>
+<p>
+    After logging in, you will find a “Org dashboard” link in the top menu, which will take you to your info page.
+</p>
+<p>
+    We are very pleased to welcome you to SciPost, and will be happy to answer any questions you might have.
+</p>
+<p>
+    Sincerely,<br><br>
+    SciPost and its Sponsors Board
+</p>
+
+{% include 'email/_footer.html' %}
diff --git a/templates/email/org_contacts/email_contact_for_activation.json b/templates/email/org_contacts/email_contact_for_activation.json
new file mode 100644
index 000000000..93aaedd2b
--- /dev/null
+++ b/templates/email/org_contacts/email_contact_for_activation.json
@@ -0,0 +1,8 @@
+{
+    "subject": "SciPost: account activation",
+    "to_address": "user.email",
+    "bcc_to": "sponsors@scipost.org",
+    "from_address_name": "SciPost Sponsors Admin",
+    "from_address": "sponsors@scipost.org",
+    "context_object": "contact"
+}
-- 
GitLab