defmodule DaProductAppWeb.SettlementLive.FileTracker do use DaProductAppWeb, :live_view alias DaProductApp.Settlements.SettlementManagement require Logger @ysp_api "http://localhost:4099/api/v1/merchant/ysp_summaries" @aani_api "http://localhost:4099/api/v1/merchant/aani_settlements" @impl true def mount(_params, _session, socket) do files = SettlementManagement.list_settlement_files() {:ok, assign(socket, files: files, current_page: "file_tracker", audits: %{}, view: "alipay")} end @impl true def handle_event("upload", %{"file" => upload}, socket) do {:ok, file} = SettlementManagement.create_settlement_file(%{ filename: upload.filename, status: "uploaded" }) SettlementManagement.create_file_audit(%{ settlement_file_id: file.id, action: "upload", inserted_at: DateTime.utc_now() }) files = SettlementManagement.list_settlement_files() {:noreply, assign(socket, files: files)} end @impl true def handle_event("toggle_view", %{"view" => "alipay"}, socket) do files = SettlementManagement.list_settlement_files() {:noreply, assign(socket, files: files, view: "alipay")} end @impl true def handle_event("toggle_view", %{"view" => "ysp"}, socket) do case fetch_ysp_summaries() do {:ok, ysp_files} -> {:noreply, assign(socket, files: ysp_files, view: "ysp")} {:error, _} -> {:noreply, assign(socket, files: [], view: "ysp")} end end @impl true def handle_event("toggle_view", %{"view" => "aani"}, socket) do case fetch_aani_settlements() do {:ok, settlements} -> {:noreply, assign(socket, files: settlements, view: "aani")} {:error, _} -> {:noreply, assign(socket, files: [], view: "aani")} end end @impl true def handle_event("reprocess", %{"id" => id}, socket) do {:ok, _audit} = SettlementManagement.create_file_audit(%{ settlement_file_id: id, action: "reprocess", inserted_at: DateTime.utc_now() }) files = SettlementManagement.list_settlement_files() {:noreply, assign(socket, files: files)} end @impl true def handle_event("show_audits", %{"id" => id}, socket) do key = to_string(id) if Map.has_key?(socket.assigns.audits, key) do {:noreply, assign(socket, audits: Map.delete(socket.assigns.audits, key))} else audits = SettlementManagement.list_file_audits(id) {:noreply, assign(socket, audits: Map.put(socket.assigns.audits, key, audits))} end end defp fetch_ysp_summaries do case :httpc.request(:get, {to_charlist(@ysp_api), []}, [], [{:body_format, :binary}]) do {:ok, {{_, 200, _}, _headers, body}} -> case Jason.decode(body) do {:ok, %{"ysp_summaries" => items}} -> {:ok, Enum.map(items, &map_ysp_to_row/1)} _ -> {:error, :decode_failed} end error -> Logger.error("Failed to fetch YSP summaries: #{inspect(error)}") {:error, :http_failed} end end defp fetch_aani_settlements do case :httpc.request(:get, {to_charlist(@aani_api), []}, [], [{:body_format, :binary}]) do {:ok, {{_, 200, _}, _headers, body}} -> case Jason.decode(body) do {:ok, %{"aani_settlements" => items}} -> {:ok, Enum.map(items, &map_aani_to_row/1)} _ -> {:error, :decode_failed} end error -> Logger.error("Failed to fetch AANI settlements: #{inspect(error)}") {:error, :http_failed} end end defp map_ysp_to_row(df) do %{ id: df["id"], filename: df["filename"] || "-", source: df["source"] || "-", dump_date: df["dump_date"] || "-", status: df["status"] || "-", processed_at: df["processed_at"] || "-", total_records: df["total_records"] || "-", error: df["error"] || "", file_size_bytes: df["file_size_bytes"] || "-" } end defp map_aani_to_row(s) do %{ id: s["id"], settlement_id: s["settlement_id"] || "-", date: s["date"] || "-", status: s["status"] || "-", amount: s["amount"] || "-", merchant_tag: s["merchant_tag"] || "-", bank_user_id: s["bank_user_id"] || "-", batch_number: s["batch_number"] || "-", total_transaction_count: s["total_transaction_count"] || "-", gross_settlement_amount: s["gross_settlement_amount"] || "-", net_settlement_amount: s["net_settlement_amount"] || "-", net_settlement_currency: s["net_settlement_currency"] || "-" } end end