Merge remote-tracking branch 'mainRepo/master' into feature/6561/invoices-webhook
This commit is contained in:
commit
4147b8f891
40 changed files with 1094 additions and 142 deletions
|
|
@ -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
|
||||
|
|
@ -212,6 +212,15 @@ class UserHostingKey(models.Model):
|
|||
# self.save(update_fields=['public_key'])
|
||||
return private_key, public_key
|
||||
|
||||
def delete(self,*args,**kwargs):
|
||||
if bool(self.private_key) and os.path.isfile(self.private_key.path):
|
||||
logger.debug("Removing private key {}".format(self.private_key.path))
|
||||
os.remove(self.private_key.path)
|
||||
else:
|
||||
logger.debug("No private_key to remove")
|
||||
|
||||
super(UserHostingKey, self).delete(*args,**kwargs)
|
||||
|
||||
|
||||
class HostingBill(AssignPermissionsMixin, models.Model):
|
||||
customer = models.ForeignKey(StripeCustomer)
|
||||
|
|
@ -276,14 +285,17 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
|
|||
# Try to infer the HostingOrder from subscription id or VM_ID
|
||||
if len(args['subscription_ids_csv']) > 0:
|
||||
sub_ids = [sub_id.strip() for sub_id in args['subscription_ids_csv'].split(",")]
|
||||
if len(sub_ids) == 1:
|
||||
set_sub_ids = set(sub_ids)
|
||||
if len(set_sub_ids) == 1:
|
||||
# the multiple line items belong to the same subscription
|
||||
sub_id = set_sub_ids.pop()
|
||||
try:
|
||||
args['order'] = HostingOrder.objects.get(
|
||||
subscription_id=sub_ids[0]
|
||||
subscription_id=sub_id
|
||||
)
|
||||
except HostingOrder.DoesNotExist as dne:
|
||||
logger.error("Hosting order for {} doesn't exist".format(
|
||||
sub_ids[0]
|
||||
sub_id
|
||||
))
|
||||
args['order'] = None
|
||||
else:
|
||||
|
|
@ -293,7 +305,7 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
|
|||
)
|
||||
logger.debug("SUB_IDS={}".format(','.join(sub_ids)))
|
||||
logger.debug("Not importing invoices")
|
||||
return
|
||||
return None
|
||||
elif len(args['lines_meta_data_csv']) > 0:
|
||||
vm_ids = [vm_id.strip() for vm_id in args['lines_meta_data_csv'].split(",")]
|
||||
if len(vm_ids) == 1:
|
||||
|
|
@ -305,11 +317,11 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
|
|||
)
|
||||
logger.debug("VM_IDS={}".format(','.join(vm_ids)))
|
||||
logger.debug("Not importing invoices")
|
||||
return
|
||||
return None
|
||||
else:
|
||||
logger.debug("Neither subscription id nor vm_id available")
|
||||
logger.debug("Can't import invoice")
|
||||
return
|
||||
return None
|
||||
|
||||
instance = cls.objects.create(
|
||||
created=datetime.utcfromtimestamp(
|
||||
|
|
@ -342,6 +354,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_id=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 +391,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)
|
||||
|
|
@ -390,14 +424,18 @@ class MonthlyHostingBill(AssignPermissionsMixin, models.Model):
|
|||
if len(self.lines_meta_data_csv) > 0:
|
||||
vm_ids = [vm_id.strip() for vm_id in
|
||||
self.lines_meta_data_csv.split(",")]
|
||||
if len(vm_ids) == 1:
|
||||
return vm_ids[0]
|
||||
unique_vm_ids=set(vm_ids)
|
||||
unique_vm_ids.discard("")
|
||||
if len(unique_vm_ids) == 1:
|
||||
vm_id = unique_vm_ids.pop()
|
||||
logger.debug("Getting invoice for {}".format(vm_id))
|
||||
return vm_id
|
||||
else:
|
||||
logger.debug(
|
||||
"More than one VM_ID"
|
||||
"for MonthlyHostingBill {}".format(self.invoice_id)
|
||||
)
|
||||
logger.debug("VM_IDS=".format(','.join(vm_ids)))
|
||||
logger.debug("VM_IDS={}".format(unique_vm_ids))
|
||||
return return_value
|
||||
|
||||
def get_period_start(self):
|
||||
|
|
@ -427,7 +465,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()
|
||||
|
|
@ -444,6 +485,55 @@ class HostingBillLineItem(AssignPermissionsMixin, models.Model):
|
|||
('view_hostingbilllineitem', 'View Monthly Hosting Bill Line Item'),
|
||||
)
|
||||
|
||||
def amount_in_chf(self):
|
||||
"""
|
||||
Returns amount in chf. The amount in this model is in cents (as in
|
||||
Stripe). Hence we multiply it by 0.01 to obtain the result
|
||||
|
||||
:return:
|
||||
"""
|
||||
return self.amount * 0.01
|
||||
|
||||
def unit_amount_in_chf(self):
|
||||
"""
|
||||
Returns unit amount in chf. If its 0, we obtain it from amount and
|
||||
quantity.
|
||||
|
||||
:return:
|
||||
"""
|
||||
if self.unit_amount == 0:
|
||||
return round((self.amount / self.quantity) * 0.01, 2)
|
||||
else:
|
||||
return self.unit_amount * 0.01
|
||||
|
||||
def get_item_detail_str(self):
|
||||
"""
|
||||
Returns line item html string representation
|
||||
:return:
|
||||
"""
|
||||
item_detail = ""
|
||||
# metadata is a dict; a dict with nothing has two chars at least {}
|
||||
if self.metadata is not None and len(self.metadata) > 2:
|
||||
try:
|
||||
vm_dict = json.loads(self.metadata)
|
||||
item_detail = "VM ID: {}<br/>".format(vm_dict["VM_ID"])
|
||||
except ValueError as ve:
|
||||
logger.error(
|
||||
"Could not parse VM in metadata {}. Detail {}".format(
|
||||
self.metadata, str(ve)
|
||||
)
|
||||
)
|
||||
vm_conf = StripeUtils.get_vm_config_from_stripe_id(
|
||||
self.stripe_plan.stripe_plan_id
|
||||
)
|
||||
if vm_conf is not None:
|
||||
item_detail += ("<b>Cores</b>: {}<br/><b>RAM</b>: {} GB<br/>"
|
||||
"<b>SSD</b>: {} GB<br/>").format(
|
||||
vm_conf['cores'], int(float(vm_conf['ram'])),
|
||||
vm_conf['ssd']
|
||||
)
|
||||
return item_detail
|
||||
|
||||
def get_vm_id(self):
|
||||
"""
|
||||
If VM_ID is set in the metadata extract and return it as integer
|
||||
|
|
@ -464,7 +554,7 @@ class VMDetail(models.Model):
|
|||
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)
|
||||
configuration = models.CharField(default='', max_length=128)
|
||||
ipv4 = models.TextField(default='')
|
||||
ipv6 = models.TextField(default='')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue