Skip to content

Commit

Permalink
avoid add subs and cancel consumption twice
Browse files Browse the repository at this point in the history
  • Loading branch information
jefer94 committed Aug 22, 2024
1 parent 97103c9 commit 8e35ea7
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 14 deletions.
11 changes: 11 additions & 0 deletions breathecode/payments/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,17 @@ def validate_and_create_subscriptions(
code=404,
)

if PlanFinancing.objects.filter(plans=plan, user=user, valid_until__gt=timezone.now()).exists():
raise ValidationException(
translation(
lang,
en=f"User already has a valid subscription for this plan: {user_pk}",
es=f"Usuario ya tiene una suscripción válida para este plan: {user_pk}",
slug="user-already-has-valid-subscription",
),
code=409,
)

bag = Bag()
bag.type = Bag.Type.BAG
bag.user = user
Expand Down
19 changes: 6 additions & 13 deletions breathecode/payments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1516,17 +1516,12 @@ def __str__(self):
return f"{self.user.email}: {self.service_item.service.slug} ({self.how_many})"


PENDING = "PENDING"
DONE = "DONE"
CANCELLED = "CANCELLED"
CONSUMPTION_SESSION_STATUS = [
(PENDING, "Pending"),
(DONE, "Done"),
(CANCELLED, "Cancelled"),
]


class ConsumptionSession(models.Model):
class Status(models.TextChoices):
PENDING = "PENDING", "Pending"
DONE = "DONE", "Done"
CANCELLED = "CANCELLED", "Cancelled"

operation_code = models.SlugField(
default="default", help_text="Code that identifies the operation, it could be repeated"
)
Expand All @@ -1535,9 +1530,7 @@ class ConsumptionSession(models.Model):
eta = models.DateTimeField(help_text="Estimated time of arrival")
duration = models.DurationField(blank=False, default=timedelta, help_text="Duration of the session")
how_many = models.FloatField(default=0, help_text="How many units of this service can be used")
status = models.CharField(
max_length=12, choices=CONSUMPTION_SESSION_STATUS, default=PENDING, help_text="Status of the session"
)
status = models.CharField(max_length=12, choices=Status, default=Status.PENDING, help_text="Status of the session")
was_discounted = models.BooleanField(default=False, help_text="Was it discounted")

request = models.JSONField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Test /answer
"""

from datetime import datetime
from datetime import datetime, timedelta
from unittest.mock import MagicMock, call

import pytest
Expand Down Expand Up @@ -248,6 +248,47 @@ def test_no_payment_method(database: capy.Database, format: capy.Format, is_requ
assert build_plan_financing.delay.call_args_list == []


@pytest.mark.parametrize("is_request", [True, False])
def test_plan_already_exists(database: capy.Database, format: capy.Format, is_request: bool, utc_now: datetime) -> None:
model = database.create(
user=1,
proof_of_payment=1,
plan={"time_of_life": None, "time_of_life_unit": None},
financing_option={"how_many_months": 1},
academy=1,
city=1,
country=1,
payment_method=1,
plan_financing={
"valid_until": utc_now + timedelta(days=30),
"plan_expires_at": utc_now + timedelta(days=30),
"monthly_price": 100,
},
)
data = {"plans": [model.plan.slug], "user": model.user.id, "payment_method": 1}
academy = 1

if is_request:
data = get_request(data, user=model.user)

with pytest.raises(ValidationException, match="user-already-has-valid-subscription"):
validate_and_create_subscriptions(data, model.user, model.proof_of_payment, academy, "en")

assert database.list_of("payments.Bag") == []
assert database.list_of("payments.Invoice") == []
assert database.list_of("payments.ProofOfPayment") == [
serialize_proof_of_payment(
data={
"id": 1,
"created_by_id": 1,
"status": "PENDING",
}
),
]

assert build_plan_financing.delay.call_args_list == []


@pytest.mark.parametrize("is_request", [True, False])
@pytest.mark.parametrize("field", ["id", "username", "email"])
def test_schedule_plan_financing(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def test_cancelled(bc: Breathecode, client: rfx.Client, utc_now, fake):
data={
"duration": duration,
"eta": utc_now + duration,
"status": "CANCELLED",
},
)
]
3 changes: 3 additions & 0 deletions breathecode/payments/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,9 @@ def put(self, request, service_slug, consumptionsession_id):
consumable = session.consumable
reimburse_service_units.send_robust(instance=consumable, sender=consumable.__class__, how_many=how_many)

session.status = session.Status.CANCELLED
session.save()

return Response({"id": session.id, "status": "reversed"}, status=status.HTTP_200_OK)


Expand Down

0 comments on commit 8e35ea7

Please sign in to comment.