From 48b3fb750b6d248cdff86821781a9f1216149a65 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sun, 19 Jul 2020 17:31:28 +0200
Subject: [PATCH] Full submission workflow reimplemented; ready to start
 testing

---
 preprints/factories.py                        |   1 -
 preprints/helpers.py                          | 103 +++++--
 ...ve_preprint_scipost_preprint_identifier.py |  17 ++
 preprints/models.py                           |  11 +-
 .../scipost/personal_page/submissions.html    |   2 +-
 submissions/forms.py                          | 260 ++++++++++++------
 .../submit_choose_preprint_server.html        |   1 -
 7 files changed, 274 insertions(+), 121 deletions(-)
 create mode 100644 preprints/migrations/0011_remove_preprint_scipost_preprint_identifier.py

diff --git a/preprints/factories.py b/preprints/factories.py
index 70bd63418..da1fac394 100644
--- a/preprints/factories.py
+++ b/preprints/factories.py
@@ -21,7 +21,6 @@ class PreprintFactory(factory.django.DjangoModelFactory):
         o.identifier_wo_vn_nr, o.vn_nr))
     url = factory.lazy_attribute(lambda o: (
         'https://arxiv.org/abs/%s' % o.identifier_wo_vn_nr))
-    scipost_preprint_identifier = factory.Sequence(lambda n: Preprint.objects.count() + 1)
 
     class Meta:
         model = Preprint
diff --git a/preprints/helpers.py b/preprints/helpers.py
index 8c18ae956..78752a6f7 100644
--- a/preprints/helpers.py
+++ b/preprints/helpers.py
@@ -10,35 +10,84 @@ from submissions.models import Submission
 from .models import Preprint
 
 
-def generate_new_scipost_identifier(old_preprint=None):
+def get_new_scipost_identifier(thread_hash=None):
     """
-    Return an identifier for a new SciPost preprint series without version number.
+    Return an identifier for a new SciPost preprint (consistent with thread history).
 
-    TODO: This method will explode as soon as it will be used similtaneously by two or more people.
+    A SciPost identifier is of the form [YYYY][MM]_[#####]v[vn_nr].
+
+    For an existing thread, different cases must be treated:
+
+    * All preprints in thread are SciPost preprints: the vn_nr is incremented.
+
+    * Previous preprints are all on an external preprint server: a brand new SciPost
+      identifier is generated; the vn_nr is put to [nr of previous subs in thread] + 1.
+
+    * Previous preprints mix SciPost and external identifiers: the SciPost identifier is
+      reused, putting the vn_nr to [nr of previous subs in thread] + 1.
     """
     now = timezone.now()
 
