Skip to content

Commit

Permalink
Merge pull request #436 from FJNR-inc/develop
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
RignonNoel authored Mar 19, 2020
2 parents 1a168bb + e031b38 commit 22426c5
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
1 change: 1 addition & 0 deletions retirement/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ class Reservation(SafeDeleteModel):
('U', _("User canceled")),
('RD', _("Retreat deleted")),
('RM', _("Retreat modified")),
('A', _("Admin canceled")),
)

CANCELATION_ACTION = (
Expand Down
46 changes: 46 additions & 0 deletions retirement/tests/tests_viewset_Reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,52 @@ def test_delete_not_owner(self):

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

@responses.activate
def test_delete_reservation_of_user_as_admin_no_refundable(self):
"""
Ensure that an admin can cancel the reservations of a user.
This cancelation does not respect 'refundable', the user
will not be refunded.
The user won't receive any email.
"""
self.client.force_authenticate(user=self.admin)

self.reservation.refundable = False
self.reservation.save()

FIXED_TIME = datetime(2000, 1, 10, tzinfo=LOCAL_TIMEZONE)

with mock.patch(
'django.utils.timezone.now', return_value=FIXED_TIME):
response = self.client.delete(
reverse(
'retreat:reservation-detail',
kwargs={'pk': self.reservation.pk},
),
)

self.assertEqual(
response.status_code,
status.HTTP_204_NO_CONTENT,
response.content
)

self.reservation.refresh_from_db()

self.assertFalse(self.reservation.is_active)
self.assertEqual(self.reservation.cancelation_reason, 'A')
self.assertEqual(self.reservation.cancelation_action, 'N')
self.assertEqual(self.reservation.cancelation_date, FIXED_TIME)

self.reservation.is_active = True
self.reservation.cancelation_date = None
self.reservation.cancelation_reason = None

self.assertEqual(len(mail.outbox), 0)

self.reservation.refundable = True
self.reservation.save()

def test_delete_orderline_quantity_too_big(self):
"""
Ensure that a user can't delete a reservation if the orderline
Expand Down
28 changes: 26 additions & 2 deletions retirement/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _

import rest_framework
from rest_framework import mixins, status, viewsets
from rest_framework import serializers as rest_framework_serializers
from rest_framework.decorators import action
Expand Down Expand Up @@ -321,6 +323,11 @@ def destroy(self, request, *args, **kwargs):
user = instance.user
reservation_active = instance.is_active
order_line = instance.order_line
data = request.data
force_refund = False

if self.request.user.is_staff:
force_refund = data.get('force_refund', False)

if order_line:
order = order_line.order
Expand All @@ -333,6 +340,18 @@ def destroy(self, request, *args, **kwargs):
(retreat.start_time - timezone.now()) >=
timedelta(days=retreat.min_day_refund))

# In order to process a refund we need to be in one of those
# two cases:
#
# 1 - We respect the date limit to be refund and the retreat is
# refundable
#
# 2 - An admin want to force a refund and the user paid for
# his reservation

process_refund = (respects_minimum_days and refundable) or\
(force_refund and order_line)

with transaction.atomic():
# No need to check for previous refunds because a refunded
# reservation == canceled reservation, thus not active.
Expand All @@ -345,7 +364,7 @@ def destroy(self, request, *args, **kwargs):
"support team."
)]
})
if respects_minimum_days and refundable:
if process_refund:
try:
refund = instance.make_refund("Reservation canceled")
except PaymentAPIError as err:
Expand All @@ -372,7 +391,12 @@ def destroy(self, request, *args, **kwargs):
instance.cancelation_action = 'N'

instance.is_active = False
instance.cancelation_reason = 'U'

if self.request.user.id != user.id:
instance.cancelation_reason = 'A'
else:
instance.cancelation_reason = 'U'

instance.cancelation_date = timezone.now()
instance.save()

Expand Down

0 comments on commit 22426c5

Please sign in to comment.