zf

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

economic_event.ex (11529B)


      1 # Zenflows is designed to implement the Valueflows vocabulary,
      2 # written and maintained by srfsh <info@dyne.org>.
      3 # Copyright (C) 2021-2023 Dyne.org foundation <foundation@dyne.org>.
      4 #
      5 # This program is free software: you can redistribute it and/or modify
      6 # it under the terms of the GNU Affero General Public License as published by
      7 # the Free Software Foundation, either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU Affero General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU Affero General Public License
     16 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
     17 
     18 defmodule Zenflows.VF.EconomicEvent do
     19 @moduledoc """
     20 An observed economic flow, as opposed to a flow planned to happen in
     21 the future.  This could reflect a change in the quantity of an economic
     22 resource.  It is also defined by its behavior in relation to the economic
     23 resource.
     24 """
     25 use Zenflows.DB.Schema
     26 
     27 alias Ecto.Changeset
     28 alias Zenflows.DB.{Schema, Validate}
     29 alias Zenflows.VF.{
     30 	Action,
     31 	Agent,
     32 	Agreement,
     33 	EconomicEvent,
     34 	EconomicResource,
     35 	Measure,
     36 	Process,
     37 	ResourceSpecification,
     38 	SpatialThing,
     39 	Unit,
     40 }
     41 
     42 @type t() :: %__MODULE__{
     43 	action: Action.t(),
     44 	input_of: Process.t() | nil,
     45 	output_of: Process.t() | nil,
     46 	provider: Agent.t(),
     47 	receiver: Agent.t(),
     48 	resource_inventoried_as: EconomicResource.t() | nil,
     49 	to_resource_inventoried_as: EconomicResource.t() | nil,
     50 	resource_classified_as: [String.t()] | nil,
     51 	resource_conforms_to: ResourceSpecification.t() | nil,
     52 	resource_quantity: Measure.t() | nil,
     53 	effort_quantity: Measure.t() | nil,
     54 	has_beginning: DateTime.t() | nil,
     55 	has_end: DateTime.t() | nil,
     56 	has_point_in_time: DateTime.t() | nil,
     57 	note: String.t() | nil,
     58 	to_location: SpatialThing.t() | nil,
     59 	at_location: SpatialThing.t() | nil,
     60 	realization_of: Agreement.t() | nil,
     61 	# in_scope_of:
     62 	agreed_in: String.t() | nil,
     63 	triggered_by: EconomicEvent.t() | nil,
     64 	previous_event: nil | EconomicEvent.t(),
     65 }
     66 
     67 @derive {Jason.Encoder, only: ~w[
     68 	id
     69 	action_id
     70 	resource_classified_as
     71 	resource_quantity_has_numerical_value
     72 	effort_quantity_has_numerical_value
     73 	has_beginning has_end has_point_in_time
     74 	note agreed_in
     75 	input_of_id output_of_id
     76 	provider_id receiver_id
     77 	resource_inventoried_as_id to_resource_inventoried_as_id
     78 	resource_conforms_to_id
     79 	resource_quantity_has_unit_id effort_quantity_has_unit_id
     80 	to_location_id at_location_id
     81 	realization_of_id
     82 	triggered_by_id
     83 	previous_event_id
     84 ]a}
     85 schema "vf_economic_event" do
     86 	field :action_id, Action.ID
     87 	field :action, :map, virtual: true
     88 	belongs_to :input_of, Process
     89 	belongs_to :output_of, Process
     90 	belongs_to :provider, Agent
     91 	belongs_to :receiver, Agent
     92 	belongs_to :resource_inventoried_as, EconomicResource
     93 	belongs_to :to_resource_inventoried_as, EconomicResource
     94 	field :resource_classified_as, {:array, :string}
     95 	belongs_to :resource_conforms_to, ResourceSpecification
     96 	field :resource_quantity, :map, virtual: true
     97 	belongs_to :resource_quantity_has_unit, Unit
     98 	field :resource_quantity_has_numerical_value, :decimal
     99 	field :effort_quantity, :map, virtual: true
    100 	belongs_to :effort_quantity_has_unit, Unit
    101 	field :effort_quantity_has_numerical_value, :decimal
    102 	field :has_beginning, :utc_datetime_usec
    103 	field :has_end, :utc_datetime_usec
    104 	field :has_point_in_time, :utc_datetime_usec
    105 	field :note, :string
    106 	belongs_to :to_location, SpatialThing
    107 	belongs_to :at_location, SpatialThing
    108 	belongs_to :realization_of, Agreement
    109 	# field :in_scope_of
    110 	field :agreed_in, :string
    111 	belongs_to :triggered_by, EconomicEvent
    112 	belongs_to :previous_event, EconomicEvent
    113 	timestamps()
    114 end
    115 
    116 @insert_reqr ~w[action_id provider_id receiver_id]a
    117 @insert_cast @insert_reqr ++ ~w[
    118 	has_beginning has_end has_point_in_time note at_location_id
    119 	realization_of_id agreed_in triggered_by_id previous_event_id
    120 ]a
    121 
    122 # insert changeset
    123 @doc false
    124 @spec changeset(Schema.params()) :: Changeset.t()
    125 def changeset(params) do
    126 	%__MODULE__{}
    127 	|> Changeset.cast(params, @insert_cast)
    128 	|> Changeset.validate_required(@insert_reqr)
    129 	|> Validate.exist_or([:has_point_in_time, :has_beginning, :has_end])
    130 	|> Validate.exist_nand([:has_point_in_time, :has_beginning])
    131 	|> Validate.exist_nand([:has_point_in_time, :has_end])
    132 	|> do_changeset()
    133 	|> Validate.uri(:agreed_in)
    134 	|> Validate.note(:note)
    135 	|> Validate.class(:resource_classified_as)
    136 	|> Changeset.assoc_constraint(:input_of)
    137 	|> Changeset.assoc_constraint(:output_of)
    138 	|> Changeset.assoc_constraint(:provider)
    139 	|> Changeset.assoc_constraint(:receiver)
    140 	|> Changeset.assoc_constraint(:resource_inventoried_as)
    141 	|> Changeset.assoc_constraint(:to_resource_inventoried_as)
    142 	|> Changeset.assoc_constraint(:resource_conforms_to)
    143 	|> Changeset.assoc_constraint(:to_location)
    144 	|> Changeset.assoc_constraint(:at_location)
    145 	|> Changeset.assoc_constraint(:realization_of)
    146 	|> Changeset.assoc_constraint(:triggered_by)
    147 	|> Changeset.assoc_constraint(:previous_event)
    148 end
    149 
    150 @spec do_changeset(Changeset.t()) :: Changeset.t()
    151 defp do_changeset(%{valid?: false} = cset), do: cset
    152 defp do_changeset(%{changes: %{action_id: "raise"}} = cset) do
    153 	cset
    154 	|> Changeset.cast(cset.params, ~w[
    155 		resource_conforms_to_id resource_inventoried_as_id
    156 		resource_classified_as resource_quantity to_location_id
    157 	]a)
    158 	|> Changeset.validate_required([:resource_quantity])
    159 	|> Measure.cast(:resource_quantity)
    160 	|> Validate.value_eq([:provider_id, :receiver_id])
    161 	|> Validate.exist_xor([:resource_conforms_to_id, :resource_inventoried_as_id])
    162 end
    163 defp do_changeset(%{changes: %{action_id: "produce"}} = cset) do
    164 	cset
    165 	|> Changeset.cast(cset.params, ~w[
    166 		output_of_id resource_conforms_to_id resource_inventoried_as_id
    167 		resource_classified_as resource_quantity to_location_id
    168 	]a)
    169 	|> Changeset.validate_required(~w[output_of_id resource_quantity]a)
    170 	|> Measure.cast(:resource_quantity)
    171 	|> Validate.value_eq([:provider_id, :receiver_id])
    172 	|> Validate.exist_xor([:resource_conforms_to_id, :resource_inventoried_as_id])
    173 end
    174 defp do_changeset(%{changes: %{action_id: "lower"}} = cset) do
    175 	cset
    176 	|> Changeset.cast(cset.params, ~w[resource_inventoried_as_id resource_quantity]a)
    177 	|> Changeset.validate_required(~w[resource_inventoried_as_id resource_quantity]a)
    178 	|> Validate.value_eq([:provider_id, :receiver_id])
    179 	|> Measure.cast(:resource_quantity)
    180 end
    181 defp do_changeset(%{changes: %{action_id: "consume"}} = cset) do
    182 	cset
    183 	|> Changeset.cast(cset.params, ~w[input_of_id resource_inventoried_as_id resource_quantity]a)
    184 	|> Changeset.validate_required(~w[input_of_id resource_inventoried_as_id resource_quantity]a)
    185 	|> Measure.cast(:resource_quantity)
    186 	|> Validate.value_eq([:provider_id, :receiver_id])
    187 end
    188 defp do_changeset(%{changes: %{action_id: "use"}} = cset) do
    189 	cset
    190 	|> Changeset.cast(cset.params, ~w[
    191 		input_of_id effort_quantity
    192 		resource_inventoried_as_id resource_conforms_to_id
    193 		resource_quantity
    194 	]a)
    195 	|> Changeset.validate_required(~w[input_of_id effort_quantity]a)
    196 	|> Measure.cast(:effort_quantity)
    197 	|> Measure.cast(:resource_quantity)
    198 	|> Validate.exist_xor([:resource_inventoried_as_id, :resource_conforms_to_id])
    199 end
    200 defp do_changeset(%{changes: %{action_id: "work"}} = cset) do
    201 	cset
    202 	|> Changeset.cast(cset.params, ~w[input_of_id effort_quantity resource_conforms_to_id]a)
    203 	|> Changeset.validate_required(~w[input_of_id effort_quantity resource_conforms_to_id]a)
    204 	|> Measure.cast(:effort_quantity)
    205 end
    206 defp do_changeset(%{changes: %{action_id: "cite"}} = cset) do
    207 	cset
    208 	|> Changeset.cast(cset.params, ~w[
    209 		input_of_id resource_quantity
    210 		resource_inventoried_as_id resource_conforms_to_id
    211 	]a)
    212 	|> Changeset.validate_required(~w[input_of_id resource_quantity]a)
    213 	|> Measure.cast(:resource_quantity)
    214 	|> Validate.exist_xor([:resource_inventoried_as_id, :resource_conforms_to_id])
    215 end
    216 defp do_changeset(%{changes: %{action_id: "deliverService"}} = cset) do
    217 	cset
    218 	|> Changeset.cast(cset.params, ~w[input_of_id output_of_id resource_conforms_to_id resource_quantity]a)
    219 	|> Changeset.validate_required(~w[resource_conforms_to_id resource_quantity]a)
    220 	|> Measure.cast(:resource_quantity)
    221 	|> Validate.value_ne([:input_of_id, :output_of_id])
    222 end
    223 defp do_changeset(%{changes: %{action_id: "pickup"}} = cset) do
    224 	cset
    225 	|> Changeset.cast(cset.params, ~w[input_of_id resource_quantity resource_inventoried_as_id]a)
    226 	|> Changeset.validate_required(~w[input_of_id resource_quantity resource_inventoried_as_id]a)
    227 	|> Measure.cast(:resource_quantity)
    228 	|> Validate.value_eq([:provider_id, :receiver_id])
    229 end
    230 defp do_changeset(%{changes: %{action_id: "dropoff"}} = cset) do
    231 	cset
    232 	|> Changeset.cast(cset.params, ~w[output_of_id resource_quantity resource_inventoried_as_id to_location_id]a)
    233 	|> Changeset.validate_required(~w[output_of_id resource_quantity resource_inventoried_as_id]a)
    234 	|> Measure.cast(:resource_quantity)
    235 	|> Validate.value_eq([:provider_id, :receiver_id])
    236 end
    237 defp do_changeset(%{changes: %{action_id: "accept"}} = cset) do
    238 	cset
    239 	|> Changeset.cast(cset.params, ~w[input_of_id resource_quantity resource_inventoried_as_id]a)
    240 	|> Changeset.validate_required(~w[input_of_id resource_quantity resource_inventoried_as_id]a)
    241 	|> Measure.cast(:resource_quantity)
    242 	|> Validate.value_eq([:provider_id, :receiver_id])
    243 end
    244 defp do_changeset(%{changes: %{action_id: "modify"}} = cset) do
    245 	cset
    246 	|> Changeset.cast(cset.params, ~w[output_of_id resource_quantity resource_inventoried_as_id]a)
    247 	|> Changeset.validate_required(~w[output_of_id resource_quantity resource_inventoried_as_id]a)
    248 	|> Measure.cast(:resource_quantity)
    249 	|> Validate.value_eq([:provider_id, :receiver_id])
    250 end
    251 defp do_changeset(%{changes: %{action_id: "combine"}} = cset) do
    252 	cset
    253 	|> Changeset.cast(cset.params, ~w[]a)
    254 	|> Changeset.validate_required(~w[]a)
    255 end
    256 defp do_changeset(%{changes: %{action_id: "separate"}} = cset) do
    257 	cset
    258 	|> Changeset.cast(cset.params, ~w[]a)
    259 	|> Changeset.validate_required(~w[]a)
    260 end
    261 defp do_changeset(%{changes: %{action_id: "transferAllRights"}} = cset) do
    262 	cset
    263 	|> Changeset.cast(cset.params, ~w[
    264 		resource_inventoried_as_id to_resource_inventoried_as_id
    265 		resource_quantity resource_classified_as
    266 	]a)
    267 	|> Changeset.validate_required(~w[resource_inventoried_as_id resource_quantity]a)
    268 	|> Measure.cast(:resource_quantity)
    269 end
    270 defp do_changeset(%{changes: %{action_id: id}} = cset)
    271 		when id in ~w[transferCustody transfer] do
    272 	cset
    273 	|> Changeset.cast(cset.params, ~w[
    274 		resource_inventoried_as_id to_resource_inventoried_as_id resource_quantity
    275 		to_location_id resource_classified_as
    276 	]a)
    277 	|> Changeset.validate_required(~w[resource_inventoried_as_id resource_quantity]a)
    278 	|> Measure.cast(:resource_quantity)
    279 end
    280 defp do_changeset(%{changes: %{action_id: "move"}} = cset) do
    281 	cset
    282 	|> Changeset.cast(cset.params, ~w[
    283 		resource_inventoried_as_id to_resource_inventoried_as_id resource_quantity
    284 		to_location_id resource_classified_as
    285 	]a)
    286 	|> Changeset.validate_required(~w[resource_inventoried_as_id resource_quantity]a)
    287 	|> Measure.cast(:resource_quantity)
    288 	|> Validate.value_eq([:provider_id, :receiver_id])
    289 end
    290 
    291 @update_cast ~w[note agreed_in realization_of_id triggered_by_id]a
    292 
    293 # update changeset
    294 @doc false
    295 @spec changeset(Schema.t(), Schema.params()) :: Changeset.t()
    296 def changeset(schema, params) do
    297 	schema
    298 	|> Changeset.cast(params, @update_cast)
    299 	|> Validate.note(:note)
    300 	|> Changeset.assoc_constraint(:realization_of)
    301 	|> Changeset.assoc_constraint(:triggered_by)
    302 end
    303 end