From 616e5ad691122a201f660748e5e45c3ceeceb0d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org>
Date: Sun, 4 Dec 2022 13:37:41 +0100
Subject: [PATCH] Work on edadmin app, plagiarism checks

---
 .../edadmin/_hx_plagiarism_iThenticate.html   | 49 +++++++++++++
 .../edadmin/_hx_plagiarism_internal.html      | 72 +++++++++++++++++++
 .../edadmin/_hx_submissions_list.html         | 52 ++++++++++++++
 .../edadmin/templates/edadmin/edadmin.html    | 40 +++++++----
 scipost_django/edadmin/urls.py                | 15 ----
 scipost_django/edadmin/urls/__init__.py       | 15 ++++
 scipost_django/edadmin/urls/incoming.py       | 31 ++++++++
 scipost_django/edadmin/views/__init__.py      |  2 +
 .../edadmin/{views.py => views/base.py}       |  0
 scipost_django/edadmin/views/incoming.py      | 72 +++++++++++++++++++
 scipost_django/scipost/models.py              |  2 +-
 scipost_django/submissions/admin.py           |  2 +-
 scipost_django/submissions/forms.py           |  2 +-
 .../submissions/managers/submission.py        | 14 ++--
 .../migrations/0127_auto_20221204_1327.py     | 57 +++++++++++++++
 scipost_django/submissions/mixins.py          |  2 +-
 scipost_django/submissions/models/__init__.py |  8 ++-
 .../{plagiarism.py => iThenticate_report.py}  |  0
 .../models/plagiarism_assessment.py           | 40 +++++++++++
 .../submissions/models/submission.py          | 27 +++++--
 scipost_django/submissions/tasks.py           |  6 +-
 .../_hx_submission_workflow_diagram.html      |  9 ++-
 .../submissions/admin/plagiarism_report.html  | 18 ++---
 .../admin/submission_preassignment.html       | 12 ++--
 .../pool/_submission_info_table.html          |  6 +-
 .../submissions/pool/editorial_page.html      |  8 +--
 scipost_django/submissions/urls.py            |  4 +-
 scipost_django/submissions/views.py           | 10 +--
 28 files changed, 496 insertions(+), 79 deletions(-)
 create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html
 create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html
 create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html
 delete mode 100644 scipost_django/edadmin/urls.py
 create mode 100644 scipost_django/edadmin/urls/__init__.py
 create mode 100644 scipost_django/edadmin/urls/incoming.py
 create mode 100644 scipost_django/edadmin/views/__init__.py
 rename scipost_django/edadmin/{views.py => views/base.py} (100%)
 create mode 100644 scipost_django/edadmin/views/incoming.py
 create mode 100644 scipost_django/submissions/migrations/0127_auto_20221204_1327.py
 rename scipost_django/submissions/models/{plagiarism.py => iThenticate_report.py} (100%)
 create mode 100644 scipost_django/submissions/models/plagiarism_assessment.py

diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html
new file mode 100644
index 000000000..5076870e7
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html
@@ -0,0 +1,49 @@
+{% load bootstrap %}
+
+{% if submission.iThenticate_plagiarism_report %}
+  <table>
+    <tr>
+      <td style="min-width: 150px;">iThenticate document</td>
+      <td>{{ submission.iThenticate_plagiarism_report.doc_id }}</td>
+    </tr>
+    <tr>
+      <td>Percent match</td>
+      <td>{{ submission.iThenticate_plagiarism_report.percent_match }}%</td>
+    </tr>
+    <tr>
+      <td>Processed</td>
+      <td>{{ submission.iThenticate_plagiarism_report.processed_time }}</td>
+    </tr>
+    <tr>
+      <td>Uploaded</td>
+      <td>{{ submission.iThenticate_plagiarism_report.uploaded_time }}</td>
+    </tr>
+    <tr>
+      <td>Latest update</td>
+      <td>{{ submission.iThenticate_plagiarism_report.latest_activity }}</td>
+    </tr>
+  </table>
+{% else %}
+  No Plagiarism Report found.
+{% endif %}
+
+<form
+    class="mt-3" enctype="multipart/form-data"
+    hx-post="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+    hx-target="#submission-{{ submission.pk }}-iThenticate"
+    hx-indicator="#indicator-{{ submission.pk }}-iThenticate"
+>
+  {% csrf_token %}
+  {{ form|bootstrap }}
+  <input type="submit" class="btn btn-primary" value="{% if submission.iThenticate_plagiarism_report %}Update report status{% else %}Submit submission for plagiarism check{% endif %}">
+</form>
+<div id="indicator-{{ submission.pk }}-iThenticate" class="htmx-indicator">
+  <button class="btn btn-sm btn-warning" type="button" disabled>
+    <strong>Loading...</strong>
+    <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div>
+  </button>
+</div>
+
+{% if submission.iThenticate_plagiarism_report %}
+  <a href="{% url 'submissions:iThenticate_plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="ms-2 btn btn-default">Download report pdf</a>
+{% endif %}
diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html
new file mode 100644
index 000000000..498f23c42
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html
@@ -0,0 +1,72 @@
+<details open>
+  <summary class="m-2 p-2">
+    Submission matches
+    {% if not "submission_matches" in submission.internal_plagiarism_matches %}
+      <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span>
+    {% endif %}
+  </summary>
+  <table class="table">
+    <thead>
+      <tr>
+	<th>Submission</th>
+	<th>Title&nbsp;match&nbsp;&#37;</th>
+	<th>Authors&nbsp;match&nbsp;&#37;</th>
+	<th>Abstract&nbsp;match&nbsp;&#37;</th>
+      </tr>
+    </thead>
+    <tbody>
+      {% for match in submission_matches %}
+	<tr>
+	  <td>
+	    {{ match.submission.preprint.identifier_w_vn_nr }}
+	    &emsp;<small class="text-muted">Thread hash: {{ match.submission.thread_hash }}</small>
+	    <br>
+	    <a href="{{ match.submission.get_absolute_url }}" target="_blank">{{ match.submission.title }}</a><br>
+	    {{ match.submission.author_list }}
+	  </td>
+	  <td>{{ match.ratio_title|floatformat:2 }}</td>
+	  <td>{{ match.ratio_authors|floatformat:2 }}</td>
+	  <td>{{ match.ratio_abstract|floatformat:2 }}</td>
+	</tr>
+      {% empty %}
+	<tr><td>No matching Submissions</td></tr>
+      {% endfor %}
+    </tbody>
+  </table>
+</details>
+
+
+<details open>
+  <summary class="m-2 p-2">
+    Publication matches
+    {% if not "publication_matches" in submission.internal_plagiarism_matches %}
+      <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span>
+    {% endif %}
+  </summary>
+  <table class="table">
+    <thead>
+      <tr>
+	<th>Publication</th>
+	<th>Title&nbsp;match&nbsp;&#37;</th>
+	<th>Authors&nbsp;match&nbsp;&#37;</th>
+	<th>Abstract&nbsp;match&nbsp;&#37;</th>
+      </tr>
+    </thead>
+    <tbody>
+      {% for match in publication_matches %}
+	<tr>
+	  <td>
+	    {{ match.publication.doi_label }}<br>
+	    <a href="{{ match.publication.get_absolute_url }}" target="_blank">{{ match.publication.title }}</a><br>
+	    {{ match.publication.author_list }}
+	  </td>
+	  <td>{{ match.ratio_title|floatformat:2 }}</td>
+	  <td>{{ match.ratio_authors|floatformat:2 }}</td>
+	  <td>{{ match.ratio_abstract|floatformat:2 }}</td>
+	</tr>
+      {% empty %}
+	<tr><td>No matching Publications</td></tr>
+      {% endfor %}
+    </tbody>
+  </table>
+</details>
diff --git a/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html b/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html
new file mode 100644
index 000000000..cf0ca8b1d
--- /dev/null
+++ b/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html
@@ -0,0 +1,52 @@
+{% for submission in submissions %}
+
+  <details class="border border-2 my-2">
+    <summary class="px-4 py-2">
+      <table>
+	<tbody>
+	  <tr>
+	    <td><a href="{% url 'submissions:submission' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}">{{ submission.title }}</a></td>
+	  </tr>
+	  <tr>
+	    <td>{{ submission.author_list }}</td>
+	  </tr>
+	  <tr>
+	    <td>Submitted {{ submission.submission_date|date:"Y-m-d" }} to {{ submission.submitted_to }}</td>
+	  </tr>
+	</tbody>
+      </table>
+    </summary>
+    <div class="p-2">
+      <h1>Summary</h1>
+      {% include 'submissions/_submission_summary.html' with submission=submission hide_title=1 show_abstract=1 %}
+
+      <h1>Plagiarism</h1>
+      <div class="p-2">
+	<h2>Internal plagiarism checks</h2>
+	<button class="m-2 btn btn-primary"
+		id="submission-{{ submission.preprint.identifier_w_vn_nr }}"
+		hx-get="{% url 'edadmin:_hx_plagiarism_internal' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+		hx-swap="outerHTML"
+		hx-trigger="revealed"
+	>load internal plagiarism info</button>
+      </div>
+      <div class="p-2">
+	<h2>iThenticate checks</h2>
+	<div id="submission-{{ submission.pk }}-iThenticate">
+	  <button class="m-2 btn btn-primary"
+		  hx-get="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+		  hx-swap="outerHTML"
+		  hx-trigger="revealed"
+	  >load iThenticate plagiarism info</button>
+	</div>
+      </div>
+
+      <h1>Workflow diagram</h1>
+      <button class="m-2 btn btn-primary workflowDiagram"
+	      id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram"
+	      hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+	      hx-swap="outerHTML"
+      >Load Submission processing workflow graphs</button>
+    </div>
+  </details>
+{% endfor %}
diff --git a/scipost_django/edadmin/templates/edadmin/edadmin.html b/scipost_django/edadmin/templates/edadmin/edadmin.html
index f864ececd..36d1eb8bf 100644
--- a/scipost_django/edadmin/templates/edadmin/edadmin.html
+++ b/scipost_django/edadmin/templates/edadmin/edadmin.html
@@ -16,20 +16,36 @@
 
 {% block content %}
 
