This commit is contained in:
144
lib/policy_service/projectors/policy_projector.ex
Normal file
144
lib/policy_service/projectors/policy_projector.ex
Normal file
@@ -0,0 +1,144 @@
|
||||
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
|
||||
Reference in New Issue
Block a user