diff --git a/journals/admin.py b/journals/admin.py index a128f6021b845ab370c588f7dd4f71597c0af4ed..6b5f4cecdf14c7289cd748ca007979ae20f083c9 100644 --- a/journals/admin.py +++ b/journals/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin, messages from django import forms from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, \ - Deposit, CLOCKSSmetadata, DOAJDeposit + Deposit, DOAJDeposit from scipost.models import Contributor from submissions.models import Submission @@ -82,6 +82,4 @@ class DepositAdmin(admin.ModelAdmin): admin.site.register(Deposit, DepositAdmin) -admin.site.register(CLOCKSSmetadata) - admin.site.register(DOAJDeposit) diff --git a/journals/migrations/0035_auto_20170714_0609.py b/journals/migrations/0035_auto_20170714_0609.py new file mode 100644 index 0000000000000000000000000000000000000000..860612627d85724c62217f0d7b446223631caeac --- /dev/null +++ b/journals/migrations/0035_auto_20170714_0609.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-14 04:09 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0034_publication_cc_license'), + ] + + operations = [ + migrations.RemoveField( + model_name='clockssmetadata', + name='publication', + ), + migrations.DeleteModel( + name='CLOCKSSmetadata', + ), + ] diff --git a/journals/models.py b/journals/models.py index fe5dee82967a4c6e4b8d7d14bffccc6c3245d4f8..722fdccdf2790733789b411c760645a8a462d4e4 100644 --- a/journals/models.py +++ b/journals/models.py @@ -241,20 +241,6 @@ class Deposit(models.Model): ' for ' + self.publication.doi_label) -class CLOCKSSmetadata(models.Model): - """ - For the CLOCKSS archive, JATS formatted XML is produced. - """ - publication = models.ForeignKey(Publication, on_delete=models.CASCADE) - metadata_xml_file_CLOCKSS = models.FileField(blank=True, null=True, max_length=512) - - class Meta: - verbose_name = 'CLOCKSS metadata' - - def __str__(self): - return ('CLOCKSS metadata for ' + self.publication.doi_label) - - class DOAJDeposit(models.Model): """ For the Directory of Open Access Journals. diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html index cff6224e24894f7cc100e138777a4a6548faf709..b9ca627d8401da8c0d6225fff22d306c32f39045 100644 --- a/journals/templates/journals/manage_metadata.html +++ b/journals/templates/journals/manage_metadata.html @@ -35,7 +35,6 @@ event: "focusin" <th>Publication date</th> <th>Latest metadata update</th> <th>Latest successful Crossref deposit</th> - <th>CLOCKSS</th> <th>DOAJ</th> </tr> </thead> @@ -53,7 +52,6 @@ event: "focusin" <td>No info available</td> {% endif %} <td>{{ publication|latest_successful_crossref_deposit }}</td> - <td>{% if publication.clockssmetadata_set.all.exists %}File exists{% else %}File does not exist{% endif %}</td> <td>{{ publication|latest_successful_DOAJ_deposit }}</td> </tr> <tr id="collapse{{ publication.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ publication.id }}" style="background-color: #fff;"> @@ -91,7 +89,6 @@ event: "focusin" <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">(re)create metadata</a></li> <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li> <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li> - <li><a href="{% url 'journals:produce_CLOCKSS_metadata_file' doi_label=publication.doi_label %}">Produce CLOCKSS metadata file</a></li> <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li> <li><a href="{% url 'journals:metadata_DOAJ_deposit' doi_label=publication.doi_label %}">Deposit the metadata to DOAJ</a></li> </ul> diff --git a/journals/templates/journals/publication_metadata_jats.xml b/journals/templates/journals/publication_metadata_jats.xml deleted file mode 100644 index 6f97e3fb7fc8eb3b2ef9163e82333ab1b2f95add..0000000000000000000000000000000000000000 --- a/journals/templates/journals/publication_metadata_jats.xml +++ /dev/null @@ -1,22 +0,0 @@ -<article dtd-version="1.1d3"> -<front> -<journal-meta> -<publisher> -<publisher-name>SciPost</publisher-name> -</publisher> -<issn>{{ publication.in_issue.in_volume.in_journal.issn }}</issn> -</journal-meta> -<article-meta> -<title-group> -<article-title>{{ publication.title }}</article-title> -</title-group> -<article-id pub-id-type="doi">{{ publication.doi_string }}</article-id> -<volume>{{ publication.in_issue.in_volume.number }}</volume> -<issue>{{ publication.in_issue.number }}</issue> -<pub-date publication-format="epub" date-type="pub" iso-8601-date="{{ publication.publication_date|date:'Y-m-d' }}"> -<day>{{ publication.publication_date|date:'d' }}</day> -<month>{{ publication.publication_date|date:'m' }}</month> -<year>{{ publication.publication_date|date:'Y' }}</year> -</pub-date></article-meta> -</front> -</article> diff --git a/journals/urls/general.py b/journals/urls/general.py index eb5dbc91cb505466188ef1aae4e2a55de2472514..31e3cbec6b95190889e7cd457f5c5640f875341e 100644 --- a/journals/urls/general.py +++ b/journals/urls/general.py @@ -56,9 +56,6 @@ urlpatterns = [ url(r'^mark_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', journals_views.mark_deposit_success, name='mark_deposit_success'), - url(r'^produce_CLOCKSS_metadata_file/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.produce_CLOCKSS_metadata_file, - name='produce_CLOCKSS_metadata_file'), url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', journals_views.produce_metadata_DOAJ, name='produce_metadata_DOAJ'), diff --git a/journals/views.py b/journals/views.py index 6509c95d3d81a5f230dfe27da309d5603ccbe05b..ccf0be58c62bc682f8fa9186b64936750e4b1bf3 100644 --- a/journals/views.py +++ b/journals/views.py @@ -18,12 +18,11 @@ from django.http import HttpResponse from .exceptions import PaperNumberingError from .helpers import paper_nr_string -from .models import Journal, Issue, Publication, UnregisteredAuthor, DOAJDeposit +from .models import Journal, Issue, Publication, UnregisteredAuthor, Deposit, DOAJDeposit from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\ UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm from .utils import JournalUtils -from journals.models import Deposit, CLOCKSSmetadata from submissions.models import Submission from scipost.models import Contributor @@ -442,7 +441,7 @@ def create_metadata_xml(request, doi_label): if create_metadata_xml_form.is_valid(): publication.metadata_xml = create_metadata_xml_form.cleaned_data['metadata_xml'] publication.save() - return redirect(publication.get_absolute_url()) + return redirect(reverse('journals:manage_metadata')) # create a doi_batch_id salt = "" @@ -542,6 +541,7 @@ def create_metadata_xml(request, doi_label): '<publisher_item><item_number item_number_type="article_number">' + paper_nr_string(publication.paper_nr) + '</item_number></publisher_item>\n' + '<archive_locations><archive name="CLOCKSS"></archive></archive_locations>\n' '<doi_data>\n' '<doi>' + publication.doi_string + '</doi>\n' '<resource>https://scipost.org/' + publication.doi_string + '</resource>\n' @@ -659,33 +659,6 @@ def mark_deposit_success(request, deposit_id, success): return redirect(reverse('journals:manage_metadata')) -@permission_required('scipost.can_publish_accepted_submission', return_403=True) -def produce_CLOCKSS_metadata_file(request, doi_label): - publication = get_object_or_404(Publication, doi_label=doi_label) - context = Context({'publication': publication}) - xml = get_template('journals/publication_metadata_jats.xml').render(context) - content = ContentFile(xml) - timestamp = (publication.metadata_xml.partition( - '<timestamp>'))[2].partition('</timestamp>')[0] - path = (settings.MEDIA_ROOT + publication.in_issue.path + '/' - + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') - + '_CLOCKSS_' + timestamp + '.xml') - if os.path.isfile(path): - errormessage = 'The CLOCKSS metadata file for this metadata timestamp already exists' - return render(request, 'scipost/error.html', context={'errormessage': errormessage}) - clockssmeta = CLOCKSSmetadata(publication=publication) - clockssmeta.metadata_xml_file_CLOCKSS.save(path, content) - clockssmeta.save() - # Save a copy to the filename without timestamp - path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/' - + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') - + '_CLOCKSS.xml') - f = open(path1, 'w') - f.write(xml) - f.close() - return redirect(reverse('journals:manage_metadata')) - - @permission_required('scipost.can_publish_accepted_submission', return_403=True) def produce_metadata_DOAJ(request, doi_label): publication = get_object_or_404(Publication, doi_label=doi_label) diff --git a/mailing_lists/models.py b/mailing_lists/models.py index e9e3660f3b207f9989286f540aa3f5c6de96f680..dc636cf4c349331d62885a284e87ab25f39b0449 100644 --- a/mailing_lists/models.py +++ b/mailing_lists/models.py @@ -1,3 +1,5 @@ +import json + from django.db import models, transaction from django.contrib.auth.models import User from django.conf import settings @@ -97,7 +99,7 @@ class MailchimpList(TimeStampedModel): batch_data['operations'].append({ 'method': 'POST', 'path': add_member_path, - 'data': { + 'body': json.dumps({ 'status': status, 'status_if_new': status, 'email_address': user.email, @@ -105,10 +107,10 @@ class MailchimpList(TimeStampedModel): 'FNAME': user.first_name, 'LNAME': user.last_name, }, - } + }) }) # Make the subscribe call - client.batches.create(data=batch_data) + post_response = client.batches.create(data=batch_data) # No need to update Contributor field *yet*. MailChimp account is leading here. # Contributor.objects.filter(user__in=db_subscribers).update(accepts_SciPost_emails=True) @@ -116,7 +118,7 @@ class MailchimpList(TimeStampedModel): list_data = client.lists.get(list_id=self.mailchimp_list_id) self.subscriber_count = list_data['stats']['member_count'] self.save() - return (updated_contributors, len(db_subscribers),) + return (updated_contributors, len(db_subscribers), post_response) class MailchimpSubscription(TimeStampedModel): diff --git a/mailing_lists/templates/mailing_lists/mailchimplist_form.html b/mailing_lists/templates/mailing_lists/mailchimplist_form.html index 37347dc82164961bf6bdd427468983105174fda8..e0715f011020d5d2aa060853e6173ff62cc0f9ad 100644 --- a/mailing_lists/templates/mailing_lists/mailchimplist_form.html +++ b/mailing_lists/templates/mailing_lists/mailchimplist_form.html @@ -32,6 +32,15 @@ {{form|bootstrap}} <input type="submit" value="Update" class="btn btn-secondary" /> </form> + {% if request.GET.bulkid %} + <div class="mb-3 mt-5"> + <hr> + <h2>Synchronizing done</h2> + <p> + Response bulk ID: <code>{{request.GET.bulkid}}</code><br> + Check <a href="//us1.api.mailchimp.com/playground" target="_blank">MailChimp's Playground</a> to see the response status. + </div> + {% endif %} </div> </div> diff --git a/mailing_lists/views.py b/mailing_lists/views.py index a6952dc61e4661080127d4d588d091d3f0809ff3..3762228e50057a207ae2c60298e372fa68fdc542 100644 --- a/mailing_lists/views.py +++ b/mailing_lists/views.py @@ -48,7 +48,7 @@ def syncronize_members(request, list_id): """ _list = get_object_or_404(MailchimpList, mailchimp_list_id=list_id) form = MailchimpUpdateForm() - unsubscribed, subscribed = form.sync_members(_list) + unsubscribed, subscribed, response = form.sync_members(_list) # Let the user know text = '<h3>Syncronize members complete.</h3>' @@ -57,7 +57,7 @@ def syncronize_members(request, list_id): if subscribed: text += '<br>%i members have succesfully been subscribed.' % subscribed messages.success(request, text) - return redirect(_list.get_absolute_url()) + return redirect(_list.get_absolute_url() + '?bulkid=' + response.get('id')) class ListDetailView(MailchimpMixin, UpdateView): diff --git a/partners/constants.py b/partners/constants.py index e3f6224cd7e124253e16f7e7787731d6c72f0b24..a00f453a7dafe9df8dd6283377d5fffd55909b98 100644 --- a/partners/constants.py +++ b/partners/constants.py @@ -81,9 +81,9 @@ PARTNER_EVENTS = ( ('comment', 'Comment added'), ) - +CONTACT_GENERAL = 'gen' CONTACT_TYPES = ( - ('gen', 'General Contact'), + (CONTACT_GENERAL, 'General Contact'), ('tech', 'Technical Contact'), ('fin', 'Financial Contact'), ('leg', 'Legal Contact') @@ -91,12 +91,15 @@ CONTACT_TYPES = ( MEMBERSHIP_SUBMITTED = 'Submitted' +MEMBERSHIP_SIGNED = 'Signed' +MEMBERSHIP_HONOURED = 'Honoured' +MEMBERSHIP_COMPLETED = 'Completed' MEMBERSHIP_AGREEMENT_STATUS = ( (MEMBERSHIP_SUBMITTED, 'Request submitted by Partner'), ('Pending', 'Sent to Partner, response pending'), - ('Signed', 'Signed by Partner'), - ('Honoured', 'Honoured: payment of Partner received'), - ('Completed', 'Completed: agreement has been fulfilled'), + (MEMBERSHIP_SIGNED, 'Signed by Partner'), + (MEMBERSHIP_HONOURED, 'Honoured: payment of Partner received'), + (MEMBERSHIP_COMPLETED, 'Completed: agreement has been fulfilled'), ) MEMBERSHIP_DURATION = ( diff --git a/partners/forms.py b/partners/forms.py index 6454802bb98667250a90b45b6a7ff141ce98d0de..87322b2d67118443949252cdcdfd3d7e6c3d8faf 100644 --- a/partners/forms.py +++ b/partners/forms.py @@ -11,7 +11,7 @@ from django_countries.widgets import CountrySelectWidget from django_countries.fields import LazyTypedChoiceField from .constants import PARTNER_KINDS, PROSPECTIVE_PARTNER_PROCESSED, CONTACT_TYPES,\ - PARTNER_STATUS_UPDATE, REQUEST_PROCESSED, REQUEST_DECLINED + PARTNER_STATUS_UPDATE, REQUEST_PROCESSED, REQUEST_DECLINED, CONTACT_GENERAL from .models import Partner, ProspectivePartner, ProspectiveContact, ProspectivePartnerEvent,\ Institution, Contact, PartnerEvent, MembershipAgreement, ContactRequest,\ PartnersAttachment @@ -28,11 +28,13 @@ class MembershipAgreementForm(forms.ModelForm): 'status', 'date_requested', 'start_date', + 'end_date', 'duration', 'offered_yearly_contribution' ) widgets = { 'start_date': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}), + 'end_date': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}), 'date_requested': forms.TextInput(attrs={'placeholder': 'YYYY-MM-DD'}), } @@ -208,6 +210,10 @@ class ContactForm(forms.ModelForm): 'kind', ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['kind'].required = False + class NewContactForm(ContactForm): """ @@ -355,7 +361,9 @@ class PromoteToContactForm(forms.ModelForm): """ This form is used to create a new `partners.Contact` """ - kind = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, + promote = forms.BooleanField(label='Activate/Promote this contact', initial=True, + required=False) + kind = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, initial=[CONTACT_GENERAL], label='Contact types', choices=CONTACT_TYPES, required=False) class Meta: @@ -372,6 +380,9 @@ class PromoteToContactForm(forms.ModelForm): Check if email address is already used. """ email = self.cleaned_data['email'] + if not self.cleaned_data.get('promote', False): + # Don't promote the Contact + return email if User.objects.filter(Q(email=email) | Q(username=email)).exists(): self.add_error('email', 'This emailadres has already been used.') return email @@ -382,8 +393,11 @@ class PromoteToContactForm(forms.ModelForm): Promote ProspectiveContact's to Contact's related to a certain Partner. The status update after promotion is handled outside this method, in the Partner model. """ - # How to handle empty instances? + if not self.cleaned_data.get('promote', False): + # Don't promote the Contact + return + # How to handle empty instances? if self.errors: return forms.ValidationError # Is this a valid exception? @@ -391,7 +405,6 @@ class PromoteToContactForm(forms.ModelForm): contact_form = NewContactForm(self.cleaned_data, partner=partner) if contact_form.is_valid(): return contact_form.save(current_user=current_user) - r = contact_form.errors raise forms.ValidationError('NewContactForm invalid. Please contact Admin.') @@ -411,12 +424,22 @@ class PromoteToContactFormset(forms.BaseModelFormSet): """ contacts = [] for form in self.forms: - contacts.append(form.promote_contact(partner, current_user)) - partner.main_contact = contacts[0] + new_contact = form.promote_contact(partner, current_user) + if new_contact: + contacts.append(new_contact) + try: + partner.main_contact = contacts[0] + except IndexError: + # No contacts at all means no main-contact as well... + pass partner.save() return contacts +ContactModelFormset = forms.modelformset_factory(ProspectiveContact, PromoteToContactForm, + formset=PromoteToContactFormset, extra=0) + + class ProspectivePartnerForm(forms.ModelForm): """ This form is used to internally add a ProspectivePartner. diff --git a/partners/managers.py b/partners/managers.py index abd47528ec58a4c2cc8203cc742ab7710fbae32a..2b3e4b390a9ce49512f1a0dc01783ea7c582a968 100644 --- a/partners/managers.py +++ b/partners/managers.py @@ -1,4 +1,6 @@ from django.db import models +from django.db.models import F +from django.utils import timezone from .constants import MEMBERSHIP_SUBMITTED, PROSPECTIVE_PARTNER_PROCESSED, REQUEST_INITIATED @@ -30,6 +32,12 @@ class MembershipAgreementManager(models.Manager): def open_to_partner(self): return self.exclude(status=MEMBERSHIP_SUBMITTED) + def now_active(self): + return self.filter(start_date__lte=timezone.now().date(), + end_date__gte=timezone.now().date()) + # start_date = models.DateField() + # duration = models.DurationField(choices=MEMBERSHIP_DURATION) + class PartnersAttachmentManager(models.Manager): def my_attachments(self, current_user): diff --git a/partners/migrations/0027_membershipagreement_end_date.py b/partners/migrations/0027_membershipagreement_end_date.py new file mode 100644 index 0000000000000000000000000000000000000000..43aa365b6900fa00684bbd430f8b52ac85fcd7ea --- /dev/null +++ b/partners/migrations/0027_membershipagreement_end_date.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-19 19:12 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('partners', '0026_auto_20170627_1809'), + ] + + operations = [ + migrations.AddField( + model_name='membershipagreement', + name='end_date', + field=models.DateField(default=django.utils.timezone.now), + preserve_default=False, + ), + ] diff --git a/partners/models.py b/partners/models.py index 3a2451424bffc50c4b972cc5926cf78c6861b809..441d7f3d33b557f45c54ee436ddd1d9760a559cf 100644 --- a/partners/models.py +++ b/partners/models.py @@ -266,6 +266,7 @@ class MembershipAgreement(models.Model): status = models.CharField(max_length=16, choices=MEMBERSHIP_AGREEMENT_STATUS) date_requested = models.DateField() start_date = models.DateField() + end_date = models.DateField() duration = models.DurationField(choices=MEMBERSHIP_DURATION) offered_yearly_contribution = models.SmallIntegerField(default=0, help_text="Yearly contribution in euro's (€)") diff --git a/partners/templates/partners/supporting_partners.html b/partners/templates/partners/supporting_partners.html index 2c0d931cf4eda4a2eab1dba6112cfa39cdcdc7f4..92d8bcb60a2d8c2176d65473ca3e0dd2638a497b 100644 --- a/partners/templates/partners/supporting_partners.html +++ b/partners/templates/partners/supporting_partners.html @@ -117,6 +117,26 @@ </div> </div> +{% if current_agreements %} +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Partners</h1> + <ul class="list-unstyled mb-5"> + {% for agreement in current_agreements %} + <li class="media mb-2"> + <img class="d-flex mr-3" width="192" src="{% if agreement.partner.institution.logo %}{{agreement.partner.institution.logo.url}}{% endif %}" alt="Partner Logo"> + <div class="media-body"> + <p> + <strong>{{agreement.partner.institution.name}}</strong><br> + {{agreement.partner.institution.get_country_display}} + </p> + </div> + </li> + {% endfor %} + </ul> + </div> +</div> +{% endif %} {% if perms.scipost.can_manage_SPB %} {% if prospective_partners %} diff --git a/partners/views.py b/partners/views.py index 33d20a49fb83a44565825edb02b53836ec713bd3..04a4c5f1ef0615d1310fb3d420d3a764aad27fe6 100644 --- a/partners/views.py +++ b/partners/views.py @@ -16,8 +16,8 @@ from .models import Partner, ProspectivePartner, ProspectiveContact, ContactRequ PartnersAttachment from .forms import ProspectivePartnerForm, ProspectiveContactForm,\ EmailProspectivePartnerContactForm, PromoteToPartnerForm,\ - ProspectivePartnerEventForm, MembershipQueryForm, PromoteToContactForm,\ - PromoteToContactFormset, PartnerForm, ContactForm, ContactFormset,\ + ProspectivePartnerEventForm, MembershipQueryForm,\ + PartnerForm, ContactForm, ContactFormset, ContactModelFormset,\ NewContactForm, InstitutionForm, ActivationForm, PartnerEventForm,\ MembershipAgreementForm, RequestContactForm, RequestContactFormSet,\ ProcessRequestContactForm, PartnersAttachmentFormSet, PartnersAttachmentForm,\ @@ -26,7 +26,10 @@ from .utils import PartnerUtils def supporting_partners(request): - context = {} + current_agreements = MembershipAgreement.objects.now_active() + context = { + 'current_agreements': current_agreements + } if request.user.groups.filter(name='Editorial Administrators').exists(): # Show Agreements to Administrators only! prospective_agreements = MembershipAgreement.objects.submitted().order_by('date_requested') @@ -98,8 +101,6 @@ def promote_prospartner(request, prospartner_id): prospartner = get_object_or_404(ProspectivePartner.objects.not_yet_partner(), pk=prospartner_id) form = PromoteToPartnerForm(request.POST or None, instance=prospartner) - ContactModelFormset = modelformset_factory(ProspectiveContact, PromoteToContactForm, - formset=PromoteToContactFormset, extra=0) contact_formset = ContactModelFormset(request.POST or None, queryset=prospartner.prospective_contacts.all()) if form.is_valid() and contact_formset.is_valid(): diff --git a/scipost/templates/scipost/footer.html b/scipost/templates/scipost/footer.html index cf0e93dc29cf72679937cf6a27267644e1cd678a..d48aa8a3e5be17204832db5d715ac10013990f5f 100644 --- a/scipost/templates/scipost/footer.html +++ b/scipost/templates/scipost/footer.html @@ -5,7 +5,7 @@ <div class="col-md-4"> Copyright © <a href="{% url 'scipost:foundation' %}" target="_">SciPost Foundation</a>. <br/> - <a href="mailto:admin@scipost.org">Contact the administrators.</a> + <a href="mailto:admin@scipost.org">Contact the administrators</a> or <a href="mailto:techsupport@scipost.org">tech support</a>. <br/> <a href="{% url 'scipost:terms_and_conditions' %}">Terms and conditions.</a> </div> diff --git a/scipost/templates/scipost/index.html b/scipost/templates/scipost/index.html index d3df68ed45382791725240d323e7b52fdf503bc5..5fe4f0ff137e5b697b8ab8b94e6d94b59de0cbbf 100644 --- a/scipost/templates/scipost/index.html +++ b/scipost/templates/scipost/index.html @@ -56,6 +56,7 @@ <h3><a href="{% url 'scipost:call' %}">A call for openness</a></h3> <h3><a href="{% url 'scipost:quick_tour' %}">Quick Tour</a></h3> <h3><a href="{% url 'scipost:FAQ' %}">Frequently asked questions</a></h3> + <h3><a href="{% url 'partners:partners' %}">Supporting Partners</a></h3> <h3><a href="{% url 'scipost:about' %}">Read more</a></h3> <h4><em>In the press:</em></h4> <ul> diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html index c972b3ae8a9efe50aa22f9f66b5c7393f7e84162..3a60507fc15ee36906f8ca1cb1f85ae429a8e254 100644 --- a/scipost/templates/scipost/navbar.html +++ b/scipost/templates/scipost/navbar.html @@ -16,6 +16,9 @@ <li class="nav-item{% if '/theses/' in request.path %} active{% endif %}"> <a class="nav-link" href="{% url 'theses:theses' %}">Theses</a> </li> + <li class="nav-item{% if '/partners/' in request.path %} active{% endif %}"> + <a class="nav-link" href="{% url 'partners:partners' %}">Partners</a> + </li> {% if user.is_authenticated %} <li class="nav-item highlighted"> diff --git a/submissions/admin.py b/submissions/admin.py index dfc3dff7b8c223034d8d13ac0136463d1d54be6d..0e394cedfb8da410dfbcda6c3c72047380a6b39e 100644 --- a/submissions/admin.py +++ b/submissions/admin.py @@ -63,6 +63,9 @@ admin.site.register(EditorialAssignment, EditorialAssignmentAdmin) class RefereeInvitationAdminForm(forms.ModelForm): submission = forms.ModelChoiceField( queryset=Submission.objects.order_by('-arxiv_identifier_w_vn_nr')) + referee = forms.ModelChoiceField( + required=False, + queryset=Contributor.objects.order_by('user__last_name')) class Meta: model = RefereeInvitation diff --git a/submissions/views.py b/submissions/views.py index 071e117d82edd6af8e77a5be41630169f6ffc9ef..dbe926c6d43fff757dc1943d7400f2fe395de3c6 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -733,7 +733,9 @@ def accept_or_decline_ref_invitations(request): RefereeInvitations need to be either accepted or declined by the invited user using this view. The decision will be taken one invitation at a time. """ - invitation = RefereeInvitation.objects.filter(referee__user=request.user, accepted=None).first() + invitation = RefereeInvitation.objects.filter(referee__user=request.user, + accepted=None, + cancelled=False).first() if not invitation: messages.success(request, 'There are no Refereeing Invitations for you to consider.') return redirect(reverse('scipost:personal_page'))