continued work on price model

This commit is contained in:
Tobias Brunner 2025-05-22 16:34:15 +02:00
parent 6f41c8c344
commit a6a15150ea
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ
10 changed files with 500 additions and 1 deletions

View file

@ -19,6 +19,8 @@ from .models import (
ReusableText,
Service,
ServiceOffering,
StoragePlan,
StoragePlanPrice,
VSHNAppCatBaseFee,
VSHNAppCatPrice,
VSHNAppCatUnitRate,
@ -208,6 +210,7 @@ class ComputePlanResource(resources.ModelResource):
attribute="cloud_provider",
widget=ForeignKeyWidget(CloudProvider, "name"),
)
prices = Field(column_name="prices", attribute=None)
class Meta:
model = ComputePlan
@ -221,10 +224,35 @@ class ComputePlanResource(resources.ModelResource):
"cpu_mem_ratio",
"cloud_provider",
"active",
"term",
"valid_from",
"valid_to",
"prices",
)
def dehydrate_prices(self, compute_plan):
prices = compute_plan.prices.all()
if not prices:
return ""
return "|".join([f"{p.currency} {p.amount}" for p in prices])
def save_m2m(self, instance, row, *args, **kwargs):
super().save_m2m(instance, row, *args, **kwargs)
# Handle prices
if "prices" in row and row["prices"]:
# Clear existing prices first
instance.prices.all().delete()
# Create new prices
price_entries = row["prices"].split("|")
for entry in price_entries:
if " " in entry:
currency, amount = entry.split(" ")
ComputePlanPrice.objects.create(
compute_plan=instance, currency=currency, amount=amount
)
@admin.register(ComputePlan)
class ComputePlansAdmin(ImportExportModelAdmin):
@ -234,6 +262,7 @@ class ComputePlansAdmin(ImportExportModelAdmin):
"cloud_provider",
"vcpus",
"ram",
"term",
"display_prices",
"active",
)
@ -268,6 +297,7 @@ class VSHNAppCatPriceAdmin(admin.ModelAdmin):
list_display = (
"service",
"variable_unit",
"term",
"admin_display_base_fees",
"admin_display_unit_rates",
)
@ -299,3 +329,80 @@ class VSHNAppCatPriceAdmin(admin.ModelAdmin):
)
admin_display_unit_rates.short_description = "Unit Rates"
class StoragePlanPriceInline(admin.TabularInline):
model = StoragePlanPrice
extra = 1
fields = ("currency", "amount")
class StoragePlanResource(resources.ModelResource):
cloud_provider = Field(
column_name="cloud_provider",
attribute="cloud_provider",
widget=ForeignKeyWidget(CloudProvider, "name"),
)
prices = Field(column_name="prices", attribute=None)
class Meta:
model = StoragePlan
skip_unchanged = True
report_skipped = False
import_id_fields = ["name"]
fields = (
"name",
"cloud_provider",
"term",
"unit",
"valid_from",
"valid_to",
"prices",
)
def dehydrate_prices(self, storage_plan):
prices = storage_plan.prices.all()
if not prices:
return ""
return "|".join([f"{p.currency} {p.amount}" for p in prices])
def save_m2m(self, instance, row, *args, **kwargs):
super().save_m2m(instance, row, *args, **kwargs)
# Handle prices
if "prices" in row and row["prices"]:
# Clear existing prices first
instance.prices.all().delete()
# Create new prices
price_entries = row["prices"].split("|")
for entry in price_entries:
if " " in entry:
currency, amount = entry.split(" ")
StoragePlanPrice.objects.create(
storage_plan=instance, currency=currency, amount=amount
)
@admin.register(StoragePlan)
class StoragePlanAdmin(ImportExportModelAdmin):
resource_class = StoragePlanResource
list_display = (
"name",
"cloud_provider",
"term",
"unit",
"display_prices",
)
search_fields = ("name", "cloud_provider__name")
list_filter = ("cloud_provider",)
ordering = ("name",)
inlines = [StoragePlanPriceInline]
def display_prices(self, obj):
prices = obj.prices.all()
if not prices:
return "No prices set"
return format_html("<br>".join([f"{p.amount} {p.currency}" for p in prices]))
display_prices.short_description = "Prices (Amount Currency)"