# app/modules/tenancy/services/tenancy_widgets.py """ Tenancy dashboard widget provider. Provides widgets for tenancy-related data on admin dashboards. Implements the DashboardWidgetProviderProtocol. Widgets provided: - recent_vendors: List of recently created vendors with status """ import logging from sqlalchemy.orm import Session from app.modules.contracts.widgets import ( DashboardWidget, DashboardWidgetProviderProtocol, ListWidget, WidgetContext, WidgetListItem, ) logger = logging.getLogger(__name__) class TenancyWidgetProvider: """ Widget provider for tenancy module. Provides dashboard widgets for vendors, users, and other tenancy data. """ @property def widgets_category(self) -> str: return "tenancy" def _get_vendor_status(self, vendor) -> str: """Determine widget status indicator for a vendor.""" if not vendor.is_active: return "neutral" if not vendor.is_verified: return "warning" return "success" def get_vendor_widgets( self, db: Session, vendor_id: int, context: WidgetContext | None = None, ) -> list[DashboardWidget]: """ Get tenancy widgets for a vendor dashboard. Tenancy module doesn't provide vendor-scoped widgets (vendors don't see other vendors). Args: db: Database session vendor_id: ID of the vendor context: Optional filtering/scoping context Returns: Empty list (no vendor-scoped tenancy widgets) """ # Tenancy widgets are platform/admin-only return [] def get_platform_widgets( self, db: Session, platform_id: int, context: WidgetContext | None = None, ) -> list[DashboardWidget]: """ Get tenancy widgets for the admin/platform dashboard. Args: db: Database session platform_id: ID of the platform context: Optional filtering/scoping context Returns: List of DashboardWidget objects for the platform """ from sqlalchemy.orm import joinedload from app.modules.tenancy.models import Vendor, VendorPlatform limit = context.limit if context else 5 # Get vendor IDs for this platform vendor_ids_subquery = ( db.query(VendorPlatform.vendor_id) .filter(VendorPlatform.platform_id == platform_id) .subquery() ) # Get recent vendors for this platform vendors = ( db.query(Vendor) .options(joinedload(Vendor.company)) .filter(Vendor.id.in_(vendor_ids_subquery)) .order_by(Vendor.created_at.desc()) .limit(limit) .all() ) items = [ WidgetListItem( id=vendor.id, title=vendor.name, subtitle=vendor.vendor_code, status=self._get_vendor_status(vendor), timestamp=vendor.created_at, url=f"/admin/vendors/{vendor.id}", metadata={ "vendor_code": vendor.vendor_code, "subdomain": vendor.subdomain, "is_active": vendor.is_active, "is_verified": vendor.is_verified, "company_name": vendor.company.name if vendor.company else None, }, ) for vendor in vendors ] # Get total vendor count for platform total_count = ( db.query(Vendor) .filter(Vendor.id.in_(vendor_ids_subquery)) .count() ) return [ DashboardWidget( key="tenancy.recent_vendors", widget_type="list", title="Recent Vendors", category="tenancy", data=ListWidget( items=items, total_count=total_count, view_all_url="/admin/vendors", ), icon="shopping-bag", description="Recently created vendor accounts", order=10, ) ] # Singleton instance tenancy_widget_provider = TenancyWidgetProvider() __all__ = ["TenancyWidgetProvider", "tenancy_widget_provider"]