# app/modules/orders/services/order_features.py """ Order feature provider for the billing feature system. Declares order-related billable features (order limits, history retention, management tools) and provides usage tracking queries for feature gating. """ from __future__ import annotations from datetime import UTC, datetime from typing import TYPE_CHECKING from sqlalchemy import func from app.modules.contracts.features import ( FeatureDeclaration, FeatureScope, FeatureType, FeatureUsage, ) if TYPE_CHECKING: from sqlalchemy.orm import Session class OrderFeatureProvider: """Feature provider for the orders module. Declares: - orders_per_month: quantitative per-store limit on monthly order count - order_history_months: quantitative per-store configuration for history retention - order_management: binary merchant-level feature for order management tools - order_bulk_actions: binary merchant-level feature for bulk order operations - order_export: binary merchant-level feature for order data export - automation_rules: binary merchant-level feature for order automation """ @property def feature_category(self) -> str: return "orders" def get_feature_declarations(self) -> list[FeatureDeclaration]: return [ FeatureDeclaration( code="orders_per_month", name_key="orders.features.orders_per_month.name", description_key="orders.features.orders_per_month.description", category="orders", feature_type=FeatureType.QUANTITATIVE, scope=FeatureScope.STORE, default_limit=100, unit_key="orders.features.orders_per_month.unit", is_per_period=True, ui_icon="shopping-cart", display_order=10, ), FeatureDeclaration( code="order_history_months", name_key="orders.features.order_history_months.name", description_key="orders.features.order_history_months.description", category="orders", feature_type=FeatureType.QUANTITATIVE, scope=FeatureScope.STORE, default_limit=6, unit_key="orders.features.order_history_months.unit", ui_icon="clock", display_order=20, ), FeatureDeclaration( code="order_management", name_key="orders.features.order_management.name", description_key="orders.features.order_management.description", category="orders", feature_type=FeatureType.BINARY, scope=FeatureScope.MERCHANT, ui_icon="clipboard-list", display_order=30, ), FeatureDeclaration( code="order_bulk_actions", name_key="orders.features.order_bulk_actions.name", description_key="orders.features.order_bulk_actions.description", category="orders", feature_type=FeatureType.BINARY, scope=FeatureScope.MERCHANT, ui_icon="layers", display_order=40, ), FeatureDeclaration( code="order_export", name_key="orders.features.order_export.name", description_key="orders.features.order_export.description", category="orders", feature_type=FeatureType.BINARY, scope=FeatureScope.MERCHANT, ui_icon="download", display_order=50, ), FeatureDeclaration( code="automation_rules", name_key="orders.features.automation_rules.name", description_key="orders.features.automation_rules.description", category="orders", feature_type=FeatureType.BINARY, scope=FeatureScope.MERCHANT, ui_icon="zap", display_order=60, ), ] def get_store_usage( self, db: Session, store_id: int, ) -> list[FeatureUsage]: from app.modules.orders.models.order import Order now = datetime.now(UTC) period_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) count = ( db.query(func.count(Order.id)) .filter( Order.store_id == store_id, Order.created_at >= period_start, ) .scalar() or 0 ) return [ FeatureUsage( feature_code="orders_per_month", current_count=count, label="Orders this month", ), ] def get_merchant_usage( self, db: Session, merchant_id: int, platform_id: int, ) -> list[FeatureUsage]: from app.modules.orders.models.order import Order from app.modules.tenancy.services.platform_service import platform_service from app.modules.tenancy.services.store_service import store_service now = datetime.now(UTC) period_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) merchant_stores = store_service.get_stores_by_merchant_id(db, merchant_id) platform_store_ids = platform_service.get_store_ids_for_platform(db, platform_id) store_ids = [s.id for s in merchant_stores if s.id in platform_store_ids] count = ( db.query(func.count(Order.id)) .filter( Order.store_id.in_(store_ids), Order.created_at >= period_start, ) .scalar() or 0 ) return [ FeatureUsage( feature_code="orders_per_month", current_count=count, label="Orders this month", ), ] # Singleton instance for module registration order_feature_provider = OrderFeatureProvider() __all__ = [ "OrderFeatureProvider", "order_feature_provider", ]