forked from uncloud/uncloud
Set one payment method as primary, allow updates
This commit is contained in:
parent
f2a797874a
commit
89c705f7d2
4 changed files with 45 additions and 13 deletions
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.3 on 2020-03-05 13:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('uncloud_pay', '0002_auto_20200305_1524.py'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paymentmethod',
|
||||
name='primary',
|
||||
field=models.BooleanField(default=False, editable=False),
|
||||
),
|
||||
]
|
|
@ -4,9 +4,7 @@ from django.contrib.auth import get_user_model
|
|||
from django.core.validators import MinValueValidator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils import timezone
|
||||
from django.dispatch import receiver
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
import django.db.models.signals as signals
|
||||
|
||||
import uuid
|
||||
from functools import reduce
|
||||
|
@ -106,7 +104,7 @@ class PaymentMethod(models.Model):
|
|||
),
|
||||
default='stripe')
|
||||
description = models.TextField()
|
||||
primary = models.BooleanField(default=True)
|
||||
primary = models.BooleanField(default=False, editable=False)
|
||||
|
||||
# Only used for "Stripe" source
|
||||
stripe_payment_method_id = models.CharField(max_length=32, blank=True, null=True)
|
||||
|
@ -149,22 +147,24 @@ class PaymentMethod(models.Model):
|
|||
else:
|
||||
raise Exception('This payment method is unsupported/cannot be charged.')
|
||||
|
||||
def set_as_primary_for(self, user):
|
||||
methods = PaymentMethod.objects.filter(owner=user, primary=True)
|
||||
for method in methods:
|
||||
print(method)
|
||||
method.primary = False
|
||||
method.save()
|
||||
|
||||
self.primary = True
|
||||
self.save()
|
||||
|
||||
def get_primary_for(user):
|
||||
methods = PaymentMethod.objects.filter(owner=user)
|
||||
for method in methods:
|
||||
# Do we want to do something with non-primary method?
|
||||
if method.active and method.primary:
|
||||
if method.primary:
|
||||
return method
|
||||
|
||||
return None
|
||||
|
||||
class Meta:
|
||||
# TODO: limit to one primary method per user.
|
||||
# unique_together is no good since it won't allow more than one
|
||||
# non-primary method.
|
||||
pass
|
||||
|
||||
###
|
||||
# Bills.
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class PaymentMethodSerializer(serializers.ModelSerializer):
|
|||
class UpdatePaymentMethodSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PaymentMethod
|
||||
fields = ['description', 'primary']
|
||||
fields = ['description']
|
||||
|
||||
class ChargePaymentMethodSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=10, decimal_places=2)
|
||||
|
@ -29,7 +29,8 @@ class CreatePaymentMethodSerializer(serializers.ModelSerializer):
|
|||
please_visit = serializers.CharField(read_only=True)
|
||||
class Meta:
|
||||
model = PaymentMethod
|
||||
fields = ['source', 'description', 'primary', 'please_visit']
|
||||
fields = ['uuid', 'primary', 'source', 'description', 'please_visit']
|
||||
read_only_field = ['uuid', 'primary']
|
||||
|
||||
###
|
||||
# Orders & Products.
|
||||
|
|
|
@ -64,6 +64,10 @@ class PaymentMethodViewSet(viewsets.ModelViewSet):
|
|||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
# Set newly created method as primary if no other method is.
|
||||
if PaymentMethod.get_primary_for(request.user) == None:
|
||||
serializer.validated_data['primary'] = True
|
||||
|
||||
if serializer.validated_data['source'] == "stripe":
|
||||
# Retrieve Stripe customer ID for user.
|
||||
customer_id = uncloud_stripe.get_customer_id_for(request.user)
|
||||
|
@ -109,6 +113,7 @@ class PaymentMethodViewSet(viewsets.ModelViewSet):
|
|||
@action(detail=True, methods=['get'], url_path='register-stripe-cc', renderer_classes=[TemplateHTMLRenderer])
|
||||
def register_stripe_cc(self, request, pk=None):
|
||||
payment_method = self.get_object()
|
||||
|
||||
if payment_method.source != 'stripe':
|
||||
return Response(
|
||||
{'error': 'This is not a Stripe-based payment method.'},
|
||||
|
@ -163,6 +168,14 @@ class PaymentMethodViewSet(viewsets.ModelViewSet):
|
|||
error = 'Could not fetch payment method from stripe. Please try again.'
|
||||
return Response({'error': error})
|
||||
|
||||
@action(detail=True, methods=['post'], url_path='set-as-primary')
|
||||
def set_as_primary(self, request, pk=None):
|
||||
payment_method = self.get_object()
|
||||
payment_method.set_as_primary_for(request.user)
|
||||
|
||||
serializer = self.get_serializer(payment_method)
|
||||
return Response(serializer.data)
|
||||
|
||||
###
|
||||
# Bills and Orders.
|
||||
|
||||
|
|
Loading…
Reference in a new issue