Skip to content

Payment Accrual Code Improvements #529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

pxwxnvermx
Copy link
Contributor

@pxwxnvermx pxwxnvermx commented Mar 25, 2025

Product Description

  • Updated update_status to process bulk completed works
  • Created get_completed_work_counts to process bulk completed works, and get approved and completed counts
  • Replaced usages of approved_count, completed_count and completed properties with saved_ properties.
  • Added incremental option on update_payment_accrued to only update unprocessed completed works.

Technical Summary

Ticket Link

Safety Assurance

Safety story

Automated test coverage

  • Changes are covered under existing test cases.

Labels & Review

  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@pxwxnvermx pxwxnvermx self-assigned this Mar 25, 2025
@pxwxnvermx pxwxnvermx marked this pull request as ready for review March 25, 2025 12:45
Copy link
Collaborator

@calellowitz calellowitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few questions, generally otherwise concerned with how well tested this is, but if we are confident in our tests of this logic, i think it looks fine. Ideally we would be able to use modification dates to make sure we recalculate for anything that changed since the last calculation, but not sure how much more work that is.

@@ -186,14 +187,19 @@ def get_missing_justification_message(visits_ids):
return f"Justification is required for flagged visits: {id_list}"


def update_payment_accrued(opportunity: Opportunity, users):
"""Updates payment accrued for completed and approved CompletedWork instances."""
def update_payment_accrued(opportunity: Opportunity, users, incremental=False):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the other args have type hints, the last should too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. 5448384

access_objects = OpportunityAccess.objects.filter(user__in=users, opportunity=opportunity, suspended=False)
completed_work_filter = ~Q(status=CompletedWorkStatus.rejected)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could probably be written with simple exclude and filter statements rather than fancy Q ones, which are a bit harder to interpret

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. 8897edd

completed_work_filter = ~Q(status=CompletedWorkStatus.rejected)
if incremental:
completed_work_filter |= ~Q(status=CompletedWorkStatus.approved)
completed_work_filter &= Q(saved_approved_count=0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if one with duplicates has the second approved, will this not account for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The visit import code still runs non-incremental payment accrual updates. So if the status is updated for a duplicate visit, the payment accrual will update, taking the duplicate visit in the approved count.

counts = defaultdict(lambda: {"completed": 0, "approved": 0})

completed_works = completed_works.prefetch_related(
Prefetch("uservisit_set", queryset=UserVisit.objects.all()), "payment_unit"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the queryset necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant. I have removed the queryset since doing a preftech for uservisit set already does the same. Also removed the payment_unit prefetch here as that is also not needed.
f950ece

@pxwxnvermx pxwxnvermx requested a review from calellowitz March 31, 2025 05:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants