zf

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

commit 352d65b1fafad3fe14276c18648f8e1ccab23e26
parent 92d7f2f45932a28159f80e9ece95b2f6d6272002
Author: srfsh <dev@srf.sh>
Date:   Fri, 23 Sep 2022 16:56:34 +0300

Zenflows.VF.EconomicResource.{Domain,Filter}: improve filtering

Diffstat:
Msrc/zenflows/vf/economic_resource/domain.ex | 20++++++--------------
Asrc/zenflows/vf/economic_resource/filter.ex | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+), 14 deletions(-)

diff --git a/src/zenflows/vf/economic_resource/domain.ex b/src/zenflows/vf/economic_resource/domain.ex @@ -18,13 +18,12 @@ defmodule Zenflows.VF.EconomicResource.Domain do @moduledoc "Domain logic of EconomicResources." -import Ecto.Query - alias Ecto.Multi alias Zenflows.DB.{Paging, Repo} alias Zenflows.VF.{ Action, EconomicResource, + EconomicResource.Filter, Measure, } @@ -44,20 +43,13 @@ def one(repo, clauses) do end end -@spec all(Paging.params()) :: Paging.result() -def all(params) do - Paging.page(filter(params[:filter]), params) -end - -defp filter(params) do - Enum.reduce(params || %{}, EconomicResource, &filt(&2, &1)) +@spec all(Paging.params()) :: Filter.error() | Paging.result() +def all(params \\ %{}) do + with {:ok, q} <- Filter.filter(params[:filter] || %{}) do + Paging.page(q, params) + end end -defp filt(q, {:classified_as, v}), do: where(q, [x], fragment("? @> ?", x.classified_as, ^v)) -defp filt(q, {:primary_accountable, v}), do: where(q, [x], x.primary_accountable_id in ^v) -defp filt(q, {:custodian, v}), do: where(q, [x], x.custodian_id in ^v) -defp filt(q, {:conforms_to, v}), do: where(q, [x], x.conforms_to_id in ^v) - @spec update(id(), params()) :: {:ok, EconomicResource.t()} | {:error, error()} def update(id, params) do Multi.new() diff --git a/src/zenflows/vf/economic_resource/filter.ex b/src/zenflows/vf/economic_resource/filter.ex @@ -0,0 +1,69 @@ +# 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.EconomicResource.Filter do +@moduledoc "Filtering logic of EconomicResources." + +use Zenflows.DB.Schema + +import Ecto.Query + +alias Ecto.Query +alias Zenflows.DB.{Filter, ID} +alias Zenflows.VF.{EconomicResource, Validate} + +@type error() :: Filter.error() + +@spec filter(Filter.params()) :: Filter.result() +def filter(params) do + case chgset(params) do + %{valid?: true, changes: c} -> + {:ok, Enum.reduce(c, EconomicResource, &f(&2, &1))} + %{valid?: false} = cset -> + {:error, cset} + end +end + +@spec f(Query.t(), {atom(), term()}) :: Query.t() +defp f(q, {:classified_as, v}), + do: where(q, [x], fragment("? @> ?", x.classified_as, ^v)) +defp f(q, {:primary_accountable, v}), + do: where(q, [x], x.primary_accountable_id in ^v) +defp f(q, {:custodian, v}), + do: where(q, [x], x.custodian_id in ^v) +defp f(q, {:conforms_to, v}), + do: where(q, [x], x.conforms_to_id in ^v) + +embedded_schema do + field :classified_as, {:array, :string} + field :primary_accountable, {:array, ID} + field :custodian, {:array, ID} + field :conforms_to, {:array, ID} +end + +@cast ~w[classified_as primary_accountable custodian conforms_to]a + +@spec chgset(params()) :: Changeset.t() +defp chgset(params) do + %__MODULE__{} + |> Changeset.cast(params, @cast) + |> Validate.class(:classified_as) + |> Validate.class(:primary_accountable) + |> Validate.class(:custodian) + |> Validate.class(:conforms_to) +end +end