This commit is contained in:
34
lib/provider_service/projections/provider.ex
Normal file
34
lib/provider_service/projections/provider.ex
Normal file
@@ -0,0 +1,34 @@
|
||||
defmodule ProviderService.Projections.Provider do
|
||||
use Ecto.Schema
|
||||
|
||||
@derive {
|
||||
Flop.Schema,
|
||||
filterable: [:active, :search],
|
||||
sortable: [:name, :inserted_at],
|
||||
default_limit: 20,
|
||||
max_limit: 100,
|
||||
custom_fields: [
|
||||
search: [
|
||||
filter: {ProviderService.Projections.ProviderFilters, :search, []},
|
||||
ecto_type: :string,
|
||||
operators: [:==]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@primary_key {:provider_id, :string, autogenerate: false}
|
||||
|
||||
schema "providers" do
|
||||
field(:name, :string)
|
||||
field(:email, :string)
|
||||
field(:phone, :string)
|
||||
field(:contact_name, :string)
|
||||
field(:ruc, :string)
|
||||
field(:address, :string)
|
||||
field(:active, :boolean, default: true)
|
||||
field(:templates, :map, default: %{})
|
||||
field(:default_templates, :map, default: %{})
|
||||
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
end
|
||||
16
lib/provider_service/projections/provider_filters.ex
Normal file
16
lib/provider_service/projections/provider_filters.ex
Normal file
@@ -0,0 +1,16 @@
|
||||
defmodule ProviderService.Projections.ProviderFilters do
|
||||
import Ecto.Query
|
||||
|
||||
def search(query, %Flop.Filter{value: value}, _opts) do
|
||||
term = "%#{value}%"
|
||||
|
||||
where(
|
||||
query,
|
||||
[p],
|
||||
ilike(p.name, ^term) or
|
||||
ilike(p.email, ^term) or
|
||||
ilike(p.contact_name, ^term) or
|
||||
ilike(p.ruc, ^term)
|
||||
)
|
||||
end
|
||||
end
|
||||
196
lib/provider_service/projections/provider_projection.ex
Normal file
196
lib/provider_service/projections/provider_projection.ex
Normal file
@@ -0,0 +1,196 @@
|
||||
defmodule ProviderService.Projections.ProviderProjection do
|
||||
use Commanded.Projections.Ecto,
|
||||
application: ProviderService.CommandedApp,
|
||||
repo: ProviderService.Repo,
|
||||
name: "ProviderProjection",
|
||||
consistency: :strong
|
||||
|
||||
alias ProviderService.Events.{
|
||||
ProviderRegistered,
|
||||
ProviderUpdated,
|
||||
ProviderDeactivated,
|
||||
ProviderReactivated,
|
||||
ProviderTemplateAdded,
|
||||
ProviderTemplateActivated,
|
||||
ProviderTemplateDeactivated,
|
||||
ProviderTemplateDefaultSet,
|
||||
ProviderTemplateRemoved
|
||||
}
|
||||
|
||||
alias ProviderService.Projections.Provider
|
||||
import Ecto.Query
|
||||
|
||||
project(%ProviderRegistered{} = e, _meta, fn multi ->
|
||||
Ecto.Multi.insert(multi, :provider, %Provider{
|
||||
provider_id: e.provider_id,
|
||||
name: e.name,
|
||||
email: e.email,
|
||||
phone: e.phone,
|
||||
contact_name: e.contact_name,
|
||||
ruc: e.ruc,
|
||||
address: e.address,
|
||||
active: true,
|
||||
templates: %{},
|
||||
default_templates: %{}
|
||||
})
|
||||
end)
|
||||
|
||||
project(%ProviderUpdated{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
Ecto.Changeset.change(p,
|
||||
name: e.name,
|
||||
email: e.email,
|
||||
phone: e.phone,
|
||||
contact_name: e.contact_name,
|
||||
ruc: e.ruc,
|
||||
address: e.address
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderDeactivated{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
Ecto.Changeset.change(p, active: false)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderReactivated{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
Ecto.Changeset.change(p, active: true)
|
||||
end)
|
||||
end)
|
||||
|
||||
# templates: %{ policy_type => %{ client_type => [template] } }
|
||||
# default_templates: %{ policy_type => %{ client_type => template_id } }
|
||||
|
||||
project(%ProviderTemplateAdded{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
template = %{
|
||||
"template_id" => e.template_id,
|
||||
"client_type" => e.client_type,
|
||||
"s3_key" => e.s3_key,
|
||||
"fields" => e.fields || [],
|
||||
"version" => e.version,
|
||||
"active" => false
|
||||
}
|
||||
|
||||
updated =
|
||||
p.templates
|
||||
|> Map.update(e.policy_type, %{e.client_type => [template]}, fn inner ->
|
||||
Map.update(inner, e.client_type, [template], fn list -> list ++ [template] end)
|
||||
end)
|
||||
|
||||
Ecto.Changeset.change(p, templates: updated)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderTemplateActivated{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
updated =
|
||||
update_template_field(
|
||||
p.templates,
|
||||
e.policy_type,
|
||||
e.client_type,
|
||||
e.template_id,
|
||||
"active",
|
||||
true
|
||||
)
|
||||
|
||||
Ecto.Changeset.change(p, templates: updated)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderTemplateDeactivated{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
updated =
|
||||
update_template_field(
|
||||
p.templates,
|
||||
e.policy_type,
|
||||
e.client_type,
|
||||
e.template_id,
|
||||
"active",
|
||||
false
|
||||
)
|
||||
|
||||
template_id = e.template_id
|
||||
|
||||
default_templates =
|
||||
case get_in(p.default_templates, [e.policy_type, e.client_type]) do
|
||||
^template_id ->
|
||||
Map.update(p.default_templates, e.policy_type, %{}, &Map.delete(&1, e.client_type))
|
||||
|
||||
_ ->
|
||||
p.default_templates
|
||||
end
|
||||
|
||||
Ecto.Changeset.change(p, templates: updated, default_templates: default_templates)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderTemplateDefaultSet{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
default_templates =
|
||||
p.default_templates
|
||||
|> Map.update(e.policy_type, %{e.client_type => e.template_id}, fn inner ->
|
||||
Map.put(inner, e.client_type, e.template_id)
|
||||
end)
|
||||
|
||||
Ecto.Changeset.change(p, default_templates: default_templates)
|
||||
end)
|
||||
end)
|
||||
|
||||
project(%ProviderTemplateRemoved{} = e, _meta, fn multi ->
|
||||
multi
|
||||
|> Ecto.Multi.run(:fetch, fn repo, _ -> {:ok, repo.get!(Provider, e.provider_id)} end)
|
||||
|> Ecto.Multi.update(:provider, fn %{fetch: p} ->
|
||||
updated =
|
||||
p.templates
|
||||
|> Map.update(e.policy_type, %{}, fn inner ->
|
||||
Map.update(inner, e.client_type, [], fn list ->
|
||||
Enum.reject(list, &(&1["template_id"] == e.template_id))
|
||||
end)
|
||||
end)
|
||||
|
||||
template_id = e.template_id
|
||||
|
||||
default_templates =
|
||||
case get_in(p.default_templates, [e.policy_type, e.client_type]) do
|
||||
^template_id ->
|
||||
Map.update(p.default_templates, e.policy_type, %{}, &Map.delete(&1, e.client_type))
|
||||
|
||||
_ ->
|
||||
p.default_templates
|
||||
end
|
||||
|
||||
Ecto.Changeset.change(p, templates: updated, default_templates: default_templates)
|
||||
end)
|
||||
end)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
defp update_template_field(templates, policy_type, client_type, template_id, field, value) do
|
||||
Map.update(templates, policy_type, %{}, fn inner ->
|
||||
Map.update(inner, client_type, [], fn list ->
|
||||
Enum.map(list, fn t ->
|
||||
if t["template_id"] == template_id, do: Map.put(t, field, value), else: t
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user