Newer
Older
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from django.core.validators import validate_unicode_slug
from django.db import models
from django.urls import reverse
def cost_default_value():
return {"default": 400}
class AffiliateJournal(models.Model):
"""
A Journal which piggybacks on SciPost's services.
"""
publisher = models.ForeignKey(
"affiliates.AffiliatePublisher",
name = models.CharField(max_length=256)
short_name = models.CharField(max_length=256, default="")
slug = models.SlugField(
max_length=128,
validators=[
validate_unicode_slug,
],
unique=True,
homepage = models.URLField(max_length=256, blank=True)
# Cost per publication information
cost_info = models.JSONField(default=cost_default_value)
ordering = ["publisher", "name"]
permissions = (("manage_journal_content", "Manage Journal content"),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("affiliates:journal_detail", kwargs={"slug": self.slug})
def cost_per_publication(self, year):
try:
return int(self.cost_info[str(year)])
except KeyError:
return int(self.cost_info["default"])
@property
def balance_info(self):
return self.get_balance_info()
def get_balance_info(self, organization=None):
"""
For each publishing year, provide financial info.
"""
publications = self.publications.all()
subsidies = self.affiliatejournalyearsubsidy_set.all()
if organization:
publications = publications.filter(
pubfractions__organization=organization
)
subsidies = subsidies.filter(organization=organization)
if not publications:
return {}
maxyear = publications.first().publication_date.year
minyear = publications.last().publication_date.year
years = range(maxyear, minyear - 1, -1)
balance_info = {}
for year in years:
nr_publications = publications.filter(
publication_date__year=year).count()
subsidy_tally = subsidies.filter(
year=year
).aggregate(models.Sum("amount"))["amount__sum"]
if not subsidy_tally:
subsidy_tally = 0
balance_info[year] = {
"nr_publications": nr_publications,
"unit_cost": self.cost_per_publication(year),
"expenditure": nr_publications * self.cost_per_publication(year),
"subsidies": subsidy_tally,
"balance": (subsidy_tally -
nr_publications * self.cost_per_publication(year)),
}
if organization:
from ..models import AffiliatePubFraction
sum_pubfracs = AffiliatePubFraction.objects.filter(
publication__journal=self,
organization=organization,
publication__publication_date__year=year,
).aggregate(models.Sum("fraction"))["fraction__sum"]
if not sum_pubfracs:
sum_pubfracs = 0
balance_info[year]["pubfractions"] = sum_pubfracs
balance_info[year][
"expenditure"
] = int(sum_pubfracs * self.cost_per_publication(year))
balance_info[year][
"balance"
] = int(subsidy_tally - sum_pubfracs * self.cost_per_publication(year))
return balance_info