11defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
2- import Ecto.Query
3-
42 alias CodeCorps . {
53 Project , Repo , StripeConnectCustomer , StripeConnectAccount ,
64 StripeConnectPlan , StripeConnectSubscription , User
@@ -20,19 +18,22 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
2018
2119 - `{:ok, %StripeConnectSubscription{}}` - the created record.
2220 - `{:error, %Ecto.Changeset{}}` - the record was not created due to validation issues.
21+ - `{:error, :project_not_found}`
2322 - `{:error, :project_not_ready}` - the associated project does not meed the prerequisites for receiving donations.
23+ - `{:error, :user_not_found}`
2424 - `{:error, :user_not_ready}` - the associated user does not meet the prerequisits to donate.
2525 - `{:error, %Stripe.APIErrorResponse{}}` - there was a problem with the stripe request
26- - `{:error, :not_found}` - one of the associated records was not found
2726
2827 # Side effects
2928
3029 - If the subscription is created or found, associated project totals will get updated
3130 - If the subscription is created or found, associated donation goal states will be updated
3231 """
3332 def find_or_create ( % { "project_id" => project_id , "quantity" => _ , "user_id" => user_id } = attributes ) do
34- with { :ok , % Project { } = project } <- get_project ( project_id ) |> ProjectSubscribable . validate ,
35- { :ok , % User { } = user } <- get_user ( user_id ) |> UserCanSubscribe . validate
33+ with { :ok , % Project { } = project } <- get_project_with_preloads ( project_id ) ,
34+ { :ok , % Project { } } <- ProjectSubscribable . validate ( project ) ,
35+ { :ok , % User { } = user } <- get_user_with_preloads ( user_id ) ,
36+ { :ok , % User { } } <- UserCanSubscribe . validate ( user )
3637 do
3738 { :ok , % StripeConnectSubscription { } = subscription } = do_find_or_create ( project , user , attributes )
3839
@@ -41,7 +42,6 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
4142
4243 { :ok , subscription }
4344 else
44- nil -> { :error , :not_found }
4545 failure -> failure
4646 end
4747 end
@@ -59,9 +59,8 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
5959 def update_from_stripe ( stripe_id , connect_customer_id ) do
6060 with { :ok , % StripeConnectAccount { } = connect_account } <- retrieve_connect_account ( connect_customer_id ) ,
6161 { :ok , % Stripe.Subscription { } = stripe_subscription } <- @ api . Subscription . retrieve ( stripe_id , connect_account: connect_account . id ) ,
62- { :ok , % StripeConnectSubscription { } = subscription } <- load_subscription ( stripe_id ) ,
63- { :ok , params } <- stripe_subscription |> StripeConnectSubscriptionAdapter . to_params ( % { } ) ,
64- { :ok , % Project { } = project } <- get_project ( subscription )
62+ { :ok , % StripeConnectSubscription { stripe_connect_plan: % { project: project } } = subscription } <- load_subscription ( stripe_id ) ,
63+ { :ok , params } <- stripe_subscription |> StripeConnectSubscriptionAdapter . to_params ( % { } )
6564 do
6665 { :ok , % StripeConnectSubscription { } = subscription } = update_subscription ( subscription , params )
6766
@@ -75,29 +74,30 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
7574 end
7675 end
7776
78- defp do_find_or_create ( % Project { } = project , % User { } = user , % { } = attributes ) do
79- case find ( project , user ) do
77+ # find_or_create
78+
79+ defp do_find_or_create ( project , user , attributes ) do
80+ case find ( project . stripe_connect_plan , user ) do
8081 nil -> create ( project , user , attributes )
8182 % StripeConnectSubscription { } = subscription -> { :ok , subscription }
8283 end
8384 end
8485
85- defp find ( % Project { } = project , % User { } = user ) do
86+ defp find ( plan , user ) do
8687 StripeConnectSubscription
87- |> where ( [ s ] , s . stripe_connect_plan_id == ^ project . stripe_connect_plan . id and s . user_id == ^ user . id )
88- |> Repo . one
88+ |> Repo . get_by ( stripe_connect_plan_id: plan . id , user_id: user . id )
8989 end
9090
91- defp create ( % Project { } = project , % User { } = user , attributes ) do
91+ defp create ( project , user , attributes ) do
9292 with platform_card <- user . stripe_platform_card ,
9393 platform_customer <- user . stripe_platform_customer ,
9494 connect_account <- project . organization . stripe_connect_account ,
9595 plan <- project . stripe_connect_plan ,
9696 { :ok , connect_customer } <- StripeConnectCustomerService . find_or_create ( platform_customer , connect_account , user ) ,
9797 { :ok , connect_card } <- StripeConnectCardService . find_or_create ( platform_card , connect_customer , platform_customer , connect_account ) ,
98- create_attributes <- to_create_attributes ( connect_card , connect_customer , plan , attributes ) ,
98+ create_attributes <- api_create_attributes ( connect_card , connect_customer , plan , attributes ) ,
9999 { :ok , subscription } <- @ api . Subscription . create ( create_attributes , connect_account: connect_account . id_from_stripe ) ,
100- insert_attributes <- to_insert_attributes ( attributes , plan ) ,
100+ insert_attributes <- local_insert_attributes ( attributes , plan ) ,
101101 { :ok , params } <- StripeConnectSubscriptionAdapter . to_params ( subscription , insert_attributes ) ,
102102 { :ok , % StripeConnectSubscription { } = stripe_connect_subscription } <- insert_subscription ( params )
103103 do
@@ -108,21 +108,22 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
108108 end
109109 end
110110
111- defp get_project ( % StripeConnectSubscription { stripe_connect_plan_id: stripe_connect_plan_id } ) do
112- % StripeConnectPlan { project_id: project_id } = Repo . get ( StripeConnectPlan , stripe_connect_plan_id )
113- { :ok , get_project ( project_id , [ :stripe_connect_plan ] ) }
114- end
111+ defp get_project_with_preloads ( id ) do
112+ preloads = [ :stripe_connect_plan , [ organization: :stripe_connect_account ] ]
115113
116- @ default_project_preloads [ :stripe_connect_plan , [ { :organization , :stripe_connect_account } ] ]
117-
118- defp get_project ( project_id , preloads \\ @ default_project_preloads ) do
119- Repo . get ( Project , project_id ) |> Repo . preload ( preloads )
114+ case Repo . get ( Project , id ) |> Repo . preload ( preloads ) do
115+ nil -> { :error , :project_not_found }
116+ project -> { :ok , project }
117+ end
120118 end
121119
122- @ default_user_preloads [ :stripe_platform_customer , [ { :stripe_platform_card , :stripe_connect_cards } ] ]
120+ defp get_user_with_preloads ( user_id ) do
121+ preloads = [ :stripe_platform_customer , [ { :stripe_platform_card , :stripe_connect_cards } ] ]
123122
124- defp get_user ( user_id , preloads \\ @ default_user_preloads ) do
125- Repo . get ( User , user_id ) |> Repo . preload ( preloads )
123+ case Repo . get ( User , user_id ) |> Repo . preload ( preloads ) do
124+ nil -> { :error , :user_not_found }
125+ user -> { :ok , user }
126+ end
126127 end
127128
128129 defp insert_subscription ( params ) do
@@ -131,7 +132,7 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
131132 |> Repo . insert
132133 end
133134
134- defp to_create_attributes ( card , customer , plan , % { "quantity" => quantity } ) do
135+ defp api_create_attributes ( card , customer , plan , % { "quantity" => quantity } ) do
135136 % {
136137 application_fee_percent: 5 ,
137138 customer: customer . id_from_stripe ,
@@ -141,10 +142,12 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
141142 }
142143 end
143144
144- defp to_insert_attributes ( attrs , % StripeConnectPlan { id: stripe_connect_plan_id } ) do
145+ defp local_insert_attributes ( attrs , % StripeConnectPlan { id: stripe_connect_plan_id } ) do
145146 attrs |> Map . merge ( % { "stripe_connect_plan_id" => stripe_connect_plan_id } )
146147 end
147148
149+ # update_from_stripe
150+
148151 defp retrieve_connect_account ( connect_customer_id ) do
149152 customer =
150153 StripeConnectCustomer
@@ -155,7 +158,10 @@ defmodule CodeCorps.StripeService.StripeConnectSubscriptionService do
155158 end
156159
157160 defp load_subscription ( id_from_stripe ) do
158- subscription = Repo . get_by ( StripeConnectSubscription , id_from_stripe: id_from_stripe )
161+ subscription =
162+ StripeConnectSubscription
163+ |> Repo . get_by ( id_from_stripe: id_from_stripe )
164+ |> Repo . preload ( [ stripe_connect_plan: [ project: [ :stripe_connect_plan , :donation_goals ] ] ] )
159165
160166 { :ok , subscription }
161167 end
0 commit comments