diff --git a/stats/templates/stats/statistics.html b/stats/templates/stats/statistics.html index ac74381c7a69bce30ad7e30fd6838de7c283205b..71f94769a02aa8aaae8750a1be94bd3aca8b6f99 100644 --- a/stats/templates/stats/statistics.html +++ b/stats/templates/stats/statistics.html @@ -46,13 +46,18 @@ <th>DOI label</th> {% if year %} <th>Year</th> - <th>Nr submissions</th> - <th>Nr distinct submissions</th> - {% endif %} + <th>Nr submissions<br/>(distinct)</th> + <th>Nr submissions<br/>(including resubmissions)</th> + <th>Nr assignment failed</th> + <th>Nr accepted</th> + <th>Nr rejected</th> + <th>Nr withdrawn</th> + {% else %} <th>Nr publications</th> <th>Duration average</th> - </tr> - <tr> + {% endif %} + </tr> + <tr> {% if issue %} <td>{{ issue.doi_label }}</td> <td>{{ issue|issue_nr_publications }}</td> @@ -65,14 +70,44 @@ <td>{{ journal.doi_label }}</td> {% if year %} <td>{{ year }}</td> - <td>{{ submissions|length }}</td> <td>{{ submissions|submissions_count_distinct }}</td> - {% endif %} + <td>{{ submissions|length }}</td> + <td>{{ submissions.assignment_failed.count }}</td> + <td>{{ submissions.accepted.count }}</td> + <td>{{ submissions.rejected.count }}</td> + <td>{{ submissions.withdrawn.count }}</td> + {% else %} <td>{{ journal|journal_nr_publications }}</td> <td>{{ journal|journal_avg_processing_duration|floatformat:2 }} days</td> + {% endif %} {% endif %} </tr> </table> -{% endif %} + {% endif %} + + {% if year %} + <h2>Refereeing stats for {{ year }}</h2> + <table class="table"> + <tr> + <th>Nr refereeing<br/>invitations</th> + <th>Nr accepted</th> + <th>Nr declined</th> + <th>Nr pending</th> + <th>Nr reports<br/>obtained</th> + <th>Nr obtained<br/>(invited)</th> + <th>Nr obtained<br/>(contributed)</th> + </tr> + <tr> + <td>{{ nr_ref_inv }}</td> + <td>{{ nr_acc }} ({% widthratio nr_acc nr_ref_inv 100 %}%)</td> + <td>{{ nr_dec }} ({% widthratio nr_dec nr_ref_inv 100 %}%)</td> + <td>{{ nr_pen }} ({% widthratio nr_pen nr_ref_inv 100 %}%)</td> + <td>{{ nr_rep_obt }}</td> + <td>{{ nr_rep_obt_inv }} ({% widthratio nr_rep_obt_inv nr_rep_obt 100 %}%)</td> + <td>{{ nr_rep_obt_con }} ({% widthratio nr_rep_obt_con nr_rep_obt 100 %}%)</td> + </tr> + </table> + {% endif %} + {% endblock content %} diff --git a/stats/views.py b/stats/views.py index c698a79844ef77a55394583ec9d8e29b87ebbe7c..76225120917786ac7b8e43721ea5bd0a09554e77 100644 --- a/stats/views.py +++ b/stats/views.py @@ -1,6 +1,7 @@ from django.contrib.auth.decorators import login_required, permission_required from django.shortcuts import get_object_or_404, render +from journals.constants import SCIPOST_JOURNALS_SUBMIT from journals.models import Journal, Volume, Issue, Publication from submissions.models import Submission @@ -17,10 +18,34 @@ def statistics(request, journal_doi_label=None, volume_nr=None, issue_nr=None, y if year: context['year'] = year submissions = Submission.objects.filter( - submitted_to_journal=journal, - submission_date__year=int(year), + submitted_to_journal=journal_doi_label, + submission_date__year=year, ) context['submissions'] = submissions + nr_ref_inv = 0 + nr_acc = 0 + nr_dec = 0 + nr_pen = 0 + nr_rep_obt = 0 + nr_rep_obt_inv = 0 + nr_rep_obt_con = 0 + nr_rep_ref = 0 + nr_aw_vet = 0 + for submission in submissions: + nr_ref_inv += submission.referee_invitations.count() + nr_acc += submission.count_accepted_invitations() + nr_dec += submission.count_declined_invitations() + nr_pen += submission.count_pending_invitations() + nr_rep_obt += submission.count_obtained_reports() + nr_rep_obt_inv += submission.count_invited_reports() + nr_rep_obt_con += submission.count_contrib_reports() + context['nr_ref_inv'] = nr_ref_inv + context['nr_acc'] = nr_acc + context['nr_dec'] = nr_dec + context['nr_pen'] = nr_pen + context['nr_rep_obt'] = nr_rep_obt + context['nr_rep_obt_inv'] = nr_rep_obt_inv + context['nr_rep_obt_con'] = nr_rep_obt_con if volume_nr: volume = get_object_or_404(Volume, in_journal=journal, number=volume_nr) diff --git a/submissions/constants.py b/submissions/constants.py index 943de541f9e517ddce9b8ceb90bbaebda95e9cf5..5252e752e27ddad562a456d07f9893ef681cef8f 100644 --- a/submissions/constants.py +++ b/submissions/constants.py @@ -2,6 +2,7 @@ from journals.constants import SCIPOST_JOURNAL_PHYSICS STATUS_UNASSIGNED = 'unassigned' +STATUS_ASSIGNMENT_FAILED = 'assignment_failed' STATUS_RESUBMISSION_INCOMING = 'resubmitted_incoming' STATUS_REVISION_REQUESTED = 'revision_requested' STATUS_EIC_ASSIGNED = 'EICassigned' @@ -14,10 +15,15 @@ STATUS_REJECTED_VISIBLE = 'rejected_visible' STATUS_RESUBMITTED = 'resubmitted' STATUS_RESUBMITTED_REJECTED = 'resubmitted_and_rejected' STATUS_RESUBMITTED_REJECTED_VISIBLE = 'resubmitted_and_rejected_visible' +STATUS_VOTING_IN_PREPARATION = 'voting_in_preparation' +STATUS_PUT_TO_EC_VOTING = 'put_to_EC_voting' +STATUS_EC_VOTE_COMPLETED = 'EC_vote_completed' +STATUS_WITHDRAWN = 'withdrawn' + SUBMISSION_STATUS = ( (STATUS_UNASSIGNED, 'Unassigned, undergoing pre-screening'), (STATUS_RESUBMISSION_INCOMING, 'Resubmission incoming'), - ('assignment_failed', 'Failed to assign Editor-in-charge; manuscript rejected'), + (STATUS_ASSIGNMENT_FAILED, 'Failed to assign Editor-in-charge; manuscript rejected'), (STATUS_EIC_ASSIGNED, 'Editor-in-charge assigned, manuscript under review'), (STATUS_REVIEW_CLOSED, 'Review period closed, editorial recommendation pending'), # If revisions required: resubmission creates a new Submission object @@ -27,22 +33,22 @@ SUBMISSION_STATUS = ( (STATUS_RESUBMITTED_REJECTED_VISIBLE, 'Has been resubmitted and subsequently rejected (still publicly visible)'), # If acceptance/rejection: - ('voting_in_preparation', 'Voting in preparation (eligible Fellows being selected)'), - ('put_to_EC_voting', 'Undergoing voting at the Editorial College'), + (STATUS_VOTING_IN_PREPARATION, 'Voting in preparation (eligible Fellows being selected)'), + (STATUS_PUT_TO_EC_VOTING, 'Undergoing voting at the Editorial College'), (STATUS_AWAITING_ED_REC, 'Awaiting Editorial Recommendation'), - ('EC_vote_completed', 'Editorial College voting rounded up'), + (STATUS_EC_VOTE_COMPLETED, 'Editorial College voting rounded up'), (STATUS_ACCEPTED, 'Publication decision taken: accept'), (STATUS_REJECTED, 'Publication decision taken: reject'), (STATUS_REJECTED_VISIBLE, 'Publication decision taken: reject (still publicly visible)'), (STATUS_PUBLISHED, 'Published'), # If withdrawn: - ('withdrawn', 'Withdrawn by the Authors'), + (STATUS_WITHDRAWN, 'Withdrawn by the Authors'), ) SUBMISSION_HTTP404_ON_EDITORIAL_PAGE = [ - 'assignment_failed', + STATUS_ASSIGNMENT_FAILED, STATUS_PUBLISHED, - 'withdrawn', + STATUS_WITHDRAWN, STATUS_REJECTED, STATUS_REJECTED_VISIBLE, ] @@ -55,9 +61,9 @@ SUBMISSION_EXCLUDE_FROM_REPORTING = SUBMISSION_HTTP404_ON_EDITORIAL_PAGE + [ STATUS_AWAITING_ED_REC, STATUS_REVIEW_CLOSED, STATUS_ACCEPTED, - 'voting_in_preparation', - 'put_to_EC_voting', - 'withdrawn', + STATUS_VOTING_IN_PREPARATION, + STATUS_PUT_TO_EC_VOTING, + STATUS_WITHDRAWN, ] # Submissions which are allowed/required to submit a EIC Recommendation @@ -71,10 +77,10 @@ SUBMISSION_EIC_RECOMMENDATION_REQUIRED = [ SUBMISSION_STATUS_PUBLICLY_INVISIBLE = [ STATUS_UNASSIGNED, STATUS_RESUBMISSION_INCOMING, - 'assignment_failed', + STATUS_ASSIGNMENT_FAILED, STATUS_RESUBMITTED_REJECTED, STATUS_REJECTED, - 'withdrawn', + STATUS_WITHDRAWN, ] # Submissions which should not appear in search lists @@ -88,7 +94,7 @@ SUBMISSION_STATUS_PUBLICLY_UNLISTED = SUBMISSION_STATUS_PUBLICLY_INVISIBLE + [ SUBMISSION_STATUS_VOTING_DEPRECATED = [ STATUS_REJECTED, STATUS_PUBLISHED, - 'withdrawn', + STATUS_WITHDRAWN, ] SUBMISSION_TYPE = ( diff --git a/submissions/managers.py b/submissions/managers.py index e4b5b5f2a6ee91e784ba9b0d144543c2fe02f373..6a883e95fa3ab22474ab75dcde1bb155cf4f7e97 100644 --- a/submissions/managers.py +++ b/submissions/managers.py @@ -8,9 +8,11 @@ from .constants import SUBMISSION_STATUS_OUT_OF_POOL, SUBMISSION_STATUS_PUBLICLY SUBMISSION_STATUS_PUBLICLY_INVISIBLE, STATUS_UNVETTED, STATUS_VETTED,\ STATUS_UNCLEAR, STATUS_INCORRECT, STATUS_NOT_USEFUL, STATUS_NOT_ACADEMIC,\ SUBMISSION_HTTP404_ON_EDITORIAL_PAGE, STATUS_DRAFT, STATUS_PUBLISHED,\ - SUBMISSION_EXCLUDE_FROM_REPORTING, STATUS_REJECTED_VISIBLE,\ + SUBMISSION_EXCLUDE_FROM_REPORTING,\ + STATUS_REJECTED, STATUS_REJECTED_VISIBLE,\ STATUS_ACCEPTED, STATUS_RESUBMITTED, STATUS_RESUBMITTED_REJECTED_VISIBLE,\ - EVENT_FOR_EIC, EVENT_GENERAL, EVENT_FOR_AUTHOR, STATUS_UNASSIGNED + EVENT_FOR_EIC, EVENT_GENERAL, EVENT_FOR_AUTHOR,\ + STATUS_UNASSIGNED, STATUS_ASSIGNMENT_FAILED, STATUS_WITHDRAWN class SubmissionQuerySet(models.QuerySet): @@ -111,6 +113,19 @@ class SubmissionQuerySet(models.QuerySet): def accepted(self): return self.filter(status=STATUS_ACCEPTED) + + def assignment_failed(self): + return self.filter(status=STATUS_ASSIGNMENT_FAILED) + + + def rejected(self): + return self._newest_version_only(self.filter(status__in=[STATUS_REJECTED, + STATUS_REJECTED_VISIBLE])) + + def withdrawn(self): + return self._newest_version_only(self.filter(status=STATUS_WITHDRAWN)) + + def open_for_reporting(self): """ Return Submissions that have appriopriate status for reporting.