Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
joemull committed Dec 4, 2024
1 parent 358c7c0 commit d314d51
Show file tree
Hide file tree
Showing 51 changed files with 1,194 additions and 64 deletions.
39 changes: 37 additions & 2 deletions src/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,11 @@ class AccessRequestAdmin(admin.ModelAdmin):

class OrganizationAdmin(admin.ModelAdmin):
list_display = ('pk', 'ror', '_ror_display', '_custom_label',
'_locations', 'ror_status')
'website', '_locations', 'ror_status')
list_display_links = ('pk', 'ror')
list_filter = ('ror_status', 'locations__country')
search_fields = ('pk', 'ror_display__value', 'custom_label__value', 'labels__value',
'aliases__value', 'acronyms__value')
'aliases__value', 'acronyms__value', 'website', 'ror')
raw_id_fields = ('locations', )

def _ror_display(self, obj):
Expand Down Expand Up @@ -442,6 +442,40 @@ class LocationAdmin(admin.ModelAdmin):
'geonames_id')


class AffiliationAdmin(admin.ModelAdmin):
list_display = ('pk', '_person', 'organization', 'title', 'department', 'start', 'end')
list_display_links = ('pk', '_person')
list_filter = ('start', 'end', 'organization__locations__country')
search_fields = (
'pk',
'title',
'department',
'organization__ror_display_for',
'organization__custom_label_for',
'organization__label_for',
'organization__alias_for',
'organization__acronym_for'
'account__first_name',
'account__last_name',
'account__email',
'frozen_author__first_name',
'frozen_author__last_name',
'frozen_author__frozen_email',
'preprint_author__account__first_name',
'preprint_author__account__last_name',
'preprint_author__account__email',
)
raw_id_fields = ('account', 'frozen_author',
'preprint_author', 'organization')

def _person(self, obj):
if obj:
return obj.account or obj.frozen_author or obj.preprint_author
else:
return ''



admin_list = [
(models.AccountRole, AccountRoleAdmin),
(models.Account, AccountAdmin),
Expand Down Expand Up @@ -474,6 +508,7 @@ class LocationAdmin(admin.ModelAdmin):
(models.Organization, OrganizationAdmin),
(models.OrganizationName, OrganizationNameAdmin),
(models.Location, LocationAdmin),
(models.Affiliation, AffiliationAdmin),
]

[admin.site.register(*t) for t in admin_list]
1 change: 1 addition & 0 deletions src/core/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
AccessRequestForm,
AccountRoleForm,
AdminUserForm,
AffiliationForm,
ArticleMetaImageForm,
CBVFacetForm,
ConfirmableForm,
Expand Down
15 changes: 15 additions & 0 deletions src/core/forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,3 +940,18 @@ class AccountRoleForm(forms.ModelForm):
class Meta:
model = models.AccountRole
fields = '__all__'


class AffiliationForm(forms.ModelForm):

class Meta:
model = models.Affiliation
fields = '__all__'
widgets = {
'account': forms.HiddenInput,
'frozen_author': forms.HiddenInput,
'preprint_author': forms.HiddenInput,
'organization': forms.HiddenInput,
'start': HTMLDateInput,
'end': HTMLDateInput,
}
32 changes: 32 additions & 0 deletions src/core/include_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,38 @@
re_path(r'^manager/user/(?P<user_id>\d+)/edit/$', core_views.user_edit, name='core_user_edit'),
re_path(r'^manager/user/(?P<user_id>\d+)/history/$', core_views.user_history, name='core_user_history'),

## Affiliations
re_path(
r'^manager/user/(?P<user_id>\d+)/organization/search/$',
core_views.OrganizationListView.as_view(),
name='organization_search'
),
re_path(
r'^manager/user/(?P<user_id>\d+)/organization_name/create/$',
core_views.OrganizationNameCreateView.as_view(),
name='organization_name_create'
),
re_path(
r'^manager/user/(?P<user_id>\d+)/organization_name/(?P<organization_name_id>\d+)/update/$',
core_views.OrganizationNameUpdateView.as_view(),
name='organization_name_update'
),
re_path(
r'^manager/user/(?P<user_id>\d+)/organization/(?P<organization_id>\d+)/affiliation/create/$',
core_views.AffiliationCreateView.as_view(),
name='affiliation_create'
),
re_path(
r'^manager/user/(?P<user_id>\d+)/affiliation/(?P<affiliation_id>\d+)/update/$',
core_views.AffiliationUpdateView.as_view(),
name='affiliation_update'
),
re_path(
r'^manager/user/(?P<user_id>\d+)/affiliation/(?P<affiliation_id>\d+)/delete/$',
core_views.AffiliationDeleteView.as_view(),
name='affiliation_delete'
),

# Templates
re_path(r'^manager/templates/$', core_views.email_templates, name='core_email_templates'),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
class Migration(migrations.Migration):

