defmodule DaProductAppWeb.RefundSettlementController do use DaProductAppWeb, :controller require Logger alias DaProductApp.Settlements @doc """ Processes an uploaded refund CSV file. Expects a multipart form upload with: - file: CSV file containing refund transactions - merchant_id (optional): Merchant identifier - provider_id (optional): Provider identifier """ def process_csv(conn, params) do Logger.info("Processing refund settlement CSV upload") case Map.get(params, "file") do %Plug.Upload{filename: filename, path: path} -> try do content = File.read!(path) options = %{ merchant_id: Map.get(params, "merchant_id"), provider_id: parse_integer(Map.get(params, "provider_id")), settlement_date: parse_date(Map.get(params, "settlement_date")) } case Settlements.process_refund_settlement(filename, content, options) do {:ok, result} -> Logger.info("Successfully processed refund settlement: #{result.settlement_id}") conn |> put_status(:ok) |> json(%{ status: "SUCCESS", settlement_id: result.settlement_id, data: %{ matched_refunds: result.matched_count, total_refunds: result.total_refunds, total_amount: to_string(result.total_amount), unmatched_transactions: result.unmatched_transactions } }) {:error, reason} -> Logger.error("Failed to process refund settlement: #{inspect(reason)}") conn |> put_status(:bad_request) |> json(%{ status: "ERROR", error_code: "PROCESSING_FAILED", error_message: "Failed to process refund settlement: #{inspect(reason)}" }) end rescue error -> Logger.error("Error reading uploaded file: #{inspect(error)}") conn |> put_status(:bad_request) |> json(%{ status: "ERROR", error_code: "FILE_READ_ERROR", error_message: "Failed to read uploaded file" }) end nil -> Logger.error("No file uploaded") conn |> put_status(:bad_request) |> json(%{ status: "ERROR", error_code: "NO_FILE", error_message: "No CSV file provided" }) end end @doc """ Lists refund settlements with optional filtering. """ def list_refunds(conn, params) do # Filter settlements by refund-related criteria refund_params = params |> Map.put("details_contains", "refund") settlements = Settlements.list_settlements(refund_params) total_count = Settlements.count_settlements(refund_params) conn |> put_status(:ok) |> json(%{ status: "SUCCESS", data: %{ settlements: settlements, pagination: %{ total_count: total_count, page: parse_integer(params["page"] || "1"), page_size: parse_integer(params["page_size"] || "20") } } }) end @doc """ Gets details of a specific refund settlement. """ def get_refund_details(conn, %{"settlement_id" => settlement_id}) do case Settlements.get_settlement_by_settlement_id(settlement_id) do nil -> conn |> put_status(:not_found) |> json(%{ status: "ERROR", error_code: "NOT_FOUND", error_message: "Settlement not found" }) settlement -> # Get settlement transaction records settlement_transactions = Settlements.list_settlement_transaction_records(settlement_id) conn |> put_status(:ok) |> json(%{ status: "SUCCESS", data: %{ settlement: settlement, transactions: settlement_transactions } }) end end # Helper functions defp parse_integer(nil), do: nil defp parse_integer(""), do: nil defp parse_integer(value) when is_binary(value) do case Integer.parse(value) do {int, ""} -> int _ -> nil end end defp parse_integer(value) when is_integer(value), do: value defp parse_integer(_), do: nil defp parse_date(nil), do: nil defp parse_date(""), do: nil defp parse_date(date_str) when is_binary(date_str) do case Date.from_iso8601(date_str) do {:ok, date} -> date _ -> nil end end defp parse_date(_), do: nil end