Skip to content

Commit

Permalink
Add flag to indicate permit has pending requests
Browse files Browse the repository at this point in the history
Refs: PV-779
  • Loading branch information
danjacob-anders authored and mhieta committed Feb 14, 2024
1 parent cff80f0 commit fc5cd98
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Migration(migrations.Migration):
choices=[
("PENDING", "Pending"),
("APPROVED", "Approved"),
("REJECTED", "Rejected"),
("CANCELLED", "Cancelled"),
],
default="Pending",
max_length=12,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.1 on 2024-02-14 11:59

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("parking_permits", "0050_merge_20240208_0845"),
]

operations = [
migrations.AlterField(
model_name="parkingpermitextensionrequest",
name="status",
field=models.CharField(
choices=[
("PENDING", "Pending"),
("APPROVED", "Approved"),
("CANCELLED", "Cancelled"),
],
default="PENDING",
max_length=12,
),
),
]
27 changes: 25 additions & 2 deletions parking_permits/models/parking_permit.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,12 @@ def latest_order(self):
Multiple orders can be created for the same permit
when, for example, the vehicle or the address of
the permit is changed.
If extension request order, returns that order instead
"""
if order := self.latest_extension_request_order:
return order

return self.orders.latest("id") if self.orders.exists() else None

@property
Expand All @@ -303,14 +308,26 @@ def checkout_url(self):
return self.latest_order.talpa_checkout_url
return None

@property
def has_pending_extension_request(self):
return self.get_pending_extension_requests().exists()

@property
def latest_extension_request_order(self):
if ext_request := self.permit_extension_requests.select_related(
"order"
).first():
return ext_request.order
return None

@property
def latest_order_items(self):
"""Get latest order items for the permit"""
return self.order_items.filter(order=self.latest_order)

@property
def latest_order_item(self):
return self.latest_order_items.first() or None
return self.latest_order_items.first()

@property
def permit_prices(self):
Expand Down Expand Up @@ -443,7 +460,7 @@ def can_extend_permit(self):
return False

# do database op last
return not self.get_pending_extension_requests().exists()
return not self.has_pending_extension_request

def get_pending_extension_requests(self):
return self.permit_extension_requests.pending()
Expand Down Expand Up @@ -688,6 +705,8 @@ def end_permit(self, end_type, force_end=False):
or end_type == ParkingPermitEndType.PREVIOUS_DAY_END
):
self.status = ParkingPermitStatus.CLOSED

self.cancel_extension_requests()
self.save()

def extend_permit(self, additional_months):
Expand All @@ -696,6 +715,10 @@ def extend_permit(self, additional_months):
self.end_time = get_end_time(self.start_time, self.month_count)
self.save()

def cancel_extension_requests(self):
for ext_request in self.get_pending_extension_requests():
ext_request.cancel()

def get_refund_amount_for_unused_items(self):
total = Decimal(0)
if not self.can_be_refunded:
Expand Down
12 changes: 6 additions & 6 deletions parking_permits/models/permit_extension_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ParkingPermitExtensionRequest(TimestampedModelMixin):
class Status(models.TextChoices):
PENDING = "PENDING", _("Pending")
APPROVED = "APPROVED", _("Approved")
REJECTED = "REJECTED", _("Rejected")
CANCELLED = "CANCELLED", _("Cancelled")

permit = models.ForeignKey(
"parking_permits.ParkingPermit",
Expand Down Expand Up @@ -53,12 +53,12 @@ def __str__(self):
def is_approved(self):
return self.status == self.Status.APPROVED

def is_rejected(self):
return self.status == self.Status.REJECTED

def is_pending(self):
return self.status == self.Status.PENDING

def is_cancelled(self):
return self.status == self.Status.CANCELLED

def get_end_time(self):
return self.permit.current_period_end_time + relativedelta(
months=self.month_count
Expand All @@ -68,8 +68,8 @@ def approve(self):
self.set_status(self.Status.APPROVED)
self.permit.extend_permit(self.month_count)

def reject(self):
self.set_status(self.Status.REJECTED)
def cancel(self):
self.set_status(self.Status.CANCELLED)

def set_status(self, new_status, commit=True):
self.status = new_status
Expand Down
1 change: 1 addition & 0 deletions parking_permits/schema/parking_permit.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type PermitNode {
canEndImmediately: Boolean
canEndAfterCurrentPeriod: Boolean
canExtendPermit: Boolean
hasPendingExtensionRequest: Boolean
hasRefund: Boolean
vehicleChanged: Boolean
zoneChanged: Boolean
Expand Down
2 changes: 1 addition & 1 deletion parking_permits/talpa/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def create_item_data(cls, order, order_item):
def append_detail_meta(cls, item, permit, fixed_end_time=None, ext_request=None):
start_time = tz.localtime(permit.start_time).strftime(DATE_FORMAT)
if ext_request:
permit_type = _("Fixed period, extension %(month)d month(s)") % {
permit_type = _("Fixed period, extension %(month)d months") % {
"month": ext_request.month_count
}
elif permit.is_fixed_period:
Expand Down
31 changes: 31 additions & 0 deletions parking_permits/tests/models/test_parking_permit.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,31 @@ def test_should_return_correct_end_time_of_current_time(self):
timezone.make_aware(datetime(2022, 2, 19, 23, 59, 59, 999999)),
)

@freeze_time(timezone.make_aware(datetime(2021, 11, 20, 12, 10, 50)))
def test_should_cancel_all_extensions_on_end_permit(self):
start_time = timezone.make_aware(datetime(2021, 11, 15))
end_time = get_end_time(start_time, 6)
permit = ParkingPermitFactory(
contract_type=ContractType.FIXED_PERIOD,
start_time=start_time,
end_time=end_time,
month_count=6,
)
approved = ParkingPermitExtensionRequestFactory(
permit=permit, status=ParkingPermitExtensionRequest.Status.APPROVED
)
pending = ParkingPermitExtensionRequestFactory(
permit=permit, status=ParkingPermitExtensionRequest.Status.PENDING
)

permit.end_permit(ParkingPermitEndType.IMMEDIATELY)

approved.refresh_from_db()
assert approved.is_approved()

pending.refresh_from_db()
assert pending.is_cancelled()

@freeze_time(timezone.make_aware(datetime(2021, 11, 20, 12, 10, 50)))
def test_should_set_end_time_to_now_if_end_permit_immediately(self):
start_time = timezone.make_aware(datetime(2021, 11, 15))
Expand Down Expand Up @@ -735,6 +760,12 @@ def test_checkout_url_if_latest_order_not_none(self):
self.permit.orders.add(item.order)
self.assertEqual(self.permit.checkout_url, item.order.talpa_checkout_url)

def test_checkout_url_if_latest_order_and_pending_request(self):
ext_request = ParkingPermitExtensionRequestFactory(permit=self.permit)
item = OrderItemFactory(permit=self.permit)
self.permit.orders.add(item.order)
self.assertEqual(self.permit.checkout_url, ext_request.order.talpa_checkout_url)

def test_can_be_refunded_fixed(self):
permit = ParkingPermitFactory(
contract_type=ContractType.FIXED_PERIOD,
Expand Down
7 changes: 3 additions & 4 deletions parking_permits/tests/models/test_permit_extension_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ def test_approve(self):
self.assertEqual(self.ext_request.permit.month_count, 4)
self.assertFalse(ParkingPermitExtensionRequest.objects.pending().exists())

def test_reject(self):
self.ext_request.reject()
self.assertTrue(self.ext_request.is_rejected())
self.assertEqual(self.ext_request.permit.month_count, 1)
def test_cancel(self):
self.ext_request.cancel()
self.assertTrue(self.ext_request.is_cancelled())
self.assertFalse(ParkingPermitExtensionRequest.objects.pending().exists())
2 changes: 1 addition & 1 deletion parking_permits/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def test_should_not_extend_permit_on_unsuccessful_payment(self):
self.assertEqual(response.status_code, 400)

ext_request.refresh_from_db()
self.assertTrue(ext_request.is_rejected())
self.assertTrue(ext_request.is_cancelled())

def test_payment_view_should_return_bad_request_if_talpa_order_id_missing(self):
data = {
Expand Down
6 changes: 2 additions & 4 deletions parking_permits/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,10 +526,8 @@ def post(self, request, format=None):
logger.info(f"{order} is confirmed and order permits are set to VALID ")
return Response({"message": "Payment received"}, status=200)
else:
for (
ext_request
) in order.get_pending_permit_extension_requests().select_related("permit"):
ext_request.reject()
for ext_request in order.get_pending_permit_extension_requests():
ext_request.cancel()

return bad_request_response(f"Unknown payment event type {event_type}")

Expand Down

0 comments on commit fc5cd98

Please sign in to comment.