Skip to content

Commit d7d361d

Browse files
committed
Fix grant reimbursement creation when grant is not approved
1 parent d168bcb commit d7d361d

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

backend/reviews/admin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ def _review_grants_recap_view(self, request, review_session):
349349
change_message=f"[Review Session] Grant status updated: pending_status changed from '{grant.status}' to '{grant.pending_status}'.",
350350
)
351351

352+
# The frontend may send reimbursement categories as checked by default,
353+
# so they're always passed to the backend. However, if the grant is not approved,
354+
# we don't need to consider reimbursements at all and can skip all reimbursement logic.
355+
if grant.pending_status != Grant.Status.approved:
356+
continue
357+
352358
approved_reimbursement_categories = (
353359
approved_reimbursement_categories_decisions.get(grant.id, [])
354360
)

backend/reviews/tests/test_admin.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,3 +573,87 @@ def test_save_review_grants_modify_reimbursements(rf, mocker):
573573
object_id=str(accommodation_category.id),
574574
change_message=f"[Review Session] Reimbursement removed: {accommodation_category.name}",
575575
).exists()
576+
577+
578+
def test_save_review_grants_waiting_list_does_not_create_reimbursments(rf, mocker):
579+
mock_messages = mocker.patch("reviews.admin.messages")
580+
581+
user = UserFactory(is_staff=True, is_superuser=True)
582+
conference = ConferenceFactory()
583+
584+
# Create reimbursement categories
585+
travel_category = GrantReimbursementCategoryFactory(
586+
conference=conference,
587+
travel=True,
588+
max_amount=Decimal("500"),
589+
)
590+
ticket_category = GrantReimbursementCategoryFactory(
591+
conference=conference,
592+
ticket=True,
593+
max_amount=Decimal("100"),
594+
)
595+
accommodation_category = GrantReimbursementCategoryFactory(
596+
conference=conference,
597+
accommodation=True,
598+
max_amount=Decimal("200"),
599+
)
600+
601+
# Create review session for grants
602+
review_session = ReviewSessionFactory(
603+
conference=conference,
604+
session_type=ReviewSession.SessionType.GRANTS,
605+
status=ReviewSession.Status.COMPLETED,
606+
)
607+
AvailableScoreOptionFactory(review_session=review_session, numeric_value=0)
608+
AvailableScoreOptionFactory(review_session=review_session, numeric_value=1)
609+
610+
grant_1 = GrantFactory(conference=conference, status=Grant.Status.pending)
611+
grant_2 = GrantFactory(conference=conference, status=Grant.Status.pending)
612+
613+
post_data = {
614+
f"decision-{grant_1.id}": Grant.Status.waiting_list,
615+
f"reimbursementcategory-{grant_1.id}": [
616+
str(ticket_category.id),
617+
str(travel_category.id),
618+
],
619+
f"decision-{grant_2.id}": Grant.Status.waiting_list_maybe,
620+
f"reimbursementcategory-{grant_2.id}": [
621+
str(ticket_category.id),
622+
str(travel_category.id),
623+
str(accommodation_category.id),
624+
],
625+
}
626+
627+
request = rf.post("/", data=post_data)
628+
request.user = user
629+
630+
admin = ReviewSessionAdmin(ReviewSession, AdminSite())
631+
response = admin._review_grants_recap_view(request, review_session)
632+
633+
# Should redirect after successful save
634+
assert response.status_code == 302
635+
assert (
636+
response.url
637+
== f"/admin/reviews/reviewsession/{review_session.id}/review/recap/"
638+
)
639+
640+
# Refresh grants from database
641+
grant_1.refresh_from_db()
642+
grant_2.refresh_from_db()
643+
644+
# Verify grants were updated with pending_status
645+
assert grant_1.pending_status == Grant.Status.waiting_list
646+
assert grant_2.pending_status == Grant.Status.waiting_list_maybe
647+
648+
# Verify GrantReimbursement objects were created
649+
assert grant_1.reimbursements.count() == 0
650+
assert grant_2.reimbursements.count() == 0
651+
652+
# Verify log entries were created
653+
assert (
654+
LogEntry.objects.filter(object_id=grant_1.id).count() == 1
655+
) # 1 pending_status change, 2 reimbursement additions
656+
assert (
657+
LogEntry.objects.filter(object_id=grant_2.id).count() == 1
658+
) # 1 pending_status change, 3 reimbursement additions
659+
mock_messages.success.assert_called_once()

0 commit comments

Comments
 (0)