defmodule WorkloadService.Aggregates.SolicitationTask do use WorkloadService.Aggregates.Task, task_type: "solicitation", commands: WorkloadService.Commands.SolicitationTask, submission_type: map() def validate_submission(submission) when is_map(submission) do with {:ok, provider_policy_number} <- validate_required_string(submission, "provider_policy_number"), {:ok, effective_date} <- validate_date_string(submission, "effective_date"), {:ok, expiry_date} <- validate_date_string(submission, "expiry_date"), {:ok, _} <- validate_expiry_after_effective(effective_date, expiry_date) 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_expiry_after_effective(effective_date, expiry_date) do case {Date.from_iso8601(effective_date), Date.from_iso8601(expiry_date)} do {{:ok, effective}, {:ok, expiry}} -> if Date.compare(expiry, effective) == :gt do {:ok, :valid_date_range} else {:error, :expiry_must_be_after_effective} end _ -> {:error, :invalid_date_comparison} end end end