From 6381168bd5a39f5c7da1b80f66237f3da2d930e8 Mon Sep 17 00:00:00 2001
From: Jorran de Wit <jorrandewit@outlook.com>
Date: Fri, 30 Nov 2018 16:00:06 +0100
Subject: [PATCH] Renovation

---
 preprints/helpers.py                          |   8 +-
 submissions/admin.py                          |   1 +
 submissions/constants.py                      |   1 +
 submissions/forms.py                          | 515 ++++++++++++++----
 submissions/models.py                         |   4 +-
 .../submissions/submission_form.html          |  16 +-
 .../submissions/submission_prefill_form.html  |   3 +-
 .../submission_resubmission_candidates.html   |   2 +-
 submissions/views.py                          |  39 +-
 9 files changed, 451 insertions(+), 138 deletions(-)

diff --git a/preprints/helpers.py b/preprints/helpers.py
index 918fd3839..596cf3a1c 100644
--- a/preprints/helpers.py
+++ b/preprints/helpers.py
@@ -11,7 +11,11 @@ from .models import Preprint
 
 
 def generate_new_scipost_identifier(old_preprint=None):
-    """Return an identifier for a new SciPost preprint series without version number."""
+    """
+    Return an identifier for a new SciPost preprint series without version number.
+
+    TODO: This method will explode as soon as it will be used similtaneously by two or more people.
+    """
     now = timezone.now()
 
     if isinstance(old_preprint, Submission):
@@ -34,7 +38,7 @@ def generate_new_scipost_identifier(old_preprint=None):
         else:
             existing_identifier = str(existing_identifier + 1)
 
