This commit is contained in:
51
lib/customer_service/aggregates/corporate_customer.ex
Normal file
51
lib/customer_service/aggregates/corporate_customer.ex
Normal file
@@ -0,0 +1,51 @@
|
||||
defmodule CustomerService.Aggregates.CorporateCustomer do
|
||||
defstruct [
|
||||
:id,
|
||||
:legal_name,
|
||||
:commercial_name,
|
||||
:ruc,
|
||||
:legal_rep_name,
|
||||
:legal_rep_document_id,
|
||||
:email,
|
||||
:phone,
|
||||
:address
|
||||
]
|
||||
|
||||
alias __MODULE__
|
||||
alias Commanded.Aggregates.Aggregate
|
||||
alias CustomerService.Commands
|
||||
alias CustomerService.Events
|
||||
|
||||
@behaviour Aggregate
|
||||
|
||||
@impl Aggregate
|
||||
def execute(%CorporateCustomer{id: nil}, %Commands.CreateCorporateCustomer{} = cmd) do
|
||||
%Events.CorporateCustomerCreated{
|
||||
id: cmd.id,
|
||||
legal_name: cmd.legal_name,
|
||||
commercial_name: cmd.commercial_name,
|
||||
ruc: cmd.ruc,
|
||||
legal_rep_name: cmd.legal_rep_name,
|
||||
legal_rep_document_id: cmd.legal_rep_document_id,
|
||||
email: cmd.email,
|
||||
phone: cmd.phone,
|
||||
address: cmd.address
|
||||
}
|
||||
end
|
||||
|
||||
@impl Aggregate
|
||||
def apply(%CorporateCustomer{} = c, %Events.CorporateCustomerCreated{} = e) do
|
||||
%CorporateCustomer{
|
||||
c
|
||||
| id: e.id,
|
||||
legal_name: e.legal_name,
|
||||
commercial_name: e.commercial_name,
|
||||
ruc: e.ruc,
|
||||
legal_rep_name: e.legal_rep_name,
|
||||
legal_rep_document_id: e.legal_rep_document_id,
|
||||
email: e.email,
|
||||
phone: e.phone,
|
||||
address: e.address
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,9 @@ defmodule CustomerService.Aggregates.Customer do
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
:phone,
|
||||
:address,
|
||||
:document_id
|
||||
]
|
||||
|
||||
alias __MODULE__
|
||||
@@ -24,13 +26,15 @@ defmodule CustomerService.Aggregates.Customer do
|
||||
birth_date: cmd.birth_date,
|
||||
gender: cmd.gender,
|
||||
email: cmd.email,
|
||||
phone: cmd.phone
|
||||
phone: cmd.phone,
|
||||
document_id: cmd.document_id,
|
||||
address: cmd.address
|
||||
}
|
||||
end
|
||||
|
||||
@impl Aggregate
|
||||
def apply(%Customer{} = c, %Events.CustomerCreated{} = e) do
|
||||
%Customer{
|
||||
%__MODULE__{
|
||||
c
|
||||
| id: e.id,
|
||||
first_name: e.first_name,
|
||||
@@ -38,7 +42,9 @@ defmodule CustomerService.Aggregates.Customer do
|
||||
birth_date: e.birth_date,
|
||||
gender: e.gender,
|
||||
email: e.email,
|
||||
phone: e.phone
|
||||
phone: e.phone,
|
||||
address: e.address,
|
||||
document_id: e.document_id
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,11 @@ defmodule CustomerService.Router do
|
||||
|
||||
identify(Aggregates.Customer, by: :id)
|
||||
dispatch([Commands.CreateCustomer], to: Aggregates.Customer)
|
||||
|
||||
dispatch(Commands.CreateCorporateCustomer,
|
||||
to: Aggregates.CorporateCustomer,
|
||||
identity: :id
|
||||
)
|
||||
end
|
||||
|
||||
defmodule CustomerService.CommandedApp do
|
||||
|
||||
@@ -6,6 +6,22 @@ defmodule CustomerService.Commands.CreateCustomer do
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
:phone,
|
||||
:address,
|
||||
:document_id
|
||||
]
|
||||
end
|
||||
|
||||
defmodule CustomerService.Commands.CreateCorporateCustomer do
|
||||
defstruct [
|
||||
:id,
|
||||
:legal_name,
|
||||
:commercial_name,
|
||||
:ruc,
|
||||
:legal_rep_name,
|
||||
:legal_rep_document_id,
|
||||
:email,
|
||||
:phone,
|
||||
:address
|
||||
]
|
||||
end
|
||||
|
||||
19
lib/customer_service/customer/filters.ex
Normal file
19
lib/customer_service/customer/filters.ex
Normal file
@@ -0,0 +1,19 @@
|
||||
defmodule CustomerService.Customers.Filters do
|
||||
import Ecto.Query
|
||||
|
||||
def search(query, %Flop.Filter{value: value}, _opts) do
|
||||
term = "%#{value}%"
|
||||
|
||||
where(
|
||||
query,
|
||||
[c],
|
||||
ilike(c.first_name, ^term) or
|
||||
ilike(c.last_name, ^term) or
|
||||
ilike(c.legal_name, ^term) or
|
||||
ilike(c.email, ^term) or
|
||||
ilike(c.phone, ^term) or
|
||||
ilike(c.document_id, ^term) or
|
||||
ilike(c.ruc, ^term)
|
||||
)
|
||||
end
|
||||
end
|
||||
15
lib/customer_service/customer/queries.ex
Normal file
15
lib/customer_service/customer/queries.ex
Normal file
@@ -0,0 +1,15 @@
|
||||
defmodule CustomerService.Customer.Queries do
|
||||
alias CustomerService.Projections.Customer
|
||||
alias CustomerService.Repo
|
||||
|
||||
def list_customers(params \\ %{}) do
|
||||
Flop.validate_and_run(Customer, params, for: Customer)
|
||||
end
|
||||
|
||||
def get_customer(id) do
|
||||
case Repo.get(Customer, id) do
|
||||
nil -> {:error, :not_found}
|
||||
customer -> {:ok, customer}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,6 +7,23 @@ defmodule CustomerService.Events.CustomerCreated do
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
:phone,
|
||||
:address,
|
||||
:document_id
|
||||
]
|
||||
end
|
||||
|
||||
defmodule CustomerService.Events.CorporateCustomerCreated do
|
||||
@derive Jason.Encoder
|
||||
defstruct [
|
||||
:id,
|
||||
:legal_name,
|
||||
:commercial_name,
|
||||
:ruc,
|
||||
:legal_rep_name,
|
||||
:legal_rep_document_id,
|
||||
:email,
|
||||
:phone,
|
||||
:address
|
||||
]
|
||||
end
|
||||
|
||||
@@ -2,24 +2,66 @@ defmodule CustomerService.Projections.Customer do
|
||||
use Ecto.Schema
|
||||
|
||||
@derive {Jason.Encoder,
|
||||
only: [
|
||||
:id,
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
only: [
|
||||
:id,
|
||||
:customer_type,
|
||||
# individual
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:document_id,
|
||||
# corporate
|
||||
:legal_name,
|
||||
:commercial_name,
|
||||
:ruc,
|
||||
:legal_rep_name,
|
||||
:legal_rep_document_id,
|
||||
# shared
|
||||
:address,
|
||||
:email,
|
||||
:phone,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
|
||||
@derive {
|
||||
Flop.Schema,
|
||||
filterable: [:customer_type, :email, :phone, :document_id, :ruc, :search],
|
||||
sortable: [:last_name, :legal_name, :inserted_at],
|
||||
default_limit: 20,
|
||||
max_limit: 100,
|
||||
custom_fields: [
|
||||
search: [
|
||||
filter: {CustomerService.Customers.Filters, :search, []},
|
||||
ecto_type: :string,
|
||||
operators: [:==]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@primary_key {:id, :binary_id, autogenerate: false}
|
||||
@timestamps_opts [type: :utc_datetime_usec]
|
||||
|
||||
schema "customers" do
|
||||
field :customer_type, :string, default: "individual"
|
||||
|
||||
# individual fields
|
||||
field :first_name, :string
|
||||
field :last_name, :string
|
||||
field :birth_date, :date
|
||||
field :gender, :string
|
||||
field :document_id, :string
|
||||
|
||||
# corporate fields
|
||||
field :legal_name, :string
|
||||
field :commercial_name, :string
|
||||
field :ruc, :string
|
||||
field :legal_rep_name, :string
|
||||
field :legal_rep_document_id, :string
|
||||
|
||||
# shared
|
||||
field :address, :string
|
||||
field :email, :string
|
||||
field :phone, :string
|
||||
|
||||
|
||||
@@ -11,21 +11,40 @@ defmodule CustomerService.Projectors.Customer do
|
||||
project(%Events.CustomerCreated{} = event, fn multi ->
|
||||
Ecto.Multi.insert(multi, :customer, %Customer{
|
||||
id: event.id,
|
||||
customer_type: "individual",
|
||||
first_name: event.first_name,
|
||||
last_name: event.last_name,
|
||||
birth_date: event.birth_date,
|
||||
birth_date: parse_date(event.birth_date),
|
||||
gender: event.gender,
|
||||
email: event.email,
|
||||
phone: event.phone
|
||||
phone: event.phone,
|
||||
address: event.address,
|
||||
document_id: event.document_id
|
||||
})
|
||||
end)
|
||||
|
||||
# project %Events.CustomerDeactivated{} = event, _metadata do
|
||||
# Ecto.Multi.update_all(
|
||||
# multi,
|
||||
# :deactivate_customer,
|
||||
# from(c in Customer, where: c.customer_id == ^event.customer_id),
|
||||
# set: [active: false]
|
||||
# )
|
||||
# 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
|
||||
|
||||
project(%Events.CorporateCustomerCreated{} = e, _meta, fn multi ->
|
||||
Ecto.Multi.insert(multi, :customer, %Customer{
|
||||
id: e.id,
|
||||
customer_type: "corporate",
|
||||
legal_name: e.legal_name,
|
||||
commercial_name: e.commercial_name,
|
||||
ruc: e.ruc,
|
||||
legal_rep_name: e.legal_rep_name,
|
||||
legal_rep_document_id: e.legal_rep_document_id,
|
||||
email: e.email,
|
||||
phone: e.phone,
|
||||
address: e.address
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user