From 62ca0ea1ffc5a1c0232bf7d22595b3dc85e16945 Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Sun, 18 Nov 2018 18:05:13 +0100 Subject: [PATCH] Solve bug by making UnregisteredAuthor FK to Profile instead of 1To1 --- .../migrations/0053_auto_20181118_1758.py | 21 ++++++++++++ journals/models.py | 13 +------- profiles/forms.py | 3 +- profiles/views.py | 33 +++++++++++++++---- scipost/forms.py | 2 +- 5 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 journals/migrations/0053_auto_20181118_1758.py diff --git a/journals/migrations/0053_auto_20181118_1758.py b/journals/migrations/0053_auto_20181118_1758.py new file mode 100644 index 000000000..f2a41d010 --- /dev/null +++ b/journals/migrations/0053_auto_20181118_1758.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-11-18 16:58 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0052_journal_refereeing_period'), + ] + + operations = [ + migrations.AlterField( + model_name='unregisteredauthor', + name='profile', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='profiles.Profile'), + ), + ] diff --git a/journals/models.py b/journals/models.py index 8cab95489..f9d4e0629 100644 --- a/journals/models.py +++ b/journals/models.py @@ -36,23 +36,12 @@ from scipost.fields import ChoiceArrayField class UnregisteredAuthor(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) - profile = models.OneToOneField( + profile = models.ForeignKey( 'profiles.Profile', on_delete=models.SET_NULL, null=True, blank=True) def __str__(self): return self.last_name + ', ' + self.first_name - def merge(self, unregistered_author): - """ - Merge another UnregisteredAuthor into this object. - """ - if unregistered_author == self: # Do nothing. - return - - self.profile = unregistered_author.profile - self.save() - unregistered_author.delete() - class PublicationAuthorsTable(models.Model): publication = models.ForeignKey('journals.Publication', related_name='authors') diff --git a/profiles/forms.py b/profiles/forms.py index 38ba6550b..0ec066920 100644 --- a/profiles/forms.py +++ b/profiles/forms.py @@ -129,8 +129,7 @@ class ProfileMergeForm(forms.Form): profile.topics.add(*profile_old.topics.all()) - if hasattr(profile_old, 'unregisteredauthor') and profile_old.unregisteredauthor: - profile.unregisteredauthor.merge(profile_old.unregisteredauthor) + UnregisteredAuthor.objects.filter(profile=profile_old).update(profile=profile) # Merge email profile_old.emails.exclude( diff --git a/profiles/views.py b/profiles/views.py index 24ea72e9d..4ece47f98 100644 --- a/profiles/views.py +++ b/profiles/views.py @@ -132,18 +132,39 @@ class ProfileCreateView(PermissionsMixin, CreateView): def profile_match(request, profile_id, from_type, pk): """ Links an existing Profile to one of existing - Contributor, UnregisteredAuthor, RefereeInvitation, RegistrationInvitation. + Contributor, UnregisteredAuthor, RefereeInvitation or RegistrationInvitation. + + Profile relates to Contributor as OneToOne. + Matching is thus only allowed if there are no duplicate objects for these elements. + + For matching the Profile to a Contributor, the following preconditions are defined: + - the Profile has no association to another Contributor + - the Contributor has no association to another Profile + If these are not met, no action is taken. """ profile = get_object_or_404(Profile, pk=profile_id) nr_rows = 0 if from_type == 'contributor': + if hasattr(profile, 'contributor') and profile.contributor.id != pk: + messages.error(request, + 'Error: cannot math this Profile to this Contributor, ' + 'since this Profile already has a different Contributor.\n' + 'Please merge the duplicate Contributors first.') + return redirect(reverse('profiles:profiles')) + contributor = get_object_or_404(Contributor, pk=pk) + if contributor.profile and contributor.profile.id != profile.id: + messages.error(request, + 'Error: cannot match this Profile to this Contributor, ' + 'since this Contributor already has a different Profile.\n' + 'Please merge the duplicate Profiles first.') + return redirect(reverse('profiles:profiles')) + # Preconditions are met, match: nr_rows = Contributor.objects.filter(pk=pk).update(profile=profile) # Give priority to the email coming from Contributor - if nr_rows == 1: - profile.emails.update(primary=False) - email, __ = ProfileEmail.objects.get_or_create( - profile=profile, email=get_object_or_404(Contributor, pk=pk).user.email) - profile.emails.filter(id=email.id).update(primary=True, still_valid=True) + profile.emails.update(primary=False) + email, __ = ProfileEmail.objects.get_or_create( + profile=profile, email=contributor.user.email) + profile.emails.filter(id=email.id).update(primary=True, still_valid=True) elif from_type == 'unregisteredauthor': nr_rows = UnregisteredAuthor.objects.filter(pk=pk).update(profile=profile) elif from_type == 'refereeinvitation': diff --git a/scipost/forms.py b/scipost/forms.py index e4a3f09c1..9a2a80710 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -532,7 +532,7 @@ class ContributorMergeForm(forms.Form): publications = Publication.objects.filter(authors_registered__in=[contrib_from,]).all() for publication in publications: publication.authors_registered.remove(contrib_from) - publication.authors_registared.add(contrib_into) + publication.authors_registered.add(contrib_into) publications = Publication.objects.filter(authors_claims__in=[contrib_from,]).all() for publication in publications: publication.authors_claims.remove(contrib_from) -- GitLab