From 3386c528e8ddd09f6e5049d88631b51364bd4114 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sat, 5 Sep 2020 19:18:54 +0200
Subject: [PATCH] Rework ontology models, populate instances from
 scipost.constants

---
 colleges/admin.py                             |   5 +-
 colleges/models.py                            | 127 ------------------
 ...905_1539.py => 0006_auto_20200905_1904.py} |   6 +-
 .../migrations/0007_Branch_Field_Specialty.py |  51 +++++++
 ontology/models/academic_field.py             |   4 +-
 ontology/models/specialty.py                  |   4 +-
 6 files changed, 60 insertions(+), 137 deletions(-)
 delete mode 100644 colleges/models.py
 rename ontology/migrations/{0006_auto_20200905_1539.py => 0006_auto_20200905_1904.py} (92%)
 create mode 100644 ontology/migrations/0007_Branch_Field_Specialty.py

diff --git a/colleges/admin.py b/colleges/admin.py
index 0e280aa24..0e75922d4 100644
--- a/colleges/admin.py
+++ b/colleges/admin.py
@@ -4,7 +4,10 @@ __license__ = "AGPL v3"
 
 from django.contrib import admin
 
-from .models import Fellowship, PotentialFellowship, PotentialFellowshipEvent
+from .models import College, Fellowship, PotentialFellowship, PotentialFellowshipEvent
+
+
+admin.site.register(College)
 
 
 def fellowhip_is_active(fellowship):
diff --git a/colleges/models.py b/colleges/models.py
deleted file mode 100644
index f61517b51..000000000
--- a/colleges/models.py
+++ /dev/null
@@ -1,127 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-import datetime
-
-from django.db import models
-from django.urls import reverse
-from django.utils import timezone
-
-from .constants import POTENTIAL_FELLOWSHIP_STATUSES,\
-    POTENTIAL_FELLOWSHIP_IDENTIFIED, POTENTIAL_FELLOWSHIP_EVENTS
-from .managers import FellowQuerySet, PotentialFellowshipQuerySet
-
-from scipost.behaviors import TimeStampedModel
-from scipost.models import get_sentinel_user
-
-
-class Fellowship(TimeStampedModel):
-    """A Fellowship gives access to the Submission Pool to Contributors.
-
-    Editorial College Fellowship connects the Editorial College and Contributors,
-    possibly with a limiting start/until date and/or a Proceedings event.
-
-    The date range will effectively be used while determining 'the pool' for a specific
-    Submission, so it has a direct effect on the submission date.
-    """
-
-    contributor = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE,
-                                    related_name='fellowships')
-    start_date = models.DateField(null=True, blank=True)
-    until_date = models.DateField(null=True, blank=True)
-
-    guest = models.BooleanField('Guest Fellowship', default=False)
-
-    objects = FellowQuerySet.as_manager()
-
-    class Meta:
-        ordering = ['contributor__user__last_name']
-        unique_together = ('contributor', 'start_date', 'until_date')
-
-    def __str__(self):
-        _str = self.contributor.__str__()
-        if self.guest:
-            _str += ' (guest fellowship)'
-        return _str
-
-    def get_absolute_url(self):
-        """Return the admin fellowship page."""
-        return reverse('colleges:fellowship_detail', kwargs={'pk': self.id})
-
-    def sibling_fellowships(self):
-        """Return all Fellowships that are directly related to the Fellow of this Fellowship."""
-        return self.contributor.fellowships.all()
-
-    def is_active(self):
-        """Check if the instance is within start and until date."""
-        today = datetime.date.today()
-        if not self.start_date:
-            if not self.until_date:
-                return True
-            return today <= self.until_date
-        elif not self.until_date:
-            return today >= self.start_date
-        return today >= self.start_date and today <= self.until_date
-
-
-class PotentialFellowship(models.Model):
-    """
-    A PotentialFellowship is defined when a researcher has been identified by
-    Admin or EdAdmin as a potential member of an Editorial College,
-    or when a current Advisory Board member or Fellow nominates the person.
-
-    It is linked to Profile as ForeignKey and not as OneToOne, since the same
-    person can eventually be approached on different occasions.
-
-    Using Profile allows to treat both registered Contributors
-    and non-registered people equally well.
-    """
-
-    profile = models.ForeignKey('profiles.Profile', on_delete=models.CASCADE)
-    status = models.CharField(max_length=32, choices=POTENTIAL_FELLOWSHIP_STATUSES,
-                              default=POTENTIAL_FELLOWSHIP_IDENTIFIED)
-    in_agreement = models.ManyToManyField(
-        'scipost.Contributor',
-        related_name='in_agreement_with_election', blank=True)
-    in_abstain = models.ManyToManyField(
-        'scipost.Contributor',
-        related_name='in_abstain_with_election', blank=True)
-    in_disagreement = models.ManyToManyField(
-        'scipost.Contributor',
-        related_name='in_disagreement_with_election', blank=True)
-    voting_deadline = models.DateTimeField('voting deadline', default=timezone.now)
-    elected = models.NullBooleanField()
-
-    objects = PotentialFellowshipQuerySet.as_manager()
-
-    class Meta:
-        ordering = ['profile__last_name']
-
-    def __str__(self):
-        return '%s, %s' % (self.profile.__str__(), self.get_status_display())
-
-    def latest_event_details(self):
-        event = self.potentialfellowshipevent_set.order_by('-noted_on').first()
-        if not event:
-            return 'No event recorded'
-        return '%s [%s]' % (event.get_event_display(), event.noted_on.strftime('%Y-%m-%d'))
-
-
-class PotentialFellowshipEvent(models.Model):
-    """Any event directly related to a PotentialFellowship instance registered as plain text."""
-
-    potfel = models.ForeignKey('colleges.PotentialFellowship', on_delete=models.CASCADE)
-    event = models.CharField(max_length=32, choices=POTENTIAL_FELLOWSHIP_EVENTS)
-    comments = models.TextField(blank=True)
-
-    noted_on = models.DateTimeField(auto_now_add=True)
-    noted_by = models.ForeignKey('scipost.Contributor',
-                                 on_delete=models.SET(get_sentinel_user),
-                                 blank=True, null=True)
-
-    def __str__(self):
-        return '%s, %s %s: %s' % (self.potfel.profile.last_name,
-                                  self.potfel.profile.get_title_display(),
-                                  self.potfel.profile.first_name,
-                                  self.get_event_display())
diff --git a/ontology/migrations/0006_auto_20200905_1539.py b/ontology/migrations/0006_auto_20200905_1904.py
similarity index 92%
rename from ontology/migrations/0006_auto_20200905_1539.py
rename to ontology/migrations/0006_auto_20200905_1904.py
index 9bdd0a630..13b44e282 100644
--- a/ontology/migrations/0006_auto_20200905_1539.py
+++ b/ontology/migrations/0006_auto_20200905_1904.py
@@ -1,4 +1,4 @@
-# Generated by Django 2.2.11 on 2020-09-05 13:39
+# Generated by Django 2.2.11 on 2020-09-05 17:04
 
 from django.db import migrations, models
 import django.db.models.deletion