-  <h2 class="highlight">Preassignment</h2>
-  {% for submission in preassignment %}
 
-    {% include 'submissions/_submission_events.html' with events=submission.events.for_edadmin %}
-
-    <details>
-      <summary>{{ submission }}</summary>
-      <button class="m-2 btn btn-primary workflowDiagram"
-	      id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram"
-	      hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+  <details class="border border-2 my-4">
+    <summary class="bg-info px-4 py-2">
+      <h1>Incoming</h1>
+    </summary>
+    <div class="p-2">
+      <button class="m-2 btn btn-primary"
+	      id="incoming"
+	      hx-get="{% url 'edadmin:_hx_incoming_list' %}"
 	      hx-swap="outerHTML"
-      >Load Submission processing workflow graphs</button>
-    </details>
-  {% endfor %}
+      >Load incoming Submissions</button>
+    </div>
+  </details>
+
+  <details>
+    <summary>Preassignment</summary>
+    {% for submission in preassignment %}
+
+      {% include 'submissions/_submission_events.html' with events=submission.events.for_edadmin %}
+
+      <details>
+	<summary>{{ submission }}</summary>
+	<button class="m-2 btn btn-primary workflowDiagram"
+		id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram"
+		hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}"
+		hx-swap="outerHTML"
+	>Load Submission processing workflow graphs</button>
+      </details>
+    {% endfor %}
+  </details>
 
 {% endblock content %}
 
diff --git a/scipost_django/edadmin/urls.py b/scipost_django/edadmin/urls.py
deleted file mode 100644
index 9caf5624b..000000000
--- a/scipost_django/edadmin/urls.py
+++ /dev/null
@@ -1,15 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-from django.urls import path, re_path
-from django.views.generic import TemplateView
-
-from . import views
-
-app_name = "edadmin"
-
-
-urlpatterns = [
-    path("", views.edadmin, name="edadmin"),
-]
diff --git a/scipost_django/edadmin/urls/__init__.py b/scipost_django/edadmin/urls/__init__.py
new file mode 100644
index 000000000..c1ae4f9db
--- /dev/null
+++ b/scipost_django/edadmin/urls/__init__.py
@@ -0,0 +1,15 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.urls import include, path
+
+from ..views import base
+
+app_name = "edadmin"
+
+
+urlpatterns = [
+    path("", base.edadmin, name="edadmin"),
+    path("incoming/", include("edadmin.urls.incoming")),
+]
diff --git a/scipost_django/edadmin/urls/incoming.py b/scipost_django/edadmin/urls/incoming.py
new file mode 100644
index 000000000..d7815dc60
--- /dev/null
+++ b/scipost_django/edadmin/urls/incoming.py
@@ -0,0 +1,31 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.urls import include, path
+
+from ..views import incoming
+
+
+urlpatterns = [
+    path(
+        "_hx_incoming_list",
+        incoming._hx_incoming_list,
+        name="_hx_incoming_list",
+    ),
+    path(
+        "<identifier:identifier_w_vn_nr>/",
+        include([
+            path(
+                "_hx_plagiarism_internal",
+                incoming._hx_plagiarism_internal,
+                name="_hx_plagiarism_internal",
+            ),
+            path(
+                "_hx_plagiarism_iThenticate",
+                incoming._hx_plagiarism_iThenticate,
+                name="_hx_plagiarism_iThenticate",
+            ),
+        ])
+    ),
+]
diff --git a/scipost_django/edadmin/views/__init__.py b/scipost_django/edadmin/views/__init__.py
new file mode 100644
index 000000000..5dfd5d6b6
--- /dev/null
+++ b/scipost_django/edadmin/views/__init__.py
@@ -0,0 +1,2 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
diff --git a/scipost_django/edadmin/views.py b/scipost_django/edadmin/views/base.py
similarity index 100%
rename from scipost_django/edadmin/views.py
rename to scipost_django/edadmin/views/base.py
diff --git a/scipost_django/edadmin/views/incoming.py b/scipost_django/edadmin/views/incoming.py
new file mode 100644
index 000000000..f78658efa
--- /dev/null
+++ b/scipost_django/edadmin/views/incoming.py
@@ -0,0 +1,72 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.contrib.auth.decorators import login_required, user_passes_test
+from django.shortcuts import get_object_or_404, render
+
+from guardian.shortcuts import get_objects_for_user
+
+from colleges.permissions import is_edadmin
+from submissions.models import Submission
+from submissions.forms import iThenticateReportForm
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_incoming_list(request):
+    """
+    EdAdmin page for incoming Submissions.
+    """
+    submissions = get_objects_for_user(request.user, "submissions.take_edadmin_actions")
+    context = { "submissions": submissions.incoming() }
+    return render(request, "edadmin/_hx_submissions_list.html", context)
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_plagiarism_internal(request, identifier_w_vn_nr):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    context = {"submission_matches": [], "publication_matches": []}
+    if "submission_matches" in submission.internal_plagiarism_matches:
+        for sub_match in submission.internal_plagiarism_matches["submission_matches"]:
+            context["submission_matches"].append(
+                {
+                    "submission": Submission.objects.get(
+                        preprint__identifier_w_vn_nr=sub_match["identifier_w_vn_nr"],
+                    ),
+                    "ratio_title": sub_match["ratio_title"],
+                    "ratio_authors": sub_match["ratio_authors"],
+                    "ratio_abstract": sub_match["ratio_abstract"],
+                }
+            )
+    if "publication_matches" in submission.internal_plagiarism_matches:
+        for pub_match in submission.internal_plagiarism_matches["publication_matches"]:
+            context["publication_matches"].append(
+                {
+                    "publication": Publication.objects.get(doi_label=pub_match["doi_label"]),
+                    "ratio_title": pub_match["ratio_title"],
+                    "ratio_authors": pub_match["ratio_authors"],
+                    "ratio_abstract": pub_match["ratio_abstract"],
+                }
+            )
+    return render(request, "edadmin/_hx_plagiarism_internal.html", context)
+
+
+@login_required
+@user_passes_test(is_edadmin)
+def _hx_plagiarism_iThenticate(request, identifier_w_vn_nr):
+    submission = get_object_or_404(
+        Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr
+    )
+    form = iThenticateReportForm(submission, request.POST or None)
+    if form.is_valid():
+        form.save()
+        submission.refresh_from_db()
+    context = {
+        "submission": submission,
+        "form": form,
+    }
+    return render(request, "edadmin/_hx_plagiarism_iThenticate.html", context)
diff --git a/scipost_django/scipost/models.py b/scipost_django/scipost/models.py
index 952f9af40..f6d259ce5 100644
--- a/scipost_django/scipost/models.py
+++ b/scipost_django/scipost/models.py
@@ -192,7 +192,7 @@ class Contributor(models.Model):
 
     @property
     def is_active_senior_fellow(self):
