"""Subscription billing for Nexus POS SaaS.""" from tenant_db import get_master_conn PLANS = { 'free': {'name': 'Gratis', 'price_mxn': 0, 'max_products': 100, 'max_employees': 2, 'max_branches': 1}, 'basic': {'name': 'Basico', 'price_mxn': 499, 'max_products': 5000, 'max_employees': 5, 'max_branches': 2}, 'pro': {'name': 'Pro', 'price_mxn': 1499, 'max_products': 50000, 'max_employees': 15, 'max_branches': 5}, 'enterprise': {'name': 'Enterprise', 'price_mxn': 3999, 'max_products': None, 'max_employees': None, 'max_branches': None}, } PLAN_ORDER = ['free', 'basic', 'pro', 'enterprise'] def get_plan(tenant_id): """Get current plan for a tenant.""" conn = get_master_conn() cur = conn.cursor() cur.execute("SELECT plan FROM tenants WHERE id = %s", (tenant_id,)) row = cur.fetchone() cur.close() conn.close() if not row: return 'free' plan_key = row[0] or 'free' if plan_key not in PLANS: plan_key = 'free' return plan_key def get_plan_details(tenant_id): """Get plan key + full details for a tenant.""" plan_key = get_plan(tenant_id) return {**PLANS[plan_key], 'key': plan_key} def next_plan(current_plan): """Return the next upgrade plan key, or None if already enterprise.""" idx = PLAN_ORDER.index(current_plan) if current_plan in PLAN_ORDER else 0 if idx < len(PLAN_ORDER) - 1: return PLAN_ORDER[idx + 1] return None def check_limit(tenant_id, resource, current_count): """Check if tenant is within plan limits. Args: tenant_id: Tenant ID resource: One of 'max_products', 'max_employees', 'max_branches' current_count: Current count of that resource Returns: (allowed: bool, limit: int|None, current: int) """ plan_key = get_plan(tenant_id) plan = PLANS[plan_key] limit = plan.get(resource) if limit is None: return (True, None, current_count) return (current_count < limit, limit, current_count) def upgrade_plan(tenant_id, new_plan): """Change tenant's plan.""" if new_plan not in PLANS: return {'error': f'Invalid plan: {new_plan}'} conn = get_master_conn() cur = conn.cursor() cur.execute("UPDATE tenants SET plan = %s WHERE id = %s", (new_plan, tenant_id)) conn.commit() cur.close() conn.close() return {'success': True, 'plan': new_plan, 'details': PLANS[new_plan]}