diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 4083889191653f3b3464621e2b8374370f43dd47..861544adb28ad4486484f1974dffafa2cb563a9a 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -240,6 +240,7 @@ JOURNALS_DIR = 'journals'
 
 CROSSREF_LOGIN_ID = ''
 CROSSREF_LOGIN_PASSWORD = ''
+DOAJ_API_KEY = ''
 
 # Google reCaptcha with Google's global test keys
 # https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha-v2-what-should-i-do
diff --git a/SciPost_v1/settings/production.py b/SciPost_v1/settings/production.py
index b6f220c85893695023746f93a09ea40c130f7c14..ab2cfb01f139d2fd78784cccc683cbfb7267adc6 100644
--- a/SciPost_v1/settings/production.py
+++ b/SciPost_v1/settings/production.py
@@ -38,6 +38,7 @@ SERVER_EMAIL = get_secret("SERVER_EMAIL")
 # Other
 CROSSREF_LOGIN_ID = get_secret("CROSSREF_LOGIN_ID")
 CROSSREF_LOGIN_PASSWORD = get_secret("CROSSREF_LOGIN_PASSWORD")
+DOAJ_API_KEY = get_secret("DOAJ_API_KEY")
 HAYSTACK_CONNECTIONS['default']['PATH'] = '/home/jscaux/webapps/scipost/SciPost_v1/whoosh_index'
 MAILCHIMP_API_USER = get_secret("MAILCHIMP_API_USER")
 MAILCHIMP_API_KEY = get_secret("MAILCHIMP_API_KEY")
diff --git a/comments/templates/comments/reply_to_report.html b/comments/templates/comments/reply_to_report.html
index 348d82701826f73a80777e21357ef24fbc042db9..d796bb1210d20cd90057e987d2eb59a5c9755c63 100644
--- a/comments/templates/comments/reply_to_report.html
+++ b/comments/templates/comments/reply_to_report.html
@@ -14,7 +14,7 @@
     <div class="row">
         <div class="col-12">
             {% if not is_author %}
-                <h2>(you are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page)</h2>
+                <h2>You are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page.</h2>
             {% else %}
                 <h2>The Submission concerned:</h2>
 
diff --git a/journals/admin.py b/journals/admin.py
index 8c82762bbe9cb7df533f9aec127ecb2ca1328fe7..6b5f4cecdf14c7289cd748ca007979ae20f083c9 100644
--- a/journals/admin.py
+++ b/journals/admin.py
@@ -1,7 +1,8 @@
 from django.contrib import admin, messages
 from django import forms
 
-from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, Deposit
+from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, \
+    Deposit, DOAJDeposit
 
 from scipost.models import Contributor
 from submissions.models import Submission
@@ -64,7 +65,7 @@ admin.site.register(Publication, PublicationAdmin)
 
 
 class DepositAdmin(admin.ModelAdmin):
-    list_display = ('doi_batch_id', 'publication', 'deposition_date',)
+    list_display = ('publication', 'timestamp', 'doi_batch_id', 'deposition_date',)
     readonly_fields = ('publication', 'doi_batch_id', 'metadata_xml', 'deposition_date',)
     actions = None
 
@@ -79,3 +80,6 @@ class DepositAdmin(admin.ModelAdmin):
 
 
 admin.site.register(Deposit, DepositAdmin)
+
+
+admin.site.register(DOAJDeposit)
diff --git a/journals/constants.py b/journals/constants.py
index 6bd5de5cf9a4285d253a22a9bbb638efde5396f0..7db8b8c2a556c43aaddb121825a6ec209746412e 100644
--- a/journals/constants.py
+++ b/journals/constants.py
@@ -56,3 +56,12 @@ ISSUE_STATUSES = (
     (STATUS_DRAFT, 'Draft'),
     (STATUS_PUBLISHED, 'Published'),
 )
+
+CCBY4 = 'CC BY 4.0'
+CCBYSA4 = 'CC BY-SA 4.0'
+CCBYNC4 = 'CC BY-NC 4.0'
+CC_LICENSES = (
+    (CCBY4, 'CC BY (4.0)'),
+    (CCBYSA4, 'CC BY-SA (4.0)'),
+    (CCBYNC4, 'CC BY-NC (4.0)'),
+)
diff --git a/journals/migrations/0024_publication_lastest_citedby_update.py b/journals/migrations/0024_publication_lastest_citedby_update.py
new file mode 100644
index 0000000000000000000000000000000000000000..30f8841d41373a0e252f990b4cfd9609a3c969cb
--- /dev/null
+++ b/journals/migrations/0024_publication_lastest_citedby_update.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-08 09:07
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0023_auto_20170517_1846'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='publication',
+            name='lastest_citedby_update',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+    ]
diff --git a/journals/migrations/0025_auto_20170708_1154.py b/journals/migrations/0025_auto_20170708_1154.py
new file mode 100644
index 0000000000000000000000000000000000000000..3290f9071eace79f55ca044d85bb776511f0a1f2
--- /dev/null
+++ b/journals/migrations/0025_auto_20170708_1154.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-08 09:54
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0024_publication_lastest_citedby_update'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='publication',
+            old_name='lastest_citedby_update',
+            new_name='latest_citedby_update',
+        ),
+    ]
diff --git a/journals/migrations/0026_auto_20170708_1542.py b/journals/migrations/0026_auto_20170708_1542.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a78e36a6d46a1237959a862edd9004f1f2dd400
--- /dev/null
+++ b/journals/migrations/0026_auto_20170708_1542.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-08 13:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0025_auto_20170708_1154'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='publication',
+            name='latest_crossref_deposit',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='latest_metadata_update',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='metadata_xml_file',
+            field=models.FileField(blank=True, null=True, upload_to=''),
+        ),
+    ]
diff --git a/journals/migrations/0027_auto_20170710_0805.py b/journals/migrations/0027_auto_20170710_0805.py
new file mode 100644
index 0000000000000000000000000000000000000000..cce57940d89031f9061d97c21fb1f0665f18708b
--- /dev/null
+++ b/journals/migrations/0027_auto_20170710_0805.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-10 06:05
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0026_auto_20170708_1542'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='publication',
+            name='metadata_xml_file',
+        ),
+        migrations.AddField(
+            model_name='deposit',
+            name='metadata_xml_file',
+            field=models.FileField(blank=True, null=True, upload_to=''),
+        ),
+        migrations.AddField(
+            model_name='deposit',
+            name='response_text',
+            field=models.TextField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='deposit',
+            name='timestamp',
+            field=models.CharField(default='', max_length=40),
+        ),
+        migrations.AlterField(
+            model_name='deposit',
+            name='deposition_date',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+    ]
diff --git a/journals/migrations/0028_auto_20170710_0906.py b/journals/migrations/0028_auto_20170710_0906.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c0d934848fa8d9ac001e5b72ea3cd1ae6c2f05d
--- /dev/null
+++ b/journals/migrations/0028_auto_20170710_0906.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-10 07:06
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0027_auto_20170710_0805'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='deposit',
+            options={'ordering': ['-timestamp']},
+        ),
+        migrations.AddField(
+            model_name='deposit',
+            name='deposit_successful',
+            field=models.NullBooleanField(default=None),
+        ),
+    ]
diff --git a/journals/migrations/0029_remove_publication_latest_crossref_deposit.py b/journals/migrations/0029_remove_publication_latest_crossref_deposit.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6c26989d2fa96aad2a3e3e93445045f151e3ec3
--- /dev/null
+++ b/journals/migrations/0029_remove_publication_latest_crossref_deposit.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-10 07:49
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0028_auto_20170710_0906'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='publication',
+            name='latest_crossref_deposit',
+        ),
+    ]
diff --git a/journals/migrations/0030_auto_20170710_1051.py b/journals/migrations/0030_auto_20170710_1051.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3534b85137c5ab4ea9c4dfe140c16ce59aeff28
--- /dev/null
+++ b/journals/migrations/0030_auto_20170710_1051.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-10 08:51
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0029_remove_publication_latest_crossref_deposit'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='deposit',
+            name='metadata_xml_file',
+            field=models.FileField(blank=True, max_length=512, null=True, upload_to=''),
+        ),
+    ]
diff --git a/journals/migrations/0031_clockssmetadata.py b/journals/migrations/0031_clockssmetadata.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9f252ab1d59866c6a86176dd8eebf6abdd03841
--- /dev/null
+++ b/journals/migrations/0031_clockssmetadata.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-11 03:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0030_auto_20170710_1051'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='CLOCKSSmetadata',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('metadata_xml_file_CLOCKSS', models.FileField(blank=True, max_length=512, null=True, upload_to='')),
+                ('publication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Publication')),
+            ],
+        ),
+    ]
diff --git a/journals/migrations/0032_auto_20170711_0952.py b/journals/migrations/0032_auto_20170711_0952.py
new file mode 100644
index 0000000000000000000000000000000000000000..25f177b24634e1d976dbad6b66e3b292b83133b5
--- /dev/null
+++ b/journals/migrations/0032_auto_20170711_0952.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-11 07:52
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0031_clockssmetadata'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='clockssmetadata',
+            options={'verbose_name': 'CLOCKSS metadata'},
+        ),
+    ]
diff --git a/journals/migrations/0033_auto_20170711_2041.py b/journals/migrations/0033_auto_20170711_2041.py
new file mode 100644
index 0000000000000000000000000000000000000000..7c77db3e5381b1873623fa4f1e9606ae3af30e7e
--- /dev/null
+++ b/journals/migrations/0033_auto_20170711_2041.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-11 18:41
+from __future__ import unicode_literals
+
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0032_auto_20170711_0952'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='DOAJDeposit',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('timestamp', models.CharField(default='', max_length=40)),
+                ('metadata_DOAJ', django.contrib.postgres.fields.jsonb.JSONField()),
+                ('deposition_date', models.DateTimeField(blank=True, null=True)),
+                ('response_text', models.TextField(blank=True, null=True)),
+                ('deposit_successful', models.NullBooleanField(default=None)),
+            ],
+            options={
+                'verbose_name': 'DOAJ deposit',
+            },
+        ),
+        migrations.AddField(
+            model_name='publication',
+            name='metadata_DOAJ',
+            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='doajdeposit',
+            name='publication',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Publication'),
+        ),
+    ]
diff --git a/journals/migrations/0034_publication_cc_license.py b/journals/migrations/0034_publication_cc_license.py
new file mode 100644
index 0000000000000000000000000000000000000000..b23b2c997bd72c6252c82999dd57c112826b2a28
--- /dev/null
+++ b/journals/migrations/0034_publication_cc_license.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-12 06:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0033_auto_20170711_2041'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='publication',
+            name='cc_license',
+            field=models.CharField(choices=[('CC BY 4.0', 'CC BY (4.0)'), ('CC BY-SA 4.0', 'CC BY-SA (4.0)'), ('CC BY-NC 4.0', 'CC BY-NC (4.0)')], default='CC BY 4.0', max_length=32),
+        ),
+    ]
diff --git a/journals/migrations/0035_auto_20170714_0609.py b/journals/migrations/0035_auto_20170714_0609.py
new file mode 100644
index 0000000000000000000000000000000000000000..860612627d85724c62217f0d7b446223631caeac
--- /dev/null
+++ b/journals/migrations/0035_auto_20170714_0609.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-14 04:09
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0034_publication_cc_license'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='clockssmetadata',
+            name='publication',
+        ),
+        migrations.DeleteModel(
+            name='CLOCKSSmetadata',
+        ),
+    ]
diff --git a/journals/models.py b/journals/models.py
index 920371b7819b43ae6d49c9e35619b65cd36c1ab0..722fdccdf2790733789b411c760645a8a462d4e4 100644
--- a/journals/models.py
+++ b/journals/models.py
@@ -7,7 +7,8 @@ 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
+                       STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES,\
+                       CCBY4, CC_LICENSES
 from .helpers import paper_nr_string, journal_name_abbrev_citation
 from .managers import IssueManager, PublicationManager
 
