From 729355df62132aacc7aadfefdda12a6f346d98ce Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Wed, 20 Feb 2019 12:55:54 +0100
Subject: [PATCH] Partial work on organizations.Contact create facilities

---
 organizations/forms.py | 90 ++++++++++++++++++++++++++++++++++++++++++
 organizations/views.py | 15 +++++++
 2 files changed, 105 insertions(+)

diff --git a/organizations/forms.py b/organizations/forms.py
index 8428febcc..079d77fd8 100644
--- a/organizations/forms.py
+++ b/organizations/forms.py
@@ -12,6 +12,96 @@ from django.db import transaction
 from .constants import ROLE_KINDS
 from .models import Contact
 
+from scipost.constants import TITLE_CHOICES
+
+
+class ContactForm(forms.ModelForm):
+    """
+    This Contact form is mainly used for editing Contact instances.
+    """
+    class Meta:
+        model = Contact
+
+
+class NewContactForm(ContactForm):
+    """
+    This Contact form is used to create new Contact instances, as it will also handle
+    possible sending and activation of User instances coming with the new Contact.
+    """
+    title = forms.ChoiceField(choices=TITLE_CHOICES, label='Title')
+    first_name = forms.CharField()
+    last_name = forms.CharField()
+    email = forms.CharField()
+    existing_user = None
+
+    def __init__(self, *args, **kwargs):
+        """
+        Organization is a required argument to tell the formset which Organization
+        the Contact is being edited for in the current form.
+        """
+        self.organization = kwargs.pop('organization')
+        super().__init__(*args, **kwargs)
+
+    def clean_email(self):
+        """
+        Check if User already is known in the system.
+        """
+        email = self.cleaned_data['email']
+        try:
+            self.existing_user = User.objects.get(email=email)
+            if not self.data.get('confirm_use_existing', '') == 'on':
+                # Do not give error if user wants to use existing User
+                self.add_error('email', 'This User is already registered.')
+            self.fields['confirm_use_existing'] = forms.BooleanField(
+                required=False, initial=False, label='Use the existing user instead: %s %s'
+                                                     % (self.existing_user.first_name,
+                                                        self.existing_user.last_name))
+        except User.DoesNotExist:
+            pass
+        return email
+
+    @transaction.atomic
+    def save(self, current_user, commit=True):
+        """
+        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
+            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)
+        user = User(
+            first_name=self.cleaned_data['first_name'],
+            last_name=self.cleaned_data['last_name'],
+            email=self.cleaned_data['email'],
+            username=self.cleaned_data['email'],
+            is_active=False,
+        )
+        user.save()
+        contact = Contact(
+            user=user,
+            title=self.cleaned_data['title']
+        )
+        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)
+        return contact
+
 
 class ContactActivationForm(forms.ModelForm):
     class Meta:
diff --git a/organizations/views.py b/organizations/views.py
index afe899e01..4fdb9c6c7 100644
--- a/organizations/views.py
+++ b/organizations/views.py
@@ -102,6 +102,21 @@ class OrganizationDetailView(DetailView):
         return queryset
 
 
+@permission_required('scipost.can_manage_SPB', return_403=True)
+def organization_add_contact(request, organization_id):
+    organization = get_object_or_404(Organization, id=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'))
+    context = {
+        'organization': organization,
+        'form': form
+    }
+    return render(request, 'organizations/organization_add_contact.html', context)
+
 
 def activate_account(request, activation_key):
     contact = get_object_or_404(Contact, user__is_active=False,
-- 
GitLab