diff --git a/hub/services/templates/services/offering_detail.html b/hub/services/templates/services/offering_detail.html index 545d319..391c99d 100644 --- a/hub/services/templates/services/offering_detail.html +++ b/hub/services/templates/services/offering_detail.html @@ -142,7 +142,7 @@ {% endif %} -
No plans available yet.
{% for category in service.categories.all %} {{ category.full_path }} diff --git a/hub/services/views/services.py b/hub/services/views/services.py index adb7e22..fc6d275 100644 --- a/hub/services/views/services.py +++ b/hub/services/views/services.py @@ -17,7 +17,8 @@ def service_list(request): # Start with all active services # Filter out services with disable_listing=True - services = Service.objects.filter(disable_listing=False) + all_services = Service.objects.filter(disable_listing=False) + services = all_services # Apply filters based on request parameters if search_query: @@ -42,86 +43,98 @@ def service_list(request): "name", # Alphabetically within each group ) - # Get all available categories from filtered services - available_category_ids = services.values_list( - "categories__id", flat=True + # Create base querysets for each filter type that apply all OTHER current filters + # This way, each filter shows options that would return results if selected + + # For category filter options, apply all other filters except category + category_filter_base = all_services + if search_query: + category_filter_base = category_filter_base.filter( + Q(name__icontains=search_query) | Q(description__icontains=search_query) + ) + if consulting_partner_id: + category_filter_base = category_filter_base.filter( + consulting_partners__id=consulting_partner_id + ) + if cloud_provider_id: + category_filter_base = category_filter_base.filter( + offerings__cloud_provider__id=cloud_provider_id + ) + + # For consulting partner filter options, apply all other filters except consulting_partner + cp_filter_base = all_services + if search_query: + cp_filter_base = cp_filter_base.filter( + Q(name__icontains=search_query) | Q(description__icontains=search_query) + ) + if category_id: + cp_filter_base = cp_filter_base.filter(categories__id=category_id) + if cloud_provider_id: + cp_filter_base = cp_filter_base.filter( + offerings__cloud_provider__id=cloud_provider_id + ) + + # For cloud provider filter options, apply all other filters except cloud_provider + cloud_filter_base = all_services + if search_query: + cloud_filter_base = cloud_filter_base.filter( + Q(name__icontains=search_query) | Q(description__icontains=search_query) + ) + if category_id: + cloud_filter_base = cloud_filter_base.filter(categories__id=category_id) + if consulting_partner_id: + cloud_filter_base = cloud_filter_base.filter( + consulting_partners__id=consulting_partner_id + ) + + # Get available categories that would return results if selected + available_parent_categories = Category.objects.filter( + parent=None, + id__in=category_filter_base.values_list( + "categories__parent__id", flat=True + ).distinct(), + ).distinct() + + # Add categories that are direct matches (not children) + direct_categories = Category.objects.filter( + parent=None, + id__in=category_filter_base.values_list("categories__id", flat=True).distinct(), + ).distinct() + + available_parent_categories = ( + available_parent_categories | direct_categories ).distinct() - available_categories = Category.objects.filter( - id__in=available_category_ids, parent=None - ) # For each parent category, get available children - for category in available_categories: - child_ids = ( - services.filter(categories__parent=category) - .values_list("categories__id", flat=True) - .distinct() - ) - category.available_children = Category.objects.filter(id__in=child_ids) + for parent_category in available_parent_categories: + parent_category.available_children = Category.objects.filter( + parent=parent_category, + id__in=category_filter_base.values_list( + "categories__id", flat=True + ).distinct(), + ).distinct() - # Get available consulting partners from filtered services - # Excluding partners with disable_listing=True - available_consulting_partner_ids = services.values_list( - "consulting_partners__id", flat=True - ).distinct() + # Get available consulting partners and cloud providers that would return results if selected available_consulting_partners = ConsultingPartner.objects.filter( - id__in=available_consulting_partner_ids, disable_listing=False - ) - - # Get available cloud providers from filtered services via offerings - # Excluding providers with disable_listing=True - available_cloud_provider_ids = services.values_list( - "offerings__cloud_provider__id", flat=True + disable_listing=False, + id__in=cp_filter_base.values_list( + "consulting_partners__id", flat=True + ).distinct(), ).distinct() + available_cloud_providers = CloudProvider.objects.filter( - id__in=available_cloud_provider_ids, disable_listing=False - ) - - # For the current selection, we need to make sure we include the selected items - # even if they don't match other filters - if category_id: - try: - selected_category = Category.objects.get(id=category_id) - if selected_category.parent: - parent_category = selected_category.parent - if parent_category not in available_categories: - available_categories = list(available_categories) - available_categories.append(parent_category) - parent_category.available_children = [selected_category] - elif selected_category not in available_categories: - available_categories = list(available_categories) - available_categories.append(selected_category) - except Category.DoesNotExist: - pass - - if consulting_partner_id: - try: - cp_id = int(consulting_partner_id) - if cp_id not in available_consulting_partner_ids: - selected_partner = ConsultingPartner.objects.get(id=cp_id) - available_consulting_partners = list(available_consulting_partners) - available_consulting_partners.append(selected_partner) - except (ValueError, ConsultingPartner.DoesNotExist): - pass - - if cloud_provider_id: - try: - cp_id = int(cloud_provider_id) - if cp_id not in available_cloud_provider_ids: - selected_provider = CloudProvider.objects.get(id=cp_id) - available_cloud_providers = list(available_cloud_providers) - available_cloud_providers.append(selected_provider) - except (ValueError, CloudProvider.DoesNotExist): - pass + disable_listing=False, + id__in=cloud_filter_base.values_list( + "offerings__cloud_provider__id", flat=True + ).distinct(), + ).distinct() context = { "services": services, - "categories": Category.objects.filter(parent=None), - "consulting_partners": ConsultingPartner.objects.filter(disable_listing=False), - "cloud_providers": CloudProvider.objects.filter(disable_listing=False), - "available_categories": available_categories, + "available_categories": available_parent_categories, "available_consulting_partners": available_consulting_partners, "available_cloud_providers": available_cloud_providers, + "search_query": search_query, } return render(request, "services/service_list.html", context)