Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions lib/code_corps/stripe_service/stripe_connect_plan.ex
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
defmodule CodeCorps.StripeService.StripeConnectPlanService do
alias CodeCorps.Organization
alias CodeCorps.Project
alias CodeCorps.Repo
alias CodeCorps.{Project, Repo, StripeConnectPlan}
alias CodeCorps.StripeService.Adapters.StripeConnectPlanAdapter
alias CodeCorps.StripeConnectAccount
alias CodeCorps.StripeConnectPlan
alias CodeCorps.StripeService.Validators.ProjectCanEnableDonations

@api Application.get_env(:code_corps, :stripe)

def create(%{"project_id" => project_id} = attributes) do
with %Project{donation_goals: [_h | _t], organization: %Organization{stripe_connect_account: %StripeConnectAccount{id_from_stripe: connect_account_id}}} <-
get_records(project_id),
%{} = create_attributes <-
get_create_attributes(),
{:ok, plan} <-
@api.Plan.create(create_attributes, connect_account: connect_account_id),
{:ok, params} <-
StripeConnectPlanAdapter.to_params(plan, attributes)
with {:ok, %Project{} = project} <- get_project(project_id) |> ProjectCanEnableDonations.validate,
%{} = create_attributes <- get_create_attributes(),
connect_account_id <- project.organization.stripe_connect_account.id_from_stripe,
{:ok, plan} <- @api.Plan.create(create_attributes, connect_account: connect_account_id),
{:ok, params} <- StripeConnectPlanAdapter.to_params(plan, attributes)
do
%StripeConnectPlan{}
|> StripeConnectPlan.create_changeset(params)
|> Repo.insert
else
%Project{donation_goals: []} -> {:error, :donation_goals_not_found}
{:error, :project_not_ready} -> {:error, :project_not_ready}
{:error, error} -> {:error, error}
nil -> {:error, :not_found}
end
Expand All @@ -39,7 +33,7 @@ defmodule CodeCorps.StripeService.StripeConnectPlanService do
}
end

defp get_records(project_id) do
defp get_project(project_id) do
Project
|> Repo.get(project_id)
|> Repo.preload([:donation_goals, {:organization, :stripe_connect_account}])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
defmodule CodeCorps.StripeService.Validators.ProjectCanEnableDonations do
@moduledoc """
Ensures a `CodeCorps.Project` is able to receive subscriptions.
"""

alias CodeCorps.{Organization, Project, StripeConnectAccount}

@doc """
Determines if the provided `CodeCorps.Project` can enable donations.

For a project to be able to enable donations,
it needs to have proper associations set up.

These are:

* At least one `CodeCorps.DonationGoal`
* `Organization` with a `StripeConnectAccount`, which has `charges_enabled: true`

If the project has these relationships set up, it returns `{:ok, project}`

In any other case, it returns {:error, :project_not_ready}
"""
def validate(%Project{} = project), do: do_validate(project)

@invalid {:error, :project_not_ready}

defp do_validate(%Project{
donation_goals: [_h | _t],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to specify head and tail here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbatson5 no, this just validates that it's non-empty.

organization: %Organization{stripe_connect_account: %StripeConnectAccount{charges_enabled: true}}
} = project), do: {:ok, project}
defp do_validate(_), do: @invalid
end
6 changes: 3 additions & 3 deletions test/controllers/stripe_connect_plan_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do

describe "create" do
@tag :authenticated
test "creates and renders resource user is authenticated and authorized", %{conn: conn, current_user: current_user} do
test "creates and renders resource when user is authenticated and authorized", %{conn: conn, current_user: current_user} do
organization = insert(:organization)
insert(:organization_membership, role: "owner", member: current_user, organization: organization)
insert(:stripe_connect_account, organization: organization)
insert(:stripe_connect_account, organization: organization, charges_enabled: true)
project = insert(:project, organization: organization)
insert(:donation_goal, project: project)

Expand All @@ -65,7 +65,7 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do
insert(:organization_membership, role: "owner", member: current_user, organization: organization)
insert(:stripe_connect_account, organization: organization)
project = insert(:project, organization: organization)

assert conn |> request_create(%{project: project}) |> json_response(422)
end
end
Expand Down
2 changes: 1 addition & 1 deletion web/controllers/stripe_connect_plan_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule CodeCorps.StripeConnectPlanController do
defp handle_create_result({:ok, %StripeConnectPlan{}} = result, conn) do
result |> CodeCorps.Analytics.Segment.track(:created, conn)
end
defp handle_create_result({:error, :donation_goals_not_found}, conn) do
defp handle_create_result({:error, :project_not_ready}, conn) do
conn
|> put_status(422)
|> render(CodeCorps.ErrorView, "422.json-api")
Expand Down