-        return self.fellowships.active().senior().exists()
+        return self.fellowships.active().senior().exists() or self.user.is_superuser
 
     def session_fellowship(self, request):
         """Return session's fellowship, if any; if Fellow, set session_fellowship_id if not set."""
diff --git a/scipost_django/submissions/admin.py b/scipost_django/submissions/admin.py
index 7cc43db97..78fc925a8 100644
--- a/scipost_django/submissions/admin.py
+++ b/scipost_django/submissions/admin.py
@@ -96,7 +96,7 @@ class SubmissionAdmin(GuardedModelAdmin):
         "authors",
         "authors_claims",
         "authors_false_claims",
-        "plagiarism_report",
+        "iThenticate_plagiarism_report",
         "topics",
     ]
     inlines = [
diff --git a/scipost_django/submissions/forms.py b/scipost_django/submissions/forms.py
index 5cd343173..77716af80 100644
--- a/scipost_django/submissions/forms.py
+++ b/scipost_django/submissions/forms.py
@@ -2789,7 +2789,7 @@ class iThenticateReportForm(forms.ModelForm):
         else:
             report.save()
             Submission.objects.filter(id=self.submission.id).update(
-                plagiarism_report=report
+                iThenticate_plagiarism_report=report
             )
         return report
 
diff --git a/scipost_django/submissions/managers/submission.py b/scipost_django/submissions/managers/submission.py
index 9c02988ef..1eb8f2057 100644
--- a/scipost_django/submissions/managers/submission.py
+++ b/scipost_django/submissions/managers/submission.py
@@ -183,8 +183,10 @@ class SubmissionQuerySet(models.QuerySet):
             f_ids = user.contributor.fellowships.active()
             qs = qs.filter(fellows__in=f_ids)
 
+        if user.contributor.is_scipost_admin:
+            pass
         # Fellows can't see incoming and (non-Senior) preassignment
-        if user.contributor.is_active_senior_fellow:
+        elif user.contributor.is_active_senior_fellow:
             qs = qs.exclude(status__in=[self.model.INCOMING,])
         elif user.contributor.is_active_fellow:
             qs = qs.exclude(status__in=[self.model.INCOMING, self.model.PREASSIGNMENT])
@@ -338,13 +340,13 @@ class SubmissionEventQuerySet(models.QuerySet):
             created__gte=timezone.now() - datetime.timedelta(hours=hours)
         )
 
-    def plagiarism_report_to_be_uploaded(self):
+    def iThenticate_plagiarism_report_to_be_uploaded(self):
         """Return Submissions that has not been sent to iThenticate for their plagiarism check."""
         return self.filter(
-            models.Q(plagiarism_report__isnull=True)
-            | models.Q(plagiarism_report__status=constants.STATUS_WAITING)
+            models.Q(iThenticate_plagiarism_report__isnull=True)
+            | models.Q(iThenticate_plagiarism_report__status=constants.STATUS_WAITING)
         ).distinct()
 