@@ -17,7 +17,7 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('name', models.CharField(max_length=128)),
                 ('slug', models.SlugField(allow_unicode=True, unique=True)),
-                ('order', models.PositiveSmallIntegerField(unique=True)),
+                ('order', models.PositiveSmallIntegerField()),
             ],
             options={
                 'ordering': ['branch', 'order'],
@@ -42,7 +42,7 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('name', models.CharField(max_length=128)),
                 ('slug', models.SlugField(allow_unicode=True, unique=True)),
-                ('order', models.PositiveSmallIntegerField(unique=True)),
+                ('order', models.PositiveSmallIntegerField()),
                 ('acad_field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='specialties', to='ontology.AcademicField')),
             ],
             options={
diff --git a/ontology/migrations/0007_Branch_Field_Specialty.py b/ontology/migrations/0007_Branch_Field_Specialty.py
new file mode 100644
index 000000000..540d95e25
--- /dev/null
+++ b/ontology/migrations/0007_Branch_Field_Specialty.py
@@ -0,0 +1,51 @@
+# Generated by Django 2.2.11 on 2020-09-05 14:07
+
+from django.db import migrations
+from django.utils.text import slugify
+
+from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS
+
+
+def populate(apps, schema_editor):
+    Branch = apps.get_model('ontology', 'Branch')
+    AcademicField = apps.get_model('ontology', 'AcademicField')
+    Specialty = apps.get_model('ontology', 'Specialty')
+
+    for d in SCIPOST_DISCIPLINES:
+        slug = slugify(d[0], allow_unicode=True)
+        order = Branch.objects.count() + 1
+        branch, created = Branch.objects.get_or_create(
+            name=d[0],
+            slug=slug,
+            order=order
+        )
+        for f in d[1]:
+            f_order = AcademicField.objects.filter(branch=branch).count() + 1
+            acad_field, created = AcademicField.objects.get_or_create(
+                branch=branch,
+                name=f[1],
+                slug=f[0],
+                order=f_order
+            )
+            for sa in SCIPOST_SUBJECT_AREAS:
+                if sa[0] == f[1]:
+                    for code, spec in sa[1]:
+                        slug = slugify(code.replace(':', '-'))
+                        s_order = Specialty.objects.filter(acad_field=acad_field).count() + 1
+                        specialty, created = Specialty.objects.get_or_create(
+                            acad_field=acad_field,
+                            name=spec,
+                            slug=slug,
+                            order=s_order
+                        )
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ontology', '0006_auto_20200905_1904'),
+    ]
+
+    operations = [
+        migrations.RunPython(populate, reverse_code=migrations.RunPython.noop),
+    ]
diff --git a/ontology/models/academic_field.py b/ontology/models/academic_field.py
index b372d59e4..a21196c3d 100644
--- a/ontology/models/academic_field.py
+++ b/ontology/models/academic_field.py
@@ -25,9 +25,7 @@ class AcademicField(models.Model):
         allow_unicode=True
     )
 
-    order = models.PositiveSmallIntegerField(
-        unique=True
-    )
+    order = models.PositiveSmallIntegerField()
 
     class Meta:
         constraints = [
diff --git a/ontology/models/specialty.py b/ontology/models/specialty.py
index 865cc195b..1c554e64e 100644
--- a/ontology/models/specialty.py
+++ b/ontology/models/specialty.py
@@ -25,9 +25,7 @@ class Specialty(models.Model):
         allow_unicode=True
     )
 
-    order = models.PositiveSmallIntegerField(
-        unique=True
-    )
+    order = models.PositiveSmallIntegerField()
 
     class Meta:
         constraints = [
-- 
GitLab