-        identifier = '{year}{month}_{identifier}'.format(
+        identifier = '{year}{month}_{identifier}v1'.format(
             year=now.year, month=str(now.month).rjust(2, '0'),
             identifier=existing_identifier.rjust(5, '0'))
         return identifier, int(existing_identifier)
diff --git a/submissions/admin.py b/submissions/admin.py
index 7e02b3362..7b7a19e8e 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -67,6 +67,7 @@ class SubmissionAdmin(GuardedModelAdmin):
             'fields': (
                 'is_current',
                 'is_resubmission',
+                'is_resubmission_of',
                 'list_of_changes'),
         }),
         ('Submission details', {
diff --git a/submissions/constants.py b/submissions/constants.py
index d32c9d654..a10841d53 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -46,6 +46,7 @@ NO_REQUIRED_ACTION_STATUSES = [
 ]
 
 SUBMISSION_TYPE = (
+    # ('', None),
     ('Letter', 'Letter (broad-interest breakthrough results)'),
     ('Article', 'Article (in-depth reports on specialized research)'),
     ('Review', 'Review (candid snapshot of current research in a given area)'),
diff --git a/submissions/forms.py b/submissions/forms.py
index 75ce8df0b..85cd7f1fe 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -98,43 +98,190 @@ class SubmissionPoolFilterForm(forms.Form):
 # Submission and resubmission #
 ###############################
 
-class SubmissionChecks:
-    """Mixin with checks run at least the Submission creation form."""
+class SubmissionService:
+    """
+    Object to run checks for prefiller and submit manuscript forms.
+    """
 
-    use_arxiv_preprint = True
     arxiv_data = {}
-    is_resubmission = False
-    last_submission = None
 
-    def __init__(self, *args, **kwargs):
-        self.requested_by = kwargs.pop('requested_by', None)
-        super().__init__(*args, **kwargs)
-        # Prefill `is_resubmission` property if data is coming from initial data
-        if kwargs.get('initial', None):
-            if kwargs['initial'].get('is_resubmission', None):
-                self.is_resubmission = kwargs['initial']['is_resubmission'] in ('True', True)
-            elif kwargs['initial'].get('resubmission', None):
-                # Resubmission is explicitly chosen by user.
-                self.is_resubmission = True
+    def __init__(self, requested_by, preprint_server, identifier=None, resubmission_of_id=None):
+        self.requested_by = requested_by
+        self.preprint_server = preprint_server
+        self.identifier = identifier
+        self.resubmission_of_id = resubmission_of_id
+
+        if self.preprint_server == 'arxiv':
+            # Do the call here to prevent multiple calls to the arXiv API in one request.
+            self._call_arxiv()
+
+    @property
+    def latest_submission(self):
+        """
+        Return latest version of preprint series or None.
+        """
+        if hasattr(self, '_latest_submission'):
+            return self._latest_submission
+
+        if self.identifier:
+            # Check if is resubmission when identifier data is submitted.
+            identifier = self.identifier.rpartition('v')[0]
+            self._latest_submission = Submission.objects.filter(
+                preprint__identifier_wo_vn_nr=identifier).order_by(
+                '-preprint__vn_nr').first()
+        elif self.resubmission_of_id:
+            # Resubmission (submission id) is selected by user.
+            try:
+                self._latest_submission = Submission.objects.filter(
+                    id=int(self.resubmission_of_id)).order_by('-preprint__vn_nr').first()
+            except ValueError:
+                self._latest_submission = None
+        return self._latest_submission
 
-        # `is_resubmission` property if data is coming from (POST) request
-        if kwargs.get('data', None):
-            if kwargs['data'].get('is_resubmission', None):
-                self.is_resubmission = kwargs['data']['is_resubmission'] in ('True', True)
+    def run_checks(self):
+        """
+        Do several pre-checks (using the arXiv API if needed).
+
+        This is needed for both the prefill and submission forms.
+        """
+        self.arxiv_data = {}
+        self._submission_already_exists()
+        self._submission_previous_version_is_valid_for_submission()
+
+        if self.preprint_server == 'arxiv':
+            self._submission_is_already_published()
 
-    def _submission_already_exists(self, identifier):
+    def get_latest_submission_data(self):
+        """
+        Return initial form data originating from earlier Submission.
+        """
+        if self.is_resubmission():
+            return {
+                'title': self.latest_submission.title,
+                'abstract': self.latest_submission.abstract,
+                'author_list': self.latest_submission.author_list,
+                'discipline': self.latest_submission.discipline,
+                'domain': self.latest_submission.domain,
+                'referees_flagged': self.latest_submission.referees_flagged,
+                'referees_suggested': self.latest_submission.referees_suggested,
+                'secondary_areas': self.latest_submission.secondary_areas,
+                'subject_area': self.latest_submission.subject_area,
+                'submitted_to': self.latest_submission.submitted_to,
+                'submission_type': self.latest_submission.submission_type,
+            }
+        return {}
+
+    def is_resubmission(self):
+        """
+        Check if Submission is a SciPost or arXiv resubmission.
+        """
+        return self.latest_submission is not None
+
+    def identifier_matches_regex(self, journal_code):
+        """
+        Check if identifier is valid for the Journal submitting to.
+        """
+        if self.preprint_server != 'arxiv':
+            # Only check arXiv identifiers
+            return
+
+        if journal_code in EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS.keys():
+            regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS[journal_code]
+        else:
+            regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS['default']
+
+        pattern = re.compile(regex)
+        if not pattern.match(self.identifier):
+            # No match object returned, identifier is invalid
+            error_message = ('The journal you want to submit to does not allow for this'
+                             ' identifier. Please contact SciPost if you have'
+                             ' any further questions.')
+            raise forms.ValidationError(error_message, code='submitted_to')
+
+    def process_resubmission_procedure(self, submission):
+        """
+        Update all fields for new and old Submission and EditorialAssignments to comply with
+        the resubmission procedures.
+
+        -- submission: the new version of the Submission series.
+        """
+        if not self.latest_submission:
+            raise Submission.DoesNotExist
+
+        # Close last submission
+        Submission.objects.filter(id=self.latest_submission.id).update(
+            is_current=False, open_for_reporting=False, status=STATUS_RESUBMITTED)
+
+        # Copy Topics
+        submission.topics.add(*self.latest_submission.topics.all())
+
+        # Open for comment and reporting and copy EIC info
+        Submission.objects.filter(id=submission.id).update(
+            open_for_reporting=True,
+            open_for_commenting=True,
+            is_resubmission=True,
+            visible_pool=True,
+            refereeing_cycle=CYCLE_UNDETERMINED,
+            editor_in_charge=self.latest_submission.editor_in_charge,
+            status=STATUS_EIC_ASSIGNED)
+
+        # Add author(s) (claim) fields
+        submission.authors.add(*self.latest_submission.authors.all())
+        submission.authors_claims.add(*self.latest_submission.authors_claims.all())
+        submission.authors_false_claims.add(*self.latest_submission.authors_false_claims.all())
+
+        # Create new EditorialAssigment for the current Editor-in-Charge
+        EditorialAssignment.objects.create(
+            submission=submission,
+            to=self.latest_submission.editor_in_charge,
+            status=STATUS_ACCEPTED)
+
+    def _submission_already_exists(self):
         """
         Check if preprint has already been submitted before.
         """
-        if Submission.objects.filter(preprint__identifier_w_vn_nr=identifier).exists():
+        if Submission.objects.filter(preprint__identifier_w_vn_nr=self.identifier).exists():
             error_message = 'This preprint version has already been submitted to SciPost.'
             raise forms.ValidationError(error_message, code='duplicate')
 
-    def _call_arxiv(self, identifier):
+    def _submission_previous_version_is_valid_for_submission(self):
+        """
+        Check if previous submitted versions have the appropriate status.
+        """
+
+        if self.latest_submission:
+            if self.latest_submission.status == STATUS_REJECTED:
+                # Explicitly give rejected status warning.
+                error_message = ('This preprint has previously undergone refereeing '
+                                 'and has been rejected. Resubmission is only possible '
+                                 'if the manuscript has been substantially reworked into '
+                                 'a new submission with distinct identifier.')
+                raise forms.ValidationError(error_message)
+            elif self.latest_submission.open_for_resubmission:
+                # Check if verified author list contains current user.
+                self.is_resubmission = True
+                if self.requested_by.contributor not in self.latest_submission.authors.all():
+                    error_message = ('There exists a preprint with this identifier '
+                                     'but an earlier version number. Resubmission is only possible'
+                                     ' if you are a registered author of this manuscript.')
+                    raise forms.ValidationError(error_message)
+            else:
+                # Submission has not an appropriate status for resubmission.
+                error_message = ('There exists a preprint with this identifier '
+                                 'but an earlier version number, which is still undergoing '
+                                 'peer refereeing. '
+                                 'A resubmission can only be performed after request '
+                                 'from the Editor-in-charge. Please wait until the '
+                                 'closing of the previous refereeing round and '
+                                 'formulation of the Editorial Recommendation '
+                                 'before proceeding with a resubmission.')
+                raise forms.ValidationError(error_message)
+
+    def _call_arxiv(self):
         """
         Retrieve all data from the ArXiv database for `identifier`.
         """
-        caller = ArxivCaller(identifier)
+        caller = ArxivCaller(self.identifier)
         if caller.is_valid:
             self.arxiv_data = caller.data
             self.metadata = caller.metadata
@@ -142,7 +289,7 @@ class SubmissionChecks:
             error_message = 'A preprint associated to this identifier does not exist.'
             raise forms.ValidationError(error_message)
 
-    def _submission_is_already_published(self, identifier):
+    def _submission_is_already_published(self):
         """
         Check if preprint number is already registered with a DOI in the *ArXiv* database.
         """
@@ -158,117 +305,257 @@ class SubmissionChecks:
             raise forms.ValidationError(error_message, code='published',
                                         params={'published_id': published_id})
 
-    def _submission_previous_version_is_valid_for_submission(self, identifier):
+
+class SubmissionForm(forms.ModelForm):
+    """
+    Form to submit a new (re)Submission.
+    """
+
+    identifier_w_vn_nr = forms.CharField(widget=forms.HiddenInput())
+    preprint_file = forms.FileField()
+
+    class Meta:
+        model = Submission
+        fields = [
+            'is_resubmission_of',
+            'discipline',
+            'submitted_to',
+            'proceedings',
+            'submission_type',
+            'domain',
+            'subject_area',
+            'secondary_areas',
+            'title',
+            'author_list',
+            'abstract',
+            'author_comments',
+            'list_of_changes',
+            'remarks_for_editors',
+            'referees_suggested',
+            'referees_flagged',
+            'arxiv_link',
+        ]
+        widgets = {
+            'is_resubmission_of': forms.HiddenInput(),
+            'secondary_areas': forms.SelectMultiple(choices=SCIPOST_SUBJECT_AREAS),
+            'arxiv_link': forms.TextInput(
+                attrs={'placeholder': 'ex.:  arxiv.org/abs/1234.56789v1'}),
+            'remarks_for_editors': forms.Textarea(
+                attrs={'placeholder': 'Any private remarks (for the editors only)', 'rows': 5}),
+            'referees_suggested': forms.Textarea(
+                attrs={'placeholder': 'Optional: names of suggested referees', 'rows': 5}),
+            'referees_flagged': forms.Textarea(
+                attrs={
+                    'placeholder': 'Optional: names of referees whose reports should be treated with caution (+ short reason)',
+                    'rows': 5
+                }),
+            'author_comments': forms.Textarea(
+                attrs={'placeholder': 'Your resubmission letter (will be viewable online)'}),
+            'list_of_changes': forms.Textarea(
+                attrs={'placeholder': 'Give a point-by-point list of changes (will be viewable online)'}),
+        }
+
+    def __init__(self, *args, **kwargs):
+        self.requested_by = kwargs.pop('requested_by')
+        self.preprint_server = kwargs.pop('preprint_server', 'arxiv')
+        self.resubmission_preprint = kwargs['initial'].get('resubmission', False)
+
+        self.service = SubmissionService(
+            self.requested_by, self.preprint_server,
+            identifier=kwargs['initial'].get('identifier_w_vn_nr', None),
+            resubmission_of_id=self.resubmission_preprint)
+        if self.preprint_server == 'scipost':
+            kwargs['initial'] = self.service.get_latest_submission_data()
+
+        super().__init__(*args, **kwargs)
+        # self.service.run_checks()
+
+        if not self.preprint_server == 'arxiv':
+            # No arXiv-specific data required.
+            del self.fields['identifier_w_vn_nr']
+            del self.fields['arxiv_link']
+        elif not self.preprint_server == 'scipost':
+            # No need for a file upload if user is not using the SciPost preprint server.
+            del self.fields['preprint_file']
+
+        # Find all submission allowed to be resubmitted by current user.
+        self.fields['is_resubmission_of'].queryset = Submission.objects.candidate_for_resubmission(
+            self.requested_by)
+
+        # Fill resubmission-dependent fields
+        if self.is_resubmission():
+            self.fields['is_resubmission_of'].initial = self.service.latest_submission
+        else:
+            # These fields are only available for resubmissions.
+            del self.fields['author_comments']
+            del self.fields['list_of_changes']
+
+        if not self.fields['is_resubmission_of'].initial:
+            # No intial nor submitted data found.
+            del self.fields['is_resubmission_of']
+
+        # Select Journal instances.
+        self.fields['submitted_to'].queryset = Journal.objects.active()
+        self.fields['submitted_to'].label = 'Journal: submit to'
+
+        # Proceedings submission fields
+        qs = self.fields['proceedings'].queryset.open_for_submission()
+        self.fields['proceedings'].queryset = qs
+        self.fields['proceedings'].empty_label = None
+        if not qs.exists():
+            # No proceedings issue to submit to, so adapt the form fields
+            self.fields['submitted_to'].queryset = self.fields['submitted_to'].queryset.exclude(
+                doi_label=SCIPOST_JOURNAL_PHYSICS_PROC)
+            del self.fields['proceedings']
+
+    def is_resubmission(self):
+        return self.service.is_resubmission()
+
+    def clean(self, *args, **kwargs):
         """
-        Check if previous submitted versions have the appropriate status.
+        Do all general checks for Submission.
         """
-        identifiers = self.identifier_into_parts(identifier)
-        self.last_submission = Submission.objects.filter(
-            preprint__identifier_wo_vn_nr=identifiers['identifier_wo_vn_nr']).order_by(
-            'preprint__vn_nr').last()
-
-        # If submissions are found; check their statuses
-        if self.last_submission:
-            if self.last_submission.open_for_resubmission:
-                self.is_resubmission = True
-                if self.requested_by.contributor not in self.last_submission.authors.all():
-                    error_message = ('There exists a preprint with this identifier '
-                                     'but an earlier version number. Resubmission is only possible'
-                                     ' if you are a registered author of this manuscript.')
-                    raise forms.ValidationError(error_message)
-            elif self.last_submission.status == STATUS_REJECTED:
-                error_message = ('This preprint has previously undergone refereeing '
-                                 'and has been rejected. Resubmission is only possible '
-                                 'if the manuscript has been substantially reworked into '
-                                 'a new submission with distinct identifier.')
-                raise forms.ValidationError(error_message)
-            else:
-                error_message = ('There exists a preprint with this identifier '
-                                 'but an earlier version number, which is still undergoing '
-                                 'peer refereeing. '
-                                 'A resubmission can only be performed after request '
-                                 'from the Editor-in-charge. Please wait until the '
-                                 'closing of the previous refereeing round and '
-                                 'formulation of the Editorial Recommendation '
-                                 'before proceeding with a resubmission.')
-                raise forms.ValidationError(error_message)
+        cleaned_data = super().clean(*args, **kwargs)
+
+        # SciPost preprints are auto-generated here.
+        if 'identifier_w_vn_nr' not in cleaned_data:
+            self.service.identifier, self.scipost_identifier = generate_new_scipost_identifier(
+                cleaned_data.get('resubmission', None))
+            # Also copy to the form data
+            self.cleaned_data['identifier_w_vn_nr'] = self.service.identifier
+
+        # Run checks again to clean any possible human intervention and run checks again
+        # with possibly newly generated identifier.
+        self.service.run_checks()
+        self.service.identifier_matches_regex(cleaned_data['submitted_to'].doi_label)
+
+        if self.cleaned_data['submitted_to'].doi_label != SCIPOST_JOURNAL_PHYSICS_PROC:
+            try:
+                del self.cleaned_data['proceedings']
+            except KeyError:
+                # No proceedings returned to data
+                return cleaned_data
+        return cleaned_data
 
-    def identifier_matches_regex(self, identifier, journal_code):
+    def clean_author_list(self):
         """
-        Check if identifier is valid for the Journal submitting to.
+        Check if author list matches the Contributor submitting.
         """
-        if journal_code in EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS.keys():
-            regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS[journal_code]
-        else:
-            regex = EXPLICIT_REGEX_MANUSCRIPT_CONSTRAINTS['default']
+        if not self.requested_by.last_name.lower() in self.cleaned_data['author_list'].lower():
+            error_message = ('Your name does not match that of any of the authors. '
+                             'You are not authorized to submit this preprint.')
+            self.add_error('author_list', error_message)
+        return self.cleaned_data['author_list']
 
-        pattern = re.compile(regex)
-        if not pattern.match(identifier):
-            # No match object returned, identifier is invalid
-            error_message = ('The journal you want to submit to does not allow for this'
-                             ' identifier. Please contact SciPost if you have'
-                             ' any further questions.')
-            raise forms.ValidationError(error_message, code='submitted_to')
+    def clean_submission_type(self):
+        """
+        Validate Submission type for the SciPost Physics journal.
+        """
+        submission_type = self.cleaned_data['submission_type']
+        journal_doi_label = self.cleaned_data['submitted_to'].doi_label
+        if journal_doi_label == SCIPOST_JOURNAL_PHYSICS and not submission_type:
+            self.add_error('submission_type', 'Please specify the submission type.')
+        return submission_type
 
-    def submission_is_resubmission(self):
-        """Check if the Submission is a resubmission."""
-        return self.is_resubmission
+    def set_pool(self, submission):
+        """
+        Set the default set of (guest) Fellows for this Submission.
+        """
+        qs = Fellowship.objects.active()
+        fellows = qs.regular().filter(
+            contributor__discipline=submission.discipline).return_active_for_submission(submission)
+        submission.fellows.set(fellows)
 
-    def identifier_into_parts(self, identifier):
-        """Split the preprint identifier into parts."""
-        data = {
-            'identifier_w_vn_nr': identifier,
-            'identifier_wo_vn_nr': identifier.rpartition('v')[0],
-            'vn_nr': int(identifier.rpartition('v')[2])
-        }
-        return data
+        if submission.proceedings:
+            # Add Guest Fellowships if the Submission is a Proceedings manuscript
+            guest_fellows = qs.guests().filter(
+                proceedings=submission.proceedings).return_active_for_submission(submission)
+            submission.fellows.add(*guest_fellows)
 
-    def do_pre_checks(self, identifier):
-        """Group call of different checks."""
-        self._submission_already_exists(identifier)
-        if self.use_arxiv_preprint:
-            self._call_arxiv(identifier)
-        self._submission_is_already_published(identifier)
-        self._submission_previous_version_is_valid_for_submission(identifier)
+    @transaction.atomic
+    def save(self):
+        """
+        Create the new Submission and Preprint instances.
+        """
+        submission = super().save(commit=False)
+        submission.submitted_by = self.requested_by.contributor
+
+        # Save identifiers
+        identifiers = self.cleaned_data['identifier_w_vn_nr'].rpartition('v')
+        preprint, __ = Preprint.objects.get_or_create(
+            identifier_w_vn_nr=self.cleaned_data['identifier_w_vn_nr'],
+            identifier_wo_vn_nr=identifiers[0],
+            vn_nr=identifiers[2],
+            url=self.cleaned_data.get('arxiv_link', ''),
+            scipost_preprint_identifier=self.scipost_identifier,
+            _file=self.cleaned_data.get('preprint_file', None), )
+
+        # Save metadata directly from ArXiv call without possible user interception
+        submission.metadata = self.service.metadata
+        submission.preprint = preprint
+
+        submission.save()
+        if self.is_resubmission():
+            self.process_resubmission_procedure(submission)
+
+        # Gather first known author and Fellows.
+        submission.authors.add(self.requested_by.contributor)
+        self.set_pool(submission)
+
+        # Return latest version of the Submission. It could be outdated by now.
+        submission.refresh_from_db()
+        return submission
 
 
-class SubmissionIdentifierForm(SubmissionChecks, forms.Form):
-    """Prefill SubmissionForm using this form that takes an arXiv ID only."""
+class SubmissionIdentifierForm(forms.Form):
+    """
+    Prefill SubmissionForm using this form that takes an arXiv ID only.
+    """
 
     IDENTIFIER_PLACEHOLDER = 'new style (with version nr) ####.####(#)v#(#)'
 
     identifier_w_vn_nr = forms.RegexField(
+        label='arXiv identifier with version number',
         regex=IDENTIFIER_PATTERN_NEW, strip=True,
         error_messages={'invalid': strings.arxiv_query_invalid},
         widget=forms.TextInput({'placeholder': IDENTIFIER_PLACEHOLDER}))
 
+    def __init__(self, *args, **kwargs):
+        self.requested_by = kwargs.pop('requested_by')
+        return super().__init__(*args, **kwargs)
+
     def clean_identifier_w_vn_nr(self):
-        """Do basic prechecks based on the arXiv ID only."""
+        """
+        Do basic prechecks based on the arXiv ID only.
+        """
         identifier = self.cleaned_data['identifier_w_vn_nr']
-        self.do_pre_checks(identifier)
+        self.service = SubmissionService(self.requested_by, 'arxiv', identifier=identifier)
+        self.service.run_checks()
         return identifier
 
-    def request_arxiv_preprint_form_prefill_data(self):
-        """Return dictionary to prefill `RequestSubmissionForm`."""
-        form_data = self.arxiv_data
+    def get_initial_submission_data(self):
+        """
+        Return dictionary to prefill `SubmissionForm`.
+        """
+        form_data = self.service.arxiv_data
         form_data['identifier_w_vn_nr'] = self.cleaned_data['identifier_w_vn_nr']
-        if self.submission_is_resubmission():
+        if self.service.is_resubmission():
             form_data.update({
-                'is_resubmission': True,
-                'discipline': self.last_submission.discipline,
-                'domain': self.last_submission.domain,
-                'referees_flagged': self.last_submission.referees_flagged,
-                'referees_suggested': self.last_submission.referees_suggested,
-                'secondary_areas': self.last_submission.secondary_areas,
-                'subject_area': self.last_submission.subject_area,
-                'submitted_to': self.last_submission.submitted_to,
-                'submission_type': self.last_submission.submission_type,
+                'discipline': self.service.latest_submission.discipline,
+                'domain': self.service.latest_submission.domain,
+                'referees_flagged': self.service.latest_submission.referees_flagged,
+                'referees_suggested': self.service.latest_submission.referees_suggested,
+                'secondary_areas': self.service.latest_submission.secondary_areas,
+                'subject_area': self.service.latest_submission.subject_area,
+                'submitted_to': self.service.latest_submission.submitted_to,
+                'submission_type': self.service.latest_submission.submission_type,
             })
         return form_data
 
 
-class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
-    """Form to submit a new Submission."""
+# class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
+class RequestSubmissionForm(forms.ModelForm):
+    """DEPRECATD: Form to submit a new Submission."""
 
     scipost_identifier = None
 
@@ -316,12 +603,15 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
         super().__init__(*args, **kwargs)
 
         # Update resubmission-dependent fields
-        resubmission_preprint = kwargs.get('initial', {}).get('resubmission', None)
+        self.resubmission_preprint = kwargs.get('initial', {}).get('resubmission', None)
         self.fields['resubmission'].queryset = Submission.objects.candidate_for_resubmission(
             self.requested_by)  # This is auto-filled by the resubmit_manuscript view.
-        if resubmission_preprint:
-            self.fields['resubmission'].initial = self.fields['resubmission'].queryset.get(
-                    preprint__identifier_w_vn_nr=resubmission_preprint)
+        if self.resubmission_preprint and self.resubmission_preprint not in ('false', False):
+            try:
+                self.fields['resubmission'].initial = self.fields['resubmission'].queryset.get(
+                        preprint__identifier_w_vn_nr=self.resubmission_preprint)
+            except Submission.DoesNotExist:
+                self.form_complete = False
 
         if not self.submission_is_resubmission():
             # These fields are only available for resubmissions
@@ -360,6 +650,11 @@ class RequestSubmissionForm(SubmissionChecks, forms.ModelForm):
     def clean(self, *args, **kwargs):
         """Do all prechecks which are also done in the prefiller."""
         cleaned_data = super().clean(*args, **kwargs)
+
+        if not self.form_complete:
+            self.add_error(None, 'The preprint identifier selected for resubmission is not valid.')
+            return cleaned_data
+
         # SciPost preprints are auto-generated here.
         if 'identifier_w_vn_nr' not in cleaned_data:
             cleaned_data['identifier_w_vn_nr'], self.scipost_identifier = generate_new_scipost_identifier(cleaned_data.get('resubmission', None))
diff --git a/submissions/models.py b/submissions/models.py
index 58acca549..19e17e177 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -75,6 +75,8 @@ class Submission(models.Model):
     is_current = models.BooleanField(default=True)
     visible_public = models.BooleanField("Is publicly visible", default=False)
     visible_pool = models.BooleanField("Is visible in the Pool", default=False)
+    is_resubmission_of = models.ForeignKey(
+        'self', blank=True, null=True, related_name='successor')
     is_resubmission = models.BooleanField(default=False)
     refereeing_cycle = models.CharField(
         max_length=30, choices=SUBMISSION_CYCLES, default=CYCLE_DEFAULT, blank=True)
@@ -84,7 +86,7 @@ class Submission(models.Model):
 
     subject_area = models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS,
                                     verbose_name='Primary subject area', default='Phys:QP')
-    submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE)
+    submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE, blank=True)
     submitted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
                                      related_name='submitted_submissions')
     voting_fellows = models.ManyToManyField('colleges.Fellowship', blank=True,
diff --git a/submissions/templates/submissions/submission_form.html b/submissions/templates/submissions/submission_form.html
index e397677c9..433ff7ed5 100644
--- a/submissions/templates/submissions/submission_form.html
+++ b/submissions/templates/submissions/submission_form.html
@@ -48,16 +48,24 @@
         <p>
             Please prepare your manuscript according to the <a href="{% url 'submissions:author_guidelines' %}">author guidelines</a>.
         </p>
-        {% if form.fields.resubmission %}
+
+
+        {% if form.is_resubmission %}
             <hr>
             <p class="mb-1">You are submitting a new version of your manuscript:</p>
-            <h3><a href="{{ form.fields.resubmission.initial.get_absolute_url }}" target="_blank">{{ form.fields.resubmission.initial.title }}</a></h3>
+            <h3><a href="{{ form.fields.is_resubmission_of.initial.get_absolute_url }}" target="_blank">{{ form.fields.is_resubmission_of.initial.title }}</a></h3>
             <p>
-                by {{ form.fields.resubmission.initial.author_list }}
+                by {{ form.fields.is_resubmission_of.initial.author_list }}
                 <br>
-                Preprint number: {{ form.fields.resubmission.initial.preprint.identifier_w_vn_nr }}
+                Preprint number: {{ form.fields.is_resubmission_of.initial.preprint.identifier_w_vn_nr }}
             </p>
         {% endif %}
+
+        {% comment %}
+        {% if not form.form_complete %}
+            <h3 class="text-danger">Please check the preprint identifier used for resubmission. Current identifier {{ form.resubmission_preprint }} is not valid.</h3>
+        {% endif %}
+        {% endcomment %}
     </div>
 </div>
 
diff --git a/submissions/templates/submissions/submission_prefill_form.html b/submissions/templates/submissions/submission_prefill_form.html
index 0b9cdb911..9a4e96e80 100644
--- a/submissions/templates/submissions/submission_prefill_form.html
+++ b/submissions/templates/submissions/submission_prefill_form.html
@@ -35,7 +35,8 @@
             <div class='card-body'>
                 <h3>Please provide the arXiv identifier for your Submission</h3>
                 <p><em>(give the identifier without prefix but with version number, as per the placeholder)</em></p>
-                <form action="{% url 'submissions:submit_manuscript_arxiv' %}" method="get">
+                <form action="{% url 'submissions:prefill_using_identifier' %}" method="post">
+                  {% csrf_token %}
                   {{ form|bootstrap }}
                   <input type="submit" class="btn btn-outline-secondary" value="Query arXiv"/>
                       <br>
diff --git a/submissions/templates/submissions/submission_resubmission_candidates.html b/submissions/templates/submissions/submission_resubmission_candidates.html
index 446835d47..8cc116580 100644
--- a/submissions/templates/submissions/submission_resubmission_candidates.html
+++ b/submissions/templates/submissions/submission_resubmission_candidates.html
@@ -21,7 +21,7 @@
                         <br>
                         Preprint number: {{ submission.preprint.identifier_w_vn_nr }}
                         <br>
-                        <button type="submit" name="submission" value="{{ submission.preprint.identifier_w_vn_nr }}"class="btn btn-primary py-1 mt-1">Resubmit this Submission</button>
+                        <button type="submit" name="submission" value="{{ submission.preprint.id }}"class="btn btn-primary py-1 mt-1">Resubmit this Submission</button>
                     </li>
                 {% endfor %}
             </ul>
diff --git a/submissions/views.py b/submissions/views.py
index f48425f2c..95070361e 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -30,7 +30,7 @@ from .models import (
     Submission, EICRecommendation, EditorialAssignment, RefereeInvitation, Report, SubmissionEvent)
 from .mixins import SubmissionAdminViewMixin
 from .forms import (
-    SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSearchForm, RecommendationVoteForm,
+    SubmissionIdentifierForm, SubmissionForm, RequestSubmissionForm, SubmissionSearchForm, RecommendationVoteForm,
     ConsiderAssignmentForm, InviteEditorialAssignmentForm, EditorialAssignmentForm, VetReportForm,
     SetRefereeingDeadlineForm, RefereeSearchForm, #RefereeSelectForm,
     iThenticateReportForm, VotingEligibilityForm,
@@ -77,16 +77,20 @@ def resubmit_manuscript(request):
     if request.POST and request.POST.get('submission'):
         if request.POST['submission'] == 'new':
             return redirect(reverse('submissions:submit_manuscript_scipost') + '?resubmission=false')
-        try:
-            last_submission = Submission.objects.candidate_for_resubmission(request.user).get(
-                preprint__identifier_w_vn_nr=request.POST['submission'])
-            extra_param = '?resubmission={}'.format(request.POST['submission'])
 
+        last_submission = Submission.objects.candidate_for_resubmission(request.user).filter(
+            id=request.POST['submission']).first()
+
+        if last_submission:
             if last_submission.preprint.scipost_preprint_identifier:
                 # Determine right preprint-view.
+                extra_param = '?resubmission={}'.format(request.POST['submission'])
                 return redirect(reverse('submissions:submit_manuscript_scipost') + extra_param)
-            return redirect(reverse('submissions:submit_manuscript') + extra_param)
-        except Submission.DoesNotExist:
+            else:
+                extra_param = '?identifier_w_vn_nr={}'.format(
+                    last_submission.preprint.identifier_w_vn_nr)
+                return redirect(reverse('submissions:submit_manuscript') + extra_param)
+        else:
             # POST request invalid. Try again with GET request.
             return redirect('submissions:resubmit_manuscript')
     context = {
@@ -100,7 +104,7 @@ class RequestSubmissionView(LoginRequiredMixin, PermissionRequiredMixin, CreateV
 
     permission_required = 'scipost.can_submit_manuscript'
     success_url = reverse_lazy('scipost:personal_page')
-    form_class = RequestSubmissionForm
+    form_class = SubmissionForm  #RequestSubmissionForm
     template_name = 'submissions/submission_form.html'
 
     def get_context_data(self, *args, **kwargs):
@@ -154,15 +158,17 @@ class RequestSubmissionUsingArXivView(RequestSubmissionView):
         form = SubmissionIdentifierForm(request.GET or None, requested_by=self.request.user)
         if form.is_valid():
             # Gather data from ArXiv API if prefill form is valid
-            self.initial_data = form.request_arxiv_preprint_form_prefill_data()
+            self.initial_data = form.get_initial_submission_data()
             return super().get(request)
         else:
+            raise
             return redirect('submissions:prefill_using_identifier')
 
     def get_form_kwargs(self):
         """Form requires extra kwargs."""
         kwargs = super().get_form_kwargs()
-        kwargs['use_arxiv_preprint'] = True
+        # kwargs['use_arxiv_preprint'] = True
+        kwargs['preprint_server'] = 'arxiv'
         return kwargs
 
 
@@ -179,7 +185,8 @@ class RequestSubmissionUsingSciPostView(RequestSubmissionView):
     def get_form_kwargs(self):
         """Form requires extra kwargs."""
         kwargs = super().get_form_kwargs()
-        kwargs['use_arxiv_preprint'] = False
+        # kwargs['use_arxiv_preprint'] = False
+        kwargs['preprint_server'] = 'scipost'
         return kwargs
 
 
@@ -189,13 +196,10 @@ def prefill_using_arxiv_identifier(request):
     """Form view asking for the arXiv ID related to the new Submission to submit."""
     query_form = SubmissionIdentifierForm(request.POST or None, initial=request.GET or None,
                                           requested_by=request.user)
-    if query_form.is_valid():
-        prefill_data = query_form.request_arxiv_preprint_form_prefill_data()
-        form = RequestSubmissionForm(
-            initial=prefill_data, requested_by=request.user, use_arxiv_preprint=True)
 
+    if query_form.is_valid():
         # Submit message to user
-        if query_form.submission_is_resubmission():
+        if query_form.service.is_resubmission():
             resubmessage = ('There already exists a preprint with this arXiv identifier '
                             'but a different version number. \nYour Submission will be '
                             'handled as a resubmission.')
@@ -203,9 +207,6 @@ def prefill_using_arxiv_identifier(request):
         else:
             messages.success(request, strings.acknowledge_arxiv_query, fail_silently=True)
 
-        context = {
-            'form': form,
-        }
         response = redirect('submissions:submit_manuscript_arxiv')
         response['location'] += '?identifier_w_vn_nr={}'.format(
             query_form.cleaned_data['identifier_w_vn_nr'])
-- 
GitLab