Skip to content

Commit

Permalink
Refactor make refund
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerome-Celle committed Nov 21, 2019
1 parent ce2bdc4 commit c87e737
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 83 deletions.
50 changes: 45 additions & 5 deletions retirement/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
import traceback
from datetime import timedelta

from django.conf import settings

import requests
from django.conf import settings
from django.core.mail import mail_admins, send_mail
from django.template.loader import render_to_string
from django.utils import timezone
from rest_framework.reverse import reverse

from blitz_api.models import Address
from django.contrib.auth import get_user_model
Expand All @@ -22,10 +19,12 @@
from simple_history.models import HistoricalRecords

from log_management.models import Log
from store.models import Membership, OrderLine, BaseProduct,\
Coupon
from store.models import Membership, OrderLine, BaseProduct, \
Coupon, Refund
from store.services import refund_amount

User = get_user_model()
TAX_RATE = settings.LOCAL_SETTINGS['SELLING_TAX']


class Retreat(Address, SafeDeleteModel, BaseProduct):
Expand Down Expand Up @@ -498,6 +497,47 @@ class Reservation(SafeDeleteModel):
def __str__(self):
return str(self.user)

def get_refund_value(self, total_refund=False):
# First get net pay: total cost
refund_value = float(self.order_line.cost)
# Add the tax rate, so we have the real value pay by the user
refund_value *= TAX_RATE + 1.0

if not total_refund:
# keep only the part that the retreat allow to refund
refund_value *= self.retreat.refund_rate / 100

# Remove value already refund
previous_refunds = self.order_line.refunds
if previous_refunds:
refund_value -= sum(
previous_refunds.all().values_list('amount', flat=True)
)

return round(refund_value, 2) if refund_value > 0 else 0

def make_refund(self, refund_reason, total_refund=False):

amount_to_refund = self.get_refund_value(total_refund)

# paysafe use value without cent
amount_to_refund_paysafe = int(round(amount_to_refund * 100))

refund_response = refund_amount(
self.order_line.order.settlement_id,
amount_to_refund_paysafe
)
refund_res_content = refund_response.json()

refund = Refund.objects.create(
orderline=self.order_line,
refund_date=timezone.now(),
amount=amount_to_refund,
details=refund_reason,
refund_id=refund_res_content['id'],
)
return refund


class WaitQueue(models.Model):
"""
Expand Down
9 changes: 3 additions & 6 deletions retirement/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from copy import copy
from datetime import timedelta
from decimal import Decimal, DecimalException
from decimal import Decimal
import json
import requests
import traceback
Expand All @@ -11,33 +10,31 @@
from django.core.mail import mail_admins
from django.core.mail import send_mail
from django.db import transaction
from django.db.models import F
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers, status
from rest_framework import serializers
from rest_framework.reverse import reverse
from rest_framework.validators import UniqueValidator

from blitz_api.services import (check_if_translated_field,
remove_translation_fields,
getMessageTranslate)
from log_management.models import Log
from retirement.services import refund_retreat
from store.exceptions import PaymentAPIError
from store.models import Order, OrderLine, PaymentProfile, Refund
from store.serializers import BaseProductSerializer, CouponSerializer
from store.services import (charge_payment,
create_external_payment_profile,
create_external_card,
get_external_cards,
PAYSAFE_CARD_TYPE,
PAYSAFE_EXCEPTION,
refund_amount, )

from .fields import TimezoneField
from .models import (Picture, Reservation, Retreat, WaitQueue,
WaitQueueNotification, RetreatInvitation)
from .services import refund_retreat

User = get_user_model()

Expand Down
153 changes: 140 additions & 13 deletions retirement/tests/tests_model_Reservation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timedelta
from datetime import datetime

import pytz
from django.conf import settings
Expand All @@ -8,20 +8,21 @@

from blitz_api.factories import UserFactory

from store.models import Order, OrderLine
from store.models import Order, OrderLine, Coupon

from ..models import Reservation, Retreat

LOCAL_TIMEZONE = pytz.timezone(settings.TIME_ZONE)

TAX_RATE = settings.LOCAL_SETTINGS['SELLING_TAX']


class ReservationTests(APITestCase):
@classmethod
def setUpClass(cls):
super(ReservationTests, cls).setUpClass()
cls.user = UserFactory()
cls.retreat_type = ContentType.objects.get_for_model(Retreat)
cls.retreat = Retreat.objects.create(

def setUp(self):
self.user = UserFactory()
self.retreat_type = ContentType.objects.get_for_model(Retreat)
self.retreat = Retreat.objects.create(
name="random_retreat",
details="This is a description of the retreat.",
seats=40,
Expand All @@ -42,16 +43,16 @@ def setUpClass(cls):
review_url='example3.com',
has_shared_rooms=True
)
cls.order = Order.objects.create(
user=cls.user,
self.order = Order.objects.create(
user=self.user,
transaction_date=timezone.now(),
authorization_id=1,
settlement_id=1,
)
cls.order_line = OrderLine.objects.create(
order=cls.order,
self.order_line = OrderLine.objects.create(
order=self.order,
quantity=999,
content_type=cls.retreat_type,
content_type=self.retreat_type,
object_id=1,
)

Expand All @@ -67,3 +68,129 @@ def test_create(self):
)

self.assertEqual(str(reservation), str(self.user))

def test_refund_value_with_coupon(self):

retreat = Retreat.objects.create(
name="random_retreat",
details="This is a description of the retreat.",
seats=40,
address_line1="123 random street",
postal_code="123 456",
state_province="Random state",
country="Random country",
price=100,
start_time=LOCAL_TIMEZONE.localize(datetime(2130, 1, 15, 8)),
end_time=LOCAL_TIMEZONE.localize(datetime(2130, 1, 17, 12)),
min_day_refund=7,
min_day_exchange=7,
refund_rate=90,
is_active=True,
accessibility=True,
form_url="example.com",
carpool_url='example2.com',
review_url='example3.com',
has_shared_rooms=True
)

order = Order.objects.create(
user=self.user,
transaction_date=timezone.now(),
authorization_id=1,
settlement_id=1,
)

coupon = Coupon.objects.create(
value=20,
code="ASD1234E",
start_time="2019-01-06T15:11:05-05:00",
end_time="2020-01-06T15:11:06-05:00",
max_use=100,
max_use_per_user=2,
details="detail",
owner=self.user,
)

order_line = OrderLine.objects.create(
order=order,
quantity=999,
content_type=self.retreat_type,
object_id=1,
cost=80,
coupon_real_value=20,
coupon=coupon
)

reservation = Reservation.objects.create(
user=self.user,
retreat=retreat,
order_line=order_line,
is_active=True,
)

refund_value = reservation.get_refund_value()

self.assertEqual(refund_value, round(72 * (TAX_RATE + 1.0), 2))

def test_refund_value_100(self):

retreat = Retreat.objects.create(
name="random_retreat",
details="This is a description of the retreat.",
seats=40,
address_line1="123 random street",
postal_code="123 456",
state_province="Random state",
country="Random country",
price=100,
start_time=LOCAL_TIMEZONE.localize(datetime(2130, 1, 15, 8)),
end_time=LOCAL_TIMEZONE.localize(datetime(2130, 1, 17, 12)),
min_day_refund=7,
min_day_exchange=7,
refund_rate=100,
is_active=True,
accessibility=True,
form_url="example.com",
carpool_url='example2.com',
review_url='example3.com',
has_shared_rooms=True
)

order = Order.objects.create(
user=self.user,
transaction_date=timezone.now(),
authorization_id=1,
settlement_id=1,
)

coupon = Coupon.objects.create(
value=20,
code="ASD1234E",
start_time="2019-01-06T15:11:05-05:00",
end_time="2020-01-06T15:11:06-05:00",
max_use=100,
max_use_per_user=2,
details="detail",
owner=self.user,
)

order_line = OrderLine.objects.create(
order=order,
quantity=999,
content_type=self.retreat_type,
object_id=1,
cost=80,
coupon_real_value=20,
coupon=coupon
)

reservation = Reservation.objects.create(
user=self.user,
retreat=retreat,
order_line=order_line,
is_active=True,
)

refund_value = reservation.get_refund_value()

self.assertEqual(refund_value, round(80 * (TAX_RATE + 1.0), 2))
Loading

0 comments on commit c87e737

Please sign in to comment.