Skip to content

Commit

Permalink
fix: filters for only active policies for spend_limit check (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 authored Jun 25, 2024
1 parent 52a6f72 commit 1c20396
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ def test_update_views(self, is_patch, request_payload):
enterprise_customer_uuid=self.enterprise_uuid,
display_name='old display_name',
spend_limit=5,
active=False,
active=True,
)

action = self.client.patch if is_patch else self.client.put
Expand Down Expand Up @@ -680,14 +680,13 @@ def test_update_views_with_exceeding_spend_limit(self):
enterprise_customer_uuid=self.enterprise_uuid,
display_name='old display_name',
spend_limit=5,
active=False,
active=True,
)

request_payload = {
'description': 'the new description',
'display_name': 'new display_name',
'active': True,
'retired': True,
'catalog_uuid': str(uuid4()),
'subsidy_uuid': str(uuid4()),
'access_method': AccessMethods.ASSIGNED,
Expand All @@ -699,10 +698,46 @@ def test_update_views_with_exceeding_spend_limit(self):
'api:v1:subsidy-access-policies-detail',
kwargs={'uuid': str(policy_for_edit.uuid)}
)

with self.assertRaises(ValidationError):
self.client.patch(url, data=request_payload)

def test_update_views_with_exceeding_spend_limit_for_inactive_policies(self):
"""
Test that the update and partial_update views can modify certain
fields of a policy record.
"""
# Set the JWT-based auth to an operator.
self.set_jwt_cookie([
{'system_wide_role': SYSTEM_ENTERPRISE_OPERATOR_ROLE, 'context': str(TEST_ENTERPRISE_UUID)}
])

policy_for_edit = PerLearnerSpendCapLearnerCreditAccessPolicyFactory(
enterprise_customer_uuid=self.enterprise_uuid,
display_name='old display_name',
spend_limit=5,
active=True,
)

request_payload = {
'description': 'the new description',
'display_name': 'new display_name',
'catalog_uuid': str(uuid4()),
'active': False,
'subsidy_uuid': str(uuid4()),
'access_method': AccessMethods.ASSIGNED,
'spend_limit': 6,
'per_learner_spend_limit': 10000,
}

url = reverse(
'api:v1:subsidy-access-policies-detail',
kwargs={'uuid': str(policy_for_edit.uuid)}
)

response = self.client.patch(url, data=request_payload)

self.assertEqual(response.status_code, status.HTTP_200_OK)

@ddt.data(
{
'enterprise_customer_uuid': str(uuid4()),
Expand All @@ -726,7 +761,7 @@ def test_update_views_fields_disallowed_for_update(self, request_payload):
policy_for_edit = PerLearnerSpendCapLearnerCreditAccessPolicyFactory(
enterprise_customer_uuid=self.enterprise_uuid,
spend_limit=5,
active=False,
active=True,
)
url = reverse(
'api:v1:subsidy-access-policies-detail',
Expand Down
26 changes: 17 additions & 9 deletions enterprise_access/apps/subsidy_access_policy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,16 +317,13 @@ def total_spend_limit_for_all_policies_associated_to_subsidy(self):
"""
Sums the policies spend_limit excluding the db's instance of this policy
"""
policy_balances = []
policy_balances.append(self.spend_limit or 0)
sibling_policies = SubsidyAccessPolicy.objects.filter(
spend_limit = self.spend_limit if self.active and self.spend_limit else 0
sibling_policies_sum = SubsidyAccessPolicy.objects.filter(
enterprise_customer_uuid=self.enterprise_customer_uuid,
subsidy_uuid=self.subsidy_uuid,
).exclude(uuid=self.uuid)

for sibling in sibling_policies:
policy_balances.append(sibling.spend_limit or 0)
return sum(policy_balances)
active=True
).exclude(uuid=self.uuid).aggregate(models.Sum("spend_limit", default=0))["spend_limit__sum"]
return spend_limit + sibling_policies_sum

@property
def is_spend_limit_updated(self):
Expand All @@ -339,6 +336,17 @@ def is_spend_limit_updated(self):
record_from_db = SubsidyAccessPolicy.objects.get(uuid=self.uuid)
return record_from_db.spend_limit != self.spend_limit

@property
def is_active_updated(self):
"""
Checks if SubsidyAccessPolicy object exists in the database, and determines if the
database value of active flag differs from the current instance of active
"""
if self._state.adding:
return False
record_from_db = SubsidyAccessPolicy.objects.get(uuid=self.uuid)
return record_from_db.active != self.active

@property
def is_assignable(self):
"""
Expand All @@ -350,7 +358,7 @@ def clean(self):
"""
Used to help validate field values before saving this model instance.
"""
if self.is_spend_limit_updated:
if self.active and (self.is_active_updated or self.is_spend_limit_updated):
if self.total_spend_limit_for_all_policies_associated_to_subsidy > self.subsidy_total_deposits():
raise ValidationError(f'{self} {VALIDATION_ERROR_SPEND_LIMIT_EXCEEDS_STARTING_BALANCE}')
for field_name, (constraint_function, error_message) in self.FIELD_CONSTRAINTS.items():
Expand Down

0 comments on commit 1c20396

Please sign in to comment.