Handle getting the correct user_card_detail
Fixes
Traceback (most recent call last):
File "<console>", line 2, in <module>
File "/home/app/pyvenv/lib/python3.5/site-packages/django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/app/pyvenv/lib/python3.5/site-packages/django/db/models/query.py", line 391, in get
(self.model._meta.object_name, num)
hosting.models.MultipleObjectsReturned: get() returned more than one UserCardDetail -- it returned 2!
This commit is contained in:
parent
fc1dc37840
commit
60ddfa78b0
3 changed files with 93 additions and 7 deletions
|
|
@ -613,7 +613,7 @@ class OrderConfirmationView(DetailView, FormView):
|
|||
# TODO check when we go through this case (to me, it seems useless)
|
||||
card_id = self.request.session.get('card_id')
|
||||
logger.debug("NO id_payment_method, using card: %s" % card_id)
|
||||
card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
context['cc_last4'] = card_detail.last4
|
||||
context['cc_brand'] = card_detail.brand
|
||||
context['cc_exp_year'] = card_detail.exp_year
|
||||
|
|
@ -852,7 +852,7 @@ class OrderConfirmationView(DetailView, FormView):
|
|||
return show_error(msg, self.request)
|
||||
elif 'card_id' in request.session:
|
||||
card_id = request.session.get('card_id')
|
||||
user_card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
user_card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
card_details_dict = {
|
||||
'last4': user_card_detail.last4,
|
||||
'brand': user_card_detail.brand,
|
||||
|
|
@ -1206,7 +1206,7 @@ def set_user_card(card_id, stripe_api_cus_id, custom_user,
|
|||
card_details_response):
|
||||
if card_id:
|
||||
logger.debug("card_id %s was in request" % card_id)
|
||||
user_card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
user_card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
card_details_dict = {
|
||||
'last4': user_card_detail.last4,
|
||||
'brand': user_card_detail.brand,
|
||||
|
|
|
|||
|
|
@ -700,7 +700,7 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
|
|||
@staticmethod
|
||||
def save_default_card_local(stripe_api_cus_id, card_id):
|
||||
stripe_cust = StripeCustomer.objects.get(stripe_id=stripe_api_cus_id)
|
||||
user_card_detail = UserCardDetail.objects.get(
|
||||
user_card_detail = UserCardDetail.get_ucd_from_stripe_cust_n_card_id(
|
||||
stripe_customer=stripe_cust, card_id=card_id
|
||||
)
|
||||
for card in stripe_cust.usercarddetail_set.all():
|
||||
|
|
@ -709,6 +709,92 @@ class UserCardDetail(AssignPermissionsMixin, models.Model):
|
|||
user_card_detail.preferred = True
|
||||
user_card_detail.save()
|
||||
|
||||
@staticmethod
|
||||
def get_ucd_from_card_id(card_id):
|
||||
try:
|
||||
user_card_details = UserCardDetail.objects.filter(
|
||||
card_id=card_id
|
||||
).order_by('-id')
|
||||
|
||||
if user_card_details.count() > 1:
|
||||
# Log a warning about the duplicate entries
|
||||
logger.warning(
|
||||
f"Multiple UserCardDetail objects found for card_id={card_id}. "
|
||||
f"Found {user_card_details.count()} objects. Using the latest one."
|
||||
)
|
||||
# Use the first object found
|
||||
user_card_detail = user_card_details.first()
|
||||
elif user_card_details.count() == 1:
|
||||
# Exactly one object found, proceed as intended
|
||||
user_card_detail = user_card_details.first()
|
||||
else:
|
||||
# No object found for the given customer and card_id.
|
||||
# Depending on expected behavior, you might want to raise an error or handle this case.
|
||||
# If the original get() call happened here, it would raise DoesNotExist.
|
||||
logger.error(
|
||||
f"No UserCardDetail found for card_id={card_id}."
|
||||
)
|
||||
raise UserCardDetail.DoesNotExist(f"No UserCardDetail found for card {card_id}")
|
||||
if user_card_details.count() > 1:
|
||||
# Log a warning about the duplicate entries
|
||||
logger.warning(
|
||||
f"Multiple UserCardDetail objects found for card_id={card_id}. "
|
||||
f"Found {user_card_details.count()} objects. Using the first one."
|
||||
)
|
||||
# Use the first object found
|
||||
user_card_detail = user_card_details.first()
|
||||
elif user_card_details.count() == 1:
|
||||
# Exactly one object found, proceed as intended
|
||||
user_card_detail = user_card_details.first()
|
||||
else:
|
||||
# No object found for the given customer and card_id.
|
||||
# Depending on expected behavior, you might want to raise an error or handle this case.
|
||||
# If the original get() call happened here, it would raise DoesNotExist.
|
||||
logger.error(
|
||||
f"No UserCardDetail found for card_id={card_id}."
|
||||
)
|
||||
raise UserCardDetail.DoesNotExist(f"No UserCardDetail found for card {card_id}")
|
||||
except Exception as e:
|
||||
# Catch other potential exceptions during the filter/get process if necessary
|
||||
logger.error(f"An unexpected error occurred while fetching UserCardDetail: {e}")
|
||||
raise
|
||||
return user_card_detail
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_ucd_from_stripe_cust_n_card_id(stripe_cust, card_id):
|
||||
try:
|
||||
user_card_details = UserCardDetail.objects.filter(
|
||||
stripe_customer=stripe_cust, card_id=card_id
|
||||
).order_by('-id')
|
||||
|
||||
if user_card_details.count() > 1:
|
||||
# Log a warning about the duplicate entries
|
||||
logger.warning(
|
||||
f"Multiple UserCardDetail objects found for stripe_customer_id={stripe_cust.id} and card_id={card_id}. "
|
||||
f"Found {user_card_details.count()} objects. Using the first one."
|
||||
)
|
||||
# Use the first object found
|
||||
user_card_detail = user_card_details.first()
|
||||
elif user_card_details.count() == 1:
|
||||
# Exactly one object found, proceed as intended
|
||||
user_card_detail = user_card_details.first()
|
||||
else:
|
||||
# No object found for the given customer and card_id.
|
||||
# Depending on expected behavior, you might want to raise an error or handle this case.
|
||||
# If the original get() call happened here, it would raise DoesNotExist.
|
||||
logger.error(
|
||||
f"No UserCardDetail found for stripe_customer_id={stripe_cust.id} and card_id={card_id}."
|
||||
)
|
||||
raise UserCardDetail.DoesNotExist(f"No UserCardDetail found for customer {stripe_cust.id}, card {card_id}")
|
||||
|
||||
except Exception as e:
|
||||
# Catch other potential exceptions during the filter/get process if necessary
|
||||
logger.error(f"An unexpected error occurred while fetching UserCardDetail: {e}")
|
||||
raise
|
||||
return user_card_detail
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_user_card_details(stripe_customer, card_details):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -810,7 +810,7 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
|||
card_id = form.cleaned_data.get('card')
|
||||
customer = owner.stripecustomer
|
||||
try:
|
||||
user_card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
user_card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
if not request.user.has_perm(
|
||||
'view_usercarddetail', user_card_detail
|
||||
):
|
||||
|
|
@ -1014,7 +1014,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
|||
context['cc_exp_month'] = card_details_response['exp_month']
|
||||
else:
|
||||
card_id = self.request.session.get('card_id')
|
||||
card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
context['cc_last4'] = card_detail.last4
|
||||
context['cc_brand'] = card_detail.brand
|
||||
context['cc_exp_year'] = card_detail.exp_year
|
||||
|
|
@ -1128,7 +1128,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
|||
return JsonResponse(response)
|
||||
else:
|
||||
card_id = request.session.get('card_id')
|
||||
user_card_detail = UserCardDetail.objects.get(id=card_id)
|
||||
user_card_detail = UserCardDetail.get_ucd_from_card_id(card_id=card_id)
|
||||
card_details_dict = {
|
||||
'last4': user_card_detail.last4,
|
||||
'brand': user_card_detail.brand,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue