Complete implementation of fetch_stripe_bills

This commit is contained in:
PCoder 2019-04-03 06:12:48 +02:00
parent 8dc00c9dd9
commit 6d42f88be1
3 changed files with 97 additions and 27 deletions

View file

@ -1,9 +1,13 @@
import logging
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from hosting.models import UserCardDetail from hosting.models import MonthlyHostingBill
from membership.models import CustomUser from membership.models import CustomUser
from utils.stripe_utils import StripeUtils from utils.stripe_utils import StripeUtils
logger = logging.getLogger(__name__)
class Command(BaseCommand): class Command(BaseCommand):
help = '''Fetches invoices from Stripe and creates bills for a given help = '''Fetches invoices from Stripe and creates bills for a given
@ -18,11 +22,32 @@ class Command(BaseCommand):
stripe_utils = StripeUtils() stripe_utils = StripeUtils()
user = CustomUser.objects.get(email=email) user = CustomUser.objects.get(email=email)
if hasattr(user, 'stripecustomer'): if hasattr(user, 'stripecustomer'):
self.stdout.write(self.style.SUCCESS('Found %s. Fetching bills for him.' % email)) self.stdout.write(self.style.SUCCESS(
stripe_utils.get_all_invoices( 'Found %s. Fetching bills for him.' % email))
user.stripecustomer.stripe_id mhb = MonthlyHostingBill.objects.last(
customer=user.stripecustomer
)
created_gt = {}
if mhb is not None:
# fetch only invoices which is created after
# mhb.created, because we already have invoices till
# this date
created_gt = {'gt': mhb.created}
all_invoices_response = stripe_utils.get_all_invoices(
user.stripecustomer.stripe_id,
created=created_gt
)
all_invoices = all_invoices_response['response_object']
logger.debug(
"Obtained {} invoices".format(len(all_invoices))
)
for invoice in all_invoices:
MonthlyHostingBill.create(
invoice, stripe_customer=user.stripecustomer
) )
else: else:
self.stdout.write(self.style.SUCCESS('Customer email %s does not have a stripe customer.' % email)) self.stdout.write(self.style.SUCCESS(
'Customer email %s does not have a stripe customer.' % email))
except Exception as e: except Exception as e:
print(" *** Error occurred. Details {}".format(str(e))) print(" *** Error occurred. Details {}".format(str(e)))

View file

@ -235,16 +235,24 @@ class HostingBill(AssignPermissionsMixin, models.Model):
class MonthlyHostingBill(AssignPermissionsMixin, models.Model): class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
customer = models.ForeignKey(StripeCustomer) customer = models.ForeignKey(StripeCustomer)
order = models.ForeignKey(HostingOrder) order = models.ForeignKey(HostingOrder)
created = models.DateTimeField(help_text="When the invoice was created")
receipt_number = models.CharField( receipt_number = models.CharField(
help_text="The receipt number that is generated on Stripe" help_text="The receipt number that is generated on Stripe",
max_length=100
) )
invoice_number = models.CharField( invoice_number = models.CharField(
help_text="The invoice number that is generated on Stripe" help_text="The invoice number that is generated on Stripe",
max_length=100
) )
billing_period = models.CharField( paid_at = models.DateTimeField(help_text="Date on which the bill was paid")
help_text="The billing period for which the bill is valid" period_start = models.DateTimeField()
) period_end = models.DateTimeField()
date_paid = models.DateField(help_text="Date on which the bill was paid") billing_reason = models.CharField(max_length=25)
discount = models.PositiveIntegerField()
total = models.IntegerField()
lines_data_count = models.IntegerField()
invoice_id = models.CharField(unique=True, max_length=100)
lines_meta_data_csv = models.TextField()
permissions = ('view_monthlyhostingbill',) permissions = ('view_monthlyhostingbill',)
@ -253,6 +261,24 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
('view_monthlyhostingbill', 'View Monthly Hosting'), ('view_monthlyhostingbill', 'View Monthly Hosting'),
) )
@classmethod
def create(cls, stripe_customer, **args):
instance = cls.objects.create(args)
instance.customer = stripe_customer
if len(instance.lines_meta_data_csv) > 0:
vm_ids = [vm_id.strip() for vm_id in instance.lines_meta_data_csv.split(",")]
if len(vm_ids) == 1:
instance.order = HostingOrder.objects.get(vm_id=vm_ids[0])
else:
logger.debug(
"More than one VM_ID"
"for MonthlyHostingBill {}".format(instance.invoice_id)
)
logger.debug("VM_IDS=".format(','.join(vm_ids)))
instance.assign_permissions(stripe_customer.user)
instance.save()
return instance
class VMDetail(models.Model): class VMDetail(models.Model):
user = models.ForeignKey(CustomUser) user = models.ForeignKey(CustomUser)

View file

@ -123,22 +123,41 @@ class StripeUtils(object):
return card_details return card_details
@handleStripeError @handleStripeError
def get_all_invoices(self, customer_id): def get_all_invoices(self, customer_id, created):
invoices = stripe.Invoice.list(limit=100, customer=customer_id)
return_list = [] return_list = []
for invoice in invoices: has_more_invoices = True
starting_after = False
while has_more_invoices:
if starting_after:
invoices = stripe.Invoice.list(
limit=10, customer=customer_id, created=created
)
else:
invoices = stripe.Invoice.list(
limit=10, customer=customer_id, created=created,
starting_after=starting_after
)
has_more_invoices = invoices.has_more
for invoice in invoices.data:
invoice_details = { invoice_details = {
'created': invoice.created, 'created': invoice.created,
'receipt_number': invoice.receipt_number, 'receipt_number': invoice.receipt_number,
'invoice_number': invoice.number, 'invoice_number': invoice.number,
'date_paid': invoice.date_paid, 'paid_at': invoice.status_transitions.paid_at if invoice.paid else 0,
'period_start': invoice.period_start, 'period_start': invoice.period_start,
'period_end': invoice.period_end, 'period_end': invoice.period_end,
'paid': invoice.paid,
'billing_reason': invoice.billing_reason, 'billing_reason': invoice.billing_reason,
'discount': invoice.discount.coupon.amount_off if invoice.discount else 0, 'discount': invoice.discount.coupon.amount_off if invoice.discount else 0,
'total': invoice.total 'total': invoice.total,
# to see how many line items we have in this invoice and
# then later check if we have more than 1
'lines_data_count': len(invoice.lines.data),
'invoice_id': invoice.id,
'lines_meta_data_csv': ','.join(
[line.metadata.VM_ID for line in invoice.lines.data]
)
} }
starting_after = invoice.id
return_list.append(invoice_details) return_list.append(invoice_details)
return return_list return return_list