# lib/policy_service_web/controllers/car_policy_controller.ex defmodule PolicyServiceWeb.CarPolicyController do use PolicyServiceWeb, :controller use OpenApiSpex.ControllerSpecs alias OpenApiSpex.Schema alias PolicyServiceWeb.Schemas.CarPolicy.{QuoteRequest, QuoteResponse} alias PolicyService.Commands.Car.SubmitCarPolicyApplication tags(["Car Policy"]) security([%{"bearerAuth" => []}]) operation(:request_quote, summary: "Solicitar cotización de seguro de auto", description: "Envía una solicitud de cotización a los proveedores seleccionados", request_body: {"Quote request body", "application/json", QuoteRequest, required: true}, responses: [ created: {"Solicitud creada exitosamente", "application/json", QuoteResponse}, unprocessable_entity: {"Error de validación", "application/json", %Schema{ type: :object, properties: %{ errors: %Schema{type: :object} } }} ] ) def request_quote(conn, params) do user = %{"id" => "test", "org_id" => "test"} cmd = %SubmitCarPolicyApplication{ application_id: Ecto.UUID.generate(), org_id: user["org_id"], submitted_by: user["id"], applicant_info: %{ name: params["applicant_info"]["name"], date_of_birth: Date.from_iso8601!(params["applicant_info"]["date_of_birth"]), document_id: params["applicant_info"]["document_id"] }, car_details: %{ plate: params["car_details"]["plate"], make: params["car_details"]["make"], model: params["car_details"]["model"], year: params["car_details"]["year"], car_value: parse_number(params["car_details"]["car_value"]), use_type: String.to_atom(params["car_details"]["use_type"]), car_type: String.to_atom(params["car_details"]["car_type"]), chassis_number: params["car_details"]["chassis_number"], engine_number: params["car_details"]["engine_number"] }, selected_providers: Enum.map(params["selected_providers"], fn p -> %{id: p["id"], email: p["email"]} end) } case PolicyService.CommandedApp.dispatch(cmd) do :ok -> conn |> put_status(:created) |> json(%{ application_id: cmd.applicant_info, status: "awaiting_quotes" }) {:error, reason} -> conn |> put_status(:unprocessable_entity) |> json(%{errors: reason}) end end defp parse_number(val) when is_float(val), do: val defp parse_number(val) when is_integer(val), do: val * 1.0 defp parse_number(val) when is_binary(val) do case Float.parse(val) do {f, _} -> f :error -> raise "invalid number: #{val}" end end end