-    if isinstance(old_preprint, Submission):
-        old_preprint = old_preprint.preprint
-
-    if old_preprint:
-        # Generate new version number of existing series.
-        preprint_series = Preprint.objects.filter(
-            scipost_preprint_identifier=old_preprint.scipost_preprint_identifier).values_list(
-            'vn_nr', flat=True)
-        identifier = '{}v{}'.format(old_preprint.identifier_wo_vn_nr, max(preprint_series) + 1)
-        return identifier, old_preprint.scipost_preprint_identifier
-    else:
-        # New series of Preprints.
-        existing_identifier = Preprint.objects.filter(
-            created__year=now.year, created__month=now.month).aggregate(
-            identifier=Max('scipost_preprint_identifier'))['identifier']
-        if not existing_identifier:
-            existing_identifier = '1'
-        else:
-            existing_identifier = str(existing_identifier + 1)
-
-        identifier = 'scipost_{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)
+    submissions_in_thread = Submission.objects.filter(thread_hash=thread_hash)
+
+    scipost_submissions_in_thread = submissions_in_thread.filter(
+        preprint__identifier_w_vn_nr__startswith='scipost')
+
+    # At least one previous submission on SciPost's preprint server
+    if len(scipost_submissions_in_thread) > 0:
+        identifier = '{}v{}'.format(
+            scipost_submissions_in_thread.first().identifier_wo_vn_nr,
+            str(len(scipost_submissions_in_thread) + 1))
+        return identifier
+
+    # No previous Submission, or no previous SciPost preprint in thread; new identifier
+    current_identifier_prefix = 'scipost_%s%s' % (now.year, str(now.month).rjust(2,'0'))
+    try:
+        next_identifier_nr = int(Preprint.objects.filter(
+            identifier_w_vn_nr__startswith=current_identifier_prefix
+        ).first().identifier_w_vn_nr.rpartition('v')[0].rpartition('_')[2]) + 1
+    except AttributeError:
+        next_identifier_nr = 1
+
+    identifier = 'scipost_{year}{month}_{identifier}v{vn_nr}'.format(
+        year=now.year, month=str(now.month).rjust(2, '0'),
+        identifier=str(next_identifier_nr).rjust(5, '0'),
+        vn_nr=str(len(submissions_in_thread) + 1)
+    )
+    return identifier
+
+
+# def generate_new_scipost_identifier_BUGGED(old_preprint=None):
+#     """
+#     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):
+#         old_preprint = old_preprint.preprint
+
+#     if old_preprint:
+#         # Generate new version number of existing series.
+#         # BUGGED! This fails to make scipost_preprint_identifier globally unique
+#         # BUGGED! Instead, scipost_preprint_identifier can be repeated each month.
+#         preprint_series = Preprint.objects.filter(
+#             scipost_preprint_identifier=old_preprint.scipost_preprint_identifier).values_list(
+#             'vn_nr', flat=True)
+#         identifier = '{}v{}'.format(old_preprint.identifier_wo_vn_nr, max(preprint_series) + 1)
+#         return identifier, old_preprint.scipost_preprint_identifier
+#     else:
+#         # New series of Preprints.
+#         existing_identifier = Preprint.objects.filter(
+#             created__year=now.year, created__month=now.month).aggregate(
+#             identifier=Max('scipost_preprint_identifier'))['identifier']
+#         if not existing_identifier:
+#             existing_identifier = '1'
+#         else:
+#             existing_identifier = str(existing_identifier + 1)
+
+#         identifier = 'scipost_{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/preprints/migrations/0011_remove_preprint_scipost_preprint_identifier.py b/preprints/migrations/0011_remove_preprint_scipost_preprint_identifier.py
new file mode 100644
index 000000000..306529a65
--- /dev/null
+++ b/preprints/migrations/0011_remove_preprint_scipost_preprint_identifier.py
@@ -0,0 +1,17 @@
+# Generated by Django 2.2.11 on 2020-07-19 15:30
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('preprints', '0010_merge_20181207_1008'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='preprint',
+            name='scipost_preprint_identifier',
+        ),
+    ]
diff --git a/preprints/models.py b/preprints/models.py
index 511278ef5..ead67904e 100644
--- a/preprints/models.py
+++ b/preprints/models.py
@@ -8,10 +8,10 @@ from django.http import Http404
 
 
 class Preprint(models.Model):
-    """A link with arXiv or standalone/SciPost-hosted preprint.
+    """
+    A preprint object, either at SciPost or with link to external preprint server.
 
