From 4be098d07a057cea96de9469569a6df1923ab9e5 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 20 Apr 2019 11:53:47 +0200 Subject: [PATCH 1/4] Add stripe_plan_name field to datacenterlight's StripePlan model --- .../0028_stripeplan_stripe_plan_name.py | 20 +++++++++++++++++++ datacenterlight/models.py | 1 + 2 files changed, 21 insertions(+) create mode 100644 datacenterlight/migrations/0028_stripeplan_stripe_plan_name.py diff --git a/datacenterlight/migrations/0028_stripeplan_stripe_plan_name.py b/datacenterlight/migrations/0028_stripeplan_stripe_plan_name.py new file mode 100644 index 00000000..1592e2e5 --- /dev/null +++ b/datacenterlight/migrations/0028_stripeplan_stripe_plan_name.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2019-04-20 09:52 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0027_dclcalculatorpluginmodel_enable_512mb_ram'), + ] + + operations = [ + migrations.AddField( + model_name='stripeplan', + name='stripe_plan_name', + field=models.CharField(default='', max_length=512, null=True), + ), + ] diff --git a/datacenterlight/models.py b/datacenterlight/models.py index 729bbdf9..5b1ebb79 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -103,6 +103,7 @@ class StripePlan(models.Model): A model to store Data Center Light's created Stripe plans """ stripe_plan_id = models.CharField(max_length=256, null=True) + stripe_plan_name = models.CharField(max_length=512, default="", null=True) @classmethod def create(cls, stripe_plan_id): From c8e35e63f08964b48305b3ae6deb59fb119b2d22 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 20 Apr 2019 12:22:49 +0200 Subject: [PATCH 2/4] Update datacenterlight StripePlan further - Add field amount to stripeplan - Add field interval to stripeplan --- .../migrations/0029_auto_20190420_1022.py | 25 +++++++++++++++++++ datacenterlight/models.py | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 datacenterlight/migrations/0029_auto_20190420_1022.py diff --git a/datacenterlight/migrations/0029_auto_20190420_1022.py b/datacenterlight/migrations/0029_auto_20190420_1022.py new file mode 100644 index 00000000..05a3f27e --- /dev/null +++ b/datacenterlight/migrations/0029_auto_20190420_1022.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2019-04-20 10:22 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0028_stripeplan_stripe_plan_name'), + ] + + operations = [ + migrations.AddField( + model_name='stripeplan', + name='amount', + field=models.PositiveIntegerField(default=0), + ), + migrations.AddField( + model_name='stripeplan', + name='interval', + field=models.CharField(default='', max_length=128, null=True), + ), + ] diff --git a/datacenterlight/models.py b/datacenterlight/models.py index 5b1ebb79..6410254b 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -104,6 +104,8 @@ class StripePlan(models.Model): """ stripe_plan_id = models.CharField(max_length=256, null=True) stripe_plan_name = models.CharField(max_length=512, default="", null=True) + amount = models.PositiveIntegerField(default=0) + interval = models.CharField(max_length=128, default="", null=True) @classmethod def create(cls, stripe_plan_id): From 38d074811a12c73d5cc1390422adf75a9b960570 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 20 Apr 2019 12:41:30 +0200 Subject: [PATCH 3/4] Link HostingBillLineItem to StripePlan --- .../0053_hostingbilllineitem_stripe_plan.py | 22 +++++++++++++++++++ hosting/models.py | 7 ++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 hosting/migrations/0053_hostingbilllineitem_stripe_plan.py diff --git a/hosting/migrations/0053_hostingbilllineitem_stripe_plan.py b/hosting/migrations/0053_hostingbilllineitem_stripe_plan.py new file mode 100644 index 00000000..21580447 --- /dev/null +++ b/hosting/migrations/0053_hostingbilllineitem_stripe_plan.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2019-04-20 10:10 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0028_stripeplan_stripe_plan_name'), + ('hosting', '0052_hostingbilllineitem'), + ] + + operations = [ + migrations.AddField( + model_name='hostingbilllineitem', + name='stripe_plan', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='datacenterlight.StripePlan'), + ), + ] diff --git a/hosting/models.py b/hosting/models.py index a113b80a..8ef36ffb 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -10,7 +10,7 @@ from django.db import models from django.utils import timezone from django.utils.functional import cached_property -from datacenterlight.models import VMPricing, VMTemplate +from datacenterlight.models import VMPricing, VMTemplate, StripePlan from membership.models import StripeCustomer, CustomUser from utils.mixins import AssignPermissionsMixin from utils.models import BillingAddress @@ -431,7 +431,10 @@ class HostingBillLineItem(AssignPermissionsMixin, models.Model): """ Corresponds to InvoiceItem object of Stripe """ - monthly_hosting_bill = models.ForeignKey(MonthlyHostingBill) + monthly_hosting_bill = models.ForeignKey(MonthlyHostingBill, + on_delete=models.CASCADE) + stripe_plan = models.ForeignKey(StripePlan, null=True, + on_delete=models.CASCADE) amount = models.PositiveSmallIntegerField() description = models.CharField(max_length=255) discountable = models.BooleanField() From c592c0768e58f882628838d301c900294070f971 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 20 Apr 2019 12:48:13 +0200 Subject: [PATCH 4/4] Extract stripe plan from invoice and set it to MHB If the plan does not exist, it implies that it was created in the dashboard. So, we create it in the backend also. --- hosting/models.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/hosting/models.py b/hosting/models.py index 8ef36ffb..25c8dab8 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -342,6 +342,27 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model): if 'line_items' in args: line_items = args['line_items'] for item in line_items: + stripe_plan = None + if item.type == "subscription" or item.type == "invoiceitem": + # Check stripe plan and prepare it for linking to bill item + stripe_plan_id = item.plan.id + try: + stripe_plan = StripePlan.objects.get( + stripe_plan_name=stripe_plan_id + ) + except StripePlan.DoesNotExist as dne: + logger.error( + "StripePlan %s doesn't exist" % stripe_plan_id + ) + if stripe_plan_id is not None: + # Create Stripe Plan because we don't have it + stripe_plan = StripePlan.objects.create( + stripe_plan_id=stripe_plan_id, + stripe_plan_name=item.plan.name, + amount=item.plan.amount, + interval=item.plan.interval + ) + logger.debug("Creatd StripePlan " + stripe_plan_id) line_item_instance = HostingBillLineItem.objects.create( monthly_hosting_bill=instance, amount=item.amount, @@ -358,7 +379,8 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model): # https://stripe.com/docs/api/invoiceitems/object#invoiceitem_object-unit_amount # So, for the time being I set the unit_amount to 0 if not # found in the line item - unit_amount=item.unit_amount if hasattr(item, "unit_amount") else 0 + unit_amount=item.unit_amount if hasattr(item, "unit_amount") else 0, + stripe_plan=stripe_plan ) line_item_instance.assign_permissions(instance.customer.user) instance.assign_permissions(instance.customer.user)