| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | from Crypto.PublicKey import RSA | 
					
						
							|  |  |  | from dateutil.relativedelta import relativedelta | 
					
						
							| 
									
										
										
										
											2015-05-27 12:21:30 +02:00
										 |  |  | from django.db import models | 
					
						
							| 
									
										
										
										
											2017-09-30 18:05:02 +05:30
										 |  |  | from django.utils import timezone | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  | from django.utils.functional import cached_property | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 18:33:10 +02:00
										 |  |  | from datacenterlight.models import VMPricing, VMTemplate | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  | from membership.models import StripeCustomer, CustomUser | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | from utils.models import BillingAddress | 
					
						
							| 
									
										
										
										
											2017-08-21 00:41:46 +05:30
										 |  |  | from utils.mixins import AssignPermissionsMixin | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  | from utils.stripe_utils import StripeUtils | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 16:23:03 +05:30
										 |  |  | logger = logging.getLogger(__name__) | 
					
						
							| 
									
										
										
										
											2016-04-17 19:52:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  | class HostingPlan(models.Model): | 
					
						
							|  |  |  |     disk_size = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     cpu_cores = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     memory = models.FloatField(default=0.0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def serialize(self): | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'id': self.id, | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |             'cpu': self.cpu_cores, | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  |             'memory': self.memory, | 
					
						
							|  |  |  |             'disk_size': self.disk_size, | 
					
						
							|  |  |  |             'price': self.price(), | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_serialized_configs(cls): | 
					
						
							|  |  |  |         return [cfg.serialize() | 
					
						
							|  |  |  |                 for cfg in cls.objects.all()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def price(self): | 
					
						
							| 
									
										
										
										
											2017-05-14 02:17:48 +02:00
										 |  |  |         price = self.disk_size * 0.6 | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  |         price += self.cpu_cores * 5 | 
					
						
							|  |  |  |         price += self.memory * 2 | 
					
						
							|  |  |  |         return price | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 22:30:23 +02:00
										 |  |  | class OrderDetail(AssignPermissionsMixin, models.Model): | 
					
						
							| 
									
										
										
										
											2018-07-01 19:23:05 +02:00
										 |  |  |     vm_template = models.ForeignKey( | 
					
						
							|  |  |  |         VMTemplate, blank=True, null=True, default=None, | 
					
						
							|  |  |  |         on_delete=models.SET_NULL | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-07-01 18:33:10 +02:00
										 |  |  |     cores = models.IntegerField(default=0) | 
					
						
							|  |  |  |     memory = models.IntegerField(default=0) | 
					
						
							|  |  |  |     hdd_size = models.IntegerField(default=0) | 
					
						
							|  |  |  |     ssd_size = models.IntegerField(default=0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							| 
									
										
										
										
											2018-07-01 19:46:21 +02:00
										 |  |  |         return "%s - %s, %s cores, %s GB RAM, %s GB SSD" % ( | 
					
						
							|  |  |  |             self.vm_template.name, self.vm_template.vm_type, self.cores, | 
					
						
							|  |  |  |             self.memory, self.ssd_size | 
					
						
							| 
									
										
										
										
											2018-07-01 18:33:10 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  | class HostingOrder(AssignPermissionsMixin, models.Model): | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     ORDER_APPROVED_STATUS = 'Approved' | 
					
						
							|  |  |  |     ORDER_DECLINED_STATUS = 'Declined' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |     vm_id = models.IntegerField(default=0) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     customer = models.ForeignKey(StripeCustomer) | 
					
						
							|  |  |  |     billing_address = models.ForeignKey(BillingAddress) | 
					
						
							|  |  |  |     created_at = models.DateTimeField(auto_now_add=True) | 
					
						
							|  |  |  |     approved = models.BooleanField(default=False) | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     last4 = models.CharField(max_length=4) | 
					
						
							|  |  |  |     cc_brand = models.CharField(max_length=10) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     stripe_charge_id = models.CharField(max_length=100, null=True) | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |     price = models.FloatField() | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |     subscription_id = models.CharField(max_length=100, null=True) | 
					
						
							| 
									
										
										
										
											2018-04-16 03:23:09 +02:00
										 |  |  |     vm_pricing = models.ForeignKey(VMPricing) | 
					
						
							| 
									
										
										
										
											2018-07-01 22:30:23 +02:00
										 |  |  |     order_detail = models.ForeignKey( | 
					
						
							|  |  |  |         OrderDetail, null=True, blank=True, default=None, | 
					
						
							| 
									
										
										
										
											2018-07-01 19:23:05 +02:00
										 |  |  |         on_delete=models.SET_NULL | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  |     permissions = ('view_hostingorder',) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Meta: | 
					
						
							|  |  |  |         permissions = ( | 
					
						
							|  |  |  |             ('view_hostingorder', 'View Hosting Order'), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-14 02:12:42 -04:30
										 |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return "%s" % (self.id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |     @cached_property | 
					
						
							|  |  |  |     def status(self): | 
					
						
							|  |  |  |         return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2018-04-21 22:27:43 +05:30
										 |  |  |     def create(cls, price=None, vm_id=0, customer=None, | 
					
						
							| 
									
										
										
										
											2018-04-16 03:36:56 +02:00
										 |  |  |                billing_address=None, vm_pricing=None): | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |         instance = cls.objects.create( | 
					
						
							|  |  |  |             price=price, | 
					
						
							|  |  |  |             vm_id=vm_id, | 
					
						
							|  |  |  |             customer=customer, | 
					
						
							| 
									
										
										
										
											2018-04-16 03:36:56 +02:00
										 |  |  |             billing_address=billing_address, | 
					
						
							|  |  |  |             vm_pricing=vm_pricing | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-07-10 22:08:51 -05:00
										 |  |  |         instance.assign_permissions(customer.user) | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |         return instance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_approved(self): | 
					
						
							|  |  |  |         self.approved = True | 
					
						
							|  |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_stripe_charge(self, stripe_charge): | 
					
						
							|  |  |  |         self.stripe_charge_id = stripe_charge.id | 
					
						
							| 
									
										
										
										
											2016-05-03 00:59:40 -05:00
										 |  |  |         self.last4 = stripe_charge.source.last4 | 
					
						
							|  |  |  |         self.cc_brand = stripe_charge.source.brand | 
					
						
							| 
									
										
										
										
											2016-04-26 01:16:03 -05:00
										 |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |     def set_subscription_id(self, subscription_id, cc_details): | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         When creating a Stripe subscription, we have subscription id. | 
					
						
							|  |  |  |         We store this in the subscription_id field. | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         This method sets the subscription id | 
					
						
							|  |  |  |         and the last4 and credit card brands used for this order. | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         :param subscription_id: Stripe's subscription id | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         :param cc_details: A dict containing card details | 
					
						
							|  |  |  |         {last4, brand} | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2017-09-29 08:42:17 +02:00
										 |  |  |         self.subscription_id = subscription_id | 
					
						
							| 
									
										
										
										
											2017-08-24 12:51:55 +05:30
										 |  |  |         self.last4 = cc_details.get('last4') | 
					
						
							|  |  |  |         self.cc_brand = cc_details.get('brand') | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |         self.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 00:11:33 -05:00
										 |  |  |     def get_cc_data(self): | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'last4': self.last4, | 
					
						
							|  |  |  |             'cc_brand': self.cc_brand, | 
					
						
							|  |  |  |         } if self.last4 and self.cc_brand else None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-23 02:22:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  | class UserHostingKey(models.Model): | 
					
						
							|  |  |  |     user = models.ForeignKey(CustomUser) | 
					
						
							|  |  |  |     public_key = models.TextField() | 
					
						
							| 
									
										
										
										
											2017-08-17 18:16:36 +02:00
										 |  |  |     private_key = models.FileField(upload_to='private_keys', blank=True) | 
					
						
							| 
									
										
										
										
											2017-05-03 23:19:32 -05:00
										 |  |  |     created_at = models.DateTimeField(auto_now_add=True) | 
					
						
							|  |  |  |     name = models.CharField(max_length=100) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def generate_RSA(bits=2048): | 
					
						
							|  |  |  |         '''
 | 
					
						
							|  |  |  |         Generate an RSA keypair with an exponent of 65537 in PEM format | 
					
						
							|  |  |  |         param: bits The key length in bits | 
					
						
							|  |  |  |         Return private key and public key | 
					
						
							|  |  |  |         '''
 | 
					
						
							|  |  |  |         new_key = RSA.generate(2048, os.urandom) | 
					
						
							|  |  |  |         public_key = new_key.publickey().exportKey("OpenSSH") | 
					
						
							|  |  |  |         private_key = new_key.exportKey("PEM") | 
					
						
							|  |  |  |         return private_key, public_key | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def generate_keys(cls): | 
					
						
							|  |  |  |         private_key, public_key = cls.generate_RSA() | 
					
						
							|  |  |  |         # self.public_key = public_key | 
					
						
							|  |  |  |         # self.save(update_fields=['public_key']) | 
					
						
							|  |  |  |         return private_key, public_key | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 14:59:11 +02:00
										 |  |  | class HostingBill(AssignPermissionsMixin, models.Model): | 
					
						
							|  |  |  |     customer = models.ForeignKey(StripeCustomer) | 
					
						
							|  |  |  |     billing_address = models.ForeignKey(BillingAddress) | 
					
						
							| 
									
										
										
										
											2017-05-06 14:44:08 +02:00
										 |  |  |     total_price = models.FloatField(default=0.0) | 
					
						
							| 
									
										
										
										
											2017-05-05 14:59:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     permissions = ('view_hostingbill',) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Meta: | 
					
						
							|  |  |  |         permissions = ( | 
					
						
							|  |  |  |             ('view_hostingbill', 'View Hosting Bill'), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return "%s" % (self.customer.user.email) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 04:41:45 +02:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def create(cls, customer=None, billing_address=None): | 
					
						
							| 
									
										
										
										
											2017-08-24 11:59:38 +05:30
										 |  |  |         instance = cls.objects.create(customer=customer, | 
					
						
							|  |  |  |                                       billing_address=billing_address) | 
					
						
							| 
									
										
										
										
											2017-05-09 04:41:45 +02:00
										 |  |  |         return instance | 
					
						
							| 
									
										
										
										
											2017-09-25 00:00:45 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VMDetail(models.Model): | 
					
						
							|  |  |  |     user = models.ForeignKey(CustomUser) | 
					
						
							|  |  |  |     vm_id = models.IntegerField(default=0) | 
					
						
							|  |  |  |     disk_size = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     cores = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     memory = models.FloatField(default=0.0) | 
					
						
							|  |  |  |     configuration = models.CharField(default='', max_length=25) | 
					
						
							|  |  |  |     ipv4 = models.TextField(default='') | 
					
						
							|  |  |  |     ipv6 = models.TextField(default='') | 
					
						
							|  |  |  |     created_at = models.DateTimeField(auto_now_add=True) | 
					
						
							|  |  |  |     terminated_at = models.DateTimeField(null=True) | 
					
						
							| 
									
										
										
										
											2017-09-30 17:55:49 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     def end_date(self): | 
					
						
							| 
									
										
										
										
											2017-09-30 18:05:02 +05:30
										 |  |  |         end_date = self.terminated_at if self.terminated_at else timezone.now() | 
					
						
							| 
									
										
										
										
											2017-09-30 18:08:02 +05:30
										 |  |  |         months = relativedelta(end_date, self.created_at).months or 1 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:10:34 +05:30
										 |  |  |         end_date = self.created_at + relativedelta(months=months, days=-1) | 
					
						
							| 
									
										
										
										
											2017-09-30 17:55:49 +05:30
										 |  |  |         return end_date | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class UserCardDetail(AssignPermissionsMixin, models.Model): | 
					
						
							|  |  |  |     permissions = ('view_usercarddetail',) | 
					
						
							| 
									
										
										
										
											2017-10-15 21:21:36 +02:00
										 |  |  |     stripe_customer = models.ForeignKey(StripeCustomer) | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  |     last4 = models.CharField(max_length=4) | 
					
						
							| 
									
										
										
										
											2017-10-15 19:49:44 +02:00
										 |  |  |     brand = models.CharField(max_length=10) | 
					
						
							| 
									
										
										
										
											2017-10-21 13:27:35 +02:00
										 |  |  |     card_id = models.CharField(max_length=100, blank=True, default='') | 
					
						
							| 
									
										
										
										
											2017-10-15 21:19:13 +02:00
										 |  |  |     fingerprint = models.CharField(max_length=100) | 
					
						
							|  |  |  |     exp_month = models.IntegerField(null=False) | 
					
						
							|  |  |  |     exp_year = models.IntegerField(null=False) | 
					
						
							| 
									
										
										
										
											2017-10-15 20:06:56 +02:00
										 |  |  |     preferred = models.BooleanField(default=False) | 
					
						
							| 
									
										
										
										
											2017-10-15 18:00:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     class Meta: | 
					
						
							|  |  |  |         permissions = ( | 
					
						
							|  |  |  |             ('view_usercarddetail', 'View User Card'), | 
					
						
							| 
									
										
										
										
											2017-10-21 00:00:21 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def create(cls, stripe_customer=None, last4=None, brand=None, | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |                fingerprint=None, exp_month=None, exp_year=None, card_id=None, | 
					
						
							|  |  |  |                preferred=False): | 
					
						
							| 
									
										
										
										
											2017-10-21 00:00:21 +02:00
										 |  |  |         instance = cls.objects.create( | 
					
						
							|  |  |  |             stripe_customer=stripe_customer, last4=last4, brand=brand, | 
					
						
							| 
									
										
										
										
											2017-10-21 13:27:35 +02:00
										 |  |  |             fingerprint=fingerprint, exp_month=exp_month, exp_year=exp_year, | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |             card_id=card_id, preferred=preferred | 
					
						
							| 
									
										
										
										
											2017-10-21 00:00:21 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  |         instance.assign_permissions(stripe_customer.user) | 
					
						
							|  |  |  |         return instance | 
					
						
							| 
									
										
										
										
											2017-10-21 21:27:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_all_cards_list(cls, stripe_customer): | 
					
						
							| 
									
										
										
										
											2017-10-21 21:34:54 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Get all the cards of the given customer as a list | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :param stripe_customer: The StripeCustomer object | 
					
						
							|  |  |  |         :return: A list of all cards; an empty list if the customer object is | 
					
						
							|  |  |  |                  None | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         cards_list = [] | 
					
						
							|  |  |  |         if stripe_customer is None: | 
					
						
							|  |  |  |             return cards_list | 
					
						
							| 
									
										
										
										
											2017-10-21 21:27:21 +02:00
										 |  |  |         user_card_details = UserCardDetail.objects.filter( | 
					
						
							|  |  |  |             stripe_customer_id=stripe_customer.id | 
					
						
							| 
									
										
										
										
											2017-10-28 22:32:35 +02:00
										 |  |  |         ).order_by('-preferred', 'id') | 
					
						
							| 
									
										
										
										
											2017-10-21 21:27:21 +02:00
										 |  |  |         for card in user_card_details: | 
					
						
							|  |  |  |             cards_list.append({ | 
					
						
							| 
									
										
										
										
											2017-10-28 20:45:00 +02:00
										 |  |  |                 'last4': card.last4, 'brand': card.brand, 'id': card.id, | 
					
						
							|  |  |  |                 'preferred': card.preferred | 
					
						
							| 
									
										
										
										
											2017-10-21 21:27:21 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |         return cards_list | 
					
						
							| 
									
										
										
										
											2017-10-26 17:56:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_or_create_user_card_detail(cls, stripe_customer, card_details): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         A method that checks if a UserCardDetail object exists already | 
					
						
							|  |  |  |         based upon the given card_details and creates it for the given | 
					
						
							|  |  |  |         customer if it does not exist. It returns the UserCardDetail object | 
					
						
							|  |  |  |         matching the given card_details if it exists. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :param stripe_customer: The given StripeCustomer object to whom the | 
					
						
							|  |  |  |                 card object should belong to | 
					
						
							|  |  |  |         :param card_details: A dictionary identifying a given card | 
					
						
							|  |  |  |         :return: UserCardDetail object | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2018-07-03 23:23:02 +02:00
										 |  |  |             if ('fingerprint' in card_details and 'exp_month' in card_details | 
					
						
							|  |  |  |                     and 'exp_year' in card_details): | 
					
						
							|  |  |  |                 card_detail = UserCardDetail.objects.get( | 
					
						
							|  |  |  |                     stripe_customer=stripe_customer, | 
					
						
							|  |  |  |                     fingerprint=card_details['fingerprint'], | 
					
						
							|  |  |  |                     exp_month=card_details['exp_month'], | 
					
						
							|  |  |  |                     exp_year=card_details['exp_year'] | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise UserCardDetail.DoesNotExist() | 
					
						
							| 
									
										
										
										
											2017-10-26 17:56:12 +02:00
										 |  |  |         except UserCardDetail.DoesNotExist: | 
					
						
							| 
									
										
										
										
											2017-10-28 15:26:15 +02:00
										 |  |  |             preferred = False | 
					
						
							|  |  |  |             if 'preferred' in card_details: | 
					
						
							|  |  |  |                 preferred = card_details['preferred'] | 
					
						
							| 
									
										
										
										
											2017-10-26 17:56:12 +02:00
										 |  |  |             card_detail = UserCardDetail.create( | 
					
						
							|  |  |  |                 stripe_customer=stripe_customer, | 
					
						
							|  |  |  |                 last4=card_details['last4'], | 
					
						
							|  |  |  |                 brand=card_details['brand'], | 
					
						
							|  |  |  |                 fingerprint=card_details['fingerprint'], | 
					
						
							|  |  |  |                 exp_month=card_details['exp_month'], | 
					
						
							|  |  |  |                 exp_year=card_details['exp_year'], | 
					
						
							| 
									
										
										
										
											2017-10-28 15:26:15 +02:00
										 |  |  |                 card_id=card_details['card_id'], | 
					
						
							|  |  |  |                 preferred=preferred | 
					
						
							| 
									
										
										
										
											2017-10-26 17:56:12 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |         return card_detail | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-28 22:18:54 +02:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def set_default_card(stripe_api_cus_id, stripe_source_id): | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Sets the given stripe source as the default source for the given | 
					
						
							|  |  |  |         Stripe customer | 
					
						
							|  |  |  |         :param stripe_api_cus_id: Stripe customer id | 
					
						
							|  |  |  |         :param stripe_source_id: The Stripe source id | 
					
						
							|  |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         stripe_utils = StripeUtils() | 
					
						
							|  |  |  |         cus_response = stripe_utils.get_customer(stripe_api_cus_id) | 
					
						
							|  |  |  |         cu = cus_response['response_object'] | 
					
						
							|  |  |  |         cu.default_source = stripe_source_id | 
					
						
							|  |  |  |         cu.save() | 
					
						
							| 
									
										
										
										
											2017-10-28 22:18:54 +02:00
										 |  |  |         UserCardDetail.save_default_card_local( | 
					
						
							|  |  |  |             stripe_api_cus_id, stripe_source_id | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-28 22:18:54 +02:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def set_default_card_from_stripe(stripe_api_cus_id): | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |         stripe_utils = StripeUtils() | 
					
						
							|  |  |  |         cus_response = stripe_utils.get_customer(stripe_api_cus_id) | 
					
						
							|  |  |  |         cu = cus_response['response_object'] | 
					
						
							|  |  |  |         default_source = cu.default_source | 
					
						
							| 
									
										
										
										
											2017-10-28 15:14:42 +02:00
										 |  |  |         if default_source is not None: | 
					
						
							| 
									
										
										
										
											2017-10-28 22:18:54 +02:00
										 |  |  |             UserCardDetail.save_default_card_local( | 
					
						
							|  |  |  |                 stripe_api_cus_id, default_source | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-28 22:18:54 +02:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def save_default_card_local(stripe_api_cus_id, card_id): | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |         stripe_cust = StripeCustomer.objects.get(stripe_id=stripe_api_cus_id) | 
					
						
							|  |  |  |         user_card_detail = UserCardDetail.objects.get( | 
					
						
							|  |  |  |             stripe_customer=stripe_cust, card_id=card_id | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2017-10-28 16:47:10 +02:00
										 |  |  |         for card in stripe_cust.usercarddetail_set.all(): | 
					
						
							|  |  |  |             card.preferred = False | 
					
						
							|  |  |  |             card.save() | 
					
						
							| 
									
										
										
										
											2017-10-27 00:40:38 +02:00
										 |  |  |         user_card_detail.preferred = True | 
					
						
							| 
									
										
										
										
											2017-10-28 16:47:10 +02:00
										 |  |  |         user_card_detail.save() | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							| 
									
										
										
										
											2017-10-29 21:31:11 +01:00
										 |  |  |     def get_user_card_details(stripe_customer, card_details): | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         A utility function to check whether a StripeCustomer is already | 
					
						
							|  |  |  |         associated with the card having given details | 
					
						
							| 
									
										
										
										
											2017-10-29 21:31:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  |         :param stripe_customer: | 
					
						
							|  |  |  |         :param card_details: | 
					
						
							| 
									
										
										
										
											2018-07-05 09:58:57 +02:00
										 |  |  |         :return: The UserCardDetails object if it exists, None otherwise | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2017-10-29 21:31:11 +01:00
										 |  |  |             ucd = UserCardDetail.objects.get( | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  |                 stripe_customer=stripe_customer, | 
					
						
							|  |  |  |                 fingerprint=card_details['fingerprint'], | 
					
						
							|  |  |  |                 exp_month=card_details['exp_month'], | 
					
						
							|  |  |  |                 exp_year=card_details['exp_year'] | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2017-10-29 21:31:11 +01:00
										 |  |  |             return ucd | 
					
						
							| 
									
										
										
										
											2017-10-28 18:28:14 +02:00
										 |  |  |         except UserCardDetail.DoesNotExist: | 
					
						
							| 
									
										
										
										
											2018-07-05 09:58:57 +02:00
										 |  |  |             return None |