commit 42f3875dd465a4f963b418ea5eb7ebc291ad80d4
parent 81e8fed627f9637d23b9d3320c471e46bd72edc2
Author: srfsh <dev@srf.sh>
Date: Tue, 15 Nov 2022 01:07:12 +0300
Zenflows.VF.EconomicEvent.{Domain,Type,Resolv}: introducte previous call
This is one step forward the implementation of trace.
Diffstat:
4 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/src/zenflows/vf/economic_event/domain.ex b/src/zenflows/vf/economic_event/domain.ex
@@ -25,8 +25,10 @@ alias Zenflows.DB.{Page, Repo, Schema}
alias Zenflows.VF.{
Action,
EconomicEvent,
+ EconomicEvent.Query,
EconomicResource,
Measure,
+ Process,
}
@spec one(Ecto.Repo.t(), Schema.id() | map() | Keyword.t())
@@ -58,6 +60,16 @@ def all!(page \\ Page.new()) do
value
end
+@spec previous(EconomicEvent.t() | Schema.id())
+ :: nil | Process.t() | EconomicEvent.t() | EconomicResource.t()
+def previous(%EconomicEvent{id: id}), do: previous(id)
+def previous(id) do
+ case Query.previous(id) do
+ nil -> nil
+ q -> Repo.one!(q)
+ end
+end
+
@spec create(Schema.params(), nil | Schema.params())
:: {:ok, EconomicEvent.t()} | {:error, String.t() | Changeset.t()}
def create(evt_params, res_params \\ nil) do
@@ -144,6 +156,7 @@ defp handle_insert(key, %{action_id: action_id} = evt, res_params)
evt.resource_conforms_to_id != nil ->
res_params =
(res_params || %{})
+ |> Map.put(:previous_event_id, evt.id)
|> Map.put(:primary_accountable_id, evt.receiver_id)
|> Map.put(:custodian_id, evt.receiver_id)
|> Map.put(:conforms_to_id, evt.resource_conforms_to_id)
@@ -662,6 +675,7 @@ defp handle_insert(key, %{action_id: "transferCustody"} = evt, res_params) do
else
res_params =
(res_params || %{})
+ |> Map.put(:previous_event_id, evt.id)
|> Map.put(:primary_accountable_id, evt.receiver_id)
|> Map.put(:custodian_id, evt.receiver_id)
|> Map.put(:conforms_to_id, res.conforms_to_id)
@@ -786,6 +800,7 @@ defp handle_insert(key, %{action_id: "transferAllRights"} = evt, res_params) do
else
res_params =
(res_params || %{})
+ |> Map.put(:previous_event_id, evt.id)
|> Map.put(:primary_accountable_id, evt.receiver_id)
|> Map.put(:custodian_id, evt.receiver_id)
|> Map.put(:conforms_to_id, res.conforms_to_id)
@@ -917,6 +932,7 @@ defp handle_insert(key, %{action_id: "transfer"} = evt, res_params) do
else
res_params =
(res_params || %{})
+ |> Map.put(:previous_event_id, evt.id)
|> Map.put(:primary_accountable_id, evt.receiver_id)
|> Map.put(:custodian_id, evt.receiver_id)
|> Map.put(:conforms_to_id, res.conforms_to_id)
@@ -1055,6 +1071,7 @@ defp handle_insert(key, %{action_id: "move"} = evt, res_params) do
else
res_params =
(res_params || %{})
+ |> Map.put(:previous_event_id, evt.id)
|> Map.put(:primary_accountable_id, evt.receiver_id)
|> Map.put(:custodian_id, evt.receiver_id)
|> Map.put(:conforms_to_id, res.conforms_to_id)
diff --git a/src/zenflows/vf/economic_event/query.ex b/src/zenflows/vf/economic_event/query.ex
@@ -0,0 +1,66 @@
+# Zenflows is designed to implement the Valueflows vocabulary,
+# written and maintained by srfsh <info@dyne.org>.
+# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+defmodule Zenflows.VF.EconomicEvent.Query do
+@moduledoc false
+
+import Ecto.Query
+
+alias Ecto.{Multi, Queryable}
+alias Zenflows.DB.{Repo, Schema}
+alias Zenflows.VF.{EconomicEvent, EconomicResource, Process}
+
+@spec previous(Schema.id()) :: nil | Queryable.t()
+def previous(id) do
+ Multi.new()
+ |> Multi.run(:event, fn repo, _ ->
+ where(EconomicEvent, id: ^id)
+ |> select(~w[
+ action_id output_of_id triggered_by_id
+ resource_inventoried_as_id previous_event_id
+ ]a)
+ |> repo.one()
+ |> case do
+ nil -> {:error, "does not exist"}
+ v -> {:ok, v}
+ end
+ end)
+ |> Multi.run(:query, fn _, %{event: evt} ->
+ {:ok, cond do
+ evt.output_of_id != nil ->
+ where(Process, id: ^evt.output_of_id)
+ evt.triggered_by_id != nil ->
+ where(EconomicEvent, id: ^evt.triggered_by_id)
+ evt.action_id == "raise" and evt.previous_event_id == nil ->
+ nil
+ evt.resource_inventoried_as_id != nil ->
+ where(EconomicResource, id: ^evt.resource_inventoried_as_id)
+ true ->
+ nil
+ end}
+ end)
+ |> Repo.transaction()
+ |> case do
+ # Instead of returning and error, we return nil
+ # just so because we did the same thing with other
+ # "previous" queries. We returned empty lists to
+ # indicate nilness.
+ {:ok, %{query: q}} -> q
+ {:error, _, _, _} -> nil
+ end
+end
+end
diff --git a/src/zenflows/vf/economic_event/resolv.ex b/src/zenflows/vf/economic_event/resolv.ex
@@ -116,4 +116,8 @@ def triggered_by(eco_evt, _, _) do
eco_evt = Domain.preload(eco_evt, :triggered_by)
{:ok, eco_evt.triggered_by}
end
+
+def previous(eco_evt, _, _) do
+ {:ok, Domain.previous(eco_evt)}
+end
end
diff --git a/src/zenflows/vf/economic_event/type.ex b/src/zenflows/vf/economic_event/type.ex
@@ -20,7 +20,12 @@ defmodule Zenflows.VF.EconomicEvent.Type do
use Absinthe.Schema.Notation
-alias Zenflows.VF.EconomicEvent.Resolv
+alias Zenflows.VF.{
+ EconomicEvent,
+ EconomicEvent.Resolv,
+ EconomicResource,
+ Process,
+}
@action """
Relates an economic event to a verb, such as consume, produce, work,
@@ -96,6 +101,15 @@ policies or calculations which govern this economic event.
@triggered_by "References another economic event that implied this economic event, often based on a prior agreement."
@triggered_by_id "(`EconomicEvent`) #{@triggered_by}"
+union :production_flow_item do
+ types [:process, :economic_event, :economic_resource]
+ resolve_type fn
+ %Process{}, _ -> :process
+ %EconomicEvent{}, _ -> :economic_event
+ %EconomicResource{}, _ -> :economic_resource
+ end
+end
+
@desc """
An observed economic flow, as opposed to a flow planned to happen in
the future. This could reflect a change in the quantity of an economic
@@ -171,6 +185,9 @@ object :economic_event do
@desc @triggered_by
field :triggered_by, :economic_event,
resolve: &Resolv.triggered_by/3
+
+ field :previous, :production_flow_item,
+ resolve: &Resolv.previous/3
end
input_object :economic_event_create_params do