Some checks are pending
Build and Publish / build-release (push) Waiting to run
145 lines
4.3 KiB
Elixir
145 lines
4.3 KiB
Elixir
defmodule PolicyService.Projectors.PolicyProjector do
|
|
use Commanded.Projections.Ecto,
|
|
application: PolicyService.CommandedApp,
|
|
repo: PolicyService.Repo,
|
|
name: "PolicyApplicationProjection",
|
|
consistency: :strong
|
|
|
|
alias PolicyService.Events.Policy.{
|
|
PolicyApplicationSubmitted,
|
|
ProviderQuoteReceived,
|
|
AllQuotesReceived,
|
|
QuoteAccepted,
|
|
SolicitationSent,
|
|
PolicyIssued
|
|
}
|
|
|
|
alias PolicyService.Projections.PolicyApplication
|
|
alias PolicyService.Aggregates.PolicyId
|
|
import Ecto.Query
|
|
|
|
project(%PolicyApplicationSubmitted{} = e, _meta, fn multi ->
|
|
%{policy_type: policy_type, application_id: application_id, org_id: org_id} = e.id
|
|
|
|
Ecto.Multi.insert(multi, :policy_application, %PolicyApplication{
|
|
id: to_string(PolicyId.new(org_id, policy_type, application_id)),
|
|
application_id: application_id,
|
|
org_id: org_id,
|
|
submitted_by: e.submitted_by,
|
|
policy_type: policy_type,
|
|
applicant_info: atomize(e.applicant_info),
|
|
policy_details: atomize(e.policy_details),
|
|
selected_providers: Enum.map(e.selected_providers, & &1["provider_id"]),
|
|
quotes: %{},
|
|
status: "quote_requested",
|
|
submitted_at: parse_datetime(e.submitted_at)
|
|
})
|
|
end)
|
|
|
|
project(%ProviderQuoteReceived{} = e, _meta, fn multi ->
|
|
multi
|
|
|> Ecto.Multi.run(:fetch, fn repo, _ ->
|
|
{:ok, repo.get!(PolicyApplication, to_string(e.id))}
|
|
end)
|
|
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
|
|
quote_data = %{
|
|
"quote_id" => e.quote_id,
|
|
"provider_id" => e.provider_id,
|
|
"valid_until" => e.valid_until,
|
|
"received_at" => parse_datetime(e.received_at),
|
|
"plans" => e.plans || []
|
|
}
|
|
|
|
Ecto.Changeset.change(p, quotes: Map.put(p.quotes, e.provider_id, quote_data))
|
|
end)
|
|
end)
|
|
|
|
project(%AllQuotesReceived{} = e, _meta, fn multi ->
|
|
multi
|
|
|> Ecto.Multi.run(:fetch, fn repo, _ ->
|
|
{:ok, repo.get!(PolicyApplication, to_string(e.id))}
|
|
end)
|
|
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
|
|
Ecto.Changeset.change(p, status: "quotes_received")
|
|
end)
|
|
end)
|
|
|
|
project(%QuoteAccepted{} = e, _meta, fn multi ->
|
|
multi
|
|
|> Ecto.Multi.run(:fetch, fn repo, _ ->
|
|
{:ok, repo.get!(PolicyApplication, to_string(e.id))}
|
|
end)
|
|
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
|
|
Ecto.Changeset.change(p,
|
|
accepted_quote_id: e.quote.quote_id,
|
|
accepted_plan_id: e.plan.plan_id,
|
|
accepted_provider_id: e.provider.id,
|
|
accepted_at: parse_datetime(e.accepted_at),
|
|
status: "solicitation_sent"
|
|
)
|
|
end)
|
|
end)
|
|
|
|
project(%SolicitationSent{} = e, _meta, fn multi ->
|
|
multi
|
|
|> Ecto.Multi.run(:fetch, fn repo, _ ->
|
|
{:ok, repo.get!(PolicyApplication, to_string(e.id))}
|
|
end)
|
|
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
|
|
Ecto.Changeset.change(p,
|
|
solicitation_id: e.solicitation_id,
|
|
solicitation_s3_key: e.s3_key,
|
|
solicitation_sent_at: parse_datetime(e.sent_at)
|
|
)
|
|
end)
|
|
end)
|
|
|
|
project(%PolicyIssued{} = e, _meta, fn multi ->
|
|
multi
|
|
|> Ecto.Multi.run(:fetch, fn repo, _ ->
|
|
{:ok, repo.get!(PolicyApplication, to_string(e.id))}
|
|
end)
|
|
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
|
|
Ecto.Changeset.change(p,
|
|
policy_number: e.policy_number,
|
|
effective_date: parse_date(e.effective_date),
|
|
expiry_date: parse_date(e.expiry_date),
|
|
issued_at: parse_datetime(e.issued_at),
|
|
status: "issued"
|
|
)
|
|
end)
|
|
end)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
defp atomize(nil), do: nil
|
|
|
|
defp atomize(map) when is_map(map) do
|
|
Map.new(map, fn {k, v} ->
|
|
{if(is_atom(k), do: Atom.to_string(k), else: k), v}
|
|
end)
|
|
end
|
|
|
|
defp parse_datetime(nil), do: nil
|
|
defp parse_datetime(%DateTime{} = dt), do: dt
|
|
|
|
defp parse_datetime(str) when is_binary(str) do
|
|
case DateTime.from_iso8601(str) do
|
|
{:ok, dt, _} -> dt
|
|
_ -> nil
|
|
end
|
|
end
|
|
|
|
defp parse_date(nil), do: nil
|
|
defp parse_date(%Date{} = d), do: d
|
|
|
|
defp parse_date(str) when is_binary(str) do
|
|
case Date.from_iso8601(str) do
|
|
{:ok, d} -> d
|
|
_ -> nil
|
|
end
|
|
end
|
|
end
|