Source code for ferrosoft.apps.ferrobase.views.tenant

#  Copyright (c) 2025 Ferrosoft GmbH. All rights reserved.
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.urls import reverse

from ferrosoft.apps.ferrobase.forms import TenantForm
from ferrosoft.apps.ferrobase.middleware import TenantMiddleware
from ferrosoft.apps.ferrobase.models import Tenant, Organization
from ferrosoft.apps.ferrobase.views.generic import (
    UpdateView,
    DeleteView,
    model_crud_routes,
    DependentCreateView,
)


def _tenant_options(request):
    """Build the ``(label, url)`` tenant-selection options for the current user.

    Superusers see every tenant; regular users see only the tenants attached
    to their organisation. Each generated URL preserves the post-selection
    redirect target via ``?next=…``.
    """
    go_to_url = request.GET.get("next", None)
    if go_to_url is None:
        go_to_url = reverse("ferrobase:index")
    tenants = (
        Tenant.all_ordered()
        if request.user.is_superuser
        else request.user.organization.tenants.order_by("name")
    )
    return [
        (
            str(tenant),
            "%s?%s=%s"
            % (
                go_to_url,
                TenantMiddleware.TENANT_REQUEST_KEY,
                str(tenant.pk),
            ),
        )
        for tenant in tenants
    ]


[docs] @login_required def choose_tenant(request): """Tenant-selection page; auto-redirects when the user has a single tenant.""" options = _tenant_options(request) if len(options) == 1: return redirect(options[0][1]) return render( request, "ferrobase/tenant-list.html", context={ "tenant_options": options, }, )
[docs] class TenantCreateView(DependentCreateView): """Create a tenant scoped to an :class:`Organization` (the dependent parent).""" form_class = TenantForm model = Tenant parent_model = Organization template_name = "ferrobase/tenant/create.html"
[docs] def get_form_kwargs(self): """Enable add-tenant mode and prefill ``organization`` from the parent.""" return super().get_form_kwargs() | { "enable_add_tenant": True, "initial": { "organization": self.parent_object, }, }
[docs] def cancel_view(self): """Return to the parent organisation, or hide the cancel button.""" return ( None if self.parent_object is None else reverse("ferrobase:organization_update", args=[self.parent_object.pk]) )
[docs] class TenantUpdateView(UpdateView): """Update a tenant; navigation always returns to the parent organisation.""" form_class = TenantForm model = Tenant related_links_default = False
[docs] def cancel_view(self): """Cancel returns to the owning organisation's update page.""" return reverse( "ferrobase:organization_update", args=[self.object.organization.pk] )
[docs] def get_success_url(self): """Success also returns to the owning organisation's update page.""" return reverse( "ferrobase:organization_update", args=[self.object.organization.pk] )
[docs] class TenantDeleteView(DeleteView): """Delete a tenant; redirects back to the owning organisation.""" model = Tenant
[docs] def get_success_url(self): """Return to the owning organisation's update page after deletion.""" return reverse( "ferrobase:organization_update", args=[self.object.organization.pk] )
tenant_urls = model_crud_routes( Tenant, create_view=TenantCreateView, update_view=TenantUpdateView, delete_view=TenantDeleteView, )