@@ -140,14 +141,18 @@ class Publication(models.Model):
                                                   related_name='authors_pub_false_claims')
     abstract = models.TextField()
     pdf_file = models.FileField(upload_to='UPLOADS/PUBLICATIONS/%Y/%m/', max_length=200)
+    cc_license = models.CharField(max_length=32, choices=CC_LICENSES, default=CCBY4)
     metadata = JSONField(default={}, blank=True, null=True)
     metadata_xml = models.TextField(blank=True, null=True)  # for Crossref deposit
+    latest_metadata_update = models.DateTimeField(blank=True, null=True)
+    metadata_DOAJ = JSONField(blank=True, null=True)
     BiBTeX_entry = models.TextField(blank=True, null=True)
     doi_label = models.CharField(max_length=200, unique=True, db_index=True,
                                  validators=[doi_publication_validator])
     submission_date = models.DateField(verbose_name='submission date')
     acceptance_date = models.DateField(verbose_name='acceptance date')
     publication_date = models.DateField(verbose_name='publication date')
+    latest_citedby_update = models.DateTimeField(null=True, blank=True)
     latest_activity = models.DateTimeField(default=timezone.now)
     citedby = JSONField(default={}, blank=True, null=True)
 
@@ -211,6 +216,7 @@ class Publication(models.Model):
         return template.render(context)
 
 
+
 class Deposit(models.Model):
     """
     Each time a Crossref deposit is made for a Publication,
@@ -219,10 +225,35 @@ class Deposit(models.Model):
     All deposit history is thus contained here.
     """
     publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
+    timestamp = models.CharField(max_length=40, default='')
     doi_batch_id = models.CharField(max_length=40, default='')
     metadata_xml = models.TextField(blank=True, null=True)
-    deposition_date = models.DateTimeField(default=timezone.now)
+    metadata_xml_file = models.FileField(blank=True, null=True, max_length=512)
+    deposition_date = models.DateTimeField(blank=True, null=True)
+    response_text = models.TextField(blank=True, null=True)
+    deposit_successful = models.NullBooleanField(default=None)
+
+    class Meta:
+        ordering = ['-timestamp']
 
     def __str__(self):
         return (self.deposition_date.strftime('%Y-%m-%D') +
-                ' for 10.21468/' + self.publication.doi_label)
+                ' for ' + self.publication.doi_label)
+
+
+class DOAJDeposit(models.Model):
+    """
+    For the Directory of Open Access Journals.
+    """
+    publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
+    timestamp = models.CharField(max_length=40, default='')
+    metadata_DOAJ = JSONField()
+    deposition_date = models.DateTimeField(blank=True, null=True)
+    response_text = models.TextField(blank=True, null=True)
+    deposit_successful = models.NullBooleanField(default=None)
+
+    class Meta:
+        verbose_name = 'DOAJ deposit'
+
+    def __str__(self):
+        return ('DOAJ deposit for ' + self.publication.doi_label)
diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html
index 977eaff19441cafbba2bc48b695399f819f4cdc2..1be0c6ec70ab651b7199a365944bf59fa65046de 100644
--- a/journals/templates/journals/add_author.html
+++ b/journals/templates/journals/add_author.html
@@ -94,7 +94,7 @@
       </div>
 
       <h3>
-          <a href="{{publication.get_absolute_url}}">Return to the publication's page</a>
+          <a href="{{publication.get_absolute_url}}">Return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a>
       </h3>
     </div>
 </div>
diff --git a/journals/templates/journals/create_citation_list_metadata.html b/journals/templates/journals/create_citation_list_metadata.html
index 037452a969156d6ed46ce3ec382531b43babf06a..a7d68067d8aeede3f8971ebc9c706923f097c72e 100644
--- a/journals/templates/journals/create_citation_list_metadata.html
+++ b/journals/templates/journals/create_citation_list_metadata.html
@@ -33,7 +33,7 @@
 
   <hr class="hr6"/>
 
-  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a></h3>
+  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></h3>
 
 </section>
 
diff --git a/journals/templates/journals/create_funding_info_metadata.html b/journals/templates/journals/create_funding_info_metadata.html
index 5c953dd55e919990876bdbad2dfa86ed3ea86efd..7e918a563af0236bd0ce89cc15ae7fdd832c8d60 100644
--- a/journals/templates/journals/create_funding_info_metadata.html
+++ b/journals/templates/journals/create_funding_info_metadata.html
@@ -27,7 +27,7 @@
 
   <hr class="hr6"/>
 
-  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a></h3>
+  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></h3>
 
 </section>
 
diff --git a/journals/templates/journals/create_metadata_xml.html b/journals/templates/journals/create_metadata_xml.html
index 3caea010544c52b21d392abdfd87f0f02badd9c1..6fcb9803386abcfba0d9d5996538c6e700ab2db2 100644
--- a/journals/templates/journals/create_metadata_xml.html
+++ b/journals/templates/journals/create_metadata_xml.html
@@ -27,7 +27,7 @@
 
   <hr class="hr6"/>
 
-  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a></h3>
+  <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></h3>
 
 </section>
 
diff --git a/journals/templates/journals/harvest_citedby_list.html b/journals/templates/journals/harvest_citedby_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..85672fe0818c9f207041c252e5e7d0e06e3bd514
--- /dev/null
+++ b/journals/templates/journals/harvest_citedby_list.html
@@ -0,0 +1,65 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block pagetitle %}: Harvest citedby data{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Harvest citedby data</span>
+{% endblock %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Harvest citedby data</h1>
+    </div>
+</div>
+
+<div class="row">
+    <div class="col-12">
+        <table class="table">
+            <thead>
+                <tr>
+                    <th>doi</th>
+                    <th>Publication date</th>
+		    <th>Nr citations</th>
+                    <th>Latest Cited-by update</th>
+                    <th>Actions</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for publication in publications %}
+                    <tr>
+                        <td><a href="{{publication.get_absolute_url}}">{{ publication.doi_label }}</a></td>
+                        <td>{{ publication.publication_date }}</td>
+                        {% if publication.latest_citedby_update %}
+			<td>
+			  {{ publication.citedby|length }}
+			</td>
+                        <td>
+                          {{ publication.latest_citedby_update }}
+			</td>
+                        {% else %}
+			<td>0</td>
+                        <td>No information available</td>
+                        {% endif %}
+                        <td>
+                            <ul>
+                                <li><a href="{% url 'journals:harvest_citedby_links' publication.doi_label %}">Harvest citedby data now</a></li>
+                            </ul>
+                        </td>
+                    </tr>
+                {% empty %}
+                    <tr>
+                        <td colspan="5">No publications found.</td>
+                    </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+
+
+{% endblock content %}
diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html
new file mode 100644
index 0000000000000000000000000000000000000000..b9ca627d8401da8c0d6225fff22d306c32f39045
--- /dev/null
+++ b/journals/templates/journals/manage_metadata.html
@@ -0,0 +1,166 @@
+{% extends 'scipost/_personal_page_base.html' %}
+
+{% block pagetitle %}: Manage metadata{% endblock pagetitle %}
+
+{% load bootstrap %}
+
+{% load journals_extras %}
+
+<script>
+$(function() {
+$( "#accordion" ).accordion({
+event: "focusin"
+});
+});
+</script>
+
+{% block breadcrumb_items %}
+    {{block.super}}
+    <span class="breadcrumb-item">Manage metadata</span>
+{% endblock %}
+
+{% block content %}
+
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Manage Publications Metadata</h1>
+    </div>
+</div>
+
+
+<table class="table table-hover mb-5">
+  <thead class="thead-default">
+    <tr>
+      <th>doi</th>
+      <th>Publication date</th>
+      <th>Latest metadata update</th>
+      <th>Latest successful Crossref deposit</th>
+      <th>DOAJ</th>
+    </tr>
+  </thead>
+
+  <tbody id="accordion" role="tablist" aria-multiselectable="true">
+    {% for publication in publications %}
+    <tr data-toggle="collapse" data-parent="#accordion" href="#collapse{{ publication.id }}" aria-expanded="true" aria-controls="collapse{{ publication.id }}" style="cursor: pointer;">
+      <td><a href="{{ publication.get_absolute_url }}">{{ publication.doi_label }}</a></td>
+      <td>{{ publication.publication_date }}</td>
+      {% if publication.latest_metadata_update %}
+      <td>
+        {{ publication.latest_metadata_update }}
+      </td>
+      {% else %}
+      <td>No info available</td>
+      {% endif %}
+      <td>{{ publication|latest_successful_crossref_deposit }}</td>
+      <td>{{ publication|latest_successful_DOAJ_deposit }}</td>
+    </tr>
+    <tr id="collapse{{ publication.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ publication.id }}" style="background-color: #fff;">
+      <td colspan="5">
+	<h3 class="ml-3">Actions</h3>
+        <ul>
+          <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }} {% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %})
+	    <div class="row">
+              <div class="col-md-5">
+                <p>registered authors:</p>
+                <ul>
+                  {% for author in publication.authors.all %}
+                  <li>
+                    <a href="{% url 'journals:mark_first_author' publication_id=publication.id contributor_id=author.id %}">{{ author }}</a>
+                  </li>
+                  {% endfor %}
+                </ul>
+              </div>
+              <div class="col-md-5">
+                <p>unregistered authors:</p>
+                <ul>
+                  {% for author_unreg in publication.authors_unregistered.all %}
+                  <li>
+                    <a href="{% url 'journals:mark_first_author_unregistered' publication_id=publication.id unregistered_author_id=author_unreg.id %}">{{ author_unreg }}</a>
+                  </li>
+                  {% endfor %}
+                </ul>
+              </div>
+	    </div>
+          </li>
+          <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li>
+          <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li>
+          <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li>
+
+          <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">(re)create metadata</a></li>
+          <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li>
+          <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li>
+	  <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li>
+	  <li><a href="{% url 'journals:metadata_DOAJ_deposit' doi_label=publication.doi_label %}">Deposit the metadata to DOAJ</a></li>
+        </ul>
+	<h3 class="ml-3">Crossref Deposits</h3>
+	<table class="ml-5">
+	  <thead class="thead-default">
+	    <th>Timestamp</th>
+	    <th>batch id</th>
+	    <th>deposition date</th>
+	    <th>Successful?</th>
+	    <th>actions</th>
+	  </thead>
+	  <tbody>
+	    {% for deposit in publication.deposit_set.all %}
+	    <tr>
+	      <td>{{ deposit.timestamp }}</td>
+	      <td>{{ deposit.doi_batch_id }}</td>
+	      <td>{% if deposit.deposition_date %}{{ deposit.deposition_date }}{% else %}Not deposited{% endif %}</td>
+	      <td>{{ deposit.deposit_successful }}</td>
+	      <td>Mark deposit as
+		<ul>
+		  <li><a href="{% url 'journals:mark_deposit_success' deposit_id=deposit.id success=1 %}">successful</a></li>
+		  <li><a href="{% url 'journals:mark_deposit_success' deposit_id=deposit.id success=0 %}">unsuccessful</a></li>
+		</ul>
+	      </td>
+	    </tr>
+	    {% empty %}
+	    <tr>
+	      <td colspan="5">No Deposits found for this publication</td>
+	    </tr>
+	    {% endfor %}
+	  </tbody>
+	</table>
+
+	<h3 class="ml-3">DOAJ Deposits</h3>
+	<table class="ml-5">
+	  <thead class="thead-default">
+	    <th>Timestamp</th>
+	    <th>deposition date</th>
+	    <th>Successful?</th>
+	    <th>actions</th>
+	  </thead>
+	  <tbody>
+	    {% for deposit in publication.doajdeposit_set.all %}
+	    <tr>
+	      <td>{{ deposit.timestamp }}</td>
+	      <td>{% if deposit.deposition_date %}{{ deposit.deposition_date }}{% else %}Not deposited{% endif %}</td>
+	      <td>{{ deposit.deposit_successful }}</td>
+	      <td>Mark deposit as
+		<ul>
+		  <li><a href="{% url 'journals:mark_doaj_deposit_success' deposit_id=deposit.id success=1 %}">successful</a></li>
+		  <li><a href="{% url 'journals:mark_doaj_deposit_success' deposit_id=deposit.id success=0 %}">unsuccessful</a></li>
+		</ul>
+	      </td>
+	    </tr>
+	    {% empty %}
+	    <tr>
+	      <td colspan="4">No Deposits found for this publication</td>
+	    </tr>
+	    {% endfor %}
+	  </tbody>
+	</table>
+
+      </td>
+    </tr>
+    {% empty %}
+    <tr>
+      <td colspan="4">No publications found.</td>
+    </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+
+{% endblock content %}
diff --git a/journals/templates/journals/metadata_xml_deposit.html b/journals/templates/journals/metadata_xml_deposit.html
index bc16e8cc58a40b697bfbac89e9691e310288a04a..645cba7c0b3d86dd2356e729ce5f22c62bcc7956 100644
--- a/journals/templates/journals/metadata_xml_deposit.html
+++ b/journals/templates/journals/metadata_xml_deposit.html
@@ -22,7 +22,7 @@
   <h3>Response text:</h3>
   <p>{{ response_text|linebreaks }}</p>
 
-  <h3><a href="{{publication.get_absolute_url}}">return to the publication's page</a></h3>
+  <h3><a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></h3>
 
 </section>
 
diff --git a/journals/templatetags/journals_extras.py b/journals/templatetags/journals_extras.py
index 382ac91e2b0e6a2528fbd9c54349ca4a9e0ac332..d995ca07c160a96cad93d8efab44c91e72bf4dc2 100644
--- a/journals/templatetags/journals_extras.py
+++ b/journals/templatetags/journals_extras.py
@@ -8,3 +8,21 @@ register = template.Library()
 @register.filter(name='paper_nr_string_filter')
 def paper_nr_string_filter(nr):
     return paper_nr_string(nr)
+
+@register.filter(name='latest_successful_crossref_deposit')
+def latest_successful_crossref_deposit(publication):
+    latest = publication.deposit_set.filter(
+        deposit_successful=True).order_by('-deposition_date').first()
+    if latest:
+        return latest.deposition_date.strftime('%Y-%m-%d')
+    else:
+        return "No successful deposit found"
+
+@register.filter(name='latest_successful_DOAJ_deposit')
+def latest_successful_DOAJ_deposit(publication):
+    latest = publication.doajdeposit_set.filter(
+        deposit_successful=True).order_by('-deposition_date').first()
+    if latest:
+        return latest.deposition_date.strftime('%Y-%m-%d')
+    else:
+        return "No successful deposit found"
diff --git a/journals/urls/general.py b/journals/urls/general.py
index 76d8ab0b758416a861fe8b654cdd747bb3c4b7be..31e3cbec6b95190889e7cd457f5c5640f875341e 100644
--- a/journals/urls/general.py
+++ b/journals/urls/general.py
@@ -7,7 +7,8 @@ from journals import views as journals_views
 urlpatterns = [
     # Journals
     url(r'^$', TemplateView.as_view(template_name='journals/journals.html'), name='journals'),
-    url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page', args=['SciPostPhys']))),
+    url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page',
+                                                 args=['SciPostPhys']))),
     url(r'^journals_terms_and_conditions$',
         TemplateView.as_view(template_name='journals/journals_terms_and_conditions.html'),
         name='journals_terms_and_conditions'),
@@ -37,6 +38,9 @@ urlpatterns = [
     url(r'^add_new_unreg_author/(?P<publication_id>[0-9]+)$',
         journals_views.add_new_unreg_author,
         name='add_new_unreg_author'),
+    url(r'^manage_metadata/$',
+        journals_views.manage_metadata,
+        name='manage_metadata'),
     url(r'^create_citation_list_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
         journals_views.create_citation_list_metadata,
         name='create_citation_list_metadata'),
@@ -49,6 +53,21 @@ urlpatterns = [
     url(r'^metadata_xml_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/(?P<option>[a-z]+)$',
         journals_views.metadata_xml_deposit,
         name='metadata_xml_deposit'),
+    url(r'^mark_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$',
+        journals_views.mark_deposit_success,
+        name='mark_deposit_success'),
+    url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
+        journals_views.produce_metadata_DOAJ,
+        name='produce_metadata_DOAJ'),
+    url(r'^metadata_DOAJ_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
+        journals_views.metadata_DOAJ_deposit,
+        name='metadata_DOAJ_deposit'),
+    url(r'^mark_doaj_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$',
+        journals_views.mark_doaj_deposit_success,
+        name='mark_doaj_deposit_success'),
+    url(r'^harvest_citedby_list/$',
+        journals_views.harvest_citedby_list,
+        name='harvest_citedby_list'),
     url(r'^harvest_citedby_links/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$',
         journals_views.harvest_citedby_links,
         name='harvest_citedby_links'),
diff --git a/journals/utils.py b/journals/utils.py
index b1e7630d7fc7656e2a559f33977dedad3b42f3ba..1f1f0e0bd21261c6a9e11ed714e2036c245da992 100644
--- a/journals/utils.py
+++ b/journals/utils.py
@@ -39,5 +39,48 @@ class JournalUtils(object):
         emailmessage.send(fail_silently=False)
 
     @classmethod
-    def generate_metadata_xml_file(cls):
+    def generate_metadata_DOAJ(cls):
         """ Requires loading 'publication' attribute. """
+        md = {
+            'bibjson': {
+                'author': [{'name': cls.publication.author_list}],
+                'title': cls.publication.title,
+                'abstract': cls.publication.abstract,
+                'year': cls.publication.publication_date.strftime('%Y'),
+                'month': cls.publication.publication_date.strftime('%m'),
+                'start_page': cls.publication.get_paper_nr(),
+                'identifier': [
+                    {
+                        'type': 'doi',
+                        'id': cls.publication.doi_string
+                    }
+                ],
+                'link': [
+                    {
+                        'url': cls.request.build_absolute_uri(cls.publication.get_absolute_url()),
+                        'type': 'fulltext',
+                    }
+                ],
+                'journal': {
+                    'publisher': 'SciPost',
+                    'volume': str(cls.publication.in_issue.in_volume.number),
+                    'number': str(cls.publication.in_issue.number),
+                    'identifier': [{
+                        'type': 'eissn',
+                        'id': str(cls.publication.in_issue.in_volume.in_journal.issn)
+                    }],
+                    'license': [
+                        {
+                            'url': cls.request.build_absolute_uri(
+                                cls.publication.in_issue.in_volume.in_journal.get_absolute_url()),
+                            'open_access': 'true',
+                            'type': cls.publication.get_cc_license_display(),
+                            'title': cls.publication.get_cc_license_display(),
+                        }
+                    ],
+                    'language': ['EN'],
+                    'title': cls.publication.in_issue.in_volume.in_journal.get_name_display(),
+                }
+            }
+        }
+        return md
diff --git a/journals/views.py b/journals/views.py
index c901e579b419c757e395de4d9054f3b1ef467a33..ccf0be58c62bc682f8fa9186b64936750e4b1bf3 100644
--- a/journals/views.py
+++ b/journals/views.py
@@ -6,16 +6,19 @@ import string
 import xml.etree.ElementTree as ET
 
 from django.core.urlresolvers import reverse
+from django.core.files.base import ContentFile
 from django.conf import settings
 from django.contrib import messages
 from django.utils import timezone
 from django.shortcuts import get_object_or_404, render, redirect
+from django.template import Context
+from django.template.loader import get_template
 from django.db import transaction
 from django.http import HttpResponse
 
 from .exceptions import PaperNumberingError
 from .helpers import paper_nr_string
-from .models import Journal, Issue, Publication, UnregisteredAuthor
+from .models import Journal, Issue, Publication, UnregisteredAuthor, Deposit, DOAJDeposit
 from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\
                    UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm
 from .utils import JournalUtils
@@ -135,7 +138,6 @@ def issue_detail(request, doi_label):
     return render(request, 'journals/journal_issue_detail.html', context)
 
 
-
 #######################
 # Publication process #
 #######################
@@ -269,6 +271,15 @@ def validate_publication(request):
     return render(request, 'journals/validate_publication.html', context)
 
 
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+def manage_metadata(request):
+    publications = Publication.objects.order_by('-publication_date', '-paper_nr')
+    context = {
+        'publications': publications
+    }
+    return render(request, 'journals/manage_metadata.html', context)
+
+
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
 @transaction.atomic
 def mark_first_author(request, publication_id, contributor_id):
@@ -430,7 +441,7 @@ def create_metadata_xml(request, doi_label):
         if create_metadata_xml_form.is_valid():
             publication.metadata_xml = create_metadata_xml_form.cleaned_data['metadata_xml']
             publication.save()
-            return redirect(publication.get_absolute_url())
+            return redirect(reverse('journals:manage_metadata'))
 
     # create a doi_batch_id
     salt = ""
@@ -460,11 +471,13 @@ def create_metadata_xml(request, doi_label):
         '<body>\n'
         '<journal>\n'
         '<journal_metadata>\n'
-        '<full_title>' + publication.in_issue.in_volume.in_journal.get_name_display() + '</full_title>\n'
+        '<full_title>' + publication.in_issue.in_volume.in_journal.get_name_display()
+        + '</full_title>\n'
         '<abbrev_title>'
         + publication.in_issue.in_volume.in_journal.get_abbreviation_citation() +
         '</abbrev_title>\n'
-        '<issn>' + publication.in_issue.in_volume.in_journal.issn + '</issn>\n'
+        '<issn media_type=\'electronic\'>' + publication.in_issue.in_volume.in_journal.issn
+        + '</issn>\n'
         '<doi_data>\n'
         '<doi>' + publication.in_issue.in_volume.in_journal.doi_string + '</doi>\n'
         '<resource>https://scipost.org/'
@@ -528,6 +541,7 @@ def create_metadata_xml(request, doi_label):
         '<publisher_item><item_number item_number_type="article_number">'
         + paper_nr_string(publication.paper_nr) +
         '</item_number></publisher_item>\n'
+        '<archive_locations><archive name="CLOCKSS"></archive></archive_locations>\n'
         '<doi_data>\n'
         '<doi>' + publication.doi_string + '</doi>\n'
         '<resource>https://scipost.org/' + publication.doi_string + '</resource>\n'
@@ -555,6 +569,7 @@ def create_metadata_xml(request, doi_label):
         '</journal>\n'
     )
     initial['metadata_xml'] += '</body>\n</doi_batch>'
