From a11cf2c017b917eafb2f7a368c72e645069846c6 Mon Sep 17 00:00:00 2001
From: Boris Ponsioen <boris1592@gmail.com>
Date: Fri, 23 Dec 2016 15:08:49 +0100
Subject: [PATCH] Move as much logic as possible to submission model

The submission process contains some logic that
could be either handled using default values in the
model (where possible) or abstracted into model
methods. This has the great advantage that the
individual parts can be unit-tested (which is a lot
harder to do with code in the view).

For now there is still some commented-out code for
easy reference. This code will be removed as it is
replaced by the classes above it.
---
 submissions/models.py | 64 +++++++++++++++++++++++++++++++++++++++++--
 submissions/views.py  | 49 ++++-----------------------------
 2 files changed, 67 insertions(+), 46 deletions(-)

diff --git a/submissions/models.py b/submissions/models.py
index 718821309..b9b77f8a6 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -1,6 +1,8 @@
+import datetime
+
 from django.utils import timezone
 from django.utils.safestring import mark_safe
-from django.db import models
+from django.db import models, transaction
 from django.contrib.auth.models import User
 from django.contrib.postgres.fields import ArrayField, JSONField
 from django.template import Template, Context
@@ -138,8 +140,64 @@ class Submission(models.Model):
             return True
         return False
 
-
-    def header_as_table (self):
+    @transaction.atomic
+    def finish_submission(self):
+        if self.is_resubmission:
+            self.mark_other_versions_as_deprecated()
+            self.copy_authors_from_previous_version()
+            self.copy_EIC_from_previous_version()
+            self.set_resubmission_defaults()
+        else:
+            self.authors.add(self.submitted_by)
+
+        self.save()
+
+    def make_assignment(self):
+        assignment = EditorialAssignment(
+            submission=self,
+            to=self.editor_in_charge,
+            accepted=True,
+            date_created=timezone.now(),
+            date_answered=timezone.now(),
+        )
+        assignment.save()
+
+    def set_resubmission_defaults(self):
+        self.open_for_reporting = True
+        self.open_for_commenting = True
+        if self.other_versions()[0].submitted_to_journal == 'SciPost Physics Lecture Notes':
+            self.reporting_deadline = timezone.now() + datetime.timedelta(days=56)
+        else:
+            self.reporting_deadline = timezone.now() + datetime.timedelta(days=28)
+
+    def copy_EIC_from_previous_version(self):
+        last_version = self.other_versions()[0]
+        self.editor_in_charge = last_version.editor_in_charge
+        self.status = 'EICassigned'
+
+    def copy_authors_from_previous_version(self):
+        last_version = self.other_versions()[0]
+
+        for author in last_version.authors.all():
+            self.authors.add(author)
+        for author in last_version.authors_claims.all():
+            self.authors_claims.add(author)
+        for author in last_version.authors_false_claims.all():
+            self.authors_false_claims.add(author)
+
+    def mark_other_versions_as_deprecated(self):
+        for sub in self.other_versions():
+            sub.is_current = False
+            sub.open_for_reporting = False
+            sub.status = 'resubmitted'
+            sub.save()
+
+    def other_versions(self):
+        return Submission.objects.filter(
+            arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr
+        ).exclude(pk=self.id).order_by('-arxiv_vn_nr')
+
+    def header_as_table(self):
         # for Submission page
         header = '<table>'
         header += '<tr><td>Title: </td><td>&nbsp;</td><td>{{ title }}</td></tr>'
diff --git a/submissions/views.py b/submissions/views.py
index 81a73f5da..8495322d5 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -162,7 +162,8 @@ class PrefillUsingIdentifierView(FormView):
                                'arxiv_identifier_w_vn_nr': caller.identifier_with_vn_nr,
                                'arxiv_identifier_wo_vn_nr': caller.identifier_without_vn_nr,
                                'arxiv_vn_nr': caller.version_nr,
-                               'arxiv_link': arxiv_link, 'abstract': abstract}
+                               'arxiv_link': arxiv_link, 'abstract': abstract,
+                               'is_current': True}
                 if is_resubmission:
                     previous_submissions = caller.previous_submissions
                     resubmessage = ('There already exists a preprint with this arXiv identifier '
@@ -256,48 +257,14 @@ class SubmissionCreateView(CreateView):
     def form_valid(self, form):
         submitted_by = Contributor.objects.get(user=self.request.user)
         form.instance.submitted_by = submitted_by
-        form.instance.is_current = True
-
-        if form.cleaned_data['is_resubmission']:
-            form.instance.open_for_reporting = True
-            form.instance.open_for_commenting = True
-
-            deadline = timezone.now() + datetime.timedelta(days=28)  # for papers
-            if form.cleaned_data['submitted_to_journal'] == 'SciPost Physics Lecture Notes':
-                deadline += datetime.timedelta(days=28)
-            form.instance.reporting_deadline = deadline
-
-            # Take information from previous submission(s)
-            previous_submissions = self.previous_submissions(form)
-            form.instance.editor_in_charge = previous_submissions[0].editor_in_charge
-            form.instance.status = 'EICassigned'
-
-            self.mark_previous_submissions_as_deprecated(previous_submissions)
 
+        # Save all the information contained in the form
         submission = form.save()
 
-        if form.cleaned_data['is_resubmission']:
-            # Add many-to-many data
-            for author in previous_submissions[0].authors.all():
-                print('Previous submissions!!')
-                submission.authors.add(author)
-            for author in previous_submissions[0].authors_claims.all():
-                submission.authors_claims.add(author)
-            for author in previous_submissions[0].authors_false_claims.all():
-                submission.authors_false_claims.add(author)
-
-            submission.save()
-
-            # Make assignment
-            assignment = EditorialAssignment(
-                submission=submission,
-                to=submission.editor_in_charge,
-                accepted=True,
-                date_created=timezone.now(),
-                date_answered=timezone.now(),
-            )
-            assignment.save()
+        # Perform all extra actions and set information not contained in the form
+        submission.finish_submission()
 
+        if submission.is_resubmission:
             # Assign permissions
             assign_perm('can_take_editorial_actions', submission.editor_in_charge.user, submission)
             ed_admins = Group.objects.get(name='Editorial Administrators')
@@ -308,10 +275,6 @@ class SubmissionCreateView(CreateView):
             SubmissionUtils.send_authors_resubmission_ack_email()
             SubmissionUtils.send_EIC_reappointment_email()
         else:
-            # Add many-to-many data
-            submission.authors.add(submitted_by)
-            submission.save()
-
             # Send emails
             SubmissionUtils.load({'submission': submission})
             SubmissionUtils.send_authors_submission_ack_email()
-- 
GitLab