diff --git a/hypha/apply/determinations/views.py b/hypha/apply/determinations/views.py index 9ce6aec833..ed3691d73c 100644 --- a/hypha/apply/determinations/views.py +++ b/hypha/apply/determinations/views.py @@ -45,7 +45,6 @@ from .utils import ( determination_actions, has_final_determination, - outcome_from_actions, transition_from_outcome, ) @@ -245,41 +244,6 @@ def form_valid(self, form): ) return response - @classmethod - def should_redirect(cls, request, submissions, actions): - excluded = [] - for submission in submissions: - if has_final_determination(submission): - excluded.append(submission) - - non_determine_states = set(actions) - set(DETERMINATION_OUTCOMES.keys()) - if not any(non_determine_states): - if excluded: - messages.warning( - request, - _( - "A determination already exists for the following submissions and they have been excluded: {submissions}" - ).format( - submissions=", ".join( - [submission.title_text_display for submission in excluded] - ), - ), - ) - - submissions = submissions.exclude( - id__in=[submission.id for submission in excluded] - ) - action = outcome_from_actions(actions) - return HttpResponseRedirect( - reverse_lazy("apply:submissions:determinations:batch") - + "?action=" - + action - + "&submissions=" - + ",".join([str(submission.id) for submission in submissions]) - ) - elif set(actions) != non_determine_states: - raise ValueError("Inconsistent states provided - please talk to an admin") - def get_success_url(self): try: return self.request.GET["next"] diff --git a/hypha/apply/funds/utils.py b/hypha/apply/funds/utils.py index 089e0cbe50..d67cade67b 100644 --- a/hypha/apply/funds/utils.py +++ b/hypha/apply/funds/utils.py @@ -191,3 +191,22 @@ def get_copied_form_name(original_form_name: str) -> str: # If a copied timestamp already exists, remove it new_name = re.sub(name_reg, "", original_form_name) return f"{new_name} ({copy_str.format(copy_time=copy_time)})" + + +def check_submissions_same_determination_form(submissions): + """ + Checks if all the submission have same determination forms. + + We can not create batch determination with submissions using two different + type of forms. + """ + + same_form = True + # check form id + determination_form_ids = [ + submission.get_from_parent("determination_forms").first().id + for submission in submissions + ] + if any(d_id != determination_form_ids[0] for d_id in determination_form_ids): + same_form = False + return same_form diff --git a/hypha/apply/funds/views/all.py b/hypha/apply/funds/views/all.py index ce6b6d3fc8..799ed36a2b 100644 --- a/hypha/apply/funds/views/all.py +++ b/hypha/apply/funds/views/all.py @@ -10,6 +10,7 @@ from django.db import models from django.http import HttpRequest, HttpResponse, HttpResponseForbidden from django.shortcuts import render +from django.urls import reverse_lazy from django.utils.translation import gettext as _ from django.views.decorators.http import require_http_methods from django_htmx.http import HttpResponseClientRedirect, HttpResponseClientRefresh @@ -17,10 +18,18 @@ from hypha.apply.activity.messaging import MESSAGES, messenger from hypha.apply.categories.models import Option -from hypha.apply.determinations.views import BatchDeterminationCreateView +from hypha.apply.determinations.utils import ( + has_final_determination, + outcome_from_actions, +) from hypha.apply.funds.models.screening import ScreeningStatus from hypha.apply.funds.utils import export_submissions_to_csv -from hypha.apply.funds.workflows import PHASES, get_action_mapping, review_statuses +from hypha.apply.funds.workflows import ( + DETERMINATION_OUTCOMES, + PHASES, + get_action_mapping, + review_statuses, +) from hypha.apply.search.filters import apply_date_filter from hypha.apply.search.query_parser import parse_search_query from hypha.apply.users.decorators import ( @@ -37,6 +46,7 @@ from ..tables import ( SubmissionFilter, ) +from ..utils import check_submissions_same_determination_form User = get_user_model() @@ -355,11 +365,47 @@ def bulk_update_submissions_status(request: HttpRequest) -> HttpResponse: submissions = ApplicationSubmission.objects.filter(id__in=submission_ids) - redirect: HttpResponse = BatchDeterminationCreateView.should_redirect( - request, submissions, transitions - ) - if redirect: - return HttpResponseClientRedirect(redirect.url) + # should redirect + excluded = [] + for submission in submissions: + if has_final_determination(submission): + excluded.append(submission) + + non_determine_states = set(transitions) - set(DETERMINATION_OUTCOMES.keys()) + if not any(non_determine_states): + if excluded: + messages.warning( + request, + _( + "A determination already exists for the following submissions and they have been excluded: {submissions}" + ).format( + submissions=", ".join( + [submission.title_text_display for submission in excluded] + ), + ), + ) + + submissions = submissions.exclude( + id__in=[submission.id for submission in excluded] + ) + if not check_submissions_same_determination_form(submissions): + messages.error( + request, "Submissions expect different forms - please contact admin" + ) + return HttpResponseClientRefresh() + action = outcome_from_actions(transitions) + return HttpResponseClientRedirect( + reverse_lazy("apply:submissions:determinations:batch") + + "?action=" + + action + + "&submissions=" + + ",".join([str(submission.id) for submission in submissions]), + ) + elif set(transitions) != non_determine_states: + messages.error( + request, "Inconsistent states provided - please talk to an admin" + ) + return HttpResponseClientRefresh() failed = [] phase_changes = {} diff --git a/hypha/apply/funds/views/partials.py b/hypha/apply/funds/views/partials.py index 77db81fcfc..edb7e4686b 100644 --- a/hypha/apply/funds/views/partials.py +++ b/hypha/apply/funds/views/partials.py @@ -32,6 +32,7 @@ from ..models import ApplicationSubmission, Round from ..permissions import can_change_external_reviewers from ..utils import ( + check_submissions_same_determination_form, get_or_create_default_screening_statuses, get_statuses_as_params, status_and_phases_mapping, @@ -309,6 +310,8 @@ def sub_menu_update_status(request: HttpRequest) -> HttpResponse: submission_ids = request.GET.getlist("selectedSubmissionIds") qs = ApplicationSubmission.objects.filter(id__in=submission_ids) + allow_determination = check_submissions_same_determination_form(qs) + list_of_actions_list = [s.get_actions_for_user(request.user) for s in qs] action_names = [[x[1] for x in action_list] for action_list in list_of_actions_list] common_actions = ( @@ -317,6 +320,13 @@ def sub_menu_update_status(request: HttpRequest) -> HttpResponse: else [] ) + # hide determination actions if submissions have different forms + if not allow_determination: + determination_actions = ["Dismiss", "Request More Information", "Accept"] + common_actions = [ + action for action in common_actions if action not in determination_actions + ] + ctx = { "statuses": {slugify(a): a for a in common_actions}.items(), }