+    publication.latest_metadata_update = timezone.now()
     publication.save()
 
     context = {'publication': publication,
@@ -572,6 +587,16 @@ def metadata_xml_deposit(request, doi_label, option='test'):
     Makes use of the python requests module.
     """
     publication = get_object_or_404(Publication, doi_label=doi_label)
+    timestamp = (publication.metadata_xml.partition(
+        '<timestamp>'))[2].partition('</timestamp>')[0]
+    doi_batch_id = (publication.metadata_xml.partition(
+        '<doi_batch_id>'))[2].partition('</doi_batch_id>')[0]
+    path = (settings.MEDIA_ROOT + publication.in_issue.path + '/'
+            + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_')
+            + '_Crossref_' + timestamp + '.xml')
+    if os.path.isfile(path):
+        errormessage = 'The metadata file for this metadata timestamp already exists'
+        return render(request, 'scipost/error.html', context={'errormessage': errormessage})
     if option == 'deposit':
         url = 'http://doi.crossref.org/servlet/deposit'
     elif option == 'test':
@@ -579,7 +604,10 @@ def metadata_xml_deposit(request, doi_label, option='test'):
     else:
         errormessage = 'metadata_xml_deposit can only be called with options test or deposit'
         return render(request, 'scipost/error.html', context={'errormessage': errormessage})
-
+    if publication.metadata_xml is None:
+        errormessage = 'This publication has no metadata. Produce it first before saving it.'
+        return render(request, 'scipost/error.html', context={'errormessage': errormessage})
+    # First perform the actual deposit to Crossref
     params = {
         'operation': 'doMDUpload',
         'login_id': settings.CROSSREF_LOGIN_ID,
@@ -592,6 +620,25 @@ def metadata_xml_deposit(request, doi_label, option='test'):
                       )
     response_headers = r.headers
     response_text = r.text
+
+    # Then create the associated Deposit object (saving the metadata to a file)
+    if option == 'deposit':
+        content = ContentFile(publication.metadata_xml)
+        deposit = Deposit(publication=publication, timestamp=timestamp, doi_batch_id=doi_batch_id,
+                          metadata_xml=publication.metadata_xml, deposition_date=timezone.now())
+        deposit.metadata_xml_file.save(path, content)
+        deposit.response_text = r.text
+        deposit.save()
+        publication.latest_crossref_deposit = timezone.now()
+        publication.save()
+        # Save a copy to the filename without timestamp
+        path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/'
+                 + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_')
+                 + '_Crossref.xml')
+        f = open(path1, 'w')
+        f.write(publication.metadata_xml)
+        f.close()
+
     context = {
         'option': option,
         'publication': publication,
@@ -601,6 +648,114 @@ def metadata_xml_deposit(request, doi_label, option='test'):
     return render(request, 'journals/metadata_xml_deposit.html', context)
 
 
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+def mark_deposit_success(request, deposit_id, success):
+    deposit = get_object_or_404(Deposit, pk=deposit_id)
+    if success == '1':
+        deposit.deposit_successful = True
+    elif success == '0':
+        deposit.deposit_successful = False
+    deposit.save()
+    return redirect(reverse('journals:manage_metadata'))
+
+
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+def produce_metadata_DOAJ(request, doi_label):
+    publication = get_object_or_404(Publication, doi_label=doi_label)
+    JournalUtils.load({'request': request, 'publication': publication})
+    publication.metadata_DOAJ = JournalUtils.generate_metadata_DOAJ()
+    publication.save()
+    messages.success(request, '<h3>%s</h3>Successfully produced metadata DOAJ.'
+                              % publication.doi_label)
+    return redirect(reverse('journals:manage_metadata'))
+
+
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+@transaction.atomic
+def metadata_DOAJ_deposit(request, doi_label):
+    """
+    DOAJ metadata deposit.
+    Makes use of the python requests module.
+    """
+    publication = get_object_or_404(Publication, doi_label=doi_label)
+    if not publication.metadata_DOAJ:
+        messages.warning(request, '<h3>%s</h3>Failed: please first produce '
+                                  'DOAJ metadata before depositing.' % publication.doi_label)
+        return redirect(reverse('journals:manage_metadata'))
+
+    timestamp = (publication.metadata_xml.partition(
+        '<timestamp>'))[2].partition('</timestamp>')[0]
+    path = (settings.MEDIA_ROOT + publication.in_issue.path + '/'
+            + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_')
+            + '_DOAJ_' + timestamp + '.json')
+    if os.path.isfile(path):
+        errormessage = 'The metadata file for this metadata timestamp already exists'
+        return render(request, 'scipost/error.html', context={'errormessage': errormessage})
+    url = 'https://doaj.org/api/v1/articles'
+
+    params = {
+        'operation': 'doMDUpload',
+        'api_key': settings.DOAJ_API_KEY,
+        }
+    files = {'fname': ('metadata.json', publication.metadata_xml, 'application/json')}
+    try:
+        r = requests.post(url, params=params, files=files)
+        r.raise_for_status()
+    except requests.exceptions.HTTPError:
+        messages.warning(request, '<h3>%s</h3>Failed: Post went wrong. Did you set the right '
+                                  'DOAJ API KEY?' % publication.doi_label)
+        return redirect(reverse('journals:manage_metadata'))
+
+    # Then create the associated Deposit object (saving the metadata to a file)
+    content = ContentFile(publication.metadata_xml)
+    deposit = DOAJDeposit(publication=publication, timestamp=timestamp,
+                          metadata_DOAJ=publication.metadata_DOAJ, deposition_date=timezone.now())
+    deposit.metadata_xml_file.save(path, content)
+    deposit.response_text = r.text
+    deposit.save()
+    publication.latest_crossref_deposit = timezone.now()
+    publication.save()
+
+    # Save a copy to the filename without timestamp
+    path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/'
+             + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_')
+             + '_DOAJ.json')
+    f = open(path1, 'w')
+    f.write(publication.metadata_DOAJ)
+    f.close()
+
+    # response_headers = r.headers
+    # response_text = r.text
+    # context = {
+    #     'publication': publication,
+    #     'response_headers': response_headers,
+    #     'response_text': response_text,
+    # }
+    messages.success(request, '<h3>%s</h3>Successfull deposit of metadata DOAJ.'
+                              % publication.doi_label)
+    return redirect(reverse('journals:manage_metadata'))
+
+
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+def mark_doaj_deposit_success(request, deposit_id, success):
+    deposit = get_object_or_404(DOAJDeposit, pk=deposit_id)
+    if success == '1':
+        deposit.deposit_successful = True
+    elif success == '0':
+        deposit.deposit_successful = False
+    deposit.save()
+    return redirect(reverse('journals:manage_metadata'))
+
+
+@permission_required('scipost.can_publish_accepted_submission', return_403=True)
+def harvest_citedby_list(request):
+    publications = Publication.objects.order_by('-publication_date')
+    context = {
+        'publications': publications
+    }
+    return render(request, 'journals/harvest_citedby_list.html', context)
+
+
 @permission_required('scipost.can_publish_accepted_submission', return_403=True)
 @transaction.atomic
 def harvest_citedby_links(request, doi_label):
@@ -637,7 +792,7 @@ def harvest_citedby_links(request, doi_label):
     if r.status_code == 401:
         messages.warning(request, ('<h3>Crossref credentials are invalid.</h3>'
                                    'Please contact the SciPost Admin.'))
-        return redirect(publication.get_absolute_url())
+        return redirect(reverse('journals:harvest_all_publications'))
     response_headers = r.headers
     response_text = r.text
     response_deserialized = ET.fromstring(r.text)
@@ -680,6 +835,7 @@ def harvest_citedby_links(request, doi_label):
                           'item_number': item_number,
                           'year': year, })
     publication.citedby = citations
+    publication.latest_citedby_update = timezone.now()
     publication.save()
     context = {
         'publication': publication,
diff --git a/mailing_lists/models.py b/mailing_lists/models.py
index e9e3660f3b207f9989286f540aa3f5c6de96f680..dc636cf4c349331d62885a284e87ab25f39b0449 100644
--- a/mailing_lists/models.py
+++ b/mailing_lists/models.py
@@ -1,3 +1,5 @@
+import json
+
 from django.db import models, transaction
 from django.contrib.auth.models import User
 from django.conf import settings
@@ -97,7 +99,7 @@ class MailchimpList(TimeStampedModel):
             batch_data['operations'].append({
                 'method': 'POST',
                 'path': add_member_path,
-                'data': {
+                'body': json.dumps({
                     'status': status,
                     'status_if_new': status,
                     'email_address': user.email,
@@ -105,10 +107,10 @@ class MailchimpList(TimeStampedModel):
                         'FNAME': user.first_name,
                         'LNAME': user.last_name,
                     },
-                }
+                })
             })
         # Make the subscribe call
-        client.batches.create(data=batch_data)
+        post_response = client.batches.create(data=batch_data)
 
         # No need to update Contributor field *yet*. MailChimp account is leading here.
         # Contributor.objects.filter(user__in=db_subscribers).update(accepts_SciPost_emails=True)
@@ -116,7 +118,7 @@ class MailchimpList(TimeStampedModel):
         list_data = client.lists.get(list_id=self.mailchimp_list_id)
         self.subscriber_count = list_data['stats']['member_count']
         self.save()
-        return (updated_contributors, len(db_subscribers),)
+        return (updated_contributors, len(db_subscribers), post_response)
 
 
 class MailchimpSubscription(TimeStampedModel):
diff --git a/mailing_lists/templates/mailing_lists/mailchimplist_form.html b/mailing_lists/templates/mailing_lists/mailchimplist_form.html
index 37347dc82164961bf6bdd427468983105174fda8..e0715f011020d5d2aa060853e6173ff62cc0f9ad 100644
--- a/mailing_lists/templates/mailing_lists/mailchimplist_form.html
+++ b/mailing_lists/templates/mailing_lists/mailchimplist_form.html
@@ -32,6 +32,15 @@
             {{form|bootstrap}}
             <input type="submit" value="Update" class="btn btn-secondary" />
         </form>
+        {% if request.GET.bulkid %}
+            <div class="mb-3 mt-5">
+                <hr>
+                <h2>Synchronizing done</h2>
+                <p>
+                    Response bulk ID: <code>{{request.GET.bulkid}}</code><br>
+                    Check <a href="//us1.api.mailchimp.com/playground" target="_blank">MailChimp's Playground</a> to see the response status.
+            </div>
+        {% endif %}
     </div>
 </div>
 
diff --git a/mailing_lists/views.py b/mailing_lists/views.py
index a6952dc61e4661080127d4d588d091d3f0809ff3..3762228e50057a207ae2c60298e372fa68fdc542 100644
--- a/mailing_lists/views.py
+++ b/mailing_lists/views.py
@@ -48,7 +48,7 @@ def syncronize_members(request, list_id):
     """
     _list = get_object_or_404(MailchimpList, mailchimp_list_id=list_id)
     form = MailchimpUpdateForm()
-    unsubscribed, subscribed = form.sync_members(_list)
+    unsubscribed, subscribed, response = form.sync_members(_list)
 
     # Let the user know
     text = '<h3>Syncronize members complete.</h3>'
@@ -57,7 +57,7 @@ def syncronize_members(request, list_id):
     if subscribed:
         text += '<br>%i members have succesfully been subscribed.' % subscribed
     messages.success(request, text)
-    return redirect(_list.get_absolute_url())
+    return redirect(_list.get_absolute_url() + '?bulkid=' + response.get('id'))
 
 
 class ListDetailView(MailchimpMixin, UpdateView):
diff --git a/partners/constants.py b/partners/constants.py
index e3f6224cd7e124253e16f7e7787731d6c72f0b24..a00f453a7dafe9df8dd6283377d5fffd55909b98 100644
--- a/partners/constants.py
+++ b/partners/constants.py
@@ -81,9 +81,9 @@ PARTNER_EVENTS = (
     ('comment', 'Comment added'),
 )
 
-
+CONTACT_GENERAL = 'gen'
 CONTACT_TYPES = (
-    ('gen', 'General Contact'),
+    (CONTACT_GENERAL, 'General Contact'),
     ('tech', 'Technical Contact'),
     ('fin', 'Financial Contact'),
     ('leg', 'Legal Contact')
@@ -91,12 +91,15 @@ CONTACT_TYPES = (
 
 
 MEMBERSHIP_SUBMITTED = 'Submitted'
+MEMBERSHIP_SIGNED = 'Signed'
+MEMBERSHIP_HONOURED = 'Honoured'
+MEMBERSHIP_COMPLETED = 'Completed'
 MEMBERSHIP_AGREEMENT_STATUS = (
     (MEMBERSHIP_SUBMITTED, 'Request submitted by Partner'),
     ('Pending', 'Sent to Partner, response pending'),
-    ('Signed', 'Signed by Partner'),
-    ('Honoured', 'Honoured: payment of Partner received'),
-    ('Completed', 'Completed: agreement has been fulfilled'),
+    (MEMBERSHIP_SIGNED, 'Signed by Partner'),
+    (MEMBERSHIP_HONOURED, 'Honoured: payment of Partner received'),
+    (MEMBERSHIP_COMPLETED, 'Completed: agreement has been fulfilled'),
 )
 
 MEMBERSHIP_DURATION = (
diff --git a/partners/forms.py b/partners/forms.py
index 6454802bb98667250a90b45b6a7ff141ce98d0de..87322b2d67118443949252cdcdfd3d7e6c3d8faf 100644
--- a/partners/forms.py
+++ b/partners/forms.py
@@ -11,7 +11,7 @@ from django_countries.widgets import CountrySelectWidget
 from django_countries.fields import LazyTypedChoiceField
 
 from .constants import PARTNER_KINDS, PROSPECTIVE_PARTNER_PROCESSED, CONTACT_TYPES,\
-                       PARTNER_STATUS_UPDATE, REQUEST_PROCESSED, REQUEST_DECLINED
+                       PARTNER_STATUS_UPDATE, REQUEST_PROCESSED, REQUEST_DECLINED, CONTACT_GENERAL
 from .models import Partner, ProspectivePartner, ProspectiveContact, ProspectivePartnerEvent,\
                     Institution, Contact, PartnerEvent, MembershipAgreement, ContactRequest,\
                     PartnersAttachment
@@ -28,11 +28,13 @@ class MembershipAgreementForm(forms.ModelForm):
             'status',
             'date_requested',
             'start_date',
+            'end_date',
             'duration',
             'offered_yearly_contribution'
         )
         widgets = {
             'start_date': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}),
+            'end_date': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}),
             'date_requested': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}),
         }
 
