Commit 27543490 authored by Antonis Kalou's avatar Antonis Kalou

Cleanup ValueFlows.Proposal

parent 6d6b7686
......@@ -48,11 +48,11 @@ defmodule ValueFlows.Proposal do
end
@required ~w(name is_public)a
@cast @required ++ ~w(note has_beginning has_end unit_based eligible_location_id)a
@cast @required ++
~w(note has_beginning has_end unit_based eligible_location_id context_id)a
def create_changeset(
%User{} = creator,
%{id: _} = context,
attrs
) do
%Proposal{}
......@@ -61,51 +61,17 @@ defmodule ValueFlows.Proposal do
|> Changeset.change(
created: DateTime.utc_now(),
creator_id: creator.id,
context_id: context.id,
is_public: true
)
|> common_changeset()
end
def create_changeset(
%User{} = creator,
attrs
) do
%Proposal{}
|> Changeset.cast(attrs, @cast)
|> Changeset.validate_required(@required)
|> Changeset.change(
created: DateTime.utc_now(),
creator_id: creator.id,
is_public: true
)
|> common_changeset()
end
def update_changeset(
%Proposal{} = proposal,
%{id: _} = context,
attrs
) do
proposal
|> Changeset.cast(attrs, @cast)
|> Changeset.change(context_id: context.id)
|> common_changeset()
end
def update_changeset(%Proposal{} = proposal, attrs) do
proposal
|> Changeset.cast(attrs, @cast)
|> common_changeset()
end
def change_eligible_location(changeset, %Geolocation{} = location) do
Changeset.change(changeset,
eligible_location: location,
eligible_location_id: location.id
)
end
defp common_changeset(changeset) do
changeset
|> change_public()
......
......@@ -3,42 +3,19 @@ defmodule ValueFlows.Proposal.GraphQL do
# default to 100 km radius
@radius_default_distance 100_000
# alias CommonsPub.Web.GraphQL.{CommonResolver}
require Logger
alias CommonsPub.{
# Activities,
# Communities,
GraphQL,
Repo
# User
}
alias CommonsPub.{GraphQL, Repo}
alias CommonsPub.GraphQL.{
ResolveField,
# ResolveFields,
# ResolvePage,
# ResolvePages,
ResolveRootPage,
FetchPage
# FetchPages,
# CommonResolver
}
# alias CommonsPub.Resources.Resource
# alias CommonsPub.Common.Enums
alias CommonsPub.Meta.Pointers
# alias CommonsPub.Communities.Community
# alias CommonsPub.Web.GraphQL.CommunitiesResolver
# alias ValueFlows.Proposal
alias ValueFlows.Proposal.Proposals
# alias ValueFlows.Proposal.Queries
# alias CommonsPub.Web.GraphQL.CommonResolver
# use Absinthe.Schema.Notation
# import_sdl path: "lib/value_flows/graphql/schemas/proposal.gql"
## resolvers
......@@ -243,62 +220,19 @@ defmodule ValueFlows.Proposal.GraphQL do
proposals_filter_next([param_remove], filter_add, page_opts, filters_acc)
end
def create_proposal(%{proposal: %{in_scope_of: context_ids} = attrs}, info)
when is_list(context_ids) do
# FIXME: support multiple contexts?
context_id = List.first(context_ids)
Repo.transact_with(fn ->
do_create(attrs, info, fn user, attrs ->
with {:ok, pointer} <- Pointers.one(id: context_id) do
context = Pointers.follow!(pointer)
Proposals.create(user, context, attrs)
end
end)
end)
end
# FIXME: duplication!
def create_proposal(%{proposal: attrs}, info) do
Repo.transact_with(fn ->
do_create(attrs, info, &Proposals.create/2)
end)
end
defp do_create(%{} = attrs, info, create_fn) do
with {:ok, user} <- GraphQL.current_user_or_not_logged_in(info),
proposal_attrs = Map.merge(attrs, %{is_public: true}),
{:ok, proposal} <- create_fn.(user, proposal_attrs) do
{:ok, proposal} <- Proposals.create(user, proposal_attrs) do
{:ok, %{proposal: proposal}}
end
end
def update_proposal(%{proposal: %{in_scope_of: context_ids} = changes}, info) do
context_id = List.first(context_ids)
Repo.transact_with(fn ->
do_update(changes, info, fn proposal, changes ->
with {:ok, pointer} <- Pointers.one(id: context_id) do
context = Pointers.follow!(pointer)
Proposals.update(proposal, context, changes)
end
end)
end)
end
def update_proposal(%{proposal: changes}, info) do
Repo.transact_with(fn ->
do_update(changes, info, fn proposal, changes ->
Proposals.update(proposal, changes)
end)
end)
end
defp do_update(%{id: id} = changes, info, update_fn) do
def update_proposal(%{proposal: %{id: id} = changes}, info) do
with {:ok, user} <- GraphQL.current_user_or_not_logged_in(info),
{:ok, proposal} <- proposal(%{id: id}, info),
:ok <- ensure_update_permission(user, proposal),
{:ok, proposal} <- update_fn.(proposal, changes) do
{:ok, proposal} <- Proposals.update(proposal, changes) do
{:ok, %{proposal: proposal}}
end
end
......
# SPDX-License-Identifier: AGPL-3.0-only
defmodule ValueFlows.Proposal.Proposals do
import CommonsPub.Common, only: [maybe_put: 3]
alias CommonsPub.{Activities, Common, Feeds, Repo}
alias CommonsPub.GraphQL.{Fields, Page}
alias CommonsPub.Contexts
......@@ -113,45 +115,29 @@ defmodule ValueFlows.Proposal.Proposals do
)
end
def preloads(proposal) do
CommonsPub.Repo.maybe_preload(proposal, [
:context,
def preload_all(proposal) do
Repo.preload(proposal, [
:creator,
:eligible_location,
:creator
# :proposed_to,
# :publishes
# pointers, not supported
:context,
])
end
## mutations
# @spec create(User.t(), Community.t(), attrs :: map) :: {:ok, Proposal.t()} | {:error, Changeset.t()}
def create(%User{} = creator, %{id: _id} = context, attrs)
when is_map(attrs) do
do_create(creator, attrs, fn ->
Proposal.create_changeset(creator, context, attrs)
end)
end
# @spec create(User.t(), attrs :: map) :: {:ok, Proposal.t()} | {:error, Changeset.t()}
@spec create(User.t(), attrs :: map) :: {:ok, Proposal.t()} | {:error, Changeset.t()}
def create(%User{} = creator, attrs) when is_map(attrs) do
do_create(creator, attrs, fn ->
Proposal.create_changeset(creator, attrs)
end)
end
attrs = prepare_attrs(attrs)
def do_create(creator, attrs, changeset_fn) do
Repo.transact_with(fn ->
cs = changeset_fn.()
with {:ok, cs} <- change_eligible_location(cs, attrs),
{:ok, item} <- Repo.insert(cs),
with {:ok, proposal} <- Repo.insert(Proposal.create_changeset(creator, attrs)),
act_attrs = %{verb: "created", is_local: true},
# FIXME
{:ok, activity} <- Activities.create(creator, item, act_attrs),
:ok <- index(item),
:ok <- publish(creator, item, activity, :created) do
{:ok, item}
{:ok, activity} <- Activities.create(creator, proposal, act_attrs),
:ok <- index(proposal),
:ok <- publish(creator, proposal, activity, :created) do
{:ok, preload_all(proposal)}
end
end)
end
......@@ -200,25 +186,12 @@ defmodule ValueFlows.Proposal.Proposals do
end
# TODO: take the user who is performing the update
# @spec update(%Proposal{}, attrs :: map) :: {:ok, Proposal.t()} | {:error, Changeset.t()}
@spec update(%Proposal{}, attrs :: map) :: {:ok, Proposal.t()} | {:error, Changeset.t()}
def update(%Proposal{} = proposal, attrs) do
do_update(proposal, attrs, &Proposal.update_changeset(&1, attrs))
end
def update(%Proposal{} = proposal, %{id: _id} = context, attrs) do
do_update(proposal, attrs, &Proposal.update_changeset(&1, context, attrs))
end
attrs = prepare_attrs(attrs)
def do_update(proposal, attrs, changeset_fn) do
Repo.transact_with(fn ->
proposal = preloads(proposal)
cs =
proposal
|> changeset_fn.()
with {:ok, cs} <- change_eligible_location(cs, attrs),
{:ok, proposal} <- Repo.update(cs),
with {:ok, proposal} <- Repo.update(Proposal.update_changeset(proposal, attrs)),
:ok <- publish(proposal, :updated) do
{:ok, proposal}
end
......@@ -307,21 +280,15 @@ defmodule ValueFlows.Proposal.Proposals do
end
def fields_filter(e) do
# IO.inspect(e)
case e do
{key, {key2, val}} ->
if key not in @ignore and key2 not in @ignore and is_list(val) do
{field_key(key), {field_key(key2), for(n <- val, do: fields_filter(n))}}
# else
# IO.inspect(hmm1: e)
end
{key, val} ->
if key not in @ignore and is_list(val) do
{field_key(key), for(n <- val, do: fields_filter(n))}
# else
# IO.inspect(hmm2: e)
end
_ ->
......@@ -359,11 +326,11 @@ defmodule ValueFlows.Proposal.Proposals do
ValueFlows.Util.ap_prepare_activity(activity_name, proposal, ap_object_prepare(proposal.id))
end
defp change_eligible_location(changeset, %{eligible_location: id}) do
with {:ok, location} <- Geolocations.one([:default, id: id]) do
{:ok, Proposal.change_eligible_location(changeset, location)}
end
defp prepare_attrs(attrs) do
attrs
|> maybe_put(:context_id,
attrs |> Map.get(:in_scope_of) |> CommonsPub.Common.maybe(&List.first/1)
)
|> maybe_put(:eligible_location_id, Map.get(attrs, :eligible_location))
end
defp change_eligible_location(changeset, _attrs), do: {:ok, changeset}
end
......@@ -247,18 +247,11 @@ defmodule ValueFlows.Simulate do
intent
end
def fake_proposal!(user, context \\ nil, overrides \\ %{})
def fake_proposal!(user, context, overrides) when is_nil(context) do
def fake_proposal!(user, overrides \\ %{}) do
{:ok, proposal} = Proposals.create(user, proposal(overrides))
proposal
end
def fake_proposal!(user, context, overrides) do
{:ok, proposal} = Proposals.create(user, context, proposal(overrides))
proposal
end
def fake_proposed_intent!(proposal, intent, overrides \\ %{}) do
{:ok, proposed_intent} =
Proposals.propose_intent(proposal, intent, proposed_intent(overrides))
......
......@@ -29,10 +29,7 @@ defmodule Valueflows.Agent.Person.GraphQLTest do
# attach some data to the person...
intent =
fake_intent!(user, nil, nil, %{
provider: user.id
})
fake_intent!(user, %{ provider: user.id })
resource =
fake_economic_resource!(user, %{
......
......@@ -31,13 +31,12 @@ defmodule ValueFlows.Proposal.GraphQLTest do
test "fetches a full nested proposal by ID (via Absinthe.run)" do
user = fake_user!()
parent = fake_user!()
location = fake_geolocation!(user)
proposal = fake_proposal!(user, parent, %{eligible_location_id: location.id})
proposal = fake_proposal!(user, %{
in_scope_of: [parent.id],
eligible_location_id: location.id
})
intent = fake_intent!(user)
some(5, fn ->
......@@ -120,7 +119,7 @@ defmodule ValueFlows.Proposal.GraphQLTest do
test "fetches an associated eligible location" do
user = fake_user!()
location = fake_geolocation!(user)
proposal = fake_proposal!(user, nil, %{eligible_location_id: location.id})
proposal = fake_proposal!(user, %{eligible_location_id: location.id})
q = proposal_query(fields: [eligible_location: [:id]])
conn = user_conn(user)
......@@ -133,7 +132,7 @@ defmodule ValueFlows.Proposal.GraphQLTest do
test "returns the scope of the proposal" do
user = fake_user!()
parent = fake_user!()
proposal = fake_proposal!(user, parent)
proposal = fake_proposal!(user, %{in_scope_of: [parent.id]})
q = proposal_query(fields: [in_scope_of: [:__typename]])
conn = user_conn(user)
......@@ -194,7 +193,7 @@ defmodule ValueFlows.Proposal.GraphQLTest do
test "updates an existing proposal with a new scope" do
user = fake_user!()
scope = fake_community!(user)
proposal = fake_proposal!(user, scope)
proposal = fake_proposal!(user, %{in_scope_of: [scope.id]})
new_scope = fake_community!(user)
q = update_proposal_mutation()
......
......@@ -43,9 +43,9 @@ defmodule ValueFlows.Proposal.ProposalsTest do
user = fake_user!()
parent = fake_user!()
assert {:ok, proposal} = Proposals.create(user, parent, proposal())
assert {:ok, proposal} = Proposals.create(user, proposal(%{in_scope_of: [parent.id]}))
assert_proposal_full(proposal)
assert proposal.context_id == parent.id
assert proposal.context.id == parent.id
end
test "can create a proposal with an eligible location" do
......@@ -73,10 +73,10 @@ defmodule ValueFlows.Proposal.ProposalsTest do
test "can update an existing proposal with a new context" do
user = fake_user!()
context = fake_community!(user)
proposal = fake_proposal!(user, context)
proposal = fake_proposal!(user, %{in_scope_of: [context.id]})
new_context = fake_community!(user)
assert {:ok, updated} = Proposals.update(proposal, new_context, proposal())
assert {:ok, updated} = Proposals.update(proposal, proposal(%{in_scope_of: [new_context.id]}))
assert_proposal_full(updated)
assert updated.updated_at != proposal.updated_at
assert updated.context_id == new_context.id
......
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