diff --git a/journals/migrations/0053_auto_20181118_1758.py b/journals/migrations/0053_auto_20181118_1758.py new file mode 100644 index 0000000000000000000000000000000000000000..f2a41d010006dd96dcdc203e13e60f4abc5de665 --- /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 8cab95489805a758d49b682f57d459ef30f19b85..f9d4e06292402763872dbade328c1fe0a2c87655 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 38ba6550bc2a777c565103b6ce951bceb4b6140a..0ec066920a5839c5e207eb1800df5f6cb4c4dfc5 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 24ea72e9dd20a34a4e7866fa51a924fb11ce4ffe..4ece47f98d620478e2d9520997534d56f85ba973 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 e4a3f09c1888a824d5e389c574d0848ead8b7f23..9a2a80710923123258c62f745965f75b37ce107e 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)