-    If the instance is a SciPost preprint, the `_file` and `scipost_preprint_identifier` fields
-    should be filled. Otherwise, these fields should be left blank.
+    If the instance is a SciPost preprint, the `_file` field should be filled.
     """
 
     # (arXiv) identifiers with/without version number
@@ -20,10 +20,7 @@ class Preprint(models.Model):
     vn_nr = models.PositiveSmallIntegerField(verbose_name='Version number', default=1)
     url = models.URLField(blank=True)
 
-    # SciPost-preprints only
-    scipost_preprint_identifier = models.PositiveIntegerField(
-        verbose_name='SciPost preprint ID',
-        null=True, blank=True, help_text='Unique identifier for SciPost standalone preprints')
+    # SciPost preprints only
     _file = models.FileField(
         verbose_name='Preprint file', help_text='Preprint file for SciPost standalone preprints',
         upload_to='UPLOADS/PREPRINTS/%Y/%m/', max_length=200, blank=True)
diff --git a/scipost/templates/partials/scipost/personal_page/submissions.html b/scipost/templates/partials/scipost/personal_page/submissions.html
index 1248fa733..10dad4e86 100644
--- a/scipost/templates/partials/scipost/personal_page/submissions.html
+++ b/scipost/templates/partials/scipost/personal_page/submissions.html
@@ -31,7 +31,7 @@
               <p class="card-text mt-1">
 		<ul>
                   {% if sub.open_for_resubmission %}
-                    <li><a href="{% url 'submissions:submit_choose_journal' discipline=sub.discipline thread_hash=sub.thread_hash %}"><i class="fa fa-arrow-right"></i> resubmit</a></li>
+                    <li><a href="{% url 'submissions:submit_choose_journal' discipline=sub.discipline %}?thread_hash={{ sub.thread_hash }}"><i class="fa fa-arrow-right"></i> resubmit</a></li>
                   {% endif %}
 		  {% if sub.under_consideration %}
                     {% if sub.editor_in_charge %}
diff --git a/submissions/forms.py b/submissions/forms.py
index ff7d69de4..5ec6f0865 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -38,7 +38,7 @@ from colleges.models import Fellowship
 from common.utils import Q_with_alternative_spellings
 from journals.models import Journal
 from mails.utils import DirectMailUtil
-from preprints.helpers import generate_new_scipost_identifier
+from preprints.helpers import get_new_scipost_identifier
 from preprints.models import Preprint
 from profiles.models import Profile
 from scipost.constants import SCIPOST_SUBJECT_AREAS
@@ -337,6 +337,70 @@ class SubmissionService:
 #
 ######################################################################
 
+# Checks
+
+def check_resubmission_readiness(requested_by, submission):
+    """
+    Check if submission can be resubmitted.
+    """
+    if submission:
+        if 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 submission.open_for_resubmission:
+            # Check if verified author list contains current user.
+            if requested_by.contributor not in 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 an inappropriate 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 check_identifier_is_unused(identifier):
+    # Check if identifier has already been used for submission
+    if Submission.objects.filter(preprint__identifier_w_vn_nr=identifier).exists():
+        error_message = 'This preprint version has already been submitted to SciPost.'
+        raise forms.ValidationError(error_message, code='duplicate')
+
+
+def check_arxiv_identifier_w_vn_nr(identifier):
+    caller = ArxivCaller(identifier)
+    if caller.is_valid:
+        arxiv_data = caller.data
+        metadata = caller.metadata
+    else:
+        error_message = 'A preprint associated to this identifier does not exist.'
+        raise forms.ValidationError(error_message)
+
+    # Check if this paper has already been published (according to arXiv)
+    published_id = None
+    if 'arxiv_doi' in arxiv_data:
+        published_id = arxiv_data['arxiv_doi']
+    elif 'arxiv_journal_ref' in arxiv_data:
+        published_id = arxiv_data['arxiv_journal_ref']
+
+    if published_id:
+        error_message = ('This paper has been published under DOI %(published_id)s. '
+                         'It cannot be submitted again.'),
+        raise forms.ValidationError(error_message, code='published',
+                                    params={'published_id': published_id})
+    return metadata, identifier
+
 
 class SubmissionPrefillForm(forms.Form):
     """
@@ -367,38 +431,7 @@ class SubmissionPrefillForm(forms.Form):
         """
         Consistency checks on the prefill data.
         """
-        self._check_resubmission_readiness()
-
-    def _check_resubmission_readiness(self):
-        """
-        Check if previous submitted versions (if any) can be resubmitted.
-        """
-        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.
-                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)
+        check_resubmission_readiness(self.requested_by, self.latest_submission)
 
     def get_prefill_data(self):
         return {}
@@ -471,31 +504,35 @@ class ArXivPrefillForm(SubmissionPrefillForm):
         """
         identifier = self.cleaned_data.get('arxiv_identifier_w_vn_nr', None)
 
-        caller = ArxivCaller(identifier)
-        if caller.is_valid:
-            self.arxiv_data = caller.data
-            self.metadata = caller.metadata
-        else:
-            error_message = 'A preprint associated to this identifier does not exist.'
-            raise forms.ValidationError(error_message)
+        check_identifier_is_unused(identifier)
 
-        # Check if identifier has already been used for submission
-        if Submission.objects.filter(preprint__identifier_w_vn_nr=identifier).exists():
-            error_message = 'This preprint version has already been submitted to SciPost.'
-            raise forms.ValidationError(error_message, code='duplicate')
-
-        # Check if this paper has already been published (according to arXiv)
-        published_id = None
-        if 'arxiv_doi' in self.arxiv_data:
-            published_id = self.arxiv_data['arxiv_doi']
-        elif 'arxiv_journal_ref' in self.arxiv_data:
-            published_id = self.arxiv_data['arxiv_journal_ref']
+        self.metadata, identifier = check_arxiv_identifier_w_vn_nr(identifier)
 
-        if published_id:
-            error_message = ('This paper has been published under DOI %(published_id)s. '
-                             'It cannot be submitted again.'),
-            raise forms.ValidationError(error_message, code='published',
-                                        params={'published_id': published_id})
+        # caller = ArxivCaller(identifier)
+        # if caller.is_valid:
+        #     self.arxiv_data = caller.data
+        #     self.metadata = caller.metadata
+        # else:
+        #     error_message = 'A preprint associated to this identifier does not exist.'
+        #     raise forms.ValidationError(error_message)
+
+        # # Check if identifier has already been used for submission
+        # if Submission.objects.filter(preprint__identifier_w_vn_nr=identifier).exists():
+        #     error_message = 'This preprint version has already been submitted to SciPost.'
+        #     raise forms.ValidationError(error_message, code='duplicate')
+
+        # # Check if this paper has already been published (according to arXiv)
+        # published_id = None
+        # if 'arxiv_doi' in self.arxiv_data:
+        #     published_id = self.arxiv_data['arxiv_doi']
+        # elif 'arxiv_journal_ref' in self.arxiv_data:
+        #     published_id = self.arxiv_data['arxiv_journal_ref']
+
+        # if published_id:
+        #     error_message = ('This paper has been published under DOI %(published_id)s. '
+        #                      'It cannot be submitted again.'),
+        #     raise forms.ValidationError(error_message, code='published',
+        #                                 params={'published_id': published_id})
         return identifier
 
     def get_prefill_data(self):
@@ -583,6 +620,9 @@ class SubmissionForm(forms.ModelForm):
         self.requested_by = kwargs.pop('requested_by')
         self.preprint_server = kwargs.pop('preprint_server')
         self.thread_hash = kwargs['initial'].get('thread_hash', None)
+
+        self.metadata = {} # container for possible external server-provided metadata
+
         # print("form args:\n", args)
         # print("form kwargs:\n", kwargs)
         # print("is_resubmission: %s" % self.is_resubmission())
@@ -657,17 +697,22 @@ class SubmissionForm(forms.ModelForm):
         cleaned_data = super().clean(*args, **kwargs)
 
         # SciPost preprints are auto-generated here.
-        self.scipost_identifier = None
+        # self.scipost_identifier = None
         if 'identifier_w_vn_nr' not in cleaned_data:
-            self.service.identifier, self.scipost_identifier = generate_new_scipost_identifier(
-                cleaned_data.get('is_resubmission_of', None))
-            # Also copy to the form data
-            self.cleaned_data['identifier_w_vn_nr'] = self.service.identifier
+            # self.scipost_identifier = generate_new_scipost_identifier(
+            #     cleaned_data.get('is_resubmission_of', None))
+            # # Also copy to the form data
+            # self.cleaned_data['identifier_w_vn_nr'] = self.service.identifier
+            self.cleaned_data['identifier_w_vn_nr'] = get_new_scipost_identifier(
+                thread_hash=self.thread_hash)
 
         # 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)
+        # self.service.run_checks()
+        # self.service.identifier_matches_regex(cleaned_data['submitted_to'].doi_label)
+
+        if self.is_resubmission():
+            check_resubmission_readiness(self.requested_by, cleaned_data['is_resubmission_of'])
 
         if 'Proc' not in self.cleaned_data['submitted_to'].doi_label:
             try:
@@ -693,6 +738,15 @@ class SubmissionForm(forms.ModelForm):
             self.add_error('author_list', error_message)
         return author_list
 
+    def clean_identifier_w_vn_nr(self):
+        identifier = self.cleaned_data.get('identifier_w_vn_nr', None)
+
+        check_identifier_is_unused(identifier)
+
+        if self.preprint_server == 'arXiv':
+            self.metadata, identifier = check_arxiv_identifier_w_vn_nr(identifier)
+        return identifier
+
     def clean_submission_type(self):
         """
         Validate Submission type for the SciPost Physics journal.
@@ -703,24 +757,6 @@ class SubmissionForm(forms.ModelForm):
             self.add_error('submission_type', 'Please specify the submission type.')
         return submission_type
 
-    def set_pool(self, submission):
-        """
-        Set the default set of (guest) Fellows for this Submission.
-        """
-        qs = Fellowship.objects.active()
-        fellows = qs.regular().filter(
-            contributor__profile__discipline=submission.discipline).filter(
-                Q(contributor__profile__expertises__contains=[submission.subject_area]) |
-                Q(contributor__profile__expertises__overlap=submission.secondary_areas)
-            ).return_active_for_submission(submission)
-        submission.fellows.set(fellows)
-
-        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)
-
     @transaction.atomic
     def save(self):
         """
@@ -736,16 +772,16 @@ class SubmissionForm(forms.ModelForm):
             identifier_wo_vn_nr=identifiers[0],
             vn_nr=identifiers[2],
             url=self.cleaned_data.get('arxiv_link', ''),
-            scipost_preprint_identifier=self.scipost_identifier,
+            # 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.metadata = self.metadata
         submission.preprint = preprint
 
         submission.save()
         if self.is_resubmission():
-            self.service.process_resubmission_procedure(submission)
+            self.process_resubmission(submission)
 
         # Gather first known author and Fellows.
         submission.authors.add(self.requested_by.contributor)
@@ -755,6 +791,62 @@ class SubmissionForm(forms.ModelForm):
         submission.refresh_from_db()
         return submission
 
+    def process_resubmission(self, submission):
+        """
+        Update all fields for new and old Submission and EditorialAssignments.
+
+        -- submission: the new version of the Submission series.
+        """
+        if not submission.is_resubmission_of:
+            raise Submission.DoesNotExist
+
+        previous_submission = submission.is_resubmission_of
+
+        # Close last submission
+        Submission.objects.filter(id=previous_submission.id).update(
+            is_current=False, open_for_reporting=False, status=STATUS_RESUBMITTED)
+
+        # Copy Topics
+        submission.topics.add(*previous_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,
+            visible_pool=True,
+            refereeing_cycle=CYCLE_UNDETERMINED,
+            editor_in_charge=previous_submission.editor_in_charge,
+            status=STATUS_EIC_ASSIGNED)
+
+        # Add author(s) (claim) fields
+        submission.authors.add(*previous_submission.authors.all())
+        submission.authors_claims.add(*previous_submission.authors_claims.all())
+        submission.authors_false_claims.add(*previous_submission.authors_false_claims.all())
+
+        # Create new EditorialAssigment for the current Editor-in-Charge
+        EditorialAssignment.objects.create(
+            submission=submission,
+            to=previous_submission.editor_in_charge,
+            status=STATUS_ACCEPTED)
+
+    def set_pool(self, submission):
+        """
+        Set the default set of (guest) Fellows for this Submission.
+        """
+        qs = Fellowship.objects.active()
+        fellows = qs.regular().filter(
+            contributor__profile__discipline=submission.discipline).filter(
+                Q(contributor__profile__expertises__contains=[submission.subject_area]) |
+                Q(contributor__profile__expertises__overlap=submission.secondary_areas)
+            ).return_active_for_submission(submission)
+        submission.fellows.set(fellows)
+
+        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)
+
 
 class SubmissionReportsForm(forms.ModelForm):
     """Update refereeing pdf for Submission."""
diff --git a/submissions/templates/submissions/submit_choose_preprint_server.html b/submissions/templates/submissions/submit_choose_preprint_server.html
index 2c3a16c21..2d8e3f1c8 100644
--- a/submissions/templates/submissions/submit_choose_preprint_server.html
+++ b/submissions/templates/submissions/submit_choose_preprint_server.html
@@ -49,7 +49,6 @@
 	  </div>
 	  <div class="card-body">
 	    {% if server.name == 'SciPost' %}
-	      <a class="btn btn-success text-white" role="button" href="{% url 'submissions:submit_manuscript_scipost' journal_doi_label=journal.doi_label %}{% if thread_hash %}?thread_hash={{ thread_hash }}{% endif %}"><i class="fa fa-arrow-right"></i> Go to the SciPost submission form</a>
 	      <form action="{% url 'submissions:submit_manuscript_scipost' journal_doi_label=journal.doi_label %}" method="get">
 		{{ scipost_prefill_form }}
 		{% if thread_hash %}
-- 
GitLab