From 72b4dc03cf566ab62b0faf082bd0e3f90bc46d84 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Wed, 17 May 2017 20:01:51 +0200
Subject: [PATCH] Move production to separate app. Migrate.

---
 SciPost_v1/settings/base.py                   |  1 +
 SciPost_v1/urls.py                            |  1 +
 journals/admin.py                             |  6 --
 journals/constants.py                         | 15 ----
 journals/forms.py                             | 11 ---
 .../migrations/0023_auto_20170517_1846.py     | 33 +++++++++
 journals/models.py                            | 31 +--------
 journals/urls/general.py                      |  5 --
 journals/views.py                             | 57 ----------------
 production/__init__.py                        |  0
 production/admin.py                           |  9 +++
 production/apps.py                            |  5 ++
 production/constants.py                       | 21 ++++++
 production/forms.py                           | 13 ++++
 production/migrations/0001_initial.py         | 44 ++++++++++++
 .../migrations/0002_auto_20170517_1942.py     | 20 ++++++
 production/migrations/__init__.py             |  0
 production/models.py                          | 34 ++++++++++
 .../production}/_production_event_li.html     |  0
 .../production}/_production_stream_card.html  |  4 +-
 .../templates/production}/production.html     |  2 +-
 production/tests.py                           |  3 +
 production/urls.py                            |  9 +++
 production/views.py                           | 68 +++++++++++++++++++
 submissions/views.py                          |  5 ++
 25 files changed, 270 insertions(+), 127 deletions(-)
 create mode 100644 journals/migrations/0023_auto_20170517_1846.py
 create mode 100644 production/__init__.py
 create mode 100644 production/admin.py
 create mode 100644 production/apps.py
 create mode 100644 production/constants.py
 create mode 100644 production/forms.py
 create mode 100644 production/migrations/0001_initial.py
 create mode 100644 production/migrations/0002_auto_20170517_1942.py
 create mode 100644 production/migrations/__init__.py
 create mode 100644 production/models.py
 rename {journals/templates/journals => production/templates/production}/_production_event_li.html (100%)
 rename {journals/templates/journals => production/templates/production}/_production_stream_card.html (81%)
 rename {journals/templates/journals => production/templates/production}/production.html (79%)
 create mode 100644 production/tests.py
 create mode 100644 production/urls.py
 create mode 100644 production/views.py

diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 669f3bc7e..54e67dda0 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -93,6 +93,7 @@ INSTALLED_APPS = (
     'submissions',
     'theses',
     'virtualmeetings',
+    'production',
     'webpack_loader',
 )
 
diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py
index f930e4a93..36ab1c7ce 100644
--- a/SciPost_v1/urls.py
+++ b/SciPost_v1/urls.py
@@ -42,6 +42,7 @@ urlpatterns = [
     url(r'^thesis/', include('theses.urls', namespace="theses")),
     url(r'^meetings/', include('virtualmeetings.urls', namespace="virtualmeetings")),
     url(r'^news/', include('news.urls', namespace="news")),
+    url(r'^production/', include('production.urls', namespace="production")),
 ]
 
 if settings.DEBUG:
diff --git a/journals/admin.py b/journals/admin.py
index 79667f7bf..48f9f4ee5 100644
--- a/journals/admin.py
+++ b/journals/admin.py
@@ -1,14 +1,8 @@
 from django.contrib import admin, messages
 
-from journals.models import ProductionStream, ProductionEvent
 from journals.models import Journal, Volume, Issue, Publication, Deposit
 
 
-admin.site.register(ProductionStream)
-
-
-admin.site.register(ProductionEvent)
-
 
 class JournalAdmin(admin.ModelAdmin):
     search_fields = ['name']
diff --git a/journals/constants.py b/journals/constants.py
index 3a3aa9b88..6bd5de5cf 100644
--- a/journals/constants.py
+++ b/journals/constants.py
@@ -56,18 +56,3 @@ ISSUE_STATUSES = (
     (STATUS_DRAFT, 'Draft'),
     (STATUS_PUBLISHED, 'Published'),
 )
