Newer
Older
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from django.db import models
from django.forms import ValidationError
from organizations.models import Organization
from profiles.models import Profile
from scipost.models import Contributor
from .managers import FunderQuerySet
class Funder(models.Model):
"""
A Funder instance is an organization present in the Fundref registry.
Funding info metadata, which is deposited with our normal metadata deposits
to Crossref (via Grants or generic Funders), is linked back to funders
through Crossref's Crossmark service.
name = models.CharField(max_length=256)
acronym = models.CharField(max_length=32, blank=True)
identifier = models.CharField(max_length=200, unique=True)
organization = models.ForeignKey(
"organizations.Organization", on_delete=models.CASCADE, blank=True, null=True
)
objects = FunderQuerySet.as_manager()
ordering = ["name", "acronym"]
def __str__(self):
result += " (%s)" % self.acronym
"""Return the Funder detail page."""
return reverse("funders:funder_publications", args=(self.id,))
"""Return all Publication objects linked to this Funder."""
Q(funders_generic=self) | Q(grants__funder=self)
).distinct()
class Grant(models.Model):
"""An instance of a grant, award or other funding.
In a Publication's metadata, all grants are listed
in the Crossmark part of the metadata.
"""
funder = models.ForeignKey("funders.Funder", on_delete=models.CASCADE)
number = models.CharField(max_length=64)
recipient_name = models.CharField(max_length=64, blank=True)
recipient = models.ForeignKey(
"scipost.Contributor", blank=True, null=True, on_delete=models.CASCADE
)
further_details = models.CharField(max_length=256, blank=True)
default_related_name = "grants"
ordering = ["funder", "recipient", "recipient_name", "number"]
unique_together = ("funder", "number")
def __str__(self):
grantstring = "%s, grant number %s" % (str(self.funder), self.number)
grantstring += " (%s)" % str(self.recipient)
elif self.recipient_name:
grantstring += " (%s)" % self.recipient_name
if self.further_details:
grantstring += " [%s]" % self.further_details
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
class IndividualBudget(models.Model):
"""
Generic structure of a budget from an Organization given to a single individual.
The funding source of individual subsidies.
"""
required_css_class = "required-asterisk"
description = models.TextField(blank=True)
organization = models.ForeignKey["Organization"](
"organizations.Organization", on_delete=models.CASCADE, blank=True, null=True
)
holder = models.ForeignKey["Profile"](
"profiles.Profile", on_delete=models.CASCADE, blank=True, null=True
)
budget_number = models.CharField(max_length=64, blank=True, null=True)
fundref_id = models.CharField(max_length=64, blank=True, null=True)
class Meta:
default_related_name = "individual_budgets"
ordering = ["organization", "holder"]
constraints = [
models.UniqueConstraint(
fields=["organization", "budget_number"],
name="unique_organization_budget_number",
violation_error_message="This organization already has a budget with this number.",
),
models.CheckConstraint(
check=~models.Q(organization=None, holder=None),
name="organization_or_holder_must_be_set",
violation_error_message="Either an organization or a holder must be set for the budget.",
),
]
@property
def name(self):
if self.budget_number:
return f"Budget {self.budget_number}"
return "Unnamed budget"
def __str__(self):
str_repr = f"{self.name} from {self.organization}"
if self.holder:
str_repr += f" to {self.holder}"
return str_repr