defmodule WorkloadService.Aggregates.QuoteTask do use WorkloadService.Aggregates.Task, task_type: "quote", commands: WorkloadService.Commands.QuoteTask, submission_type: map() def validate_submission(submission) when is_map(submission) do with {:ok, quote_id} <- validate_required_string(submission, "quote_id"), {:ok, recorded_by} <- validate_required_string(submission, "recorded_by"), {:ok, valid_until} <- validate_date_string(submission, "valid_until"), {:ok, plans} <- validate_plans(submission["plans"]) do :ok end end def validate_submission(_), do: {:error, :invalid_submission_format} defp validate_required_string(submission, field) do case Map.get(submission, field) do nil -> {:error, {:missing_field, field}} value when is_binary(value) and byte_size(value) > 0 -> {:ok, value} _ -> {:error, {:invalid_field, field}} end end defp validate_date_string(submission, field) do case Map.get(submission, field) do nil -> {:error, {:missing_field, field}} value when is_binary(value) -> case Date.from_iso8601(value) do {:ok, _date} -> {:ok, value} {:error, _} -> {:error, {:invalid_date_format, field}} end _ -> {:error, {:invalid_field, field}} end end defp validate_plans(plans) when is_list(plans) do if length(plans) == 0 do {:error, :no_plans_provided} else case Enum.reduce_while(plans, :ok, fn plan, _acc -> validate_plan(plan) end) do :ok -> {:ok, plans} error -> error end end end defp validate_plans(_), do: {:error, :invalid_plans_format} defp validate_plan(plan) when is_map(plan) do with {:ok, plan_id} <- validate_required_string(plan, "plan_id"), {:ok, name} <- validate_required_string(plan, "name"), {:ok, premium} <- validate_premium(plan["premium"]), {:ok, coverage_details} <- validate_coverage_details(plan["coverage_details"]) do {:cont, :ok} end end defp validate_plan(_), do: {:halt, {:error, :invalid_plan_format}} defp validate_premium(premium) when is_number(premium) and premium > 0, do: {:ok, premium} defp validate_premium(_), do: {:error, :invalid_premium} defp validate_coverage_details(details) when is_map(details), do: {:ok, details} defp validate_coverage_details(_), do: {:error, :invalid_coverage_details} end