dependencies = [
('submission', '0080_remove_frozenauthor_country_and_more'),
('repository', '0044_remove_preprintauthor_affiliation_and_more'),
('core', '0096_update_review_ack_email'),
('submission', '0080_remove_frozenauthor_country_and_more'),
('core', '0099_alter_accountrole_options'),
]

operations = [
Expand All @@ -32,6 +32,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ror', models.URLField(blank=True, help_text='Research Organization Registry identifier (URL)', validators=[core.models.validate_ror], verbose_name='ROR')),
('ror_status', models.CharField(blank=True, choices=[('active', 'Active'), ('inactive', 'Inactive'), ('withdrawn', 'Withdrawn'), ('unknown', 'Unknown')], default='unknown', max_length=10)),
('website', models.CharField(blank=True, max_length=500)),
('locations', models.ManyToManyField(blank=True, null=True, to='core.location')),
],
),
Expand Down Expand Up @@ -78,4 +79,8 @@ class Migration(migrations.Migration):
'ordering': ['-pk'],
},
),
migrations.AddConstraint(
model_name='organization',
constraint=models.UniqueConstraint(condition=models.Q(('ror__exact', ''), _negated=True), fields=('ror',), name='filled_unique'),
),
]
65 changes: 55 additions & 10 deletions src/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,10 @@ def initials(self):
def affiliation(self, obj=False, date=None):
return Affiliation.get_primary(account=self, obj=obj, date=date)

@property
def affiliations(self):
return Affiliation.objects.filter(account=self).order_by('-is_primary')

@property
def institution(self):
affil = self.affiliation(obj=True)
Expand Down Expand Up @@ -1975,7 +1979,6 @@ def validate_ror(url):
raise ValidationError(f'{ror} is not a valid ROR identifier')



class Organization(models.Model):

class RORStatus(models.TextChoices):
Expand All @@ -1996,12 +1999,32 @@ class RORStatus(models.TextChoices):
choices=RORStatus.choices,
default=RORStatus.UNKNOWN,
)
website = models.CharField(
blank=True,
max_length=500,
)
locations = models.ManyToManyField(
'Location',
blank=True,
null=True,
)

class Meta:
constraints = [
models.UniqueConstraint(
fields=['ror'],
condition=~models.Q(ror__exact=''),
name='filled_unique',
)
]

def __str__(self):
elements = [
str(self.name) if self.name else '',
str(self.location) if self.location else '',
]
return ', '.join([element for element in elements if element])

@property
def name(self):
"""
Expand All @@ -2018,20 +2041,33 @@ def name(self):
except Organization.custom_label.RelatedObjectDoesNotExist:
return self.labels.first()

def __str__(self):
elements = [
str(self.name) if self.name else '',
str(self.location) if self.location else '',
]
return ', '.join([element for element in elements if element])

@property
def location(self):
"""
Return the first location.
"""
return self.locations.first() if self.locations else None

@property
def names(self):
"""
All names.
"""
return OrganizationName.objects.filter(
models.Q(ror_display_for=self) |
models.Q(custom_label_for=self) |
models.Q(label_for=self) |
models.Q(alias_for=self) |
models.Q(acronym_for=self),
)

@property
def also_known_as(self):
"""
All names excluding the ROR display name.
"""
return self.names.exclude(ror_display_for=self)

@classmethod
def naive_get_or_create(
cls,
Expand Down Expand Up @@ -2094,9 +2130,13 @@ def create_from_ror_record(cls, record):
organization, created = cls.objects.get_or_create(
ror=record.get('id', ''),
)
if record.get('status'):
organization.ror_status = record.get('status')
organization.ror_status = record.get('status', cls.RORStatus.UNKNOWN)
for link in record.get('links', []):
if link.get('type') == 'website':
organization.website = link.get('value', '')
break
organization.save()

for name in record.get('names'):
kwargs = {}
kwargs['value'] = name.get('value', '')
Expand All @@ -2111,6 +2151,7 @@ def create_from_ror_record(cls, record):
if 'acronym' in name.get('types'):
kwargs['acronym_for'] = organization
OrganizationName.objects.get_or_create(**kwargs)

for location in record.get('locations'):
details = location.get('geonames_details', {})
country, created = Country.objects.get_or_create(
Expand Down Expand Up @@ -2198,14 +2239,18 @@ class Affiliation(models.Model):
)
is_primary = models.BooleanField(
default=False,
help_text="Each account can have one primary affiliation",
)
start = models.DateField(
blank=True,
null=True,
verbose_name="Start date",
)
end = models.DateField(
blank=True,
null=True,
verbose_name="End date",
help_text="Leave empty for a current affiliation",
)

class Meta:
Expand Down
Loading

0 comments on commit d314d51

Please sign in to comment.