""" app/admin/billing/routes.py Billing history: manual invoice entry per tenant, list view. All entries logged. Superadmin only. """ import logging from datetime import datetime, timezone from flask import Blueprint, render_template, redirect, url_for, flash, request from flask_login import login_required, current_user from app.extensions import db from app.models.platform import Tenant, TenantBillingHistory from app.admin.utils import superadmin_required, log_admin_action logger = logging.getLogger(__name__) billing_bp = Blueprint("billing", __name__, url_prefix="/billing") @billing_bp.route("/") @login_required @superadmin_required def index(): entries = ( TenantBillingHistory.query .order_by(TenantBillingHistory.created_at.desc()) .limit(100) .all() ) return render_template("admin/billing/index.html", entries=entries) @billing_bp.route("/tenant/") @login_required @superadmin_required def tenant_billing(tenant_id): tenant = Tenant.query.get_or_404(tenant_id) entries = ( TenantBillingHistory.query .filter_by(tenant_id=tenant_id) .order_by(TenantBillingHistory.created_at.desc()) .all() ) return render_template("admin/billing/tenant.html", tenant=tenant, entries=entries) @billing_bp.route("/tenant//add", methods=["GET", "POST"]) @login_required @superadmin_required def add_entry(tenant_id): tenant = Tenant.query.get_or_404(tenant_id) if request.method == "POST": try: amount = float(request.form.get("amount", 0)) except ValueError: return render_template("admin/billing/form.html", tenant=tenant, error="Invalid amount.") description = request.form.get("description", "").strip() invoice_ref = request.form.get("invoice_ref", "").strip() or None paid_at_raw = request.form.get("paid_at", "").strip() paid_at = None if paid_at_raw: try: paid_at = datetime.fromisoformat(paid_at_raw) except ValueError: pass if not description: return render_template("admin/billing/form.html", tenant=tenant, error="Description is required.") entry = TenantBillingHistory( tenant_id=tenant_id, amount=amount, description=description, invoice_ref=invoice_ref, paid_at=paid_at, recorded_by=current_user.id, ) db.session.add(entry) db.session.flush() log_admin_action( "billing.add_entry", "tenant", tenant_id, after={"amount": amount, "description": description, "invoice_ref": invoice_ref}, ) db.session.commit() logger.info("Billing entry added: tenant_id=%s amount=%s by=%s", tenant_id, amount, current_user.id) flash(f"Billing entry added for \'{tenant.name}\'.", "success") return redirect(url_for("billing.tenant_billing", tenant_id=tenant_id)) return render_template("admin/billing/form.html", tenant=tenant)