October feature list #226

Merged
tobru merged 36 commits from october into main 2025-10-22 13:43:34 +00:00
4 changed files with 37 additions and 12 deletions
Showing only changes of commit df3e3d5f0c - Show all commits

View file

@ -109,6 +109,7 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
self._send_service_welcome_email( self._send_service_welcome_email(
request, organization, user, service, service_offering request, organization, user, service, service_offering
) )
organization.limit_osb_services.add(service)
return JsonResponse({"message": "Service already enabled"}, status=200) return JsonResponse({"message": "Service already enabled"}, status=200)
odoo_data = { odoo_data = {

View file

@ -50,11 +50,13 @@ class Organization(ServalaModelMixin, models.Model):
to="CloudProvider", to="CloudProvider",
related_name="+", related_name="+",
verbose_name=_("Limit to these Cloud providers"), verbose_name=_("Limit to these Cloud providers"),
blank=True,
) )
limit_osb_services = models.ManyToManyField( limit_osb_services = models.ManyToManyField(
to="Service", to="Service",
related_name="+", related_name="+",
verbose_name=_("Services activated from OSB"), verbose_name=_("Services activated from OSB"),
blank=True,
) )
odoo_sale_order_id = models.IntegerField( odoo_sale_order_id = models.IntegerField(
@ -141,6 +143,17 @@ class Organization(ServalaModelMixin, models.Model):
return instance return instance
def get_visible_services(self):
from servala.core.models import Service
queryset = Service.objects.select_related("category")
if self.limit_cloudproviders.exists():
allowed_providers = self.limit_cloudproviders.all()
queryset = queryset.filter(
offerings__provider__in=allowed_providers
).distinct()
return queryset.prefetch_related("offerings", "offerings__provider")
class Meta: class Meta:
verbose_name = _("Organization") verbose_name = _("Organization")
verbose_name_plural = _("Organizations") verbose_name_plural = _("Organizations")

View file

@ -47,7 +47,7 @@
</div> </div>
</div> </div>
<div class="row match-height card-grid"> <div class="row match-height card-grid">
{% for offering in service.offerings.all %} {% for offering in visible_offerings %}
<div class="col-6 col-lg-3 col-md-4"> <div class="col-6 col-lg-3 col-md-4">
<div class="card"> <div class="card">
<div class="card-header card-header-with-logo"> <div class="card-header card-header-with-logo">

View file

@ -1,6 +1,6 @@
from django.contrib import messages from django.contrib import messages
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.http import HttpResponse, Http404 from django.http import Http404, HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -36,11 +36,8 @@ class ServiceListView(OrganizationViewMixin, ListView):
def get_queryset(self): def get_queryset(self):
"""Return all services.""" """Return all services."""
services = ( services = self.request.organization.get_visible_services()
Service.objects.all()
.select_related("category")
.prefetch_related("offerings__provider")
)
if self.filter_form.is_valid(): if self.filter_form.is_valid():
services = self.filter_form.filter_queryset(services) services = self.filter_form.filter_queryset(services)
return services.distinct() return services.distinct()
@ -62,10 +59,17 @@ class ServiceDetailView(OrganizationViewMixin, DetailView):
permission_type = "view" permission_type = "view"
def get_queryset(self): def get_queryset(self):
return Service.objects.select_related("category").prefetch_related( return self.request.organization.get_visible_services()
"offerings",
"offerings__provider", def get_context_data(self, **kwargs):
) context = super().get_context_data(**kwargs)
offerings = context["service"].offerings.all()
if self.request.organization.limit_cloudproviders.exists():
offerings = offerings.filter(
provider__in=self.request.organization.limit_cloudproviders.all()
)
context["visible_offerings"] = offerings.select_related("provider")
return context
class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView): class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView):
@ -76,7 +80,14 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
fragments = ("service-form", "control-plane-info") fragments = ("service-form", "control-plane-info")
def has_permission(self): def has_permission(self):
return self.has_organization_permission() if not self.has_organization_permission():
return False
if self.request.organization.limit_cloudproviders.exists():
return (
self.get_object().provider
in self.request.organization.limit_cloudproviders.all()
)
return True
def get_queryset(self): def get_queryset(self):
return ServiceOffering.objects.all().select_related( return ServiceOffering.objects.all().select_related(