-
-PRODUCTION_STREAM_STATUS = (
-    ('ongoing', 'Ongoing'),
-    ('completed', 'Completed'),
-)
-
-PRODUCTION_EVENTS = (
-    ('assigned_to_supervisor', 'Assigned to Supervisor'),
-    ('officer_tasked_with_proof_production', 'Officer tasked with proofs production'),
-    ('proofs_produced', 'Proofs have been produced'),
-    ('proofs_sent_to_authors', 'Proofs sent to Authors'),
-    ('proofs_returned_by_authors', 'Proofs returned by Authors'),
-    ('corrections_implemented', 'Corrections implemented'),
-    ('authors_have_accepted_proofs', 'Authors have accepted proofs'),
-)
diff --git a/journals/forms.py b/journals/forms.py
index 910bbd5b4..d173a3447 100644
--- a/journals/forms.py
+++ b/journals/forms.py
@@ -1,22 +1,11 @@
 from django import forms
 from django.utils import timezone
 
-from .models import ProductionEvent
 from .models import UnregisteredAuthor, Issue, Publication
 
 from submissions.models import Submission
 
 
-class ProductionEventForm(forms.ModelForm):
-    class Meta:
-        model = ProductionEvent
-        exclude = ['stream', 'noted_on', 'noted_by']
-
-    def __init__(self, *args, **kwargs):
-        super(ProductionEventForm, self).__init__(*args, **kwargs)
-        self.fields['duration'].widget.attrs.update(
-            {'placeholder': 'HH:MM:SS'})
-
 
 class InitiatePublicationForm(forms.Form):
     accepted_submission = forms.ModelChoiceField(
diff --git a/journals/migrations/0023_auto_20170517_1846.py b/journals/migrations/0023_auto_20170517_1846.py
new file mode 100644
index 000000000..b3462dcdd
--- /dev/null
+++ b/journals/migrations/0023_auto_20170517_1846.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-05-17 16:46
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0022_auto_20170517_1608'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='productionevent',
+            name='noted_by',
+        ),
+        migrations.RemoveField(
+            model_name='productionevent',
+            name='stream',
+        ),
+        migrations.RemoveField(
+            model_name='productionstream',
+            name='submission',
+        ),
+        migrations.DeleteModel(
+            name='ProductionEvent',
+        ),
+        migrations.DeleteModel(
+            name='ProductionStream',
+        ),
+    ]
diff --git a/journals/models.py b/journals/models.py
index df59b73d6..920371b78 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -7,8 +7,7 @@ from django.urls import reverse
 from .behaviors import doi_journal_validator, doi_volume_validator,\
                        doi_issue_validator, doi_publication_validator
 from .constants import SCIPOST_JOURNALS, SCIPOST_JOURNALS_DOMAINS,\
-                       STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES,\
-                       PRODUCTION_STREAM_STATUS, PRODUCTION_EVENTS
+                       STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES
 from .helpers import paper_nr_string, journal_name_abbrev_citation
 from .managers import IssueManager, PublicationManager
 
@@ -17,34 +16,6 @@ from scipost.fields import ChoiceArrayField
 from scipost.models import Contributor
 
 
-##############
-# Production #
-##############
-
-class ProductionStream(models.Model):
-    submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE)
-    opened = models.DateTimeField()
-
-    def __str__(self):
-        return str(self.submission)
-
-    def total_duration(self):
-        totdur = self.productionevent_set.all().aggregate(models.Sum('duration'))
-        return totdur['duration__sum']
-
-
-class ProductionEvent(models.Model):
-    stream = models.ForeignKey(ProductionStream, on_delete=models.CASCADE)
-    event = models.CharField(max_length=64, choices=PRODUCTION_EVENTS)
-    comments = models.TextField(blank=True, null=True)
-    noted_on = models.DateTimeField(default=timezone.now)
-    noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
-    duration = models.DurationField(blank=True, null=True)
-
-    def __str__(self):
-        return '%s: %s' % (str(self.stream.submission), self.get_event_display())
-
-
 ################
 # Journals etc #
 ################
diff --git a/journals/urls/general.py b/journals/urls/general.py
index b1a53b079..76d8ab0b7 100644
--- a/journals/urls/general.py
+++ b/journals/urls/general.py
@@ -12,11 +12,6 @@ urlpatterns = [
         TemplateView.as_view(template_name='journals/journals_terms_and_conditions.html'),
         name='journals_terms_and_conditions'),
 
-    # Production
-    url(r'^production$', journals_views.production, name='production'),
-    url(r'^add_production_event/(?P<stream_id>[0-9]+)$',
-        journals_views.add_production_event, name='add_production_event'),
-
     # Editorial and Administrative Workflow
     url(r'^initiate_publication$',
         journals_views.initiate_publication,
diff --git a/journals/views.py b/journals/views.py
index 08926503b..899edf798 100644
--- a/journals/views.py
+++ b/journals/views.py
@@ -15,9 +15,7 @@ from django.http import HttpResponse
 
 from .exceptions import PaperNumberingError
 from .helpers import paper_nr_string
-from .models import ProductionStream, ProductionEvent
 from .models import Journal, Issue, Publication, UnregisteredAuthor
-from .forms import ProductionEventForm
 from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\
                    UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm
 from .utils import JournalUtils
@@ -136,61 +134,6 @@ def issue_detail(request, doi_label):
     return render(request, 'journals/journal_issue_detail.html', context)
 
 
-######################
-# Production process #
-######################
-
-@permission_required('scipost.can_view_production', return_403=True)
-def production(request):
-    """
-    Overview page for the production process.
-    All papers with accepted but not yet published status are included here.
-    """
-    accepted_submissions = Submission.objects.filter(
-        status='accepted').order_by('latest_activity')
-    streams = ProductionStream.objects.all().order_by('opened')
-    prodevent_form = ProductionEventForm()
-    context = {
-        'accepted_submissions': accepted_submissions,
-        'streams': streams,
-        'prodevent_form': prodevent_form,
-    }
-    return render(request, 'journals/production.html', context)
-
-@permission_required('scipost.can_view_production', return_403=True)
-@transaction.atomic
-def add_production_event(request, stream_id):
-    stream = get_object_or_404(ProductionStream, pk=stream_id)
-    if request.method == 'POST':
-        prodevent_form = ProductionEventForm(request.POST)
-        if prodevent_form.is_valid():
-            prodevent = ProductionEvent(
-                stream=stream,
-                event=prodevent_form.cleaned_data['event'],
-                comments=prodevent_form.cleaned_data['comments'],
-                noted_on=timezone.now(),
-                noted_by=request.user.contributor,
-                duration=prodevent_form.cleaned_data['duration'],)
-            prodevent.save()
-            return redirect(reverse('journals:production'))
-        else:
-            errormessage = 'The form was invalidly filled.'
-            return render(request, 'scipost/error.html', {'errormessage': errormessage})
-    else:
-        errormessage = 'This view can only be posted to.'
-        return render(request, 'scipost/error.html', {'errormessage': errormessage})
-
-
-
-
-def upload_proofs(request):
-    """
-    TODO
-    Called by a member of the Production Team.
-    Upload the production version .pdf of a submission.
-    """
-    return render(request, 'journals/upload_proofs.html')
-
 
 #######################
 # Publication process #
diff --git a/production/__init__.py b/production/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/production/admin.py b/production/admin.py
new file mode 100644
index 000000000..b20b4a415
--- /dev/null
+++ b/production/admin.py
@@ -0,0 +1,9 @@
+from django.contrib import admin
+
+from .models import ProductionStream, ProductionEvent
+
+
+admin.site.register(ProductionStream)
+
+
+admin.site.register(ProductionEvent)
diff --git a/production/apps.py b/production/apps.py
new file mode 100644
index 000000000..d8fba60df
--- /dev/null
+++ b/production/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class ProductionConfig(AppConfig):
+    name = 'production'
diff --git a/production/constants.py b/production/constants.py
new file mode 100644
index 000000000..8a1ba8ea8
--- /dev/null
+++ b/production/constants.py
@@ -0,0 +1,21 @@
+
+
+PRODUCTION_STREAM_STATUS = (
+    ('ongoing', 'Ongoing'),
+    ('completed', 'Completed'),
+)
+
+
+PRODUCTION_EVENTS = (
+    ('assigned_to_supervisor', 'Assigned by EdAdmin to Supervisor'),
+    ('message_edadmin_to_supervisor', 'Message from EdAdmin to Supervisor'),
+    ('message_supervisor_to_edadmin', 'Message from Supervisor to EdAdmin'),
+    ('officer_tasked_with_proof_production', 'Supervisor tasked officer with proofs production'),
+    ('message_supervisor_to_officer', 'Message from Supervisor to Officer'),
+    ('message_officer_to_supervisor', 'Message from Officer to Supervisor'),
+    ('proofs_produced', 'Proofs have been produced'),
+    ('proofs_sent_to_authors', 'Proofs sent to Authors'),
+    ('proofs_returned_by_authors', 'Proofs returned by Authors'),
+    ('corrections_implemented', 'Corrections implemented'),
+    ('authors_have_accepted_proofs', 'Authors have accepted proofs'),
+)
diff --git a/production/forms.py b/production/forms.py
new file mode 100644
index 000000000..d783973ec
--- /dev/null
+++ b/production/forms.py
@@ -0,0 +1,13 @@
+from django import forms
+
+from .models import ProductionEvent
+
+
+class ProductionEventForm(forms.ModelForm):
+    class Meta:
+        model = ProductionEvent
+        exclude = ['stream', 'noted_on', 'noted_by']
+        widgets = {
+            'comments': forms.Textarea(attrs={'rows': 4,}),
+            'duration': forms.TextInput(attrs={'placeholder': 'HH:MM:SS'})
+        }
diff --git a/production/migrations/0001_initial.py b/production/migrations/0001_initial.py
new file mode 100644
index 000000000..3e3ed1ac3
--- /dev/null
+++ b/production/migrations/0001_initial.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-05-17 17:23
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('submissions', '0043_auto_20170512_0836'),
+        ('scipost', '0054_delete_newsitem'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ProductionEvent',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('event', models.CharField(choices=[('assigned_to_supervisor', 'Assigned to Supervisor'), ('officer_tasked_with_proof_production', 'Officer tasked with proofs production'), ('proofs_produced', 'Proofs have been produced'), ('proofs_sent_to_authors', 'Proofs sent to Authors'), ('proofs_returned_by_authors', 'Proofs returned by Authors'), ('corrections_implemented', 'Corrections implemented'), ('authors_have_accepted_proofs', 'Authors have accepted proofs')], max_length=64)),
+                ('comments', models.TextField(blank=True, null=True)),
+                ('noted_on', models.DateTimeField(default=django.utils.timezone.now)),
+                ('duration', models.DurationField(blank=True, null=True)),
+                ('noted_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='scipost.Contributor')),
+            ],
+        ),
+        migrations.CreateModel(
+            name='ProductionStream',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('opened', models.DateTimeField()),
+                ('submission', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='submissions.Submission')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='productionevent',
+            name='stream',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='production.ProductionStream'),
+        ),
+    ]
diff --git a/production/migrations/0002_auto_20170517_1942.py b/production/migrations/0002_auto_20170517_1942.py
new file mode 100644
index 000000000..53aa4d797
--- /dev/null
+++ b/production/migrations/0002_auto_20170517_1942.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-05-17 17:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('production', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='productionevent',
+            name='event',
+            field=models.CharField(choices=[('assigned_to_supervisor', 'Assigned by EdAdmin to Supervisor'), ('message_edadmin_to_supervisor', 'Message from EdAdmin to Supervisor'), ('message_supervisor_to_edadmin', 'Message from Supervisor to EdAdmin'), ('officer_tasked_with_proof_production', 'Supervisor tasked officer with proofs production'), ('message_supervisor_to_officer', 'Message from Supervisor to Officer'), ('message_officer_to_supervisor', 'Message from Officer to Supervisor'), ('proofs_produced', 'Proofs have been produced'), ('proofs_sent_to_authors', 'Proofs sent to Authors'), ('proofs_returned_by_authors', 'Proofs returned by Authors'), ('corrections_implemented', 'Corrections implemented'), ('authors_have_accepted_proofs', 'Authors have accepted proofs')], max_length=64),
+        ),
+    ]
diff --git a/production/migrations/__init__.py b/production/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/production/models.py b/production/models.py
new file mode 100644
index 000000000..8badf3eea
--- /dev/null
+++ b/production/models.py
@@ -0,0 +1,34 @@
+from django.db import models
+from django.utils import timezone
+
+from .constants import PRODUCTION_STREAM_STATUS, PRODUCTION_EVENTS
+
+from scipost.models import Contributor
+
+
+##############
+# Production #
+##############
+
+class ProductionStream(models.Model):
+    submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE)
+    opened = models.DateTimeField()
+
+    def __str__(self):
+        return str(self.submission)
+
+    def total_duration(self):
+        totdur = self.productionevent_set.all().aggregate(models.Sum('duration'))
+        return totdur['duration__sum']
+
+
+class ProductionEvent(models.Model):
+    stream = models.ForeignKey(ProductionStream, on_delete=models.CASCADE)
+    event = models.CharField(max_length=64, choices=PRODUCTION_EVENTS)
+    comments = models.TextField(blank=True, null=True)
+    noted_on = models.DateTimeField(default=timezone.now)
+    noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE)
+    duration = models.DurationField(blank=True, null=True)
+
+    def __str__(self):
+        return '%s: %s' % (str(self.stream.submission), self.get_event_display())
diff --git a/journals/templates/journals/_production_event_li.html b/production/templates/production/_production_event_li.html
similarity index 100%
rename from journals/templates/journals/_production_event_li.html
rename to production/templates/production/_production_event_li.html
diff --git a/journals/templates/journals/_production_stream_card.html b/production/templates/production/_production_stream_card.html
similarity index 81%
rename from journals/templates/journals/_production_stream_card.html
rename to production/templates/production/_production_stream_card.html
index f2a78b13f..fda086794 100644
--- a/journals/templates/journals/_production_stream_card.html
+++ b/production/templates/production/_production_stream_card.html
@@ -8,7 +8,7 @@
       <h3>Events</h3>
       <ul>
 	{% for event in stream.productionevent_set.all %}
-	{% include 'journals/_production_event_li.html' with event=event %}
+	{% include 'production/_production_event_li.html' with event=event %}
 	{% empty %}
 	<li>No events were found.</li>
 	{% endfor %}
@@ -20,7 +20,7 @@
     </div>
     <div class="col-5">
       <h3>Add an event to this production stream:</h3>
-      <form action="{% url 'journals:add_production_event' stream_id=stream.id %}" method="post">
+      <form action="{% url 'production:add_event' stream_id=stream.id %}" method="post">
 	{% csrf_token %}
 	{{ form|bootstrap }}
 	<input type="submit" name="submit" value="Submit">
diff --git a/journals/templates/journals/production.html b/production/templates/production/production.html
similarity index 79%
rename from journals/templates/journals/production.html
rename to production/templates/production/production.html
index 2f1b67f3a..36b7dcf39 100644
--- a/journals/templates/journals/production.html
+++ b/production/templates/production/production.html
@@ -10,7 +10,7 @@
     <ul class="list-group list-group-flush">
       {% for stream in streams %}
       <li class="list-group-item">
-	{% include 'journals/_production_stream_card.html' with stream=stream form=prodevent_form %}
+	{% include 'production/_production_stream_card.html' with stream=stream form=prodevent_form %}
       </li>
       <hr/>
       {% endfor %}
diff --git a/production/tests.py b/production/tests.py
new file mode 100644
index 000000000..7ce503c2d
--- /dev/null
+++ b/production/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/production/urls.py b/production/urls.py
new file mode 100644
index 000000000..11007074f
--- /dev/null
+++ b/production/urls.py
@@ -0,0 +1,9 @@
+from django.conf.urls import url
+
+from production import views as production_views
+
+urlpatterns = [
+    url(r'^$', production_views.production, name='production'),
+    url(r'^add_event/(?P<stream_id>[0-9]+)$',
+        production_views.add_event, name='add_event'),
+]
diff --git a/production/views.py b/production/views.py
new file mode 100644
index 000000000..8103f5fdb
--- /dev/null
+++ b/production/views.py
@@ -0,0 +1,68 @@
+from django.core.urlresolvers import reverse
+from django.db import transaction
+from django.shortcuts import get_object_or_404, render, redirect
+from django.utils import timezone
+
+from guardian.decorators import permission_required
+
+from .models import ProductionStream, ProductionEvent
+from .forms import ProductionEventForm
+
+from submissions.models import Submission
+from scipost.models import Contributor
+
+
+######################
+# Production process #
+######################
+
+@permission_required('scipost.can_view_production', return_403=True)
+def production(request):
+    """
+    Overview page for the production process.
+    All papers with accepted but not yet published status are included here.
+    """
+    accepted_submissions = Submission.objects.filter(
+        status='accepted').order_by('latest_activity')
+    streams = ProductionStream.objects.all().order_by('opened')
+    prodevent_form = ProductionEventForm()
+    context = {
+        'accepted_submissions': accepted_submissions,
+        'streams': streams,
+        'prodevent_form': prodevent_form,
+    }
+    return render(request, 'production/production.html', context)
+
+@permission_required('scipost.can_view_production', return_403=True)
+@transaction.atomic
+def add_event(request, stream_id):
+    stream = get_object_or_404(ProductionStream, pk=stream_id)
+    if request.method == 'POST':
+        prodevent_form = ProductionEventForm(request.POST)
+        if prodevent_form.is_valid():
+            prodevent = ProductionEvent(
+                stream=stream,
+                event=prodevent_form.cleaned_data['event'],
+                comments=prodevent_form.cleaned_data['comments'],
+                noted_on=timezone.now(),
+                noted_by=request.user.contributor,
+                duration=prodevent_form.cleaned_data['duration'],)
+            prodevent.save()
+            return redirect(reverse('production:production'))
+        else:
+            errormessage = 'The form was invalidly filled.'
+            return render(request, 'scipost/error.html', {'errormessage': errormessage})
+    else:
+        errormessage = 'This view can only be posted to.'
+        return render(request, 'scipost/error.html', {'errormessage': errormessage})
+
+
+
+
+def upload_proofs(request):
+    """
+    TODO
+    Called by a member of the Production Team.
+    Upload the production version .pdf of a submission.
+    """
+    return render(request, 'production/upload_proofs.html')
diff --git a/submissions/views.py b/submissions/views.py
index b49f185de..a3c046f0d 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -35,6 +35,7 @@ from scipost.utils import Utils
 from strings import arxiv_caller_errormessages_submissions
 
 from comments.forms import CommentForm
+from production.models import ProductionStream
 
 from django.views.generic.edit import CreateView, FormView
 from django.views.generic.list import ListView
@@ -1290,6 +1291,10 @@ def fix_College_decision(request, rec_id):
     if recommendation.recommendation in [1, 2, 3]:
         # Publish as Tier I, II or III
         recommendation.submission.status = 'accepted'
+        # Create a ProductionStream object
+        prodstream = ProductionStream(submission=recommendation.submission,
+                                      opened=timezone.now())
+        prodstream.save()
     elif recommendation.recommendation == -3:
         # Reject
         recommendation.submission.status = 'rejected'
-- 
GitLab