service level specific base fees
This commit is contained in:
parent
150250bfb1
commit
033eea92cd
9 changed files with 716 additions and 58 deletions
|
@ -250,29 +250,6 @@ class DiscountTier(models.Model):
|
|||
return f"{self.discount_model.name}: {self.min_units}+ units → {self.discount_percent}% discount"
|
||||
|
||||
|
||||
class VSHNAppCatBaseFee(models.Model):
|
||||
vshn_appcat_price_config = models.ForeignKey(
|
||||
"VSHNAppCatPrice", on_delete=models.CASCADE, related_name="base_fees"
|
||||
)
|
||||
currency = models.CharField(
|
||||
max_length=3,
|
||||
choices=Currency.choices,
|
||||
)
|
||||
amount = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
help_text="Base fee in the specified currency, excl. VAT",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Service Base Fee"
|
||||
unique_together = ("vshn_appcat_price_config", "currency")
|
||||
ordering = ["currency"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.vshn_appcat_price_config.service.name} Base Fee - {self.amount} {self.currency}"
|
||||
|
||||
|
||||
class VSHNAppCatPrice(models.Model):
|
||||
class VariableUnit(models.TextChoices):
|
||||
RAM = "RAM", "Memory (RAM)"
|
||||
|
@ -325,12 +302,6 @@ class VSHNAppCatPrice(models.Model):
|
|||
def __str__(self):
|
||||
return f"{self.service.name} - {self.get_variable_unit_display()} based pricing"
|
||||
|
||||
def get_base_fee(self, currency_code: str):
|
||||
try:
|
||||
return self.base_fees.get(currency=currency_code).amount
|
||||
except VSHNAppCatBaseFee.DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_unit_rate(self, currency_code: str, service_level: str):
|
||||
try:
|
||||
return self.unit_rates.get(
|
||||
|
@ -346,7 +317,7 @@ class VSHNAppCatPrice(models.Model):
|
|||
number_of_units: int,
|
||||
addon_ids=None,
|
||||
):
|
||||
base_fee = self.get_base_fee(currency_code)
|
||||
base_fee = self.get_base_fee(currency_code, service_level)
|
||||
unit_rate = self.get_unit_rate(currency_code, service_level)
|
||||
|
||||
if base_fee is None or unit_rate is None:
|
||||
|
@ -380,7 +351,7 @@ class VSHNAppCatPrice(models.Model):
|
|||
for addon in addons:
|
||||
addon_price = 0
|
||||
if addon.addon_type == VSHNAppCatAddon.AddonType.BASE_FEE:
|
||||
addon_price_value = addon.get_price(currency_code)
|
||||
addon_price_value = addon.get_price(currency_code, service_level)
|
||||
if addon_price_value:
|
||||
addon_price = addon_price_value
|
||||
elif addon.addon_type == VSHNAppCatAddon.AddonType.UNIT_RATE:
|
||||
|
@ -408,6 +379,15 @@ class VSHNAppCatPrice(models.Model):
|
|||
"addon_breakdown": addon_breakdown,
|
||||
}
|
||||
|
||||
def get_base_fee(self, currency_code: str, service_level: str):
|
||||
"""
|
||||
Get the base fee for the given currency and service level.
|
||||
"""
|
||||
try:
|
||||
return self.base_fees.get(currency=currency_code, service_level=service_level).amount
|
||||
except VSHNAppCatBaseFee.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
class VSHNAppCatUnitRate(models.Model):
|
||||
vshn_appcat_price_config = models.ForeignKey(
|
||||
|
@ -477,10 +457,16 @@ class VSHNAppCatAddon(models.Model):
|
|||
return f"{self.vshn_appcat_price_config.service.name} - {self.name}"
|
||||
|
||||
def get_price(self, currency_code: str, service_level: str = None):
|
||||
"""Get the price for this addon in the specified currency and service level"""
|
||||
"""
|
||||
Get the price for this addon in the specified currency and service level.
|
||||
For base fee addons, service_level is required and used.
|
||||
For unit rate addons, service_level is required and used.
|
||||
"""
|
||||
try:
|
||||
if self.addon_type == self.AddonType.BASE_FEE:
|
||||
return self.base_fees.get(currency=currency_code).amount
|
||||
if not service_level:
|
||||
raise ValueError("Service level is required for base fee addons")
|
||||
return self.base_fees.get(currency=currency_code, service_level=service_level).amount
|
||||
elif self.addon_type == self.AddonType.UNIT_RATE:
|
||||
if not service_level:
|
||||
raise ValueError("Service level is required for unit rate addons")
|
||||
|
@ -495,8 +481,9 @@ class VSHNAppCatAddon(models.Model):
|
|||
|
||||
|
||||
class VSHNAppCatAddonBaseFee(models.Model):
|
||||
"""Base fee for an addon (fixed amount regardless of units)"""
|
||||
|
||||
"""
|
||||
Base fee for an addon (fixed amount regardless of units), specified per currency and service level.
|
||||
"""
|
||||
addon = models.ForeignKey(
|
||||
VSHNAppCatAddon, on_delete=models.CASCADE, related_name="base_fees"
|
||||
)
|
||||
|
@ -504,19 +491,27 @@ class VSHNAppCatAddonBaseFee(models.Model):
|
|||
max_length=3,
|
||||
choices=Currency.choices,
|
||||
)
|
||||
service_level = models.CharField(
|
||||
max_length=2,
|
||||
choices=VSHNAppCatPrice.ServiceLevel.choices,
|
||||
default=VSHNAppCatPrice.ServiceLevel.BEST_EFFORT,
|
||||
)
|
||||
amount = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
help_text="Base fee in the specified currency, excl. VAT",
|
||||
help_text="Base fee in the specified currency and service level, excl. VAT",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Addon Base Fee"
|
||||
unique_together = ("addon", "currency")
|
||||
ordering = ["currency"]
|
||||
unique_together = ("addon", "currency", "service_level")
|
||||
ordering = ["currency", "service_level"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.addon.name} Base Fee - {self.amount} {self.currency}"
|
||||
return f"{self.addon.name} Base Fee - {self.amount} {self.currency} ({self.get_service_level_display()})"
|
||||
|
||||
def get_service_level_display(self):
|
||||
return dict(VSHNAppCatPrice.ServiceLevel.choices).get(self.service_level, self.service_level)
|
||||
|
||||
|
||||
class VSHNAppCatAddonUnitRate(models.Model):
|
||||
|
@ -548,6 +543,40 @@ class VSHNAppCatAddonUnitRate(models.Model):
|
|||
return f"{self.addon.name} - {self.get_service_level_display()} Unit Rate - {self.amount} {self.currency}"
|
||||
|
||||
|
||||
class VSHNAppCatBaseFee(models.Model):
|
||||
"""
|
||||
Base fee for a service, specified per currency and service level.
|
||||
"""
|
||||
vshn_appcat_price_config = models.ForeignKey(
|
||||
"VSHNAppCatPrice", on_delete=models.CASCADE, related_name="base_fees"
|
||||
)
|
||||
currency = models.CharField(
|
||||
max_length=3,
|
||||
choices=Currency.choices,
|
||||
)
|
||||
service_level = models.CharField(
|
||||
max_length=2,
|
||||
choices=VSHNAppCatPrice.ServiceLevel.choices,
|
||||
default=VSHNAppCatPrice.ServiceLevel.BEST_EFFORT,
|
||||
)
|
||||
amount = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
help_text="Base fee in the specified currency and service level, excl. VAT",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Service Base Fee"
|
||||
unique_together = ("vshn_appcat_price_config", "currency", "service_level")
|
||||
ordering = ["currency", "service_level"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.vshn_appcat_price_config.service.name} Base Fee - {self.amount} {self.currency} ({self.get_service_level_display()})"
|
||||
|
||||
def get_service_level_display(self):
|
||||
return dict(VSHNAppCatPrice.ServiceLevel.choices).get(self.service_level, self.service_level)
|
||||
|
||||
|
||||
class ExternalPricePlans(models.Model):
|
||||
plan_name = models.CharField()
|
||||
description = models.CharField(max_length=200, blank=True, null=True)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue