From e06105942b14ca1f06f4d4b319b57c70cba8cc4f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 30 May 2025 10:23:34 +0200 Subject: [PATCH] import for external prices --- hub/services/admin/pricing.py | 78 ++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/hub/services/admin/pricing.py b/hub/services/admin/pricing.py index 973679a..b3ba301 100644 --- a/hub/services/admin/pricing.py +++ b/hub/services/admin/pricing.py @@ -23,6 +23,7 @@ from ..models import ( ProgressiveDiscountModel, DiscountTier, ExternalPricePlans, + Service, ) @@ -102,12 +103,10 @@ class ComputePlanResource(resources.ModelResource): """Handle many-to-many relationships during import""" 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: @@ -311,10 +310,79 @@ class StoragePlanAdmin(ImportExportModelAdmin): display_prices.short_description = "Prices (Amount Currency)" -@admin.register(ExternalPricePlans) -class ExternalPricePlansAdmin(admin.ModelAdmin): - """Admin configuration for ExternalPricePlans model""" +class ExternalPricePlansResource(resources.ModelResource): + """Import/Export resource for ExternalPricePlans model""" + cloud_provider = Field( + column_name="cloud_provider", + attribute="cloud_provider", + widget=ForeignKeyWidget(CloudProvider, "name"), + ) + service = Field( + column_name="service", + attribute="service", + widget=ForeignKeyWidget(Service, "name"), + ) + compare_to = Field(column_name="compare_to", attribute=None) + + class Meta: + model = ExternalPricePlans + skip_unchanged = True + report_skipped = False + import_id_fields = ["plan_name", "cloud_provider", "service"] + fields = ( + "plan_name", + "description", + "source", + "date_retrieved", + "cloud_provider", + "service", + "currency", + "term", + "amount", + "vcpus", + "ram", + "storage", + "competitor_sla", + "replicas", + "service_level", + "compare_to", + ) + + def dehydrate_compare_to(self, external_price): + """Export compute plans this external price compares to""" + compute_plans = external_price.compare_to.all() + if not compute_plans: + return "" + return "|".join([plan.name for plan in compute_plans]) + + def save_m2m(self, instance, row, *args, **kwargs): + """Handle many-to-many relationships during import""" + super().save_m2m(instance, row, *args, **kwargs) + + # Handle compare_to relationships + if "compare_to" in row and row["compare_to"]: + # Clear existing relationships first + instance.compare_to.clear() + + # Create new relationships + plan_names = row["compare_to"].split("|") + for plan_name in plan_names: + plan_name = plan_name.strip() + if plan_name: + try: + compute_plan = ComputePlan.objects.get(name=plan_name) + instance.compare_to.add(compute_plan) + except ComputePlan.DoesNotExist: + # Log or handle missing compute plan + pass + + +@admin.register(ExternalPricePlans) +class ExternalPricePlansAdmin(ImportExportModelAdmin): + """Admin configuration for ExternalPricePlans model with import/export functionality""" + + resource_class = ExternalPricePlansResource list_display = ( "plan_name", "cloud_provider",