@@ -208,6 +210,10 @@ class ContactForm(forms.ModelForm):
             'kind',
         )
 
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.fields['kind'].required = False
+
 
 class NewContactForm(ContactForm):
     """
@@ -355,7 +361,9 @@ class PromoteToContactForm(forms.ModelForm):
     """
     This form is used to create a new `partners.Contact`
     """
-    kind = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
+    promote = forms.BooleanField(label='Activate/Promote this contact', initial=True,
+                                 required=False)
+    kind = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, initial=[CONTACT_GENERAL],
                                      label='Contact types', choices=CONTACT_TYPES, required=False)
 
     class Meta:
@@ -372,6 +380,9 @@ class PromoteToContactForm(forms.ModelForm):
         Check if email address is already used.
         """
         email = self.cleaned_data['email']
+        if not self.cleaned_data.get('promote', False):
+            # Don't promote the Contact
+            return email
         if User.objects.filter(Q(email=email) | Q(username=email)).exists():
             self.add_error('email', 'This emailadres has already been used.')
         return email
@@ -382,8 +393,11 @@ class PromoteToContactForm(forms.ModelForm):
         Promote ProspectiveContact's to Contact's related to a certain Partner.
         The status update after promotion is handled outside this method, in the Partner model.
         """
-        # How to handle empty instances?
+        if not self.cleaned_data.get('promote', False):
+            # Don't promote the Contact
+            return
 
+        # How to handle empty instances?
         if self.errors:
             return forms.ValidationError  # Is this a valid exception?
 
@@ -391,7 +405,6 @@ class PromoteToContactForm(forms.ModelForm):
         contact_form = NewContactForm(self.cleaned_data, partner=partner)
         if contact_form.is_valid():
             return contact_form.save(current_user=current_user)
-        r = contact_form.errors
         raise forms.ValidationError('NewContactForm invalid. Please contact Admin.')
 
 
@@ -411,12 +424,22 @@ class PromoteToContactFormset(forms.BaseModelFormSet):
         """
         contacts = []
         for form in self.forms:
-            contacts.append(form.promote_contact(partner, current_user))
-        partner.main_contact = contacts[0]
+            new_contact = form.promote_contact(partner, current_user)
+            if new_contact:
+                contacts.append(new_contact)
+        try:
+            partner.main_contact = contacts[0]
+        except IndexError:
+            # No contacts at all means no main-contact as well...
+            pass
         partner.save()
         return contacts
 
 
+ContactModelFormset = forms.modelformset_factory(ProspectiveContact, PromoteToContactForm,
+                                                 formset=PromoteToContactFormset, extra=0)
+
+
 class ProspectivePartnerForm(forms.ModelForm):
     """
     This form is used to internally add a ProspectivePartner.
diff --git a/partners/managers.py b/partners/managers.py
index abd47528ec58a4c2cc8203cc742ab7710fbae32a..d542b138578ce59188e4a7e20b462d54d0dec067 100644
--- a/partners/managers.py
+++ b/partners/managers.py
@@ -1,4 +1,5 @@
 from django.db import models
+from django.utils import timezone
 
 from .constants import MEMBERSHIP_SUBMITTED, PROSPECTIVE_PARTNER_PROCESSED, REQUEST_INITIATED
 
@@ -30,6 +31,12 @@ class MembershipAgreementManager(models.Manager):
     def open_to_partner(self):
         return self.exclude(status=MEMBERSHIP_SUBMITTED)
 
+    def now_active(self):
+        return self.filter(start_date__lte=timezone.now().date(),
+                           end_date__gte=timezone.now().date())
+        # start_date = models.DateField()
+        # duration = models.DurationField(choices=MEMBERSHIP_DURATION)
+
 
 class PartnersAttachmentManager(models.Manager):
     def my_attachments(self, current_user):
diff --git a/partners/migrations/0027_membershipagreement_end_date.py b/partners/migrations/0027_membershipagreement_end_date.py
new file mode 100644
index 0000000000000000000000000000000000000000..43aa365b6900fa00684bbd430f8b52ac85fcd7ea
--- /dev/null
+++ b/partners/migrations/0027_membershipagreement_end_date.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-19 19:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0026_auto_20170627_1809'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='membershipagreement',
+            name='end_date',
+            field=models.DateField(default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+    ]
diff --git a/partners/models.py b/partners/models.py
index 3a2451424bffc50c4b972cc5926cf78c6861b809..441d7f3d33b557f45c54ee436ddd1d9760a559cf 100644
--- a/partners/models.py
+++ b/partners/models.py
@@ -266,6 +266,7 @@ class MembershipAgreement(models.Model):
     status = models.CharField(max_length=16, choices=MEMBERSHIP_AGREEMENT_STATUS)
     date_requested = models.DateField()
     start_date = models.DateField()
+    end_date = models.DateField()
     duration = models.DurationField(choices=MEMBERSHIP_DURATION)
     offered_yearly_contribution = models.SmallIntegerField(default=0, help_text="Yearly contribution in euro's (€)")
 
diff --git a/partners/templates/partners/supporting_partners.html b/partners/templates/partners/supporting_partners.html
index 2c0d931cf4eda4a2eab1dba6112cfa39cdcdc7f4..92d8bcb60a2d8c2176d65473ca3e0dd2638a497b 100644
--- a/partners/templates/partners/supporting_partners.html
+++ b/partners/templates/partners/supporting_partners.html
@@ -117,6 +117,26 @@
     </div>
 </div>
 
+{% if current_agreements %}
+<div class="row">
+    <div class="col-12">
+        <h1 class="highlight">Partners</h1>
+        <ul class="list-unstyled mb-5">
+            {% for agreement in current_agreements %}
+                <li class="media mb-2">
+                    <img class="d-flex mr-3" width="192" src="{% if agreement.partner.institution.logo %}{{agreement.partner.institution.logo.url}}{% endif %}" alt="Partner Logo">
+                    <div class="media-body">
+                        <p>
+                            <strong>{{agreement.partner.institution.name}}</strong><br>
+                            {{agreement.partner.institution.get_country_display}}
+                        </p>
+                    </div>
+                </li>
+            {% endfor %}
+        </ul>
+    </div>
+</div>
+{% endif %}
 
 {% if perms.scipost.can_manage_SPB %}
 {% if prospective_partners %}
diff --git a/partners/views.py b/partners/views.py
index 33d20a49fb83a44565825edb02b53836ec713bd3..04a4c5f1ef0615d1310fb3d420d3a764aad27fe6 100644
--- a/partners/views.py
+++ b/partners/views.py
@@ -16,8 +16,8 @@ from .models import Partner, ProspectivePartner, ProspectiveContact, ContactRequ
                     PartnersAttachment
 from .forms import ProspectivePartnerForm, ProspectiveContactForm,\
                    EmailProspectivePartnerContactForm, PromoteToPartnerForm,\
-                   ProspectivePartnerEventForm, MembershipQueryForm, PromoteToContactForm,\
-                   PromoteToContactFormset, PartnerForm, ContactForm, ContactFormset,\
+                   ProspectivePartnerEventForm, MembershipQueryForm,\
+                   PartnerForm, ContactForm, ContactFormset, ContactModelFormset,\
                    NewContactForm, InstitutionForm, ActivationForm, PartnerEventForm,\
                    MembershipAgreementForm, RequestContactForm, RequestContactFormSet,\
                    ProcessRequestContactForm, PartnersAttachmentFormSet, PartnersAttachmentForm,\
@@ -26,7 +26,10 @@ from .utils import PartnerUtils
 
 
 def supporting_partners(request):
-    context = {}
+    current_agreements = MembershipAgreement.objects.now_active()
+    context = {
+        'current_agreements': current_agreements
+    }
     if request.user.groups.filter(name='Editorial Administrators').exists():
         # Show Agreements to Administrators only!
         prospective_agreements = MembershipAgreement.objects.submitted().order_by('date_requested')
@@ -98,8 +101,6 @@ def promote_prospartner(request, prospartner_id):
     prospartner = get_object_or_404(ProspectivePartner.objects.not_yet_partner(),
                                     pk=prospartner_id)
     form = PromoteToPartnerForm(request.POST or None, instance=prospartner)
-    ContactModelFormset = modelformset_factory(ProspectiveContact, PromoteToContactForm,
-                                               formset=PromoteToContactFormset, extra=0)
     contact_formset = ContactModelFormset(request.POST or None,
                                           queryset=prospartner.prospective_contacts.all())
     if form.is_valid() and contact_formset.is_valid():
diff --git a/scipost/templates/scipost/footer.html b/scipost/templates/scipost/footer.html
index cf0e93dc29cf72679937cf6a27267644e1cd678a..d48aa8a3e5be17204832db5d715ac10013990f5f 100644
--- a/scipost/templates/scipost/footer.html
+++ b/scipost/templates/scipost/footer.html
@@ -5,7 +5,7 @@
     <div class="col-md-4">
       Copyright &copy; <a href="{% url 'scipost:foundation' %}" target="_">SciPost Foundation</a>.
       <br/>
-      <a href="mailto:admin@scipost.org">Contact the administrators.</a>
+      <a href="mailto:admin@scipost.org">Contact the administrators</a> or <a href="mailto:techsupport@scipost.org">tech support</a>.
       <br/>
       <a href="{% url 'scipost:terms_and_conditions' %}">Terms and conditions.</a>
     </div>
diff --git a/scipost/templates/scipost/index.html b/scipost/templates/scipost/index.html
index d3df68ed45382791725240d323e7b52fdf503bc5..5fe4f0ff137e5b697b8ab8b94e6d94b59de0cbbf 100644
--- a/scipost/templates/scipost/index.html
+++ b/scipost/templates/scipost/index.html
@@ -56,6 +56,7 @@
                             <h3><a href="{% url 'scipost:call' %}">A call for openness</a></h3>
                             <h3><a href="{% url 'scipost:quick_tour' %}">Quick Tour</a></h3>
                             <h3><a href="{% url 'scipost:FAQ' %}">Frequently asked questions</a></h3>
+                            <h3><a href="{% url 'partners:partners' %}">Supporting Partners</a></h3>
                             <h3><a href="{% url 'scipost:about' %}">Read more</a></h3>
                             <h4><em>In the press:</em></h4>
                             <ul>
diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html
index c972b3ae8a9efe50aa22f9f66b5c7393f7e84162..3a60507fc15ee36906f8ca1cb1f85ae429a8e254 100644
--- a/scipost/templates/scipost/navbar.html
+++ b/scipost/templates/scipost/navbar.html
@@ -16,6 +16,9 @@
           <li class="nav-item{% if '/theses/' in request.path %} active{% endif %}">
             <a class="nav-link" href="{% url 'theses:theses' %}">Theses</a>
           </li>
+          <li class="nav-item{% if '/partners/' in request.path %} active{% endif %}">
+              <a class="nav-link" href="{% url 'partners:partners' %}">Partners</a>
+          </li>
 
           {% if user.is_authenticated %}
               <li class="nav-item highlighted">
diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html
index 36c2123832831132d921ecfd98c8d130ef468cd4..66207b001f604fe14d31e5234325c6fcb33daaf6 100644
--- a/scipost/templates/scipost/personal_page.html
+++ b/scipost/templates/scipost/personal_page.html
@@ -263,12 +263,18 @@
                             {% endif %}
                         </ul>
 
-                        {% if perms.scipost.can_manage_reports %}
-                        <h3>Refereeing</h3>
-                        <ul>
-                            <li><a href="{% url 'submissions:reports_accepted_list' %}">Accepted Reports</a>{% if nr_reports_without_pdf %} ({{nr_reports_without_pdf}} unfinished){% endif %}</li>
-                            <li><a href="{% url 'submissions:treated_submissions_list' %}">Fully treated Submissions</a>{% if nr_treated_submissions_without_pdf %} ({{nr_treated_submissions_without_pdf}} unfinished){% endif %}</li>
-                        </ul>
+                        {% if 'Editorial Administrators' in user_groups %}
+                            <h3>Editorial Admin actions</h3>
+                            <ul>
+                              {% if perms.scipost.can_publish_accepted_submission %}
+                			      <li><a href="{% url 'journals:manage_metadata' %}">Manage metadata</a></li>
+                                  <li><a href="{% url 'journals:harvest_citedby_list' %}">Harvest citedby data</a></li>
+                              {% endif %}
+                              {% if perms.scipost.can_manage_reports %}
+                                  <li><a href="{% url 'submissions:reports_accepted_list' %}">Accepted Reports</a>{% if nr_reports_without_pdf %} ({{nr_reports_without_pdf}} unfinished){% endif %}</li>
+                                  <li><a href="{% url 'submissions:treated_submissions_list' %}">Fully treated Submissions</a>{% if nr_treated_submissions_without_pdf %} ({{nr_treated_submissions_without_pdf}} unfinished){% endif %}</li>
+                              {% endif %}
+                            </ul>
                         {% endif %}
 
                         {% if perms.scipost.can_attend_VGMs %}
@@ -390,17 +396,50 @@
                     </div>
                 </div>
 
-                {% if unfinished_reports %}
+                {% if contributor.reports.in_draft.exists %}
                     <div class="row">
                         <div class="col-12">
                             <h3>Unfinished reports:</h3>
                         </div>
                         <div class="col-12">
                             <ul class="list-group list-group-flush">
-                            {% for report in unfinished_reports %}
+                            {% for report in contributor.reports.in_draft.all %}
                                 <li class="list-group-item">
                                     <div class="w-100">{% include 'submissions/_submission_card_content.html' with submission=report.submission %}</div>
-                                    <div class="px-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
+                                    <div class="px-2 mb-2"><a class="px-1" href="{% url 'submissions:submit_report' report.submission.arxiv_identifier_w_vn_nr %}">Finish report</a></div>
+                                </li>
+                            {% endfor %}
+                            </ul>
+                        </div>
+                    </div>
+                {% endif %}
+
+                {% if contributor.reports.non_draft.exists %}
+                    <div class="row">
+                        <div class="col-12">
+                            <h3>Finished reports:</h3>
+                        </div>
+                        <div class="col-12">
+                            <ul class="list-group list-group-flush">
+                            {% for report in contributor.reports.non_draft.all %}
+                                <li class="list-group-item">
+                                    {% comment %}
+                                        Temporary: There is already a template for a "Report summary" in a parallel (unmerged) branch. Awaiting merge to use that template.
+                                    {% endcomment %}
+                                    <div class="card-block {% block cardblock_class_block %}{% endblock %}">
+                                        <h3>Report on Submission <a href="{{report.submission.get_absolute_url}}">{{report.submission.title}}</a></h3>
+                                        <table>
+                                            <tr>
+                                                <th style='min-width: 100px;'>Received:</th><td>{{ report.date_submitted|date:'Y-n-j' }}<td>
+                                            </tr>
+                                            <tr>
+                                                <th>Status:</th><td {% if report.status == 'vetted' %}class="text-success"{% elif report.status == 'unvetted' %}class="text-danger"{% endif %}>{{report.get_status_display}}</td>
+                                            </tr>
+                                            <tr>
+                                                <th>Anonymous:</th><td>{{report.anonymous|yesno:'Yes,No'}}</td>
+                                            </tr>
+                                        </table>
+                                    </div>
                                 </li>
                             {% endfor %}
                             </ul>
diff --git a/scipost/views.py b/scipost/views.py
index 1f9ae47509c03a60a386ac794e6c00d7bc78f20a..cbaf80452b461c83839133e8c7707353f93fb18f 100644
--- a/scipost/views.py
+++ b/scipost/views.py
@@ -831,9 +831,8 @@ def personal_page(request):
         referee=contributor, accepted=None, cancelled=False).count()
     pending_ref_tasks = RefereeInvitation.objects.filter(
         referee=contributor, accepted=True, fulfilled=False)
-    unfinished_reports = Report.objects.in_draft().filter(author=contributor)
     refereeing_tab_total_count = nr_ref_inv_to_consider + len(pending_ref_tasks)
-    refereeing_tab_total_count += len(unfinished_reports)
+    refereeing_tab_total_count += Report.objects.in_draft().filter(author=contributor).count()
 
     # Verify if there exist objects authored by this contributor,
     # whose authorship hasn't been claimed yet
@@ -893,7 +892,6 @@ def personal_page(request):
         'nr_ref_inv_to_consider': nr_ref_inv_to_consider,
         'pending_ref_tasks': pending_ref_tasks,
         'refereeing_tab_total_count': refereeing_tab_total_count,
-        'unfinished_reports': unfinished_reports,
         'own_submissions': own_submissions,
         'own_commentaries': own_commentaries,
         'own_thesislinks': own_thesislinks,
diff --git a/submissions/admin.py b/submissions/admin.py
index 67dcb372e9f3e5eef62a4117d3d5b45c32548d54..1a836a83585f742aee25da59e46e4c0d1e535466 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -63,6 +63,9 @@ admin.site.register(EditorialAssignment, EditorialAssignmentAdmin)
 class RefereeInvitationAdminForm(forms.ModelForm):
     submission = forms.ModelChoiceField(
         queryset=Submission.objects.order_by('-arxiv_identifier_w_vn_nr'))
+    referee = forms.ModelChoiceField(
+        required=False,
+        queryset=Contributor.objects.order_by('user__last_name'))
 
     class Meta:
         model = RefereeInvitation
diff --git a/submissions/constants.py b/submissions/constants.py
index 140c2824fa82f42a3df3ba88475894897eb8ac1a..ff1c5cb22558481f1a9fe397b3395f0a75c42766 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -122,6 +122,7 @@ ASSIGNMENT_REFUSAL_REASONS = (
 )
 
 REFEREE_QUALIFICATION = (
+    (None, '-'),
     (4, 'expert in this subject'),
     (3, 'very knowledgeable in this subject'),
     (2, 'knowledgeable in this subject'),
@@ -130,6 +131,7 @@ REFEREE_QUALIFICATION = (
 )
 
 QUALITY_SPEC = (
+    (None, '-'),
     (6, 'perfect'),
     (5, 'excellent'),
     (4, 'good'),
@@ -141,7 +143,7 @@ QUALITY_SPEC = (
 
 # Only values between 0 and 100 are kept, anything outside those limits is discarded.
 RANKING_CHOICES = (
-    (101, '-'),
+    (None, '-'),
     (100, 'top'),
     (80, 'high'),
     (60, 'good'),
@@ -151,6 +153,7 @@ RANKING_CHOICES = (
 )
 
 REPORT_REC = (
+    (None, '-'),
     (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'),
     (2, 'Publish as Tier II (top 50% of papers in this journal)'),
     (3, 'Publish as Tier III (meets the criteria of this journal)'),
diff --git a/submissions/exceptions.py b/submissions/exceptions.py
index 0e8794a8cc841af0df2896138ce2ec0209ee0c7e..a6e26c2d6c946fec39d3b402415bd0110e63378a 100644
--- a/submissions/exceptions.py
+++ b/submissions/exceptions.py
@@ -1,4 +1,4 @@
-class CycleUpdateDeadlineError(Exception):
+class BaseCustomException(Exception):
     def __init__(self, name):
         self.name = name
 
@@ -6,9 +6,9 @@ class CycleUpdateDeadlineError(Exception):
         return self.name
 
 
-class InvalidReportVettingValue(Exception):
-    def __init__(self, name):
-        self.name = name
+class CycleUpdateDeadlineError(BaseCustomException):
+    pass
 
-    def __str__(self):
-        return self.name
+
+class InvalidReportVettingValue(BaseCustomException):
+    pass
diff --git a/submissions/forms.py b/submissions/forms.py
index ed1b46e059bd96aac5eecdb5131dfb8c1c75d5ea..5bed23fe33f6ddf2488a3d8477d9ca4337dadd40 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -432,6 +432,17 @@ class ReportForm(forms.ModelForm):
                   'recommendation', 'remarks_for_editors', 'anonymous']
 
     def __init__(self, *args, **kwargs):
+        if kwargs.get('instance'):
+            if kwargs['instance'].is_followup_report:
+                # Prefill data from latest report in the series
+                latest_report = kwargs['instance'].latest_report_from_series()
+                kwargs.update({
+                    'initial': {
+                        'qualification': latest_report.qualification,
+                        'anonymous': latest_report.anonymous
+                    }
+                })
+
         super(ReportForm, self).__init__(*args, **kwargs)
         self.fields['strengths'].widget.attrs.update({
             'placeholder': ('Give a point-by-point '
@@ -452,7 +463,28 @@ class ReportForm(forms.ModelForm):
             'cols': 100
         })
 
-    def save(self, submission, current_contributor):
+        # If the Report is not a followup: Explicitly assign more fields as being required!
+        if not self.instance.is_followup_report:
+            required_fields = [
+                'strengths',
+                'weaknesses',
+                'requested_changes',
+                'validity',
+                'significance',
+                'originality',
+                'clarity',
+                'formatting',
+                'grammar'
+            ]
+            for field in required_fields:
+                self.fields[field].required = True
+
+        # Let user know the field is required!
+        for field in self.fields:
+            if self.fields[field].required:
+                self.fields[field].label += ' *'
+
+    def save(self, submission):
         """
         Update meta data if ModelForm is submitted (non-draft).
         Possibly overwrite the default status if user asks for saving as draft.
@@ -460,7 +492,6 @@ class ReportForm(forms.ModelForm):
         report = super().save(commit=False)
 
         report.submission = submission
-        report.author = current_contributor
         report.date_submitted = timezone.now()
 
         # Save with right status asked by user
@@ -470,7 +501,7 @@ class ReportForm(forms.ModelForm):
             report.status = STATUS_UNVETTED
 
             # Update invitation and report meta data if exist
-            invitation = submission.referee_invitations.filter(referee=current_contributor).first()
+            invitation = submission.referee_invitations.filter(referee=report.author).first()
             if invitation:
                 invitation.fulfilled = True
                 invitation.save()
@@ -478,7 +509,7 @@ class ReportForm(forms.ModelForm):
 
             # Check if report author if the report is being flagged on the submission
             if submission.referees_flagged:
-                if current_contributor.user.last_name in submission.referees_flagged:
+                if report.author.user.last_name in submission.referees_flagged:
                     report.flagged = True
         report.save()
         return report
diff --git a/submissions/managers.py b/submissions/managers.py
index 7661bbd1496e025d595a0f18ae69289b9695f201..f1e2b8329562622035a020a3eae367691849dd9e 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -143,3 +143,6 @@ class ReportManager(models.Manager):
 
     def in_draft(self):
         return self.filter(status=STATUS_DRAFT)
+
+    def non_draft(self):
+        return self.exclude(status=STATUS_DRAFT)
diff --git a/submissions/migrations/0048_auto_20170721_0936.py b/submissions/migrations/0048_auto_20170721_0936.py
new file mode 100644
index 0000000000000000000000000000000000000000..657a049399d2aadca650ebbc94e78fbd0b70712d
--- /dev/null
+++ b/submissions/migrations/0048_auto_20170721_0936.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 07:36
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_submission_acceptance_date'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='requested_changes',
+            field=models.TextField(blank=True, verbose_name='requested changes'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='strengths',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='weaknesses',
+            field=models.TextField(blank=True),
+        ),
+    ]
diff --git a/submissions/migrations/0049_auto_20170721_1010.py b/submissions/migrations/0049_auto_20170721_1010.py
new file mode 100644
index 0000000000000000000000000000000000000000..4627f2592d5f4a8d77755911038deb9dc7fe64a1
--- /dev/null
+++ b/submissions/migrations/0049_auto_20170721_1010.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0048_auto_20170721_0936'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='formatting',
+            field=models.SmallIntegerField(blank=True, choices=[(6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of paper formatting'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='grammar',
+            field=models.SmallIntegerField(blank=True, choices=[(6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of English grammar'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='qualification',
+            field=models.PositiveSmallIntegerField(choices=[(4, 'expert in this subject'), (3, 'very knowledgeable in this subject'), (2, 'knowledgeable in this subject'), (1, 'generally qualified'), (0, 'not qualified')], verbose_name='Qualification to referee this: I am'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='remarks_for_editors',
+            field=models.TextField(blank=True, verbose_name='optional remarks for the Editors only'),
+        ),
+    ]
diff --git a/submissions/migrations/0050_auto_20170721_1042.py b/submissions/migrations/0050_auto_20170721_1042.py
new file mode 100644
index 0000000000000000000000000000000000000000..f81add96676950e1daed51e7c308e02dc48f82d2
--- /dev/null
+++ b/submissions/migrations/0050_auto_20170721_1042.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def report_101_to_none(apps, schema_editor):
+    Report = apps.get_model('submissions', 'Report')
+    for rep in Report.objects.all():
+        if rep.clarity == 101:
+            rep.clarity = None
+        if rep.originality == 101:
+            rep.originality = None
+        if rep.significance == 101:
+            rep.significance = None
+        if rep.validity == 101:
+            rep.validity = None
+        rep.save()
+    print('\nChanged all Report fields: {clarites,originality,significance,validity} with value'
+          ' `101` to `None`.')
+
+
+def report_none_to_101(apps, schema_editor):
+    Report = apps.get_model('submissions', 'Report')
+    for rep in Report.objects.all():
+        if not rep.clarity:
+            rep.clarity = 101
+        if not rep.originality:
+            rep.originality = 101
+        if not rep.significance:
+            rep.significance = 101
+        if not rep.validity:
+            rep.validity = 101
+        rep.save()
+    print('\nChanged all Report fields: {clarites,originality,significance,validity} with value'
+          ' `None` to `101`.')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0049_auto_20170721_1010'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='clarity',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='originality',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='significance',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='validity',
+            field=models.PositiveSmallIntegerField(blank=True, choices=[(None, '-'), (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor')], null=True),
+        ),
+        migrations.RunPython(report_101_to_none, report_none_to_101),
+    ]
diff --git a/submissions/migrations/0051_auto_20170721_1049.py b/submissions/migrations/0051_auto_20170721_1049.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ccf06a410f6f585b3f2ce23faecf963d0a88af6
--- /dev/null
+++ b/submissions/migrations/0051_auto_20170721_1049.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:49
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0050_auto_20170721_1042'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='formatting',
+            field=models.SmallIntegerField(blank=True, choices=[(None, '-'), (6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of paper formatting'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='grammar',
+            field=models.SmallIntegerField(blank=True, choices=[(None, '-'), (6, 'perfect'), (5, 'excellent'), (4, 'good'), (3, 'reasonable'), (2, 'acceptable'), (1, 'below threshold'), (0, 'mediocre')], null=True, verbose_name='Quality of English grammar'),
+        ),
+    ]
diff --git a/submissions/migrations/0052_auto_20170721_1057.py b/submissions/migrations/0052_auto_20170721_1057.py
new file mode 100644
index 0000000000000000000000000000000000000000..c89df6fc0f4aba11de3118a756d79c46e47f29d5
--- /dev/null
+++ b/submissions/migrations/0052_auto_20170721_1057.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 08:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0051_auto_20170721_1049'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='eicrecommendation',
+            name='recommendation',
+            field=models.SmallIntegerField(choices=[(None, '-'), (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), (2, 'Publish as Tier II (top 50% of papers in this journal)'), (3, 'Publish as Tier III (meets the criteria of this journal)'), (-1, 'Ask for minor revision'), (-2, 'Ask for major revision'), (-3, 'Reject')]),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='qualification',
+            field=models.PositiveSmallIntegerField(choices=[(None, '-'), (4, 'expert in this subject'), (3, 'very knowledgeable in this subject'), (2, 'knowledgeable in this subject'), (1, 'generally qualified'), (0, 'not qualified')], verbose_name='Qualification to referee this: I am'),
+        ),
+        migrations.AlterField(
+            model_name='report',
+            name='recommendation',
+            field=models.SmallIntegerField(choices=[(None, '-'), (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), (2, 'Publish as Tier II (top 50% of papers in this journal)'), (3, 'Publish as Tier III (meets the criteria of this journal)'), (-1, 'Ask for minor revision'), (-2, 'Ask for major revision'), (-3, 'Reject')]),
+        ),
+    ]
diff --git a/submissions/migrations/0053_auto_20170721_1100.py b/submissions/migrations/0053_auto_20170721_1100.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebb3fc0bfb4327f4c5a8ed239a130468efd4eae1
--- /dev/null
+++ b/submissions/migrations/0053_auto_20170721_1100.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 09:00
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0052_auto_20170721_1057'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='report',
+            name='author',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reports', to='scipost.Contributor'),
+        ),
+    ]
diff --git a/submissions/migrations/0054_auto_20170721_1148.py b/submissions/migrations/0054_auto_20170721_1148.py
new file mode 100644
index 0000000000000000000000000000000000000000..983b6b8409fd3f8249dac03b25e01f8eef31e516
--- /dev/null
+++ b/submissions/migrations/0054_auto_20170721_1148.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-07-21 09:48
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0053_auto_20170721_1100'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='report',
+            options={'ordering': ['-date_submitted']},
+        ),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index b3c04de08da6331688823dd0bfddd1c11035929a..c7a2cabc602299119b6fe4e968946e099df28974 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -4,6 +4,7 @@ from django.utils import timezone
 from django.db import models
 from django.contrib.postgres.fields import JSONField
 from django.urls import reverse
+from django.utils.functional import cached_property
 
 from .constants import ASSIGNMENT_REFUSAL_REASONS, ASSIGNMENT_NULLBOOL,\
                        SUBMISSION_TYPE, ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC,\
@@ -238,7 +239,17 @@ class RefereeInvitation(models.Model):
 ###########
 
 class Report(models.Model):
-    """ Both types of reports, invited or contributed. """
+    """
+    Both types of reports, invited or contributed.
+
+    This Report model acts as both a regular `Report` and a `FollowupReport`; A normal Report
+    should have all fields required, whereas a FollowupReport only has the `report` field as
+    a required field.
+
+    Important note!
+    Due to the construction of the two different types within a single model, it is important
+    to explicitly implement the perticular differences in for example the form used.
+    """
     status = models.CharField(max_length=16, choices=REPORT_STATUSES, default=STATUS_UNVETTED)
     submission = models.ForeignKey('submissions.Submission', related_name='reports',
                                    on_delete=models.CASCADE)
@@ -248,32 +259,40 @@ class Report(models.Model):
                                                            'the Submission')
     vetted_by = models.ForeignKey('scipost.Contributor', related_name="report_vetted_by",
                                   blank=True, null=True, on_delete=models.CASCADE)
+
     # `invited' filled from RefereeInvitation objects at moment of report submission
     invited = models.BooleanField(default=False)
+
     # `flagged' if author of report has been flagged by submission authors (surname check only)
     flagged = models.BooleanField(default=False)
     date_submitted = models.DateTimeField('date submitted')
     author = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE)
     qualification = models.PositiveSmallIntegerField(
         choices=REFEREE_QUALIFICATION,
-        verbose_name="Qualification to referee this: I am ")
+        verbose_name="Qualification to referee this: I am")
+
     # Text-based reporting
-    strengths = models.TextField()
-    weaknesses = models.TextField()
+    strengths = models.TextField(blank=True)
+    weaknesses = models.TextField(blank=True)
     report = models.TextField()
-    requested_changes = models.TextField(verbose_name="requested changes")
+    requested_changes = models.TextField(verbose_name="requested changes", blank=True)
+
     # Qualities:
-    validity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    significance = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    originality = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    clarity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES, default=101)
-    formatting = models.SmallIntegerField(choices=QUALITY_SPEC,
+    validity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                null=True, blank=True)
+    significance = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                    null=True, blank=True)
+    originality = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                                   null=True, blank=True)
+    clarity = models.PositiveSmallIntegerField(choices=RANKING_CHOICES,
+                                               null=True, blank=True)
+    formatting = models.SmallIntegerField(choices=QUALITY_SPEC, null=True, blank=True,
                                           verbose_name="Quality of paper formatting")
-    grammar = models.SmallIntegerField(choices=QUALITY_SPEC,
+    grammar = models.SmallIntegerField(choices=QUALITY_SPEC, null=True, blank=True,
                                        verbose_name="Quality of English grammar")
 
     recommendation = models.SmallIntegerField(choices=REPORT_REC)
-    remarks_for_editors = models.TextField(default='', blank=True,
+    remarks_for_editors = models.TextField(blank=True,
                                            verbose_name='optional remarks for the Editors only')
     doi_label = models.CharField(max_length=200, blank=True)
     anonymous = models.BooleanField(default=True, verbose_name='Publish anonymously')
@@ -283,7 +302,8 @@ class Report(models.Model):
 
     class Meta:
         unique_together = ('submission', 'report_nr')
-        ordering = ['report_nr']
+        default_related_name = 'reports'
+        ordering = ['-date_submitted']
 
     def __str__(self):
         return (self.author.user.first_name + ' ' + self.author.user.last_name + ' on ' +
@@ -303,9 +323,23 @@ class Report(models.Model):
             self.report_nr = self.submission.reports.count() + 1
         return super().save(*args, **kwargs)
 
-    def report_default_counter(self):
-        print(self)
-        raise
+    @cached_property
+    def is_followup_report(self):
+        """
+        Check if current Report is a `FollowupReport`. A Report is a `FollowupReport` if the
+        author of the report already has a vetted report in the series of the specific Submission.
+        """
+        return (self.author.reports.accepted()
+                .filter(submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
+                .exists())
+
+    def latest_report_from_series(self):
+        """
+        Get latest Report from the same author for the Submission series.
+        """
+        return (self.author.reports.accepted()
+                .filter(submission__arxiv_identifier_wo_vn_nr=self.submission.arxiv_identifier_wo_vn_nr)
+                .order_by('submission__arxiv_identifier_wo_vn_nr').last())
 
 
 ##########################
diff --git a/submissions/templates/submissions/_single_public_report.html b/submissions/templates/submissions/_single_public_report.html
index a733936561c287c2c8b5ccf6f579efe52b20fd56..cc4b233b4540fd5b969181a41377ac181d727a70 100644
--- a/submissions/templates/submissions/_single_public_report.html
+++ b/submissions/templates/submissions/_single_public_report.html
@@ -1,8 +1,10 @@
 {% extends 'submissions/_single_public_report_without_comments.html' %}
 
 {% block single_report_footer %}
-    <hr class="small">
-    <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3>
+    {% if user.is_authenticated and perms.scipost.can_submit_comments %}
+        <hr class="small">
+        <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3>
+    {% endif %}
 
     {% for reply in report.comment_set.vetted %}
         {% include 'comments/_single_comment_with_link.html' with comment=reply perms=perms user=user %}
diff --git a/submissions/templates/submissions/_single_public_report_without_comments.html b/submissions/templates/submissions/_single_public_report_without_comments.html
index 9ffe7650cbab4d4200e4fd55f03c5d70a86e7614..2c5c69adc82528e3cc09108b9c08eadff738020b 100644
--- a/submissions/templates/submissions/_single_public_report_without_comments.html
+++ b/submissions/templates/submissions/_single_public_report_without_comments.html
@@ -34,9 +34,10 @@
                 <div class="row">
                     <div class="col-12">
                         <h3>Remarks for editors</h3>
-                        <div class="pl-md-4">{{ report.remarks_for_editors }}</div>
+                        <div class="pl-md-4">{{ report.remarks_for_editors|default:'-' }}</div>
                     </div>
                 </div>
+
                 <div class="row">
                     <div class="col-12">
                         <h3>Recommendation</h3>
diff --git a/submissions/templates/submissions/_single_report_content.html b/submissions/templates/submissions/_single_report_content.html
index 82e06f943f39743d148e56b154382759fe1b2fa8..3e1874d8a8f4d81b1b1550dfb0bca28d0b0ce4be 100644
--- a/submissions/templates/submissions/_single_report_content.html
+++ b/submissions/templates/submissions/_single_report_content.html
@@ -1,27 +1,36 @@
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Strengths</h3>
-        <div class="pl-md-4">{{ report.strengths|linebreaks }}</div>
+{% if report.strengths %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Strengths</h3>
+            <div class="pl-md-4">{{ report.strengths|linebreaks }}</div>
+        </div>
     </div>
-</div>
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Weaknesses</h3>
-        <div class="pl-md-4">{{ report.weaknesses|linebreaks }}</div>
+{% endif %}
+
+{% if report.weaknesses %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Weaknesses</h3>
+            <div class="pl-md-4">{{ report.weaknesses|linebreaks }}</div>
+        </div>
     </div>
-</div>
+{% endif %}
+
 <div class="row">
     <div class="col-12">
         <h3 class="highlight tight">Report</h3>
         <div class="pl-md-4">{{ report.report|linebreaks }}</div>
     </div>
 </div>
-<div class="row">
-    <div class="col-12">
-        <h3 class="highlight tight">Requested changes</h3>
-        <div class="pl-md-4">
-            <p>{{ report.requested_changes|linebreaks }}</p>
-            {% include 'submissions/_single_report_ratings.html' with report=report %}
-      </div>
-  </div>
-</div>
+
+{% if report.requested_changes %}
+    <div class="row">
+        <div class="col-12">
+            <h3 class="highlight tight">Requested changes</h3>
+            <div class="pl-md-4">
+                <p>{{ report.requested_changes|linebreaksbr }}</p>
+                {% include 'submissions/_single_report_ratings.html' with report=report %}
+            </div>
+        </div>
+    </div>
+{% endif %}
diff --git a/submissions/templates/submissions/_submission_card_author_content.html b/submissions/templates/submissions/_submission_card_author_content.html
index 89a1ae41aa7b9982b41dcb8bf59095a0ee47da88..1dabd69564b13275a5cc7742cbf8f826e3baeb2f 100644
--- a/submissions/templates/submissions/_submission_card_author_content.html
+++ b/submissions/templates/submissions/_submission_card_author_content.html
@@ -8,8 +8,10 @@
     <p class="card-text">Status: {{submission.get_status_display}}</p>
 
     {% if current_user and current_user.contributor == submission.submitted_by %}
-        <p>
-            <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>
+        <p class="card-text">
+            {% if submission.editor_in_charge %}
+                <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>
+            {% endif %}
             {% if submission.status == 'revision_requested' %}
             &middot; <a href="{% url 'submissions:prefill_using_identifier' %}?identifier={{submission.arxiv_identifier_wo_vn_nr}}">Resubmit this manuscript</a>
             {% endif %}
diff --git a/submissions/templates/submissions/submit_report.html b/submissions/templates/submissions/submit_report.html
index 63f80e447b69a04de026d1a51db389b58df83e29..fb4029c449a0df7ba6ebd109247bdb01de5e6255 100644
--- a/submissions/templates/submissions/submit_report.html
+++ b/submissions/templates/submissions/submit_report.html
@@ -81,13 +81,20 @@
         <div class="col-12">
             <div class="card card-grey">
                 <div class="card-block">
-                    <h1>Your report:</h1>
-                    <p class="mb-0">A preview of text areas will appear below as you type (you can use LaTeX \$...\$ for in-text equations or \ [ ... \ ] for on-line equations).</p>
+                    <h1>Your {% if form.instance.is_followup_report %}followup {% endif %}report:</h1>
+                    <p>A preview of text areas will appear below as you type (you can use LaTeX \$...\$ for in-text equations or \ [ ... \ ] for on-line equations).</p>
+                    <p class="mb-0">Any fields with an asterisk (*) are required.</p>
+                    {% if form.instance.is_followup_report %}
+                        <p class="mb-0">
+                            Because you have already submitted a Report for this Submission series, not all fields are required.
+                        </p>
+                    {% endif %}
                 </div>
             </div>
             <form action="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post">
                 {% csrf_token %}
                 {{ form|bootstrap:'3,9' }}
+                <p>Any fields with an asterisk (*) are required.</p>
                 <input class="btn btn-primary" type="submit" name="save_submit" value="Submit your report"/>
                 <input class="btn btn-secondary ml-2" type="submit" name="save_draft" value="Save your report as draft"/>
                 <div class="my-4">
diff --git a/submissions/utils.py b/submissions/utils.py
index 908f7f35c9a12bfd2a592b2a712b31952f468bce..385dbfc3402e25ff730686360b4f49f6561e8428 100644
--- a/submissions/utils.py
+++ b/submissions/utils.py
@@ -126,7 +126,6 @@ class BaseSubmissionCycle:
         self.submission.reporting_deadline = deadline
         self.submission.save()
 
-
     def get_required_actions(self):
         '''Return list of the submission its required actions'''
         if not self.updated_action:
diff --git a/submissions/views.py b/submissions/views.py
index 9774046b445a0fbee392f55edc7c9895dd4c666a..78142aaf9db7646df08bc6e4ec97b1f8b816e4c6 100644
--- a/submissions/views.py
+++ b/submissions/views.py
@@ -817,7 +817,9 @@ def accept_or_decline_ref_invitations(request):
     RefereeInvitations need to be either accepted or declined by the invited user
     using this view. The decision will be taken one invitation at a time.
     """
-    invitation = RefereeInvitation.objects.filter(referee__user=request.user, accepted=None).first()
+    invitation = RefereeInvitation.objects.filter(referee__user=request.user,
+                                                  accepted=None,
+                                                  cancelled=False).first()
     if not invitation:
         messages.success(request, 'There are no Refereeing Invitations for you to consider.')
         return redirect(reverse('scipost:personal_page'))
@@ -1114,6 +1116,10 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
         errormessage = ('The system flagged you as a potential author of this Submission. '
                         'Please go to your personal page under the Submissions tab'
                         ' to clarify this.')
+    # if submission.reports.non_draft().filter(author=current_contributor).exists():
+    #     errormessage = ('You have already submitted a Report for this Submission. You cannot'
+    #                     ' submit an additional Report.')
+
     if errormessage:
         messages.warning(request, errormessage)
         return redirect(reverse('scipost:personal_page'))
@@ -1122,12 +1128,12 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
     try:
         report_in_draft = submission.reports.in_draft().get(author=current_contributor)
     except Report.DoesNotExist:
-        report_in_draft = None
+        report_in_draft = Report(author=current_contributor, submission=submission)
     form = ReportForm(request.POST or None, instance=report_in_draft)
 
     # Check if data sent is valid
     if form.is_valid():
-        newreport = form.save(submission, current_contributor)
+        newreport = form.save(submission)
         if newreport.status == STATUS_DRAFT:
             messages.success(request, ('Your Report has been saved. '
                                        'You may carry on working on it,'
@@ -1151,16 +1157,17 @@ def submit_report(request, arxiv_identifier_w_vn_nr):
 @permission_required('scipost.can_take_charge_of_submissions', raise_exception=True)
 def vet_submitted_reports(request):
     """
-    Reports with status `unvetted` will be shown one-by-one. A user may only
+    Reports with status `unvetted` will be shown one-by-one (oldest first). A user may only
     vet reports of submissions he/she is EIC of.
 
     After vetting an email is sent to the report author, bcc EIC. If report
     has not been refused, the submission author is also mailed.
     """
-    contributor = Contributor.objects.get(user=request.user)
+    contributor = request.user.contributor
     report_to_vet = (Report.objects.awaiting_vetting()
                      .select_related('submission')
-                     .filter(submission__editor_in_charge=contributor).first())
+                     .filter(submission__editor_in_charge=contributor)
+                     .order_by('date_submitted').first())
 
     form = VetReportForm(request.POST or None, initial={'report': report_to_vet})
     if form.is_valid():