-    def plagiarism_report_to_be_updated(self):
+    def iThenticate_plagiarism_report_to_be_updated(self):
         """Return Submissions for which their iThenticateReport has not received a report yet."""
-        return self.filter(plagiarism_report__status=constants.STATUS_SENT)
+        return self.filter(iThenticate_plagiarism_report__status=constants.STATUS_SENT)
diff --git a/scipost_django/submissions/migrations/0127_auto_20221204_1327.py b/scipost_django/submissions/migrations/0127_auto_20221204_1327.py
new file mode 100644
index 000000000..c7cba2353
--- /dev/null
+++ b/scipost_django/submissions/migrations/0127_auto_20221204_1327.py
@@ -0,0 +1,57 @@
+# Generated by Django 3.2.16 on 2022-12-04 12:27
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0126_alter_submission_status'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='PlagiarismAssessment',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('status', models.CharField(choices=[('ongoing', 'Ongoing'), ('passed', 'Passed'), ('failed_temporary', 'Failed (temporary: author action needed)'), ('failed_permanent', 'Failed (permanent: not solvable)')], default='ongoing', max_length=16)),
+                ('passed_on', models.DateTimeField(blank=True, null=True)),
+                ('comments_for_edadmin', models.TextField()),
+                ('comments_for_authors', models.TextField()),
+            ],
+        ),
+        migrations.RenameField(
+            model_name='submission',
+            old_name='plagiarism_report',
+            new_name='iThenticate_plagiarism_report',
+        ),
+        migrations.CreateModel(
+            name='InternalPlagiarismAssessment',
+            fields=[
+                ('plagiarismassessment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='submissions.plagiarismassessment')),
+            ],
+            bases=('submissions.plagiarismassessment',),
+        ),
+        migrations.CreateModel(
+            name='iThenticatePlagiarismAssessment',
+            fields=[
+                ('plagiarismassessment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='submissions.plagiarismassessment')),
+            ],
+            options={
+                'verbose_name': 'iThenticate plagiarism assessment',
+                'verbose_name_plural': 'iThenticate plagiarism assessments',
+            },
+            bases=('submissions.plagiarismassessment',),
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='iThenticate_plagiarism_assessment',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='submissions.ithenticateplagiarismassessment'),
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='internal_plagiarism_assessment',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='submissions.internalplagiarismassessment'),
+        ),
+    ]
diff --git a/scipost_django/submissions/mixins.py b/scipost_django/submissions/mixins.py
index 4a30e9236..2149b3aa3 100644
--- a/scipost_django/submissions/mixins.py
+++ b/scipost_django/submissions/mixins.py
@@ -101,7 +101,7 @@ class SubmissionAdminViewMixin(FriendlyPermissionMixin, SubmissionFormViewMixin)
         qs = super().get_queryset()
         if self.pool:
             return qs.pool(self.request.user)
-        return qs.filter_for_eic(self.request.user)
+        return qs.in_pool_filter_for_eic(self.request.user)
 
     def get_object(self):
         """
diff --git a/scipost_django/submissions/models/__init__.py b/scipost_django/submissions/models/__init__.py
index aea07c0a8..5bd066ac4 100644
--- a/scipost_django/submissions/models/__init__.py
+++ b/scipost_django/submissions/models/__init__.py
@@ -4,7 +4,13 @@ __license__ = "AGPL v3"
 
 from .submission import Submission, SubmissionEvent, SubmissionTiering
 
-from .plagiarism import iThenticateReport
+from .plagiarism_assessment import (
+    PlagiarismAssessment,
+    InternalPlagiarismAssessment,
+    iThenticatePlagiarismAssessment,
+)
+
+from .iThenticate_report import iThenticateReport
 
 from .assignment import EditorialAssignment
 
diff --git a/scipost_django/submissions/models/plagiarism.py b/scipost_django/submissions/models/iThenticate_report.py
similarity index 100%
rename from scipost_django/submissions/models/plagiarism.py
rename to scipost_django/submissions/models/iThenticate_report.py
diff --git a/scipost_django/submissions/models/plagiarism_assessment.py b/scipost_django/submissions/models/plagiarism_assessment.py
new file mode 100644
index 000000000..6f9b52629
--- /dev/null
+++ b/scipost_django/submissions/models/plagiarism_assessment.py
@@ -0,0 +1,40 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+
+class PlagiarismAssessment(models.Model):
+    STATUS_ONGOING = "ongoing"
+    STATUS_PASSED = "passed"
+    STATUS_FAILED_TEMPORARY = "failed_temporary"
+    STATUS_FAILED_PERMANENT = "failed_permanent"
+    STATUS_CHOICES = (
+        (STATUS_ONGOING, "Ongoing"),
+        (STATUS_PASSED, "Passed"),
+        (STATUS_FAILED_TEMPORARY, "Failed (temporary: author action needed)"),
+        (STATUS_FAILED_PERMANENT, "Failed (permanent: not solvable)"),
+    )
+    status = models.CharField(
+        max_length=16,
+        choices=STATUS_CHOICES,
+        default=STATUS_ONGOING,
+    )
+    passed_on = models.DateTimeField(blank=True, null=True)
+    comments_for_edadmin = models.TextField()
+    comments_for_authors = models.TextField()
+
+    @property
+    def passed(self):
+        return self.status == self.STATUS_PASSED
+
+
+class InternalPlagiarismAssessment(PlagiarismAssessment):
+    pass
+
+
+class iThenticatePlagiarismAssessment(PlagiarismAssessment):
+    class Meta:
+        verbose_name = "iThenticate plagiarism assessment"
+        verbose_name_plural = "iThenticate plagiarism assessments"
diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py
index b0e152c4a..8fa980d88 100644
--- a/scipost_django/submissions/models/submission.py
+++ b/scipost_django/submissions/models/submission.py
@@ -250,21 +250,36 @@ class Submission(models.Model):
     # Comments can be added to a Submission
     comments = GenericRelation("comments.Comment", related_query_name="submissions")
 
-    # iThenticate and conflicts
+    # Conflicts of interest
     needs_conflicts_update = models.BooleanField(default=True)
-    plagiarism_report = models.OneToOneField(
+
+    # Plagiarism
+    internal_plagiarism_matches = models.JSONField(
+        default=dict,
+        blank=True,
+        null=True,
+    )
+    internal_plagiarism_assessment = models.OneToOneField(
+        "submissions.InternalPlagiarismAssessment",
+        on_delete=models.CASCADE,
+        blank=True,
+        null=True,
+    )
+    iThenticate_plagiarism_report = models.OneToOneField(
         "submissions.iThenticateReport",
         on_delete=models.SET_NULL,
-        null=True,
         blank=True,
+        null=True,
         related_name="to_submission",
     )
-    internal_plagiarism_matches = models.JSONField(
-        default=dict,
+    iThenticate_plagiarism_assessment = models.OneToOneField(
+        "submissions.iThenticatePlagiarismAssessment",
+        on_delete=models.CASCADE,
         blank=True,
         null=True,
     )
 
+    # Refereeing pack
     pdf_refereeing_pack = models.FileField(
         upload_to="UPLOADS/REFEREE/%Y/%m/", max_length=200, blank=True
     )
@@ -563,7 +578,7 @@ class Submission(models.Model):
     @property
     def can_reset_reporting_deadline(self):
         """Check if reporting deadline is allowed to be reset."""
-        if self.status in STAGE_DECIDED:
+        if self.status in self.STAGE_DECIDED:
             return False
 
         if self.refereeing_cycle == CYCLE_DIRECT_REC:
diff --git a/scipost_django/submissions/tasks.py b/scipost_django/submissions/tasks.py
index c67da652f..eaf8e42f2 100644
--- a/scipost_django/submissions/tasks.py
+++ b/scipost_django/submissions/tasks.py
@@ -45,15 +45,15 @@ def send_editorial_assignment_invitations(self):
 @app.task(bind=True)
 def submit_submission_document_for_plagiarism(self):
     """Upload a new Submission document to iThenticate."""
-    submissions_to_upload = Submission.objects.plagiarism_report_to_be_uploaded()
-    submission_to_update = Submission.objects.plagiarism_report_to_be_updated()
+    submissions_to_upload = Submission.objects.iThenticate_plagiarism_report_to_be_uploaded()
+    submission_to_update = Submission.objects.iThenticate_plagiarism_report_to_be_updated()
 
     for submission in submissions_to_upload:
         report, __ = iThenticate.objects.get_or_create(to_submission=submission)
         # do it...
 
     for submission in submission_to_update:
-        report = submission.plagiarism_report
+        report = submission.iThenticate_plagiarism_report
         # do it...
 
 
diff --git a/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html b/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html
index be09739fe..c99d3fe9e 100644
--- a/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html
+++ b/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html
@@ -31,11 +31,14 @@
 flowchart LR
     Sub([Submission{% if submission %}<br>{{ submission.submission_date }}<br>{{ submission.submission_date|timesince }} ago{% endif %}])
     subgraph Admission
-        Admiss(Admissibility<br>and plagiarism<br>checks)
+        Admiss(Admissibility<br>check)
+        Admiss --> PlagInt(internal plagiarism<br>check)
+        PlagInt --> PlagExt(external plagiarism<br>check)
     end
     Sub --> Admiss
-    Admiss --fail--> AdmissFailed("Admission<br>failed ✉<small>A</small>") --> Close([Processing<br>closed])
-    Admiss --pass--> AdmissPassed("Admission<br>passed ✉<small>A</small>") --> Preassignment[[Goto:<br>Preassignment]]
+    PlagExt --fail--> AdmissFailed("Admission<br>failed ✉<small>A</small>") --> Close([Processing<br>closed])
+    PlagExt --pass--> AdmissPassed("Admission<br>passed ✉<small>A</small>") --> Preassignment[[Goto:<br>Preassignment]]
+    PlagInt --"pass<br>(authors created new submission<br>but this is a resubmission)"--> LinkResub("Link resubmission<br>to earlier thread") --> AdmissPassed2("Admission<br>passed ✉<small>A</small>") --> RefPrep[[Goto:<br>Refereeing<br>in preparation]]
       </pre>
     </details>
   </div>
diff --git a/scipost_django/submissions/templates/submissions/admin/plagiarism_report.html b/scipost_django/submissions/templates/submissions/admin/plagiarism_report.html
index 18ec45c65..cbbc30365 100644
--- a/scipost_django/submissions/templates/submissions/admin/plagiarism_report.html
+++ b/scipost_django/submissions/templates/submissions/admin/plagiarism_report.html
@@ -13,27 +13,27 @@
   <h1>iThenticate Plagiarism Report for <a href="{{ submission.get_absolute_url }}">{{ submission.preprint.identifier_w_vn_nr }}</a></h1>
   <h2>{{  submission.title }}</h2>
   <h3 class="mb-4">by {{ submission.author_list }}</h3>
-  {% if submission.plagiarism_report %}
+  {% if submission.iThenticate_plagiarism_report %}
     <table>
       <tr>
         <td style="min-width: 150px;">iThenticate document</td>
-        <td>{{ submission.plagiarism_report.doc_id }}</td>
+        <td>{{ submission.iThenticate_plagiarism_report.doc_id }}</td>
       </tr>
       <tr>
         <td>Percent match</td>
-        <td>{{ submission.plagiarism_report.percent_match }}%</td>
+        <td>{{ submission.iThenticate_plagiarism_report.percent_match }}%</td>
       </tr>
       <tr>
         <td>Processed</td>
-        <td>{{ submission.plagiarism_report.processed_time }}</td>
+        <td>{{ submission.iThenticate_plagiarism_report.processed_time }}</td>
       </tr>
       <tr>
         <td>Uploaded</td>
-        <td>{{ submission.plagiarism_report.uploaded_time }}</td>
+        <td>{{ submission.iThenticate_plagiarism_report.uploaded_time }}</td>
       </tr>
       <tr>
         <td>Latest update</td>
-        <td>{{ submission.plagiarism_report.latest_activity }}</td>
+        <td>{{ submission.iThenticate_plagiarism_report.latest_activity }}</td>
       </tr>
     </table>
   {% else %}
@@ -43,9 +43,9 @@
   <form method="post" class="mt-3" enctype="multipart/form-data">
     {% csrf_token %}
     {{ form|bootstrap }}
-    <input type="submit" class="btn btn-primary" value="{% if submission.plagiarism_report %}Update report status{% else %}Submit submission for plagiarism check{% endif %}">
-    {% if submission.plagiarism_report %}
-      <a href="{% url 'submissions:plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="ms-2 btn btn-default">Download report pdf</a>
+    <input type="submit" class="btn btn-primary" value="{% if submission.iThenticate_plagiarism_report %}Update report status{% else %}Submit submission for plagiarism check{% endif %}">
+    {% if submission.iThenticate_plagiarism_report %}
+      <a href="{% url 'submissions:iThenticate_plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="ms-2 btn btn-default">Download report pdf</a>
     {% endif %}
   </form>
 
diff --git a/scipost_django/submissions/templates/submissions/admin/submission_preassignment.html b/scipost_django/submissions/templates/submissions/admin/submission_preassignment.html
index bdced0586..30a8601a0 100644
--- a/scipost_django/submissions/templates/submissions/admin/submission_preassignment.html
+++ b/scipost_django/submissions/templates/submissions/admin/submission_preassignment.html
@@ -39,29 +39,29 @@
       <a href="{% url 'submissions:plagiarism_internal' submission.preprint.identifier_w_vn_nr %}">Check internal plagiarism</a>
     </li>
     <li>
-      {% if submission.plagiarism_report %}
+      {% if submission.iThenticate_plagiarism_report %}
         <span class="text-success">{% include 'bi/check-square-fill.html' %}</span>
         <a class="d-inline-block" href="{% url 'submissions:plagiarism' submission.preprint.identifier_w_vn_nr %}">Update plagiarism report</a>
         <table>
           <tr>
             <td style="min-width: 150px;">iThenticate document</td>
-            <td>{{ submission.plagiarism_report.doc_id }}</td>
+            <td>{{ submission.iThenticate_plagiarism_report.doc_id }}</td>
           </tr>
           <tr>
             <td>Percent match</td>
-            <td>{{ submission.plagiarism_report.percent_match|default:'?' }}%</td>
+            <td>{{ submission.iThenticate_plagiarism_report.percent_match|default:'?' }}%</td>
           </tr>
           <tr>
             <td>Processed</td>
-            <td>{{ submission.plagiarism_report.processed_time }}</td>
+            <td>{{ submission.iThenticate_plagiarism_report.processed_time }}</td>
           </tr>
           <tr>
             <td>Uploaded</td>
-            <td>{{ submission.plagiarism_report.uploaded_time }}</td>
+            <td>{{ submission.iThenticate_plagiarism_report.uploaded_time }}</td>
           </tr>
           <tr>
             <td>Latest update</td>
-            <td>{{ submission.plagiarism_report.latest_activity }}</td>
+            <td>{{ submission.iThenticate_plagiarism_report.latest_activity }}</td>
           </tr>
         </table>
       {% else %}
diff --git a/scipost_django/submissions/templates/submissions/pool/_submission_info_table.html b/scipost_django/submissions/templates/submissions/pool/_submission_info_table.html
index 1da291f91..6a81fca12 100644
--- a/scipost_django/submissions/templates/submissions/pool/_submission_info_table.html
+++ b/scipost_django/submissions/templates/submissions/pool/_submission_info_table.html
@@ -101,9 +101,9 @@
     <tr>
       <td>iThenticate plagiarism score</td>
       <td>
-        {% if submission.plagiarism_report %}
-          {{ submission.plagiarism_report.score }}%
-	  &emsp;<a href="{% url 'submissions:plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="ms-2 btn btn-default" target="_blank">View report pdf</a>
+        {% if submission.iThenticate_plagiarism_report %}
+          {{ submission.iThenticate_plagiarism_report.score }}%
+	  &emsp;<a href="{% url 'submissions:iThenticate_plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="ms-2 btn btn-default" target="_blank">View report pdf</a>
         {% else %}
           <a href="{% url 'submissions:plagiarism' submission.preprint.identifier_w_vn_nr %}">Run plagiarism check</a>
         {% endif %}
diff --git a/scipost_django/submissions/templates/submissions/pool/editorial_page.html b/scipost_django/submissions/templates/submissions/pool/editorial_page.html
index a4a14d1d6..e8a2d7fc2 100644
--- a/scipost_django/submissions/templates/submissions/pool/editorial_page.html
+++ b/scipost_django/submissions/templates/submissions/pool/editorial_page.html
@@ -159,13 +159,13 @@
         {% endif %}
       </td>
     </tr>
-    {% if submission.plagiarism_report or perms.scipost.can_do_plagiarism_checks %}
+    {% if submission.iThenticate_plagiarism_report or perms.scipost.can_do_plagiarism_checks %}
       <tr>
         <td>Plagiarism report:</td>
         <td>
-          {% if submission.plagiarism_report %}
-            {% if submission.plagiarism_report.percent_match %}
-              <b>{{ submission.plagiarism_report.percent_match }}%</b>
+          {% if submission.iThenticate_plagiarism_report %}
+            {% if submission.iThenticate_plagiarism_report.percent_match %}
+              <b>{{ submission.iThenticate_plagiarism_report.percent_match }}%</b>
             {% else %}
               <em>Scan in progress</em>
               {% if perms.scipost.can_do_plagiarism_checks %}
diff --git a/scipost_django/submissions/urls.py b/scipost_django/submissions/urls.py
index 02c5045c0..f946a8a71 100644
--- a/scipost_django/submissions/urls.py
+++ b/scipost_django/submissions/urls.py
@@ -140,9 +140,9 @@ urlpatterns = [
         name="plagiarism",
     ),
     path(
-        "admin/<identifier:identifier_w_vn_nr>/plagiarism/report",
+        "admin/<identifier:identifier_w_vn_nr>/plagiarism/iThenticate_report",
         views.PlagiarismReportPDFView.as_view(),
-        name="plagiarism_report",
+        name="iThenticate_plagiarism_report",
     ),
     path(
         "admin/<identifier:identifier_w_vn_nr>/plagiarism/internal",
diff --git a/scipost_django/submissions/views.py b/scipost_django/submissions/views.py
index 0330b4ca0..2a61f63d4 100644
--- a/scipost_django/submissions/views.py
+++ b/scipost_django/submissions/views.py
@@ -2950,14 +2950,14 @@ class PlagiarismView(SubmissionAdminViewMixin, UpdateView):
     """Administration detail page of Plagiarism report."""
 
     permission_required = "scipost.can_do_plagiarism_checks"
-    template_name = "submissions/admin/plagiarism_report.html"
+    template_name = "submissions/admin/iThenticate_plagiarism_report.html"
     editorial_page = True
     form_class = iThenticateReportForm
 
     def get_object(self):
-        """Get the plagiarism_report as a linked object from the Submission."""
+        """Get the iThenticate_plagiarism_report as a linked object from the Submission."""
         submission = super().get_object()
-        return submission.plagiarism_report
+        return submission.iThenticate_plagiarism_report
 
 
 class PlagiarismReportPDFView(
@@ -2971,9 +2971,9 @@ class PlagiarismReportPDFView(
     def get_redirect_url(self, *args, **kwargs):
         """Get the temporary url provided by the iThenticate API."""
         submission = self.get_object()
-        if not submission.plagiarism_report:
+        if not submission.iThenticate_plagiarism_report:
             raise Http404
-        url = submission.plagiarism_report.get_report_url()
+        url = submission.iThenticate_plagiarism_report.get_report_url()
 
         if not url:
             raise Http404
-- 
GitLab