zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/zenflows/vf/economic_event/domain.ex | 17+++++++++++++++++
Asrc/zenflows/vf/economic_event/query.ex | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/zenflows/vf/economic_event/resolv.ex | 4++++
Msrc/zenflows/vf/economic_event/type.ex | 19++++++++++++++++++-
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