diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py index fd795df86f7fd03c84d119945edb454318955ff7..6a0dc463232752ef6cf68e9fbdb66e528b3f32a1 100644 --- a/SciPost_v1/settings/base.py +++ b/SciPost_v1/settings/base.py @@ -110,7 +110,9 @@ INSTALLED_APPS = ( 'proceedings', 'production', 'profiles', + # TODO: partners to be deprecated in favour of sponsors 'partners', + 'sponsors', 'preprints', 'funders', 'stats', diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py index a8c09ab1b766c4a5dc1257e25b12c8fddf700166..4658eec2690829d7b719e8d4c270c4d0a687d809 100644 --- a/SciPost_v1/urls.py +++ b/SciPost_v1/urls.py @@ -54,7 +54,9 @@ urlpatterns = [ url(r'^proceedings/', include('proceedings.urls', namespace="proceedings")), url(r'^production/', include('production.urls', namespace="production")), url(r'^profiles/', include('profiles.urls', namespace="profiles")), + # TODO: partners to be deprecated in favour of sponsors url(r'^partners/', include('partners.urls', namespace="partners")), + url(r'^sponsors/', include('sponsors.urls', namespace="sponsors")), url(r'^stats/', include('stats.urls', namespace="stats")), # Keep temporarily for historical reasons url(r'^supporting_partners/', include('partners.urls', namespace="_partners")), diff --git a/finances/migrations/0007_auto_20181011_2146.py b/finances/migrations/0007_auto_20181011_2146.py new file mode 100644 index 0000000000000000000000000000000000000000..b00f74e426537193ab85dbbac365a016e1a3504c --- /dev/null +++ b/finances/migrations/0007_auto_20181011_2146.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-10-11 19:46 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('finances', '0006_auto_20181008_1629'), + ] + + operations = [ + migrations.AlterModelOptions( + name='subsidy', + options={'ordering': ['-date'], 'verbose_name_plural': 'subsidies'}, + ), + ] diff --git a/finances/models.py b/finances/models.py index ecfa0ffca08410d9d28010a4ab6d95c2b58c926e..f7755ead7f9b6847b1d0850c04e09b4350f2c177 100644 --- a/finances/models.py +++ b/finances/models.py @@ -42,6 +42,7 @@ class Subsidy(models.Model): class Meta: verbose_name_plural = 'subsidies' + ordering = ['-date'] def __str__(self): return format_html('{}: €{} from {}, for {}', diff --git a/finances/templates/finances/finances.html b/finances/templates/finances/finances.html index 1a6698429d4c84ffe5c018ce71810009b4b510fb..91673c89d9ff3284dc164dd88c6ade30dca249cf 100644 --- a/finances/templates/finances/finances.html +++ b/finances/templates/finances/finances.html @@ -1,5 +1,6 @@ {% extends 'finances/base.html' %} +{% load staticfiles %} {% load bootstrap %} {% block breadcrumb_items %} @@ -12,13 +13,31 @@ {% block content %} <div class="row"> <div class="col-12"> - <h3 class="highlight">Finances</h3> + <h2>Finances</h2> + + <h3 class="highlight">Sponsors</h3> + <p>Visit our <a href="{% url 'finances:sponsors' %}">Sponsors page</a> to view our list of sponsors and more information on our sponsorship scheme.</p> + + <h3 class="highlight">Subsidies</h3> <ul> <li><a href="{% url 'finances:subsidies' %}">View {% if perms.scipost.can_manage_subsidies %}(and manage) {% endif %}info on Subsidies obtained by SciPost</a></li> - {% if perms.scipost.can_view_timesheets %} + </ul> + + <h3 class="highlight" id="reports">Financial Reports</h3> + <ul> + <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2015.pdf' %}">Annual Report 2015</a></li> + <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2016.pdf' %}">Annual Report 2016</a></li> + <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2017.pdf' %}">Annual Report 2017</a></li> + </ul> + + {% if perms.scipost.can_view_timesheets %} + <h3 class="highlight">Timesheets</h3> + <ul> <li><a href="{% url 'finances:timesheets' %}">Manage Timesheets</a></li> - {% endif %} </ul> + {% endif %} + </div> </div> + {% endblock content %} diff --git a/finances/templates/finances/subsidy_list.html b/finances/templates/finances/subsidy_list.html index 286716e4bc34b3b26142c166c5efe4c8f2b10cae..6fcbb6e749c6b56226cbf08ebe262029c2ffc6db 100644 --- a/finances/templates/finances/subsidy_list.html +++ b/finances/templates/finances/subsidy_list.html @@ -36,14 +36,35 @@ $(document).ready(function($) { <div class="row"> <div class="col-12"> - <h4>Subsidies obtained:</h4> <table class="table table-hover mb-5"> <thead class="thead-default"> <tr> <th>From Organization</th> <th>Type</th> - <th>Amount</th> - <th>Date</th> + <th>Amount + {% if request.GET.ordering != 'asc' %} + <a href="?order_by=amount&ordering=asc"><i class="fa fa-sort-asc"></i></a> + {% else %} + <a href="{% url 'finances:subsidies' %}"><i class="fa fa-sort-asc"></i></a> + {% endif %} + {% if request.GET.ordering != 'desc' %} + <a href="?order_by=amount&ordering=desc"><i class="fa fa-sort-desc"></i></a> + {% else %} + <a href="{% url 'finances:subsidies' %}"><i class="fa fa-sort-desc"></i></a> + {% endif %} + </th> + <th>Date + {% if request.GET.ordering != 'asc' %} + <a href="?order_by=date&ordering=asc"><i class="fa fa-sort-asc"></i></a> + {% else %} + <a href="{% url 'finances:subsidies' %}"><i class="fa fa-sort-asc"></i></a> + {% endif %} + {% if request.GET.ordering != 'desc' %} + <a href="?order_by=date&ordering=desc"><i class="fa fa-sort-desc"></i></a> + {% else %} + <a href="{% url 'finances:subsidies' %}"><i class="fa fa-sort-desc"></i></a> + {% endif %} + </th> </tr> </thead> <tbody> diff --git a/finances/views.py b/finances/views.py index 0344eb2295bcdfa7b53f34d4b98242f84d57523b..73d12841f05cc2e65a7e4b39ea6f13bf28d313ca 100644 --- a/finances/views.py +++ b/finances/views.py @@ -58,6 +58,18 @@ class SubsidyDeleteView(PermissionsMixin, DeleteView): class SubsidyListView(ListView): model = Subsidy + def get_queryset(self): + qs = super().get_queryset() + order_by = self.request.GET.get('order_by') + ordering = self.request.GET.get('ordering') + if order_by == 'amount': + qs = qs.order_by('amount') + elif order_by == 'date': + qs = qs.order_by('date') + if ordering == 'desc': + qs = qs.reverse() + return qs + class SubsidyDetailView(DetailView): model = Subsidy diff --git a/organizations/managers.py b/organizations/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..84ccfc18926313740847825c8a5697c4a2877974 --- /dev/null +++ b/organizations/managers.py @@ -0,0 +1,13 @@ +__copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +import datetime + +from django.db import models + + +class OrganizationQuerySet(models.QuerySet): + + def current_sponsors(self): + return self.filter(subsidy__date_until__gte=datetime.date.today()) diff --git a/organizations/models.py b/organizations/models.py index d6c211f232a2933462e5d1672f45a05f13de1979..efca90455dcb05833ac17a3d437db5868893682b 100644 --- a/organizations/models.py +++ b/organizations/models.py @@ -13,6 +13,7 @@ from django.urls import reverse from django_countries.fields import CountryField from .constants import ORGANIZATION_TYPES, ORGANIZATION_STATUSES, ORGSTATUS_ACTIVE +from .managers import OrganizationQuerySet from scipost.models import Contributor from journals.models import Publication, OrgPubFraction, UnregisteredAuthor @@ -63,6 +64,8 @@ class Organization(models.Model): blank=True, null=True, help_text='NB: nr_associated_publications is a calculated field. Do not modify.') + objects = OrganizationQuerySet.as_manager() + class Meta: ordering = ['country', 'name'] @@ -105,6 +108,17 @@ class Organization(models.Model): self.cf_nr_associated_publications = self.count_publications() self.save() + def pubfraction_for_publication(self, doi_label): + """ + Return the organization's pubfraction for this publication, or the string 'Not defined'. + """ + try: + return OrgPubFraction.objects.get( + organization=self, + publication__doi_label=doi_label).fraction + except: + return 'Not yet defined' + def pubfractions_in_year(self, year): """ Returns the sum of pubfractions for the given year. diff --git a/organizations/templates/organizations/_organization_card.html b/organizations/templates/organizations/_organization_card.html index 0c97c90e43796024053463920dd31cbd12fef336..ae66514629aa3616e254b024f48e427a9cd37177 100644 --- a/organizations/templates/organizations/_organization_card.html +++ b/organizations/templates/organizations/_organization_card.html @@ -60,6 +60,9 @@ $(document).ready(function($) { <a href="{{ publication.get_absolute_url }}">{{ publication.title }}</a> <br>by {{ publication.author_list }}, <br>{{ publication.citation }} + {% if is_scipost_admin %} + <br><span class="text-muted small">Pubfraction: {{ org|pubfraction_for_publication:publication }}</span> + {% endif %} </li> {% endif %} {% endfor %} diff --git a/organizations/templates/organizations/organization_list.html b/organizations/templates/organizations/organization_list.html index 90645d7127c31c9c15c4a574da0bde61bacd8f48..0077f41174301ba2fa161ec1206a7d98701782e3 100644 --- a/organizations/templates/organizations/organization_list.html +++ b/organizations/templates/organizations/organization_list.html @@ -48,7 +48,7 @@ $(document).ready(function($) { <div class="row"> <div class="col-5"> - <p>Organizations are linked through being in a publication's author affiliations, grant-giving agencies or explicit support acknowledgements.</p> + <p>Organizations are linked through appearing in a publication's author affiliations, grant-giving agencies or explicit support acknowledgements.</p> <p>For each Organization, the NAP (number of associated publications) is given (you can order in decreasing/increasing NAP using the header arrows).</p> </div> <div class="col-1"></div> @@ -73,8 +73,16 @@ $(document).ready(function($) { <th><a href="?order_by=country">Country</a></th> <th><a href="?order_by=name">Name</a> <small>[acronym]</small></th> <th>NAP <i class="fa fa-info-circle" data-toggle="tooltip" data-html="true" title="" data-original-title="Number of associated publications<br/>For details, click on the Organization and consult the Associated Publications tab"></i> - {% if request.GET.ordering != 'asc' %}</a> <a href="?order_by=nap&ordering=asc"><i class="fa fa-sort-asc"></i></a>{% endif %} -{% if request.GET.ordering != 'desc' %}<a href="?order_by=nap&ordering=desc"><i class="fa fa-sort-desc"></i></a>{% endif %} + {% if request.GET.ordering != 'asc' %} + <a href="?order_by=nap&ordering=asc"><i class="fa fa-sort-asc"></i></a> + {% else %} + <a href="{% url 'organizations:organizations' %}"><i class="fa fa-sort-asc"></i></a> + {% endif %} + {% if request.GET.ordering != 'desc' %} + <a href="?order_by=nap&ordering=desc"><i class="fa fa-sort-desc"></i></a> + {% else %} + <a href="{% url 'organizations:organizations' %}"><i class="fa fa-sort-desc"></i></a> + {% endif %} </th> <th>SciPost sponsor?</th> </tr> diff --git a/organizations/templatetags/organizations_extras.py b/organizations/templatetags/organizations_extras.py index 80a183688a112db69594742ba6b3e35d52817ccf..513ec33f3a1a4491fb71960d24662a693196a684 100644 --- a/organizations/templatetags/organizations_extras.py +++ b/organizations/templatetags/organizations_extras.py @@ -7,6 +7,10 @@ from django import template register = template.Library() +@register.filter(name='pubfraction_for_publication') +def pubfraction_for_publication(org, publication): + return org.pubfraction_for_publication(publication.doi_label) + @register.filter(name='pubfractions_in_year') def pubfractions_in_year(org, year): return org.pubfractions_in_year(int(year)) diff --git a/scipost/templates/scipost/about.html b/scipost/templates/scipost/about.html index 217c189e52dd07996857fa291b0263925b3f1620..e2e31cb5842f72d149f3b15fcfa89eade818429e 100644 --- a/scipost/templates/scipost/about.html +++ b/scipost/templates/scipost/about.html @@ -48,7 +48,7 @@ <div class="row"> <p>As an organization, and for all its Journals, SciPost follows the <a href="https://jscaux.org/blog/post/2018/05/05/genuine-open-access/">Genuine Open Access Principles:</a></p> -<table class="table table-bordered table-responsive"> +<table class="table table-bordered table-responsive" id="GOA"> <tr> <td>[CO]</td> <td style="width: 30%;"><strong>Community Ownership</strong> </td> diff --git a/scipost/templates/scipost/foundation.html b/scipost/templates/scipost/foundation.html index d541dee897dfa5f9fb7b39264c77ca27a7186349..3c460109760ddab690e13652b04846b8ee01bb3e 100644 --- a/scipost/templates/scipost/foundation.html +++ b/scipost/templates/scipost/foundation.html @@ -101,9 +101,7 @@ <div class="card-body"> <h2 class="highlight">Financial Reports</h2> <ul> - <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2015.pdf' %}">Annual Report 2015</a></li> - <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2016.pdf' %}">Annual Report 2016</a></li> - <li><a href="{% static 'scipost/info/AnnualReports/AnnualReport_2017.pdf' %}">Annual Report 2017</a></li> + <li>See all on our <a href="{% url 'finances:finances' %}#reports">Finances page</a></li> </ul> </div> </div> diff --git a/sponsors/__init__.py b/sponsors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sponsors/admin.py b/sponsors/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e --- /dev/null +++ b/sponsors/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/sponsors/migrations/__init__.py b/sponsors/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sponsors/models.py b/sponsors/models.py new file mode 100644 index 0000000000000000000000000000000000000000..71a836239075aa6e6e4ecb700e9c42c95c022d91 --- /dev/null +++ b/sponsors/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/sponsors/static/sponsors/SciPost_Sponsorship_Agreement.pdf b/sponsors/static/sponsors/SciPost_Sponsorship_Agreement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6ef3a5e0c5711743b5992033f3c9b1ddb9a2d80b Binary files /dev/null and b/sponsors/static/sponsors/SciPost_Sponsorship_Agreement.pdf differ diff --git a/sponsors/templates/sponsors/base.html b/sponsors/templates/sponsors/base.html new file mode 100644 index 0000000000000000000000000000000000000000..8e7667e051ced72d6abd899987dd6d3158ba03ad --- /dev/null +++ b/sponsors/templates/sponsors/base.html @@ -0,0 +1,15 @@ +{% extends 'scipost/base.html' %} + +{% block body_class %}{{ block.super }} sponsors{% endblock %} + +{% block breadcrumb %} + <div class="container-outside header"> + <div class="container"> + <nav class="breadcrumb hidden-sm-down"> + {% block breadcrumb_items %} + <a href="{% url 'sponsors:sponsors' %}" class="breadcrumb-item">Sponsors</a> + {% endblock %} + </nav> + </div> + </div> +{% endblock %} diff --git a/sponsors/templates/sponsors/sponsor_petition_email.html b/sponsors/templates/sponsors/sponsor_petition_email.html new file mode 100644 index 0000000000000000000000000000000000000000..52e3d7bec89840887d161d05aa74382979253a87 --- /dev/null +++ b/sponsors/templates/sponsors/sponsor_petition_email.html @@ -0,0 +1,18 @@ +[PLEASE FILL IN THE TO FIELD ABOVE (keeping admin@scipost.org in cc)]%0D%0A +%0D%0A +Dear ...%0D%0A +%0D%0A +[PLEASE WRITE A PERSONALIZED MESSAGE]%0D%0A +%0D%0A +Here under, you will find basic information about SciPost and how you can support it.%0D%0A +%0D%0A +Sincerely,%0D%0A +[YOUR SIGNATURE]%0D%0A +%0D%0A +%0D%0A +%0D%0A +SciPost (https://scipost.org) is a top-quality next-generation Genuine Open Access publication portal managed by professional scientists. Its principles, ideals and implementation can be found at https://scipost.org/about and https://scipost.org/FAQ.%0D%0A +%0D%0A +SciPost operates on an entirely not-for-profit basis, and charges neither subscription fees nor article processing charges; instead, its activities are financed through a cost-slashing consortial model.%0D%0A +%0D%0A +Institutions and organizations that benefit from SciPost’s activities (listed on https://scipost.org/organizations) are cordially invited to become Sponsors. This enables SciPost to perform all of its publication-related activities, maintain its online portal and implement its long-term development plan. Details of the sponsorship scheme and how to join can be found at https://scipost.org/sponsors or by emailing admin@scipost.org.%0D%0A diff --git a/sponsors/templates/sponsors/sponsors.html b/sponsors/templates/sponsors/sponsors.html new file mode 100644 index 0000000000000000000000000000000000000000..6e5b94fd1c23d348b1bc4b1719cc1f616a38b94d --- /dev/null +++ b/sponsors/templates/sponsors/sponsors.html @@ -0,0 +1,115 @@ +{% extends 'sponsors/base.html' %} + +{% block pagetitle %}: Sponsors{% endblock pagetitle %} + +{% load staticfiles %} + +{% block breadcrumb_items %} +{{ block.super }} +{% endblock %} + +{% block content %} + +<div class="row"> + <div class="col"> + <h1 class="highlight">SciPost Sponsors</h1> + </div> +</div> + +<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> + </h4> + <br/> + <p> + Is your organization benefitting from SciPost's activities (check our <a href="{% url 'organizations:organizations' %}">organizations page</a>), and are they not in our list of Sponsors below? Then consider helping SciPost: + </p> + <ul> + <li> + <p> + <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=admin@scipost.org">template</a>. + </p> + </li> + <li> + <p> + <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:admin@scipost.org?subject=Sponsors enquiry">admin@scipost.org</a> to enquire about further details or initiate your sponsorship. + </p> + </li> + </ul> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <div class="card-deck"> + <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> + <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> + <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> + </div> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h3>In a nutshell, for the business savvy: support our model to reduce your costs</h3> + <p>We are able to run a fully sustainable infrastructure at an estimated cost of under €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"> + <div class="col-12"> + <h1 class="highlight">Our current Sponsors</h1> + + <div class="card-columns"> + {% for sponsor in current_sponsors %} + <div class="card"> + <img class="card-img-top {{ sponsor.css_class }} p-2" src="{% if sponsor.logo %}{{ sponsor.logo.url }}{% endif %}" alt="{{ sponsor.name }} logo"> + <div class="card-body bg-light"> + <h4 class="card-title"> + {% if sponsor.name_original %}{{ sponsor.name_original }}{% else %}{{ sponsor.name }}{% endif %}</h4> + {% if sponsor.name_original %} + <p class="card-text">({{ sponsor.name }})</p> + {% endif %} + <img src="{{ sponsor.country.flag }}" alt="{{ sponsor.country }} flag"/> <span class="text-muted"><small>[{{ sponsor.country }}]</small></span> {{ sponsor.get_country_display }} + </div> + </div> + {% endfor %} + </div> + + </div> +</div> + + + + +{% endblock content %} diff --git a/sponsors/urls.py b/sponsors/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..a9ca651a6d10a99e5f9a7aee527a35353cec877d --- /dev/null +++ b/sponsors/urls.py @@ -0,0 +1,17 @@ +__copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.conf.urls import url +from django.views.generic import TemplateView + +from . import views + +urlpatterns = [ + + url( + r'^$', + views.sponsors, + name="sponsors" + ), +] diff --git a/sponsors/views.py b/sponsors/views.py new file mode 100644 index 0000000000000000000000000000000000000000..d381acbe9bef4a50c9f3a23aa8cf8bbbb4a7fa00 --- /dev/null +++ b/sponsors/views.py @@ -0,0 +1,15 @@ +__copyright__ = "Copyright 2016-2018, Stichting SciPost (SciPost Foundation)" +__license__ = "AGPL v3" + + +from django.shortcuts import render + +from organizations.models import Organization + + +def sponsors(request): + current_sponsors = Organization.objects.current_sponsors() + context = { + 'current_sponsors': current_sponsors, + } + return render(request, 'sponsors/sponsors.html', context)