From ad6fda760ffa83e5e65b0c26430c7fa5e7f20acc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org>
Date: Thu, 14 Mar 2024 19:59:33 +0100
Subject: [PATCH] Replace journals.OrgPubFraction by finances.PubFrac (+ xtra
 migrns)

---
 .../0033_alter_storedmessage_read_by.py       |  22 ++++
 ...worklog_content_type_alter_worklog_user.py |  34 ++++++
 ...lter_grant_funder_alter_grant_recipient.py |  32 ++++++
 ...6_alter_citationnotification_invitation.py |  24 ++++
 scipost_django/journals/admin.py              |  10 --
 .../journals/api/filtersets/pubfraction.py    |   4 +-
 .../journals/api/serializers/pubfraction.py   |   4 +-
 .../journals/api/viewsets/pubfraction.py      |   4 +-
 scipost_django/journals/forms.py              |  20 ++--
 ..._journal_alter_issue_in_volume_and_more.py | 103 ++++++++++++++++++
 scipost_django/journals/models/__init__.py    |   2 +-
 scipost_django/journals/models/publication.py |  37 -------
 scipost_django/journals/views.py              |  14 +--
 scipost_django/organizations/models.py        |  15 +--
 ...petitionsignatory_organization_and_more.py |  43 ++++++++
 .../0011_alter_proceedings_fellowships.py     |  19 ++++
 .../0039_alter_profileemail_profile.py        |  21 ++++
 ...or_alter_remark_recommendation_and_more.py |  51 +++++++++
 ...editorialassignment_submission_and_more.py |  49 +++++++++
 19 files changed, 430 insertions(+), 78 deletions(-)
 create mode 100644 scipost_django/apimail/migrations/0033_alter_storedmessage_read_by.py
 create mode 100644 scipost_django/finances/migrations/0034_alter_worklog_content_type_alter_worklog_user.py
 create mode 100644 scipost_django/funders/migrations/0015_alter_grant_funder_alter_grant_recipient.py
 create mode 100644 scipost_django/invitations/migrations/0016_alter_citationnotification_invitation.py
 create mode 100644 scipost_django/journals/migrations/0129_alter_issue_in_journal_alter_issue_in_volume_and_more.py
 create mode 100644 scipost_django/petitions/migrations/0010_alter_petitionsignatory_organization_and_more.py
 create mode 100644 scipost_django/proceedings/migrations/0011_alter_proceedings_fellowships.py
 create mode 100644 scipost_django/profiles/migrations/0039_alter_profileemail_profile.py
 create mode 100644 scipost_django/scipost/migrations/0041_alter_remark_contributor_alter_remark_recommendation_and_more.py
 create mode 100644 scipost_django/submissions/migrations/0148_alter_editorialassignment_submission_and_more.py

diff --git a/scipost_django/apimail/migrations/0033_alter_storedmessage_read_by.py b/scipost_django/apimail/migrations/0033_alter_storedmessage_read_by.py
new file mode 100644
index 000000000..7e615f09f
--- /dev/null
+++ b/scipost_django/apimail/migrations/0033_alter_storedmessage_read_by.py
@@ -0,0 +1,22 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ("apimail", "0032_auto_20210716_0926"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="storedmessage",
+            name="read_by",
+            field=models.ManyToManyField(
+                blank=True, related_name="+", to=settings.AUTH_USER_MODEL
+            ),
+        ),
+    ]
diff --git a/scipost_django/finances/migrations/0034_alter_worklog_content_type_alter_worklog_user.py b/scipost_django/finances/migrations/0034_alter_worklog_content_type_alter_worklog_user.py
new file mode 100644
index 000000000..2e983d851
--- /dev/null
+++ b/scipost_django/finances/migrations/0034_alter_worklog_content_type_alter_worklog_user.py
@@ -0,0 +1,34 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ("contenttypes", "0002_remove_content_type_name"),
+        ("finances", "0033_populate_pubfracs"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="worklog",
+            name="content_type",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="contenttypes.contenttype",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="worklog",
+            name="user",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
+            ),
+        ),
+    ]
diff --git a/scipost_django/funders/migrations/0015_alter_grant_funder_alter_grant_recipient.py b/scipost_django/funders/migrations/0015_alter_grant_funder_alter_grant_recipient.py
new file mode 100644
index 000000000..32de8f795
--- /dev/null
+++ b/scipost_django/funders/migrations/0015_alter_grant_funder_alter_grant_recipient.py
@@ -0,0 +1,32 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("scipost", "0040_auto_20210310_2026"),
+        ("funders", "0014_enable_unaccent"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="grant",
+            name="funder",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="funders.funder"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="grant",
+            name="recipient",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="scipost.contributor",
+            ),
+        ),
+    ]
diff --git a/scipost_django/invitations/migrations/0016_alter_citationnotification_invitation.py b/scipost_django/invitations/migrations/0016_alter_citationnotification_invitation.py
new file mode 100644
index 000000000..8e076cf0b
--- /dev/null
+++ b/scipost_django/invitations/migrations/0016_alter_citationnotification_invitation.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("invitations", "0015_auto_20210310_2026"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="citationnotification",
+            name="invitation",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="invitations.registrationinvitation",
+            ),
+        ),
+    ]
diff --git a/scipost_django/journals/admin.py b/scipost_django/journals/admin.py
index b6e5cb157..830637dbc 100644
--- a/scipost_django/journals/admin.py
+++ b/scipost_django/journals/admin.py
@@ -15,7 +15,6 @@ from journals.models import (
     GenericDOIDeposit,
     Reference,
     PublicationAuthorsTable,
-    OrgPubFraction,
     PublicationUpdate,
     SubmissionTemplate,
     AutogeneratedFileContentTemplate,
@@ -87,14 +86,6 @@ class PublicationResourceInline(admin.TabularInline):
     extra = 0
 
 
-class OrgPubFractionInline(admin.TabularInline):
-    model = OrgPubFraction
-    list_display = ("organization", "publication", "fraction")
-    autocomplete_fields = [
-        "organization",
-    ]
-
-
 class PubFracInline(admin.TabularInline):
     model = PubFrac
     list_display = ("organization", "publication", "fraction")
@@ -120,7 +111,6 @@ class PublicationAdmin(admin.ModelAdmin):
     inlines = [
         AuthorsInline,
         ReferenceInline,
-        OrgPubFractionInline,
         PubFracInline,
         PublicationResourceInline,
     ]
diff --git a/scipost_django/journals/api/filtersets/pubfraction.py b/scipost_django/journals/api/filtersets/pubfraction.py
index a8543b79e..cbfe1d38c 100644
--- a/scipost_django/journals/api/filtersets/pubfraction.py
+++ b/scipost_django/journals/api/filtersets/pubfraction.py
@@ -4,12 +4,12 @@ __license__ = "AGPL v3"
 
 from django_filters import rest_framework as df_filters
 
-from journals.models import OrgPubFraction
+from finances.models import PubFrac
 
 
 class PubFractionPublicAPIFilterSet(df_filters.FilterSet):
     class Meta:
-        model = OrgPubFraction
+        model = PubFrac
         fields = {
             "organization__name": ["icontains", "istartswith", "exact"],
             "organization__country": [
diff --git a/scipost_django/journals/api/serializers/pubfraction.py b/scipost_django/journals/api/serializers/pubfraction.py
index ea6075965..c0294c079 100644
--- a/scipost_django/journals/api/serializers/pubfraction.py
+++ b/scipost_django/journals/api/serializers/pubfraction.py
@@ -4,7 +4,7 @@ __license__ = "AGPL v3"
 
 from rest_framework import serializers
 
-from journals.models import OrgPubFraction
+from finances.models import PubFrac
 from journals.api.serializers import PublicationPublicSearchSerializer
 from organizations.api.serializers import OrganizationPublicSerializer
 
@@ -18,5 +18,5 @@ class PubFractionPublicSerializer(serializers.ModelSerializer):
     )
 
     class Meta:
-        model = OrgPubFraction
+        model = PubFrac
         fields = ["organization", "publication", "fraction"]
diff --git a/scipost_django/journals/api/viewsets/pubfraction.py b/scipost_django/journals/api/viewsets/pubfraction.py
index 06d046213..9c9f6017d 100644
--- a/scipost_django/journals/api/viewsets/pubfraction.py
+++ b/scipost_django/journals/api/viewsets/pubfraction.py
@@ -11,7 +11,7 @@ from rest_framework_csv import renderers as r
 
 from api.viewsets.mixins import FilteringOptionsActionMixin
 
-from journals.models import OrgPubFraction
+from finances.models import PubFrac
 from journals.api.serializers import PubFractionPublicSerializer
 
 from journals.api.filtersets import PubFractionPublicAPIFilterSet
@@ -20,7 +20,7 @@ from journals.api.filtersets import PubFractionPublicAPIFilterSet
 class PubFractionPublicAPIViewSet(
     FilteringOptionsActionMixin, viewsets.ReadOnlyModelViewSet
 ):
-    queryset = OrgPubFraction.objects.all()
+    queryset = PubFrac.objects.all()
     permission_classes = [
         AllowAny,
     ]
diff --git a/scipost_django/journals/forms.py b/scipost_django/journals/forms.py
index 74ebb7acf..683fc8422 100644
--- a/scipost_django/journals/forms.py
+++ b/scipost_django/journals/forms.py
@@ -42,12 +42,12 @@ from .models import (
     Reference,
     Volume,
     PublicationAuthorsTable,
-    OrgPubFraction,
 )
 from .utils import JournalUtils
 
 
 from common.utils import get_current_domain, jatsify_tags
+from finances.models import PubFrac
 from funders.models import Grant, Funder
 from journals.models import Journal
 from mails.utils import DirectMailUtil
@@ -801,7 +801,7 @@ class DraftAccompanyingPublicationForm(forms.Form):
 
         # Add PubFractions
         for pubfrac in anchor.pubfractions.all():
-            OrgPubFraction.objects.create(
+            PubFrac.objects.create(
                 organization=pubfrac.organization,
                 publication=companion,
                 fraction=pubfrac.fraction,
@@ -1087,19 +1087,19 @@ class IssueForm(forms.ModelForm):
         return issue
 
 
-class SetOrgPubFractionForm(forms.ModelForm):
+class SetPubFracForm(forms.ModelForm):
     class Meta:
-        model = OrgPubFraction
+        model = PubFrac
         fields = ["organization", "publication", "fraction"]
 
     def __init__(self, *args, **kwargs):
-        super(SetOrgPubFractionForm, self).__init__(*args, **kwargs)
+        super(SetPubFracForm, self).__init__(*args, **kwargs)
         if self.instance.id:
             self.fields["organization"].disabled = True
             self.fields["publication"].widget = forms.HiddenInput()
 
 
-class BaseOrgPubFractionsFormSet(BaseModelFormSet):
+class BasePubFracsFormSet(BaseModelFormSet):
     def clean(self):
         """
         Checks that the fractions add up to one.
@@ -1114,11 +1114,11 @@ class BaseOrgPubFractionsFormSet(BaseModelFormSet):
             )
 
 
-OrgPubFractionsFormSet = modelformset_factory(
-    OrgPubFraction,
+PubFracsFormSet = modelformset_factory(
+    PubFrac,
     fields=("publication", "organization", "fraction"),
-    formset=BaseOrgPubFractionsFormSet,
-    form=SetOrgPubFractionForm,
+    formset=BasePubFracsFormSet,
+    form=SetPubFracForm,
     extra=0,
 )
 
diff --git a/scipost_django/journals/migrations/0129_alter_issue_in_journal_alter_issue_in_volume_and_more.py b/scipost_django/journals/migrations/0129_alter_issue_in_journal_alter_issue_in_volume_and_more.py
new file mode 100644
index 000000000..27acc5ef6
--- /dev/null
+++ b/scipost_django/journals/migrations/0129_alter_issue_in_journal_alter_issue_in_volume_and_more.py
@@ -0,0 +1,103 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("submissions", "0147_auto_20240220_1404"),
+        ("funders", "0015_alter_grant_funder_alter_grant_recipient"),
+        ("ontology", "0009_populate_specialty_topics"),
+        ("journals", "0128_populate_submission_object_types"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="issue",
+            name="in_journal",
+            field=models.ForeignKey(
+                blank=True,
+                help_text="Assign either a Volume or Journal to the Issue",
+                limit_choices_to={"structure": "IO"},
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="journals.journal",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="issue",
+            name="in_volume",
+            field=models.ForeignKey(
+                blank=True,
+                help_text="Assign either a Volume or Journal to the Issue",
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="journals.volume",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="accepted_submission",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="submissions.submission"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="funders_generic",
+            field=models.ManyToManyField(blank=True, to="funders.funder"),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="grants",
+            field=models.ManyToManyField(blank=True, to="funders.grant"),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="in_issue",
+            field=models.ForeignKey(
+                blank=True,
+                help_text="Assign either an Issue or Journal to the Publication",
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="journals.issue",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="in_journal",
+            field=models.ForeignKey(
+                blank=True,
+                help_text="Assign either an Issue or Journal to the Publication",
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="journals.journal",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="publication",
+            name="topics",
+            field=models.ManyToManyField(blank=True, to="ontology.topic"),
+        ),
+        migrations.AlterField(
+            model_name="reference",
+            name="publication",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="journals.publication"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="volume",
+            name="in_journal",
+            field=models.ForeignKey(
+                limit_choices_to={"structure": "IV"},
+                on_delete=django.db.models.deletion.CASCADE,
+                to="journals.journal",
+            ),
+        ),
+        migrations.DeleteModel(
+            name="OrgPubFraction",
+        ),
+    ]
diff --git a/scipost_django/journals/models/__init__.py b/scipost_django/journals/models/__init__.py
index ed55e2533..1ee463137 100644
--- a/scipost_django/journals/models/__init__.py
+++ b/scipost_django/journals/models/__init__.py
@@ -6,7 +6,7 @@ from .journal import Journal
 from .volume import Volume
 from .issue import Issue
 from .submission_template import SubmissionTemplate
-from .publication import PublicationAuthorsTable, Publication, Reference, OrgPubFraction
+from .publication import PublicationAuthorsTable, Publication, Reference
 from .deposits import Deposit, DOAJDeposit, GenericDOIDeposit
 from .update import PublicationUpdate
 from .autogenerated_file import AutogeneratedFileContentTemplate
diff --git a/scipost_django/journals/models/publication.py b/scipost_django/journals/models/publication.py
index 7a8bd0914..83a5bc34a 100644
--- a/scipost_django/journals/models/publication.py
+++ b/scipost_django/journals/models/publication.py
@@ -533,40 +533,3 @@ class Reference(models.Model):
         return "[{}] {}, {}".format(
             self.reference_number, self.authors[:30], self.citation[:30]
         )
-
-
-class OrgPubFraction(models.Model):
-    """
-    Associates a fraction of the funding credit for a given publication to an Organization,
-    to help answer the question: who funded this research?
-
-    Fractions for a given publication should sum up to one.
-
-    This data is used to compile publicly-displayed information on Organizations
-    as well as to set suggested contributions from Partners.
-
-    To be set (ideally) during production phase, based on information provided by the authors.
-    """
-
-    organization = models.ForeignKey(
-        "organizations.Organization",
-        on_delete=models.CASCADE,
-        related_name="pubfractions",
-        blank=True,
-        null=True,
-    )
-    publication = models.ForeignKey(
-        "journals.Publication", on_delete=models.CASCADE, related_name="pubfractions"
-    )
-    fraction = models.DecimalField(
-        max_digits=4, decimal_places=3, default=Decimal("0.000")
-    )
-
-    class Meta:
-        unique_together = (("organization", "publication"),)
-
-    @property
-    def value(self):
-        return int(self.fraction * self.publication.get_journal().cost_per_publication(
-            self.publication.publication_date.year
-        ))
diff --git a/scipost_django/journals/views.py b/scipost_django/journals/views.py
index 3bd9c3d29..c6e396659 100644
--- a/scipost_django/journals/views.py
+++ b/scipost_django/journals/views.py
@@ -55,7 +55,6 @@ from .models import (
     DOAJDeposit,
     GenericDOIDeposit,
     PublicationAuthorsTable,
-    OrgPubFraction,
     PublicationUpdate,
     AutogeneratedFileContentTemplate,
     PublicationResource,
@@ -78,7 +77,7 @@ from .forms import (
     DraftPublicationApprovalForm,
     PublicationPublishForm,
     PublicationAuthorOrderingFormSet,
-    OrgPubFractionsFormSet,
+    PubFracsFormSet,
     PublicationDynSelForm,
 )
 from .mixins import PublicationMixin, ProdSupervisorPublicationPermissionMixin
@@ -88,6 +87,7 @@ from .utils import JournalUtils
 from comments.models import Comment
 from common.utils import get_current_domain
 from common.views import HTMXInlineCRUDModelFormView, HTMXInlineCRUDModelListView
+from finances.models import PubFrac
 from funders.forms import FunderSelectForm, GrantSelectForm
 from funders.models import Grant, Funder
 from mails.views import MailEditorSubview
@@ -1377,12 +1377,12 @@ def allocate_orgpubfractions(request, doi_label):
     This view is accessible to EdAdmin.
     """
     publication = get_object_or_404(Publication, doi_label=doi_label)
-    # Create OrgPubFraction objects from existing organization links
+    # Create PubFrac objects from existing organization links
     for org in publication.get_organizations():
-        pubfrac, created = OrgPubFraction.objects.get_or_create(
+        pubfrac, created = PubFrac.objects.get_or_create(
             publication=publication, organization=org
         )
-    formset = OrgPubFractionsFormSet(
+    formset = PubFracsFormSet(
         request.POST or None, queryset=publication.pubfractions.all()
     )
     if formset.is_valid():
@@ -1405,7 +1405,7 @@ def preallocate_orgpubfractions_from_affiliations(request, doi_label):
     publication = get_object_or_404(Publication, doi_label=doi_label)
     nr_authors = publication.authors.all().count()
     # Reset all existing pubfracs to zero
-    OrgPubFraction.objects.filter(publication=publication).update(fraction=0)
+    PubFrac.objects.filter(publication=publication).update(fraction=0)
     fraction = {}
     for org in publication.get_organizations():
         fraction[org.id] = 0
@@ -1414,7 +1414,7 @@ def preallocate_orgpubfractions_from_affiliations(request, doi_label):
         for aff in author.affiliations.all():
             fraction[aff.id] += 1.0 / (nr_authors * nr_affiliations)
     for org in publication.get_organizations():
-        OrgPubFraction.objects.filter(
+        PubFrac.objects.filter(
             publication=publication,
             organization=org,
         ).update(fraction=Decimal(fraction[org.id]))
diff --git a/scipost_django/organizations/models.py b/scipost_django/organizations/models.py
index 3fae1c849..6a4bdeefb 100644
--- a/scipost_django/organizations/models.py
+++ b/scipost_django/organizations/models.py
@@ -32,7 +32,8 @@ from scipost.fields import ChoiceArrayField
 from scipost.models import Contributor
 from affiliates.models import AffiliatePublication
 from colleges.models import Fellowship
-from journals.models import Journal, Publication, OrgPubFraction
+from finances.models import PubFrac
+from journals.models import Journal, Publication
 from profiles.models import Profile
 
 
@@ -323,10 +324,10 @@ class Organization(models.Model):
         """
         Return the organization's pubfraction for a publication.
         """
-        pfs = OrgPubFraction.objects.filter(publication__doi_label=doi_label)
+        pfs = PubFrac.objects.filter(publication__doi_label=doi_label)
         try:
             return pfs.get(organization=self).fraction
-        except OrgPubFraction.DoesNotExist:
+        except PubFrac.DoesNotExist:
             children_ids = [k["id"] for k in list(self.children.all().values("id"))]
             children_contribs = pfs.filter(organization__id__in=children_ids).aggregate(
                 Sum("fraction")
@@ -349,7 +350,7 @@ class Organization(models.Model):
             publication.publication_date.year
         )
         try:
-            pf = OrgPubFraction.objects.get(
+            pf = PubFrac.objects.get(
                 publication=publication,
                 organization=self,
             )
@@ -359,12 +360,12 @@ class Organization(models.Model):
                 "expenditure": int(pf.fraction * unitcost),
                 "message": "",
             }
-        except OrgPubFraction.DoesNotExist:
+        except PubFrac.DoesNotExist:
             pass
         children_ids = [k["id"] for k in list(self.children.all().values("id"))]
         children_contrib_ids = set(
             c
-            for c in OrgPubFraction.objects.filter(
+            for c in PubFrac.objects.filter(
                 publication=publication,
                 organization__id__in=children_ids,
             ).values_list("organization__id", flat=True)
@@ -386,7 +387,7 @@ class Organization(models.Model):
         """
         Returns the sum of pubfractions for the given year.
         """
-        fractions = OrgPubFraction.objects.filter(
+        fractions = PubFrac.objects.filter(
             organization=self, publication__publication_date__year=year
         )
         return {
diff --git a/scipost_django/petitions/migrations/0010_alter_petitionsignatory_organization_and_more.py b/scipost_django/petitions/migrations/0010_alter_petitionsignatory_organization_and_more.py
new file mode 100644
index 000000000..58f0255cc
--- /dev/null
+++ b/scipost_django/petitions/migrations/0010_alter_petitionsignatory_organization_and_more.py
@@ -0,0 +1,43 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("organizations", "0021_enable_unaccent"),
+        ("scipost", "0040_auto_20210310_2026"),
+        ("petitions", "0009_auto_20210310_2026"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="petitionsignatory",
+            name="organization",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                to="organizations.organization",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="petitionsignatory",
+            name="petition",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="petitions.petition"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="petitionsignatory",
+            name="signatory",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="scipost.contributor",
+            ),
+        ),
+    ]
diff --git a/scipost_django/proceedings/migrations/0011_alter_proceedings_fellowships.py b/scipost_django/proceedings/migrations/0011_alter_proceedings_fellowships.py
new file mode 100644
index 000000000..ad9fa90bc
--- /dev/null
+++ b/scipost_django/proceedings/migrations/0011_alter_proceedings_fellowships.py
@@ -0,0 +1,19 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("colleges", "0047_fellowshipnominationvotinground_type"),
+        ("proceedings", "0010_add_proceedings_preface"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="proceedings",
+            name="fellowships",
+            field=models.ManyToManyField(blank=True, to="colleges.fellowship"),
+        ),
+    ]
diff --git a/scipost_django/profiles/migrations/0039_alter_profileemail_profile.py b/scipost_django/profiles/migrations/0039_alter_profileemail_profile.py
new file mode 100644
index 000000000..6ff0cfb8f
--- /dev/null
+++ b/scipost_django/profiles/migrations/0039_alter_profileemail_profile.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("profiles", "0038_auto_20240220_1604"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="profileemail",
+            name="profile",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="profiles.profile"
+            ),
+        ),
+    ]
diff --git a/scipost_django/scipost/migrations/0041_alter_remark_contributor_alter_remark_recommendation_and_more.py b/scipost_django/scipost/migrations/0041_alter_remark_contributor_alter_remark_recommendation_and_more.py
new file mode 100644
index 000000000..240b03342
--- /dev/null
+++ b/scipost_django/scipost/migrations/0041_alter_remark_contributor_alter_remark_recommendation_and_more.py
@@ -0,0 +1,51 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("submissions", "0147_auto_20240220_1404"),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ("scipost", "0040_auto_20210310_2026"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="remark",
+            name="contributor",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="scipost.contributor"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="remark",
+            name="recommendation",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="submissions.eicrecommendation",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="remark",
+            name="submission",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="submissions.submission",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="totpdevice",
+            name="user",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
+            ),
+        ),
+    ]
diff --git a/scipost_django/submissions/migrations/0148_alter_editorialassignment_submission_and_more.py b/scipost_django/submissions/migrations/0148_alter_editorialassignment_submission_and_more.py
new file mode 100644
index 000000000..73901ca39
--- /dev/null
+++ b/scipost_django/submissions/migrations/0148_alter_editorialassignment_submission_and_more.py
@@ -0,0 +1,49 @@
+# Generated by Django 4.2.10 on 2024-03-14 17:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        (
+            "scipost",
+            "0041_alter_remark_contributor_alter_remark_recommendation_and_more",
+        ),
+        ("submissions", "0147_auto_20240220_1404"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="editorialassignment",
+            name="submission",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="submissions.submission"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="editorialassignment",
+            name="to",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="scipost.contributor"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="editorialcommunication",
+            name="referee",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="scipost.contributor",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="editorialcommunication",
+            name="submission",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="submissions.submission"
+            ),
+        ),
+    ]
-- 
GitLab