yuyu/core/models.py

182 lines
5.3 KiB
Python
Raw Normal View History

2021-10-29 13:00:33 +07:00
import math
2021-08-31 11:11:51 +07:00
2021-09-01 19:29:24 +07:00
from django.conf import settings
2021-08-31 11:11:51 +07:00
from django.db import models
from djmoney.models.fields import MoneyField
2021-09-01 19:29:24 +07:00
from djmoney.money import Money
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
from core.component import labels
from core.utils.model_utils import BaseModel, TimestampMixin, PriceMixin, InvoiceComponentMixin
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
# region Dynamic Setting
class DynamicSetting(BaseModel):
class DataType(models.IntegerChoices):
BOOLEAN = 1
INT = 2
STR = 3
JSON = 4
key = models.CharField(max_length=256, unique=True, db_index=True)
value = models.TextField()
type = models.IntegerField(choices=DataType.choices)
# end region
# region Pricing
class FlavorPrice(BaseModel, TimestampMixin, PriceMixin):
2021-08-31 11:11:51 +07:00
flavor_id = models.CharField(max_length=256)
2021-10-29 13:00:33 +07:00
class FloatingIpsPrice(BaseModel, TimestampMixin, PriceMixin):
# No need for any additional field
pass
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
class VolumePrice(BaseModel, TimestampMixin, PriceMixin):
2021-08-31 11:11:51 +07:00
volume_type_id = models.CharField(max_length=256)
2021-10-29 13:00:33 +07:00
class RouterPrice(BaseModel, TimestampMixin, PriceMixin):
# No need for any additional field
pass
class SnapshotPrice(BaseModel, TimestampMixin, PriceMixin):
# No need for any additional field
pass
class ImagePrice(BaseModel, TimestampMixin, PriceMixin):
# No need for any additional field
pass
# end region
# region Invoicing
class BillingProject(BaseModel, TimestampMixin):
2021-08-31 11:11:51 +07:00
tenant_id = models.CharField(max_length=256)
2021-10-29 13:00:33 +07:00
class Invoice(BaseModel, TimestampMixin):
2021-08-31 11:11:51 +07:00
class InvoiceState(models.IntegerChoices):
IN_PROGRESS = 1
FINISHED = 100
project = models.ForeignKey('BillingProject', on_delete=models.CASCADE)
start_date = models.DateTimeField()
end_date = models.DateTimeField(default=None, blank=True, null=True)
state = models.IntegerField(choices=InvoiceState.choices)
tax = MoneyField(max_digits=10, decimal_places=0, default=None, blank=True, null=True)
total = MoneyField(max_digits=10, decimal_places=0, default=None, blank=True, null=True)
@property
def subtotal(self):
2021-10-29 13:00:33 +07:00
# Need to optimize?
# currently price is calculated on the fly, maybe need to save to db to make performance faster?
# or using cache?
price = 0
for component_relation_label in labels.INVOICE_COMPONENT_LABELS:
relation_all_row = getattr(self, component_relation_label).all()
price += sum(map(lambda x: x.price_charged, relation_all_row))
2021-09-01 19:29:24 +07:00
if price == 0:
return Money(amount=price, currency=settings.DEFAULT_CURRENCY)
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
return price
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
def close(self, date, tax_percentage):
self.state = Invoice.InvoiceState.FINISHED
self.end_date = date
self.tax = tax_percentage * self.subtotal
self.total = self.tax + self.subtotal
self.save()
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
# end region
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
# region Invoice Component
class InvoiceInstance(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_INSTANCES)
# Key
instance_id = models.CharField(max_length=266)
2021-09-01 19:29:24 +07:00
2021-10-29 13:00:33 +07:00
# Price Dependency
flavor_id = models.CharField(max_length=256)
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
# Informative
name = models.CharField(max_length=256)
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
class InvoiceFloatingIp(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_FLOATING_IPS)
# Key
2021-08-31 11:11:51 +07:00
fip_id = models.CharField(max_length=266)
2021-10-29 13:00:33 +07:00
# Informative
2021-08-31 11:11:51 +07:00
ip = models.CharField(max_length=256)
2021-09-01 19:29:24 +07:00
2021-10-29 13:00:33 +07:00
class InvoiceVolume(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_VOLUMES)
# Key
volume_id = models.CharField(max_length=256)
# Price Dependency
volume_type_id = models.CharField(max_length=256)
space_allocation_gb = models.FloatField()
# Informative
volume_name = models.CharField(max_length=256)
2021-09-01 19:29:24 +07:00
@property
def price_charged(self):
2021-10-29 13:00:33 +07:00
price_without_allocation = super().price_charged
return price_without_allocation * math.ceil(self.space_allocation_gb)
2021-09-01 19:29:24 +07:00
2021-10-29 13:00:33 +07:00
class InvoiceRouter(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_ROUTERS)
# Key
router_id = models.CharField(max_length=256)
2021-08-31 11:11:51 +07:00
2021-10-29 13:00:33 +07:00
# Informative
name = models.CharField(max_length=256)
2021-09-01 19:29:24 +07:00
2021-10-29 13:00:33 +07:00
class InvoiceSnapshot(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_SNAPSHOTS)
# Key
snapshot_id = models.CharField(max_length=256)
# Price Dependency
space_allocation_gb = models.FloatField()
# Informative
name = models.CharField(max_length=256)
2021-09-01 19:29:24 +07:00
@property
def price_charged(self):
2021-10-29 13:00:33 +07:00
price_without_allocation = super().price_charged
return price_without_allocation * math.ceil(self.space_allocation_gb)
class InvoiceImage(BaseModel, InvoiceComponentMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name=labels.LABEL_IMAGES)
# Key
image_id = models.CharField(max_length=256)
2021-09-01 19:29:24 +07:00
2021-10-29 13:00:33 +07:00
# Price Dependency
space_allocation_gb = models.FloatField()
# Informative
name = models.CharField(max_length=256)
@property
def price_charged(self):
price_without_allocation = super().price_charged
return price_without_allocation * math.ceil(self.space_allocation_gb)
2021-10-29 13:00:33 +07:00
# end region