Commit e45cb329 authored by Antonis Kalou's avatar Antonis Kalou

Simplify usage of relations for Event

parent 4f1ecaca
......@@ -84,7 +84,9 @@ defmodule ValueFlows.Observation.EconomicEvent do
@required ~w(action_id provider_id receiver_id is_public)a
@cast @required ++
~w(note resource_classified_as agreed_in has_beginning has_end has_point_in_time is_disabled)a
~w(note resource_classified_as agreed_in has_beginning has_end has_point_in_time is_disabled)a ++
~w(input_of_id output_of_id resource_conforms_to_id resource_inventoried_as_id to_resource_inventoried_as_id)a ++
~w(triggered_by_id at_location_id context_id)a
def create_changeset(
%User{} = creator,
......@@ -97,6 +99,7 @@ defmodule ValueFlows.Observation.EconomicEvent do
creator_id: creator.id,
is_public: true
)
|> change_measures(attrs)
|> common_changeset()
end
......@@ -108,77 +111,10 @@ defmodule ValueFlows.Observation.EconomicEvent do
def update_changeset(%EconomicEvent{} = event, attrs) do
event
|> Changeset.cast(attrs, @cast)
|> change_measures(attrs)
|> common_changeset()
end
def change_context(changeset, %{id: _} = context) do
Changeset.change(changeset,
context: context,
context_id: context.id
)
end
def change_provider(changeset, %{id: _} = provider) do
Changeset.change(changeset, provider_id: provider.id)
end
def change_receiver(changeset, %{id: _} = receiver) do
Changeset.change(changeset, receiver_id: receiver.id)
end
def change_action(changeset, %Action{} = action) do
Changeset.change(changeset, action_id: action.id)
end
def change_input_process(changeset, %Process{} = item) do
Changeset.change(changeset,
input_of: item,
input_of_id: item.id
)
end
def change_output_process(changeset, %Process{} = item) do
Changeset.change(changeset,
output_of: item,
output_of_id: item.id
)
end
def change_resource_conforms_to(changeset, %ResourceSpecification{} = conforms_to) do
Changeset.change(changeset,
resource_conforms_to: conforms_to,
resource_conforms_to_id: conforms_to.id
)
end
def change_resource_inventoried_as(changeset, %EconomicResource{} = item) do
Changeset.change(changeset,
resource_inventoried_as: item,
resource_inventoried_as_id: item.id
)
end
def change_to_resource_inventoried_as(changeset, %EconomicResource{} = item) do
Changeset.change(changeset,
to_resource_inventoried_as: item,
to_resource_inventoried_as_id: item.id
)
end
def change_at_location(changeset, %Geolocation{} = location) do
Changeset.change(changeset,
at_location: location,
at_location_id: location.id
)
end
def change_triggered_by_event(changeset, %EconomicEvent{} = item) do
Changeset.change(changeset,
triggered_by: item,
triggered_by_id: item.id
)
end
def change_measures(changeset, %{} = attrs) do
measures = Map.take(attrs, measure_fields())
......@@ -196,8 +132,12 @@ defmodule ValueFlows.Observation.EconomicEvent do
|> change_public()
|> change_disabled()
|> Changeset.foreign_key_constraint(
:at_location_id,
name: :vf_event_at_location_id_fkey
:resource_inventoried_as_id,
name: :vf_event_resource_inventoried_as_id_fkey
)
|> Changeset.foreign_key_constraint(
:to_resource_inventoried_as_id,
name: :vf_event_to_resource_inventoried_as_id_fkey
)
end
......
# SPDX-License-Identifier: AGPL-3.0-only
defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
import CommonsPub.Common, only: [maybe_put: 3]
alias CommonsPub.{Activities, Common, Feeds, Repo}
alias CommonsPub.GraphQL.{Fields, Page}
......@@ -9,8 +10,6 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
alias CommonsPub.Meta.Pointers
alias Geolocation.Geolocations
# alias Measurement.Measure
# alias ValueFlows.Knowledge.Action
alias ValueFlows.Knowledge.Action.Actions
alias ValueFlows.Knowledge.ResourceSpecification.ResourceSpecifications
......@@ -97,13 +96,19 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
def preload_all(event) do
Repo.preload(event, [
:context,
:creator,
:resource_quantity,
:effort_quantity,
:at_location,
:input_of,
:output_of,
:resource_conforms_to,
:resource_inventoried_as,
:to_resource_inventoried_as,
:provider,
:receiver
:receiver,
:triggered_by
])
|> preload_action()
end
......@@ -275,13 +280,11 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
end
def create(%User{} = creator, event_attrs) do
changeset_fn = fn ->
EconomicEvent.create_changeset(creator, event_attrs)
end
event_attrs = prepare_attrs(event_attrs)
cs = EconomicEvent.create_changeset(creator, event_attrs)
Repo.transact_with(fn ->
with {:ok, cs} <- prepare_changeset(event_attrs, changeset_fn),
{:ok, event} <- Repo.insert(cs |> EconomicEvent.create_changeset_validate()),
with {:ok, event} <- Repo.insert(cs |> EconomicEvent.create_changeset_validate()),
{:ok, event} <- ValueFlows.Util.try_tag_thing(creator, event, event_attrs),
event = preload_all(event),
{:ok, event} <- apply_resource_primary_accountable(event),
......@@ -290,8 +293,6 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
# FIXME
{:ok, activity} <- Activities.create(creator, event, act_attrs),
:ok <- publish(creator, event, activity, :created) do
event = %{event | creator: creator}
index(event)
{:ok, event}
end
......@@ -306,7 +307,7 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
creator,
new_inventoried_resource
) do
event_attrs = Map.merge(event_attrs, %{field_name => new_resource})
event_attrs = Map.merge(event_attrs, %{field_name => new_resource.id})
with {:ok, event} <- create(creator, event_attrs) do
{:ok, event, new_resource}
......@@ -317,15 +318,11 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
# TODO: take the user who is performing the update
# @spec update(%EconomicEvent{}, attrs :: map) :: {:ok, EconomicEvent.t()} | {:error, Changeset.t()}
def update(%EconomicEvent{} = event, attrs) do
do_update(event, attrs, &EconomicEvent.update_changeset(&1, attrs))
end
def do_update(event, attrs, changeset_fn) do
Repo.transact_with(fn ->
event = preload_all(event)
attrs = prepare_attrs(attrs)
with {:ok, cs} <- prepare_changeset(attrs, changeset_fn, event),
{:ok, event} <- Repo.update(cs),
with {:ok, event} <- Repo.update(EconomicEvent.update_changeset(event, attrs)),
{:ok, event} <- apply_resource_primary_accountable(event),
{:ok, event} <- ValueFlows.Util.try_tag_thing(nil, event, attrs),
:ok <- publish(event, :updated) do
......@@ -334,107 +331,6 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
end)
end
defp prepare_changeset(attrs, changeset_fn, event) do
event
|> changeset_fn.()
|> changeset_relations(attrs)
end
defp prepare_changeset(attrs, changeset_fn) do
changeset_fn.()
|> changeset_relations(attrs)
end
defp changeset_relations(cs, attrs) do
attrs = parse_measurement_attrs(attrs)
ValueFlows.Util.handle_changeset_errors(cs, attrs, [
&EconomicEvent.change_measures/2,
&change_context/2,
&change_provider/2,
&change_receiver/2,
&change_action/2,
&change_at_location/2,
&change_input_of/2,
&change_output_of/2,
&change_triggered_by_event/2,
&change_resource_conforms_to/2,
&change_resource_inventoried_as/2,
&change_to_resource_inventoried_as/2
])
end
defp change_context(changeset, %{in_scope_of: context_ids} = attrs)
when is_list(context_ids) do
# FIXME: support multiple contexts?
context_id = List.first(context_ids)
change_context(
changeset,
Map.merge(attrs, %{in_scope_of: context_id})
)
end
defp change_context(changeset, %{in_scope_of: id}) when is_binary(id) do
with {:ok, pointer} <- Pointers.one(id: id) do
EconomicEvent.change_context(changeset, pointer)
end
end
defp change_context(changeset, _attrs), do: changeset
defp change_resource_conforms_to(changeset, %{resource_conforms_to: id}) do
with {:ok, res_spec} <- ResourceSpecifications.one([:default, id: id]) do
EconomicEvent.change_resource_conforms_to(changeset, res_spec)
end
end
defp change_resource_conforms_to(changeset, _attrs), do: changeset
defp change_resource_inventoried_as(changeset, %{resource_inventoried_as: id})
when is_binary(id) do
with {:ok, resource} <- EconomicResources.one([:default, id: id]) do
EconomicEvent.change_resource_inventoried_as(changeset, resource)
end
end
defp change_resource_inventoried_as(changeset, %{resource_inventoried_as: %{} = resource}) do
EconomicEvent.change_resource_inventoried_as(changeset, resource)
end
defp change_resource_inventoried_as(changeset, _attrs), do: changeset
defp change_to_resource_inventoried_as(changeset, %{to_resource_inventoried_as: id})
when is_binary(id) do
with {:ok, resource} <- EconomicResources.one([:default, id: id]) do
EconomicEvent.change_to_resource_inventoried_as(changeset, resource)
end
end
defp change_to_resource_inventoried_as(changeset, %{to_resource_inventoried_as: %{} = resource}) do
EconomicEvent.change_to_resource_inventoried_as(changeset, resource)
end
defp change_to_resource_inventoried_as(changeset, _attrs), do: changeset
defp change_provider(changeset, %{provider: provider_id}) do
with {:ok, pointer} <- Pointers.one(id: provider_id) do
provider = Pointers.follow!(pointer)
EconomicEvent.change_provider(changeset, provider)
end
end
defp change_provider(changeset, _attrs), do: changeset
defp change_receiver(changeset, %{receiver: receiver_id}) do
with {:ok, pointer} <- Pointers.one(id: receiver_id) do
receiver = Pointers.follow!(pointer)
EconomicEvent.change_receiver(changeset, receiver)
end
end
defp change_receiver(changeset, _attrs), do: changeset
defp update_resource_primary_accountable(event, resource) do
if event.action_id in ["transfer", "transfer-all-rights"] do
EconomicResources.update(resource, %{primary_accountable: event.receiver_id})
......@@ -475,46 +371,24 @@ defmodule ValueFlows.Observation.EconomicEvent.EconomicEvents do
:ok
end
defp change_action(changeset, %{action: action_id}) do
with {:ok, action} <- Actions.action(action_id) do
EconomicEvent.change_action(changeset, action)
end
end
defp change_action(changeset, _attrs), do: changeset
defp change_input_of(changeset, %{input_of: id}) do
with {:ok, input_of} <- Processes.one([:default, id: id]) do
EconomicEvent.change_input_process(changeset, input_of)
end
end
defp change_input_of(changeset, _attrs), do: changeset
defp change_output_of(changeset, %{output_of: id}) do
with {:ok, output_of} <- Processes.one([:default, id: id]) do
EconomicEvent.change_output_process(changeset, output_of)
end
end
defp change_output_of(changeset, _attrs), do: changeset
defp change_at_location(changeset, %{at_location: id}) do
with {:ok, location} <- Geolocations.one([:default, id: id]) do
EconomicEvent.change_at_location(changeset, location)
end
end
defp change_at_location(changeset, _attrs), do: changeset
defp change_triggered_by_event(changeset, %{triggered_by: id}) do
with {:ok, triggered_by} <- one([:default, id: id]) do
EconomicEvent.change_triggered_by_event(changeset, triggered_by)
end
defp prepare_attrs(attrs) do
attrs
|> maybe_put(:action_id, Map.get(attrs, :action))
|> maybe_put(:context_id,
attrs |> Map.get(:in_scope_of) |> CommonsPub.Common.maybe(&List.first/1)
)
|> maybe_put(:provider_id, Map.get(attrs, :provider))
|> maybe_put(:receiver_id, Map.get(attrs, :receiver))
|> maybe_put(:input_of_id, Map.get(attrs, :input_of))
|> maybe_put(:output_of_id, Map.get(attrs, :output_of))
|> maybe_put(:resource_conforms_to_id, Map.get(attrs, :resource_conforms_to))
|> maybe_put(:resource_inventoried_as_id, Map.get(attrs, :resource_inventoried_as))
|> maybe_put(:to_resource_inventoried_as_id, Map.get(attrs, :to_resource_inventoried_as))
|> maybe_put(:triggered_by_id, Map.get(attrs, :triggered_by))
|> maybe_put(:at_location_id, Map.get(attrs, :at_location))
|> parse_measurement_attrs()
end
defp change_triggered_by_event(changeset, _attrs), do: changeset
defp parse_measurement_attrs(attrs) do
Enum.reduce(attrs, %{}, fn {k, v}, acc ->
if is_map(v) and Map.has_key?(v, :has_unit) do
......
......@@ -393,21 +393,13 @@ defmodule ValueFlows.Observation.EconomicEvent.GraphQL do
end)
end
def update_event(%{event: changes}, info) do
Repo.transact_with(fn ->
do_update(changes, info, fn event, changes ->
EconomicEvents.update(event, changes)
end)
end)
end
defp do_update(%{id: id} = changes, info, update_fn) do
def update_event(%{event: %{id: id} = changes}, info) do
with {:ok, user} <- GraphQL.current_user_or_not_logged_in(info),
{:ok, event} <- event(%{id: id}, info),
:ok <- ensure_update_permission(user, event),
{:ok, uploads} <- UploadResolver.upload(user, changes, info),
changes = Map.merge(changes, uploads),
{:ok, event} <- update_fn.(event, changes) do
{:ok, event} <- EconomicEvents.update(event, changes) do
{:ok, %{economic_event: event}}
end
end
......
......@@ -118,7 +118,7 @@ defmodule ValueFlows.Observation.EconomicEvent.EventsGraphQLTest do
event =
fake_economic_event!(user, %{
in_scope_of: parent.id
in_scope_of: [parent.id]
})
q = economic_event_query(fields: [in_scope_of: [:__typename]])
......
......@@ -260,7 +260,8 @@ defmodule ValueFlows.Observation.EconomicEvent.EventsResourcesGraphQLTest do
})
}
assert [%{"status" => 404, "code" => "not_found"}] = grumble_post_errors(q, conn, vars)
assert [%{"status" => 200, "code" => "foreign", "message" => "does not exist"}] =
grumble_post_errors(q, conn, vars)
end
test "create an economic event that transfers an existing resource from a provider to a receiver" do
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment