SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit a93ca214 authored by George Katsikas's avatar George Katsikas :goat:
Browse files

refactor sponsors page with yearly coverage

parent bee6de5b
No related branches found
No related tags found
No related merge requests found
......@@ -5,8 +5,10 @@ __license__ = "AGPL v3"
import datetime
from django.db import models
from django.db.models import Q
from finances.constants import SUBSIDY_PROMISED, SUBSIDY_INVOICED, SUBSIDY_RECEIVED
from finances.models.subsidy import Subsidy
class OrganizationQuerySet(models.QuerySet):
......@@ -62,3 +64,48 @@ class OrganizationQuerySet(models.QuerySet):
.annotate(total=models.Sum("subsidy__amount"))
.order_by("-total")
)
def order_by_yearly_coverage(self, year_start=None, year_end=None):
"""
Order by average yearly coverage between year_start and year_end.
If either year_start or year_end is None, assume interminable coverage of that end.
"""
subsidy_filter = Q(organization=models.OuterRef("pk"))
# If year_start and year_end are both None, no filtering is needed.
# If year_start is None, filter such that date_until <= year_end.
# If year_end is None, filter such that year_start <= date_from.
# If both are specified, filter such that
# date_from <= year_start <= year_end <= date_until.
match (year_start, year_end):
case (None, None):
pass
case (None, _):
subsidy_filter &= Q(date_until__year__lte=year_end)
case (_, None):
subsidy_filter &= Q(date_from__year__gte=year_start)
case (_, _):
subsidy_filter &= Q(date_from__year__lte=year_start)
subsidy_filter &= Q(date_until__year__gte=year_end)
return (
self.annotate(
total_yearly_coverage=models.Subquery(
Subsidy.objects.obtained()
.filter(subsidy_filter)
.annotate(
yearly_coverage=models.F("amount")
/ (
1
+ models.F("date_until__year")
- models.F("date_from__year")
)
)
.values("organization")
.annotate(total=models.Sum("yearly_coverage"))
.values("total")
)
)
.order_by(models.F("total_yearly_coverage").desc(nulls_last=True))
.distinct()
)
......@@ -6,9 +6,9 @@
hx-push-url="true"
hx-target="body">
<div class="bg-white m-2 h-100 d-flex" style="min-height: 100px;">
<div class="bg-white m-2 h-100 d-flex">
<img class="m-auto p-4 {{ sponsor.css_class }}" style="max-height: 16rem; max-width: 100%; object-fit: contain"
<img class="m-auto p-4 w-100 {{ sponsor.css_class }}" style="max-height: 200px; object-fit: contain"
{% if sponsor.logo %} src="{{ sponsor.logo.url }}" {% else %} src="{% static 'organizations/no_logo.jpg' %}" {% endif %}
alt="{{ sponsor.name }} logo" />
</div>
......
......@@ -2,14 +2,17 @@
{% load render_bundle from webpack_loader %}
{% block meta_description %}{{ block.super }} Sponsors{% endblock meta_description %}
{% block pagetitle %}: Sponsors{% endblock pagetitle %}
{% block meta_description %}
{{ block.super }} Sponsors
{% endblock meta_description %}
{% block pagetitle %}
: Sponsors
{% endblock pagetitle %}
{% load static %}
{% block breadcrumb_items %}
{{ block.super }}
{% endblock %}
{% block breadcrumb_items %}{{ block.super }}{% endblock %}
{% block content %}
......@@ -22,16 +25,18 @@
<div class="row">
<div class="col-12">
<h4>
<strong>We cordially invite organizations worldwide to join our Sponsorship scheme, and make <a href="{% url 'scipost:about' %}#GOA">Genuine Open Access</a> a reality.</strong>
<strong>We cordially invite organizations worldwide to join our Sponsorship scheme, and make <a href="{% url 'scipost:about' %}#GOA">Genuine Open Access</a> a reality.</strong>
</h4>
<br/>
<br />
<p>
Is your organization benefitting from SciPost's activities (check our <a href="{% url 'organizations:organizations' %}">organizations page</a>), and does it not appear in our list of Sponsors below? Then consider helping SciPost:
<br/>
<strong>Are you a scientist?</strong><br/>
Please petition your local librarian/director/... to consider sponsoring us. You can use this email <a href="mailto:?subject=Petition to support SciPost&body={% autoescape on %}{% include 'sponsors/sponsor_petition_email.html' %}{% endautoescape %}&cc=sponsors@{{ request.get_host }}">template</a>.
<strong>Are you a librarian, funding agency representative or other potential supporter?</strong><br/>
Take a look at our <a href="{% static 'sponsors/SciPost_Sponsorship_Agreement.pdf' %}">Sponsorship Agreement</a> template, and contact us at <a href="mailto:sponsors@{{ request.get_host }}?subject=Sponsors enquiry">sponsors@{{ request.get_host }}</a> to enquire about further details or initiate your sponsorship.
Is your organization benefitting from SciPost's activities (check our <a href="{% url 'organizations:organizations' %}">organizations page</a>), and does it not appear in our list of Sponsors below? Then consider helping SciPost:
<br />
<strong>Are you a scientist?</strong>
<br />
Please petition your local librarian/director/... to consider sponsoring us. You can use this email <a href="mailto:?subject=Petition to support SciPost&body={% autoescape on %}{% include 'sponsors/sponsor_petition_email.html' %}{% endautoescape %}&cc=sponsors@{{ request.get_host }}">template</a>.
<strong>Are you a librarian, funding agency representative or other potential supporter?</strong>
<br />
Take a look at our <a href="{% static 'sponsors/SciPost_Sponsorship_Agreement.pdf' %}">Sponsorship Agreement</a> template, and contact us at <a href="mailto:sponsors@{{ request.get_host }}?subject=Sponsors enquiry">sponsors@{{ request.get_host }}</a> to enquire about further details or initiate your sponsorship.
</p>
</div>
</div>
......@@ -39,99 +44,106 @@
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3>Community service; no user fees</h3>
</div>
<div class="card-body">
<p>SciPost does not charge any subscription fees or article processing charges (APCs): all our operations are performed as a community service, with no user-facing charges;</p>
<p>Our initiative's scope is resolutely international: we do not impose any geographical or institutional restrictions on the delivery of our services;</p>
<p>SciPost is dedicated to serving the academic community, with no further competing interests.</p>
</div>
<div class="card-header">
<h3>Community service; no user fees</h3>
</div>
<div class="card-body">
<p>
SciPost does not charge any subscription fees or article processing charges (APCs): all our operations are performed as a community service, with no user-facing charges;
</p>
<p>
Our initiative's scope is resolutely international: we do not impose any geographical or institutional restrictions on the delivery of our services;
</p>
<p>SciPost is dedicated to serving the academic community, with no further competing interests.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3>Quality through Openness</h3>
</div>
<div class="card-body">
<p>Our sharp focus on openness through our <a href="/FAQ#pwr">peer-witnessed refereeing</a> procedure equips us with arguably the most stringent editorial quality control system available;</p>
<p>Our <a href="{% url 'scipost:about' %}#editorial_college_physics">Editorial College</a> is composed of a broad selection of top academics;</p>
<p>Our fully professional publishing services meet or surpass best practices in all respects. Our flagship journal SciPost Physics has been awarded the <a href="https://doaj.org">DOAJ</a> Seal.</p>
</div>
<div class="card-header">
<h3>Quality through Openness</h3>
</div>
<div class="card-body">
<p>
Our sharp focus on openness through our <a href="/FAQ#pwr">peer-witnessed refereeing</a> procedure equips us with arguably the most stringent editorial quality control system available;
</p>
<p>
Our <a href="{% url 'scipost:about' %}#editorial_college_physics">Editorial College</a> is composed of a broad selection of top academics;
</p>
<p>
Our fully professional publishing services meet or surpass best practices in all respects. Our flagship journal SciPost Physics has been awarded the <a href="https://doaj.org">DOAJ</a> Seal.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3>Community funded</h3>
</div>
<div class="card-body">
<p>Our operations are obviously not without cost, but our strictly not-for-profit setup, community-led workflow, streamlined infrastructure and no-frills administration mean that the average per-publication costs are much lower than those of competing services;</p>
<p>Our financing model relies on sponsorship from the organizations which benefit from our activities (see our <a href="{% url 'organizations:organizations' %}">organizations page</a>);</p>
<p>All sponsorship funds are pooled and exclusively used to run our infrastructure and services.</p>
</div>
<div class="card-header">
<h3>Community funded</h3>
</div>
<div class="card-body">
<p>
Our operations are obviously not without cost, but our strictly not-for-profit setup, community-led workflow, streamlined infrastructure and no-frills administration mean that the average per-publication costs are much lower than those of competing services;
</p>
<p>
Our financing model relies on sponsorship from the organizations which benefit from our activities (see our <a href="{% url 'organizations:organizations' %}">organizations page</a>);
</p>
<p>All sponsorship funds are pooled and exclusively used to run our infrastructure and services.</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<h3>We aim to establish a healthier <a href="{% url 'finances:business_model' %}" target="_blank">business model</a> for scientific publishing</h3>
<p>We are able to run a fully sustainable infrastructure at an estimated cost of under &euro;400 per publication, much below the current norm for APCs. The more scientists shift their publishing to SciPost, the fewer subscription/article processing charges you will have to pay as an organization. Your sponsorship will help us scale up and make our initiative sustainable.</p>
<h3>
We aim to establish a healthier <a href="{% url 'finances:business_model' %}" target="_blank">business model</a> for scientific publishing
</h3>
<p>
We are able to run a fully sustainable infrastructure at an estimated cost of under &euro;400 per publication, much below the current norm for APCs. The more scientists shift their publishing to SciPost, the fewer subscription/article processing charges you will have to pay as an organization. Your sponsorship will help us scale up and make our initiative sustainable.
</p>
</div>
</div>
<div class="row" hx-boost="true">
<div class="col-12">
<h1 class="highlight">Our current Sponsors</h1>
<h3 class="highlight">&euro;20k and above:</h3>
<div class="d-grid gap-3" style="grid-template-columns: repeat(3, minmax(0, 1fr));">
{% for sponsor in sponsors_20kplus %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
<h3 class="highlight mt-4">&euro;10k and above:</h3>
<div class="d-grid gap-3" style="grid-template-columns: repeat(3, minmax(0, 1fr));">
{% for sponsor in sponsors_10kplus %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
<h1 class="highlight">Our recent Sponsors</h1>
<h3 class="highlight mt-4">&euro;5k and above:</h3>
<div class="d-grid gap-3" style="grid-template-columns: repeat(3, minmax(0, 1fr));">
{% for sponsor in sponsors_5kplus %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
<h3 class="highlight mt-4">Our other current Sponsors:</h3>
<div class="d-grid gap-3" style="grid-template-columns: repeat(3, minmax(0, 1fr));">
{% for sponsor in current_sponsors %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
<hgroup class="p-2 highlight d-flex align-items-center justify-content-between">
<h3 class="m-0">Current Sponsors</h3>
</hgroup>
<div class="d-grid gap-3"
style="grid-template-columns: repeat(3, minmax(0, 1fr))">
{% for sponsor in current_sponsors %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
<h1 class="highlight">Our recent-past Sponsors</h1>
<hgroup class="p-2 highlight d-flex align-items-center justify-content-between">
<h3 class="m-0">
Last year's Sponsors:
</h3>
<span class="text-muted">
(excludes current sponsors)
</span>
<hgroup class="p-3 mt-4 highlight d-flex align-items-center justify-content-between">
<h3 class="m-0">Last year's Sponsors:</h3>
<span class="text-muted">(excludes current sponsors)</span>
</hgroup>
<div class="d-grid gap-3" style="grid-template-columns: repeat(3, minmax(0, 1fr));">
{% for sponsor in last_year_sponsors %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
<div class="d-grid gap-3"
style="grid-template-columns: repeat(3, minmax(0, 1fr))">
{% for sponsor in last_year_sponsors %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
<details class="mt-4">
<summary class="highlight list-triangle p-3">
<h1 class="m-0">Our past Sponsors</h1>
</summary>
<div class="d-grid gap-3"
style="grid-template-columns: repeat(3, minmax(0, 1fr))">
{% for sponsor in past_sponsors %}
{% include 'sponsors/_sponsor_card.html' with sponsor=sponsor %}
{% endfor %}
</div>
</details>
</div>
</div>
{% endblock content %}
......@@ -9,26 +9,28 @@ from organizations.models import Organization
def sponsors(request):
sponsors_20kplus = Organization.objects.with_subsidy_above_and_up_to(20000)
sponsors_10kplus = Organization.objects.with_subsidy_above_and_up_to(10000, 20000)
sponsors_5kplus = Organization.objects.with_subsidy_above_and_up_to(5000, 10000)
current_sponsors = (
Organization.objects.current_sponsors().with_subsidy_above_and_up_to(0, 5000)
)
year = datetime.date.today().year
current_sponsors = Organization.objects.current_sponsors()
last_year_sponsors = (
Organization.objects.all_sponsors()
.filter(
subsidy__date_until__year__lte=datetime.date.today().year - 1,
subsidy__date_until__gt=datetime.date.today()
- datetime.timedelta(days=365),
subsidy__date_from__year__lte=year - 1,
subsidy__date_until__year__gte=year - 1,
)
.exclude(pk__in=current_sponsors.values_list("pk", flat=True))
.exclude(id__in=current_sponsors.values_list("id", flat=True))
)
past_sponsors = (
Organization.objects.all_sponsors()
.exclude(id__in=current_sponsors.values_list("id", flat=True))
.exclude(id__in=last_year_sponsors.values_list("id", flat=True))
)
context = {
"sponsors_20kplus": sponsors_20kplus,
"sponsors_10kplus": sponsors_10kplus,
"sponsors_5kplus": sponsors_5kplus,
"current_sponsors": current_sponsors.order_by_total_amount_received(),
"last_year_sponsors": last_year_sponsors.order_by_total_amount_received(),
"current_sponsors": current_sponsors.order_by_yearly_coverage(year, year),
"last_year_sponsors": last_year_sponsors.order_by_yearly_coverage(
year - 1, year - 1
),
"past_sponsors": past_sponsors.order_by_yearly_coverage(None, year - 2),
}
return render(request, "sponsors/sponsors.html", context)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment