diff --git a/scipost_django/production/models.py b/scipost_django/production/models.py index 549155d3170863db19fafb916a74c9baf414908d..65ef7165884446c0f51b4fe9e3d1ab2cafd7c388 100644 --- a/scipost_django/production/models.py +++ b/scipost_django/production/models.py @@ -118,10 +118,6 @@ class ProductionStream(models.Model): def completed(self): return self.status == PRODUCTION_STREAM_COMPLETED - @property - def notification_name(self): - return self.submission.preprint.identifier_w_vn_nr - @property def latest_activity(self): if self.events.last(): @@ -168,10 +164,6 @@ class ProductionEvent(models.Model): and not self.stream.completed ) - @property - def notification_name(self): - return self.stream.notification_name - def production_event_upload_location(instance, filename): submission = instance.production_event.stream.submission diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py index 3b9be1f43ef06e4c7f59ba98b23c28b04fcbd42c..0023801d2cfd2b6edad99e4d41d07ca6fa8664d3 100644 --- a/scipost_django/scipost/views.py +++ b/scipost_django/scipost/views.py @@ -1137,7 +1137,8 @@ def personal_page_hx_edadmin(request): Report.objects.accepted().filter(pdf_report="").count() ) context["nr_treated_submissions_without_pdf"] = ( - Submission.objects.treated().public().filter(pdf_refereeing_pack="").count() + Submission.objects.treated().public( + ).filter(pdf_refereeing_pack="").count() ) return render(request, "scipost/personal_page/_hx_edadmin.html", context) diff --git a/scipost_django/submissions/forms.py b/scipost_django/submissions/forms.py index e10ec3709ceed551c1f3f5790e010b5e3cbd02af..106fec3dfc0c4db90384d77004aa1e447b00a576 100644 --- a/scipost_django/submissions/forms.py +++ b/scipost_django/submissions/forms.py @@ -230,9 +230,11 @@ class SubmissionPoolSearchForm(forms.Form): ), ), ( - "Revision requested", + "Awaiting resubmission", ( - ("revision_requested", "Minor or major revision requested, awaiting resubmission"), + ( + Submission.AWAITING_RESUBMISSION, + "Awaiting resubmission (minor or major revision requested)"), ), ), ( @@ -450,8 +452,6 @@ class SubmissionPoolSearchForm(forms.Form): timezone.now() - datetime.timedelta(days=90) ) ).distinct().exclude(eicrecommendations__isnull=False) - elif status == "revision_requested": - submissions = submissions.revision_requested() elif status == "voting_prepare": submissions = submissions.voting_in_preparation() elif status == "voting_ongoing": @@ -1462,7 +1462,7 @@ class SubmissionForm(forms.ModelForm): EditorialAssignment.objects.create( submission=submission, to=previous_submission.editor_in_charge, - status=Submission.ACCEPTED, + status=STATUS_ACCEPTED, ) def set_fellowship(self, submission): diff --git a/scipost_django/submissions/managers/submission.py b/scipost_django/submissions/managers/submission.py index e5fbe1ad755a58a2e2c9a30b39591977982742a9..9c02988ef2a351eb5c4e73ba0887b3454b9fb82f 100644 --- a/scipost_django/submissions/managers/submission.py +++ b/scipost_django/submissions/managers/submission.py @@ -77,11 +77,54 @@ class SubmissionQuerySet(models.QuerySet): def published(self): return self.filter(status=self.model.PUBLISHED) - #### Managers mixing statuses #### + ### Managers for stages #### + def in_stage_incoming(self): + return self.filter(status=self.model.STAGE_INCOMING) + + def stage_incoming_completed(self): + return self.filter(status__in=self.model.stage_incoming_completed_statuses) + + def in_stage_preassignment(self): + return self.filter(status__in=self.model.STAGE_PREASSIGNMENT) + + def stage_preassignment_completed(self): + return self.filter(status__in=self.model.stage_preassignment_completed_statuses) + + def in_stage_assignment(self): + return self.filter(status__in=self.model.STAGE_ASSIGNMENT) + + def stage_assignment_completed(self): + return self.filter(status__in=self.model.stage_assignment_completed_statuses) + + def in_stage_refereeing_in_preparation(self): + return self.filter(status__in=self.model.STAGE_REFEREEING_IN_PREPARATION) + + def stage_refereeing_in_preparation_completed(self): + return self.filter( + status__in=self.model.stage_refereeing_in_preparation_completed_statuses + ) + + def in_stage_in_refereeing(self): + return self.filter(status__in=self.model.STAGE_IN_REFEREEING) + + def stage_in_refereeing_completed(self): + return self.filter(status__in=self.model.stage_in_refereeing_completed_statuses) + + def in_stage_decisionmaking(self): + return self.filter(status__in=self.model.STAGE_DECISIONMAKING) + + def stage_decisionmaking_completed(self): + return self.filter(status__in=self.model.STAGE_DECIDED) + + #### Other managers mixing statuses #### def under_consideration(self): return self.filter(status__in=self.model.UNDER_CONSIDERATION) + def treated(self): + """Returns Submissions (stream heads) whose streams are fully processed.""" + return self.filter(status__in=self.model.TREATED) + def accepted(self): return self.filter(status__in=[ self.model.ACCEPTED_IN_TARGET, @@ -197,17 +240,6 @@ class SubmissionQuerySet(models.QuerySet): """ return self.latest().public() - def treated(self): - """This query returns all Submissions that are presumed to be 'done'.""" - return self.filter( - status__in=[ - self.model.ACCEPTED, - self.model.REJECTED, - self.model.PUBLISHED, - self.model.RESUBMITTED, - ] - ) - def originally_submitted(self, from_date, until_date): """ Returns the submissions originally received between from_date and until_date @@ -221,22 +253,6 @@ class SubmissionQuerySet(models.QuerySet): thread_hashes.append(sub.thread_hash) return self.filter(thread_hash__in=thread_hashes) - def awaiting_puboffer_acceptance(self): - """Return Submissions for which an outstanding publication offer exists.""" - return self.filter( - status=self.model.ACCEPTED_AWAITING_PUBOFFER_ACCEPTANCE - ) - - def revision_requested(self): - """Return Submissions with a fixed EICRecommendation: minor or major revision.""" - return self.filter( - eicrecommendations__status=constants.DECISION_FIXED, - eicrecommendations__recommendation__in=[ - constants.REPORT_MINOR_REV, - constants.REPORT_MAJOR_REV, - ], - ) - def unpublished(self): """Return unpublished Submissions.""" return self.exclude(status=self.model.PUBLISHED) @@ -285,15 +301,6 @@ class SubmissionQuerySet(models.QuerySet): authors=user.contributor, ) - # CLEANUP 2022-11-27 - # def voting_in_preparation(self): - # from submissions.models import EICRecommendation - - # ids_list = [ - # r.submission.id for r in EICRecommendation.objects.voting_in_preparation() - # ] - # return self.filter(id__in=ids_list) - def undergoing_voting(self, longer_than_days=None): from submissions.models import EICRecommendation diff --git a/scipost_django/submissions/models/assignment.py b/scipost_django/submissions/models/assignment.py index d7e549fd04f4903122009839d9b881a658354f45..436f240236a0604e124a84d6850e1630b179d4bc 100644 --- a/scipost_django/submissions/models/assignment.py +++ b/scipost_django/submissions/models/assignment.py @@ -64,11 +64,6 @@ class EditorialAssignment(SubmissionRelatedObjectMixin, models.Model): """Return the url of the assignment's processing page.""" return reverse("submissions:assignment_request", args=(self.id,)) - @property - def notification_name(self): - """Return string representation of this EditorialAssigment as shown in Notifications.""" - return self.submission.preprint.identifier_w_vn_nr - @property def preassigned(self): return self.status == STATUS_PREASSIGNED diff --git a/scipost_django/submissions/models/communication.py b/scipost_django/submissions/models/communication.py index b01a52f2ed1ddd77b42791842f408a1943256deb..1ec6e6f5acde32f7079600e061d6acd3cc947371 100644 --- a/scipost_django/submissions/models/communication.py +++ b/scipost_django/submissions/models/communication.py @@ -43,12 +43,3 @@ class EditorialCommunication(SubmissionRelatedObjectMixin, models.Model): def get_absolute_url(self): """Return the url of the related Submission detail page.""" return self.submission.get_absolute_url() - - def get_notification_url(self, url_code): - """Return url related to the Communication by the `url_code` meant for Notifications.""" - if url_code == "editorial_page": - return reverse( - "submissions:editorial_page", - args=(self.submission.preprint.identifier_w_vn_nr,), - ) - return self.get_absolute_url() diff --git a/scipost_django/submissions/models/recommendation.py b/scipost_django/submissions/models/recommendation.py index a38dbb2a591e0ef76b18f41e91a0481561aa8090..fd24cf38b0e890294704834dcec15d1dcd259614 100644 --- a/scipost_django/submissions/models/recommendation.py +++ b/scipost_django/submissions/models/recommendation.py @@ -89,11 +89,6 @@ class EICRecommendation(SubmissionRelatedObjectMixin, models.Model): """ return self.submission.get_absolute_url() - @property - def notification_name(self): - """Return string representation of this EICRecommendation as shown in Notifications.""" - return self.submission.preprint.identifier_w_vn_nr - @property def nr_for(self): """Return the number of votes 'for'.""" diff --git a/scipost_django/submissions/models/referee_invitation.py b/scipost_django/submissions/models/referee_invitation.py index bcd67cd06e1ac9be86dc04df19d469a824982602..d700bff8ce071ff7997c5c7c35a0e5579592cba2 100644 --- a/scipost_django/submissions/models/referee_invitation.py +++ b/scipost_django/submissions/models/referee_invitation.py @@ -106,11 +106,6 @@ class RefereeInvitation(SubmissionRelatedObjectMixin, models.Model): return str(self.referee) return self.last_name + ", " + self.first_name - @property - def notification_name(self): - """Return string representation of this RefereeInvitation as shown in Notifications.""" - return self.submission.preprint.identifier_w_vn_nr - @property def related_report(self): """Return the Report that's been created for this invitation.""" diff --git a/scipost_django/submissions/models/report.py b/scipost_django/submissions/models/report.py index 86ec84b772c4f98b6b7accf3ad38991a3ca8d718..85e5fb9d013d8b7335602e58c084473d6d7598db 100644 --- a/scipost_django/submissions/models/report.py +++ b/scipost_django/submissions/models/report.py @@ -171,20 +171,6 @@ class Report(SubmissionRelatedObjectMixin, models.Model): """Return url of the Report on the Submission detail page.""" return self.submission.get_absolute_url() + "#report_" + str(self.report_nr) - def get_notification_url(self, url_code): - """Return url related to the Report by the `url_code` meant for Notifications.""" - if url_code == "report_form": - return reverse( - "submissions:submit_report", - args=(self.submission.preprint.identifier_w_vn_nr,), - ) - elif url_code == "editorial_page": - return reverse( - "submissions:editorial_page", - args=(self.submission.preprint.identifier_w_vn_nr,), - ) - return self.get_absolute_url() - def get_attachment_url(self): """Return url of the Report its attachment if exists.""" return reverse( @@ -220,11 +206,6 @@ class Report(SubmissionRelatedObjectMixin, models.Model): STATUS_NOT_ACADEMIC, ] - @property - def notification_name(self): - """Return string representation of this Report as shown in Notifications.""" - return self.submission.preprint.identifier_w_vn_nr - @property def doi_string(self): """Return the doi with the registrant identifier prefix.""" diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py index 6a4d0123c046997b74647dd1fecd592135f8d07f..5ad4514e19b14d97adab4c47c247c7b9783b709c 100644 --- a/scipost_django/submissions/models/submission.py +++ b/scipost_django/submissions/models/submission.py @@ -141,7 +141,13 @@ class Submission(models.Model): WITHDRAWN, PUBLISHED, ) - + TREATED = ( + ACCEPTED_IN_TARGET, + ACCEPTED_IN_ALTERNATIVE, + REJECTED, + WITHDRAWN, + PUBLISHED, + ) # Fields preprint = models.OneToOneField( "preprints.Preprint", on_delete=models.CASCADE, related_name="submission" @@ -322,8 +328,8 @@ class Submission(models.Model): return self.status in self.STAGE_INCOMING @property - def stage_incoming_completed(self): - return self.status in ( + def stage_incoming_completed_statuses(self): + return ( self.STAGE_PREASSIGNMENT + self.STAGE_ASSIGNMENT + self.STAGE_REFEREEING_IN_PREPARATION + @@ -332,59 +338,84 @@ class Submission(models.Model): self.STAGE_DECIDED ) + @property + def stage_incoming_completed(self): + return self.status in self.stage_incoming_completed_statuses + @property def in_stage_preassignment(self): return self.status in self.STAGE_PREASSIGNMENT @property - def stage_preassignment_completed(self): - return self.status in ( + def stage_preassignment_completed_statuses(self): + return ( self.STAGE_ASSIGNMENT + self.STAGE_REFEREEING_IN_PREPARATION + self.STAGE_IN_REFEREEING + self.STAGE_DECISIONMAKING + self.STAGE_DECIDED ) + + @property + def stage_preassignment_completed(self): + return self.status in self.stage_preassignment_completed_statuses + @property def in_stage_assignment(self): return self.status in self.STAGE_ASSIGNMENT @property - def stage_assignment_completed(self): - return self.status in ( + def stage_assignment_completed_statuses(self): + return ( self.STAGE_REFEREEING_IN_PREPARATION + self.STAGE_IN_REFEREEING + self.STAGE_DECISIONMAKING + self.STAGE_DECIDED ) + @property + def stage_assignment_completed(self): + return self.status in self.stage_assignment_completed_statuses + @property def in_stage_refereeing_in_preparation(self): return self.status in self.STAGE_REFEREEING_IN_PREPARATION @property - def stage_refereeing_in_preparation_completed(self): - return self.status in ( + def stage_refereeing_in_preparation_completed_statuses(self): + return ( self.STAGE_IN_REFEREEING + self.STAGE_DECISIONMAKING + self.STAGE_DECIDED ) + @property + def stage_refereeing_in_preparation_completed(self): + return self.status in self.stage_refereeing_in_preparation_completed_statuses + @property def in_stage_in_refereeing(self): return self.status in self.STAGE_IN_REFEREEING @property - def stage_in_refereeing_completed(self): - return self.status in ( + def stage_in_refereeing_completed_statuses(self): + return ( self.STAGE_DECISIONMAKING + self.STAGE_DECIDED ) + @property + def stage_in_refereeing_completed(self): + return self.status in self.stage_in_refereeing_completed_statuses + @property def in_stage_decisionmaking(self): return self.status in self.STAGE_DECISIONMAKING + @property + def stage_decisionmaking_completed_statuses(self): # include for completeness + return self.STAGE_DECIDED + @property def stage_decisionmaking_completed(self): return self.in_stage_decided @@ -453,23 +484,10 @@ class Submission(models.Model): "submissions:submission", args=(self.preprint.identifier_w_vn_nr,) ) - def get_notification_url(self, url_code): - """Return url related to the Submission by the `url_code` meant for Notifications.""" - if url_code == "editorial_page": - return reverse( - "submissions:editorial_page", args=(self.preprint.identifier_w_vn_nr,) - ) - return self.get_absolute_url() - @property def is_resubmission(self): return self.is_resubmission_of is not None - @property - def notification_name(self): - """Return string representation of this Submission as shown in Notifications.""" - return self.preprint.identifier_w_vn_nr - @property def eic_recommendation_required(self): """Return if Submission requires a EICRecommendation to be formulated.""" @@ -535,22 +553,10 @@ class Submission(models.Model): .submission_date ) - @property - def in_preassignment(self): - return self.status == self.INCOMING - @property def can_reset_reporting_deadline(self): """Check if reporting deadline is allowed to be reset.""" - blocked_statuses = [ - self.PREASSIGNMENT_FAILED, - self.RESUBMITTED, - self.ACCEPTED, - self.REJECTED, - self.WITHDRAWN, - self.PUBLISHED, - ] - if self.status in blocked_statuses: + if self.status in STAGE_DECIDED: return False if self.refereeing_cycle == CYCLE_DIRECT_REC: @@ -658,20 +664,18 @@ class Submission(models.Model): return self.editorial_assignments.filter(status=STATUS_PREASSIGNED).exists() - def has_inadequate_pool_composition(self): + def has_inadequate_fellowship_composition(self): """ - Check whether the EIC actually in the pool of the Submission. - - (Could happen on resubmission or reassignment after wrong Journal selection) + Check whether the EIC is actually in the fellowship of the Submission. """ if not self.editor_in_charge: # None assigned yet. return False - pool_contributors_ids = Contributor.objects.filter( + contributors_ids = Contributor.objects.filter( fellowships__pool=self ).values_list("id", flat=True) - return self.editor_in_charge.id not in pool_contributors_ids + return self.editor_in_charge.id not in contributors_ids @property def editorial_decision(self): diff --git a/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html b/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html index 6630a2e4048447bcd4cf82b02daad23cbfc4909e..be09739fef01a25941540efa9f1c4ebec4fa5a59 100644 --- a/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html +++ b/scipost_django/submissions/templates/submissions/_hx_submission_workflow_diagram.html @@ -35,7 +35,7 @@ flowchart LR end Sub --> Admiss Admiss --fail--> AdmissFailed("Admission<br>failed ✉<small>A</small>") --> Close([Processing<br>closed]) - Admiss --pass--> AdmissPassed("Admission<br>passed ✉<small>A</small>") --> Preassignment[[Goto:<br>preassignment]] + Admiss --pass--> AdmissPassed("Admission<br>passed ✉<small>A</small>") --> Preassignment[[Goto:<br>Preassignment]] </pre> </details> </div> @@ -48,13 +48,13 @@ flowchart LR <pre class="mermaid workflowDiagram"> flowchart LR AdmissPassed([Admission<br>passed]) - subgraph preassignment + subgraph Preassignment PreTop(Submission<br>Topics<br>specification) --> ProfMatch(Author<br>Profiles<br>matching) ProfMatch --> PreCOI(Conflict<br>of interest<br>checks) PreCOI --> PrePa(Listing of<br>potential<br>Editors-in-charge) end AdmissPassed --> PreTop - PrePa --no qualified<br>Fellows--> PreFail("preassignment<br>failed ✉<small>A</small>") --> Close([Processing<br>closed]) + PrePa --no qualified<br>Fellows--> PreFail("Preassignment<br>failed ✉<small>A</small>") --> Close([Processing<br>closed]) PrePa --"∃ qualified<br>Fellows"--> PrePass("Preassignment<br>passed ✉<small>A</small>") --> Assignment[[Goto:<br>Assignment]] </pre> </details> diff --git a/scipost_django/submissions/templates/submissions/pool/_hx_submission_details.html b/scipost_django/submissions/templates/submissions/pool/_hx_submission_details.html index a4882c5283873a505d73345dac18399034accc6b..952c644e1af89e5402debe39387d09b4d9848c65 100644 --- a/scipost_django/submissions/templates/submissions/pool/_hx_submission_details.html +++ b/scipost_django/submissions/templates/submissions/pool/_hx_submission_details.html @@ -97,7 +97,7 @@ </ul> </li> <li class="pb-2"> - {% if submission.in_preassignment %} + {% if submission.in_stage_preassignment %} <a href="{% url 'submissions:do_preassignment' submission.preprint.identifier_w_vn_nr %}">Preassignment</a> {% else %} Preassignment completed diff --git a/scipost_django/submissions/templates/submissions/pool/_hx_submission_li.html b/scipost_django/submissions/templates/submissions/pool/_hx_submission_li.html index ea37e5a423d789e430706f0939e2778555e2e8f1..b572b3ae8fe28227eee594233b8d6dd45fdae723 100644 --- a/scipost_django/submissions/templates/submissions/pool/_hx_submission_li.html +++ b/scipost_django/submissions/templates/submissions/pool/_hx_submission_li.html @@ -84,7 +84,7 @@ {% endif %} </div> </div> - {% if is_ed_admin and submission.has_inadequate_pool_composition %} + {% if is_ed_admin and submission.has_inadequate_fellowship_composition %} <div class="border border-danger text-danger mt-1 py-1 px-2"> <strong> {% include 'bi/exclamation-triangle-fill.html' %}