defmodule ArcadiaCloudWeb.InvoiceController do @moduledoc """ Tenant invoices (revenue side). platform_admin sees all tenants; others are scoped to their own tenant_id. """ use ArcadiaCloudWeb, :controller alias ArcadiaCloud.Invoicing def index(conn, params) do identity = conn.assigns.current_identity opts = if platform_admin?(identity), do: [tenant_id: params["tenant_id"], status: params["status"]], else: [tenant_id: identity.tenant_id, status: params["status"]] invoices = Invoicing.list_invoices(opts) |> Enum.map(&shape/1) json(conn, %{invoices: invoices, count: length(invoices)}) end def show(conn, %{"id" => id}) do identity = conn.assigns.current_identity case Invoicing.get_invoice(id) do nil -> conn |> put_status(:not_found) |> json(%{error: "not_found"}) invoice -> if platform_admin?(identity) or invoice.tenant_id == identity.tenant_id do json(conn, %{invoice: shape(invoice), lines: Enum.map(invoice.lines, &shape_line/1)}) else conn |> put_status(:forbidden) |> json(%{error: "forbidden"}) end end end defp platform_admin?(%{roles: roles}) when is_list(roles), do: "platform_admin" in roles defp platform_admin?(_), do: false defp shape(i) do %{ id: i.id, tenant_id: i.tenant_id, period_start: i.period_start, period_end: i.period_end, currency: i.currency, subtotal_cents: i.subtotal_cents, tax_cents: i.tax_cents, total_cents: i.total_cents, status: i.status, issued_at: i.issued_at, pushed_to_finance_at: i.pushed_to_finance_at } end defp shape_line(l) do %{ kind: l.kind, deployment_id: l.deployment_id, resource_kind: l.resource_kind, description: l.description, qty: l.qty, unit: l.unit, unit_price_cents: l.unit_price_cents, amount_cents: l.amount_cents } end end