@@ -21,10 +21,18 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
2121 assign_blocked_purchase ( socket , attendee , is_cesium_member? )
2222
2323 { :resume , attendee } ->
24- assign_resumable_purchase ( socket , attendee )
24+ if Ticketing . ticket_capacity_available? ( ticket_quantity ( attendee ) ) do
25+ assign_resumable_purchase ( socket , attendee )
26+ else
27+ assign_capacity_blocked_purchase ( socket , is_cesium_member? )
28+ end
2529
2630 :new ->
27- assign_new_purchase ( socket , is_cesium_member? )
31+ if Ticketing . available_ticket_slots ( ) > 0 do
32+ assign_new_purchase ( socket , is_cesium_member? )
33+ else
34+ assign_capacity_blocked_purchase ( socket , is_cesium_member? )
35+ end
2836 end
2937
3038 { :ok , socket }
@@ -96,30 +104,35 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
96104 price_per_ticket =
97105 if is_member , do: TicketType . price_for_member ( ) , else: TicketType . price_for_non_member ( )
98106
99- if changeset . valid? do
100- amount_to_pay =
101- if socket . assigns . has_accompany? ,
102- do: price_per_ticket * 2 ,
103- else: price_per_ticket
107+ cond do
108+ not changeset . valid? ->
109+ changeset_com_erros = Map . put ( changeset , :action , :validate )
104110
105- new_data = Ecto.Changeset . apply_changes ( changeset )
106- new_changeset = CheckoutForm . changeset_personal_data ( new_data , % { } )
111+ { :noreply ,
112+ socket
113+ |> assign ( :price_per_ticket , price_per_ticket )
114+ |> assign ( :companion_price , price_per_ticket )
115+ |> assign ( :form_data , to_form ( changeset_com_erros ) ) }
107116
108- { :noreply ,
109- socket
110- |> assign ( :price_per_ticket , price_per_ticket )
111- |> assign ( :companion_price , price_per_ticket )
112- |> assign ( :form_data , to_form ( new_changeset ) )
113- |> assign ( :amount_to_pay , amount_to_pay )
114- |> update ( :current_step , & ( & 1 + 1 ) ) }
115- else
116- changeset_com_erros = Map . put ( changeset , :action , :validate )
117+ not Ticketing . ticket_capacity_available? ( ticket_quantity ( socket . assigns . has_accompany? ) ) ->
118+ { :noreply , handle_unavailable_ticket_capacity ( socket , is_member ) }
117119
118- { :noreply ,
119- socket
120- |> assign ( :price_per_ticket , price_per_ticket )
121- |> assign ( :companion_price , price_per_ticket )
122- |> assign ( :form_data , to_form ( changeset_com_erros ) ) }
120+ true ->
121+ amount_to_pay =
122+ if socket . assigns . has_accompany? ,
123+ do: price_per_ticket * 2 ,
124+ else: price_per_ticket
125+
126+ new_data = Ecto.Changeset . apply_changes ( changeset )
127+ new_changeset = CheckoutForm . changeset_personal_data ( new_data , % { } )
128+
129+ { :noreply ,
130+ socket
131+ |> assign ( :price_per_ticket , price_per_ticket )
132+ |> assign ( :companion_price , price_per_ticket )
133+ |> assign ( :form_data , to_form ( new_changeset ) )
134+ |> assign ( :amount_to_pay , amount_to_pay )
135+ |> update ( :current_step , & ( & 1 + 1 ) ) }
123136 end
124137 end
125138
@@ -143,7 +156,8 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
143156 defp process_step3 ( socket , final_data ) do
144157 user = socket . assigns . current_scope . user
145158
146- with { :ok , attendee } <-
159+ with :ok <- validate_ticket_capacity ( socket . assigns . has_accompany? ) ,
160+ { :ok , attendee } <-
147161 get_or_create_attendee ( user . id , final_data , socket . assigns . has_accompany? ) ,
148162 { :ok , payment } <-
149163 Ticketing . start_payment (
@@ -170,6 +184,9 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
170184 { :noreply ,
171185 put_flash ( socket , :error , "Ocorreu um erro ao guardar o bilhete. Tenta novamente." ) }
172186
187+ { :error , :ticket_capacity_unavailable } ->
188+ { :noreply , handle_unavailable_ticket_capacity ( socket , final_data . is_cesium_member ) }
189+
173190 { :error , reason } ->
174191 { :noreply ,
175192 put_flash (
@@ -226,6 +243,7 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
226243 |> assign ( :companion_price , price_per_ticket )
227244 |> assign ( :payment_status , :pending )
228245 |> assign ( :purchase_blocked? , false )
246+ |> assign ( :purchase_blocked_reason , nil )
229247 |> assign ( :resuming_purchase? , false )
230248 |> assign ( :user_info , nil )
231249 end
@@ -250,6 +268,7 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
250268 |> assign ( :companion_price , price_per_ticket )
251269 |> assign ( :payment_status , payment_status ( attendee ) )
252270 |> assign ( :purchase_blocked? , false )
271+ |> assign ( :purchase_blocked_reason , nil )
253272 |> assign ( :resuming_purchase? , true )
254273 |> assign ( :user_info , attendee )
255274 end
@@ -266,10 +285,28 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
266285 |> assign ( :companion_price , price_per_ticket )
267286 |> assign ( :payment_status , :paid )
268287 |> assign ( :purchase_blocked? , true )
288+ |> assign ( :purchase_blocked_reason , :existing_ticket )
269289 |> assign ( :resuming_purchase? , false )
270290 |> assign ( :user_info , attendee )
271291 end
272292
293+ defp assign_capacity_blocked_purchase ( socket , is_cesium_member? ) do
294+ price_per_ticket = price_per_ticket ( is_cesium_member? )
295+
296+ socket
297+ |> assign ( :current_step , 1 )
298+ |> assign ( :form_data , to_form ( CheckoutForm . changeset_personal_data ( % CheckoutForm { } , % { } ) ) )
299+ |> assign ( :has_accompany? , false )
300+ |> assign ( :amount_to_pay , nil )
301+ |> assign ( :price_per_ticket , price_per_ticket )
302+ |> assign ( :companion_price , price_per_ticket )
303+ |> assign ( :payment_status , :pending )
304+ |> assign ( :purchase_blocked? , true )
305+ |> assign ( :purchase_blocked_reason , :capacity )
306+ |> assign ( :resuming_purchase? , false )
307+ |> assign ( :user_info , nil )
308+ end
309+
273310 defp checkout_form_from_attendee ( attendee ) do
274311 % CheckoutForm {
275312 full_name: attendee . full_name ,
@@ -305,6 +342,36 @@ defmodule GalliumWeb.TicketingPurchaseLive.Index do
305342 defp payment_status ( % { payment: % { status: status } } ) , do: status
306343 defp payment_status ( _attendee ) , do: :pending
307344
345+ defp validate_ticket_capacity ( has_accompany? ) do
346+ if Ticketing . ticket_capacity_available? ( ticket_quantity ( has_accompany? ) ) do
347+ :ok
348+ else
349+ { :error , :ticket_capacity_unavailable }
350+ end
351+ end
352+
353+ defp handle_unavailable_ticket_capacity ( socket , is_cesium_member? ) do
354+ case Ticketing . available_ticket_slots ( ) do
355+ 0 ->
356+ assign_capacity_blocked_purchase ( socket , is_cesium_member? )
357+
358+ remaining_slots ->
359+ put_flash (
360+ socket ,
361+ :error ,
362+ "Já só #{ remaining_ticket_slots_text ( remaining_slots ) } disponível. Remove o acompanhante para continuar."
363+ )
364+ end
365+ end
366+
367+ defp remaining_ticket_slots_text ( 1 ) , do: "existe 1 lugar"
368+ defp remaining_ticket_slots_text ( count ) , do: "existem #{ count } lugares"
369+
370+ defp ticket_quantity ( % { accompany: nil } ) , do: 1
371+ defp ticket_quantity ( % { accompany: _accompany } ) , do: 2
372+ defp ticket_quantity ( true ) , do: 2
373+ defp ticket_quantity ( false ) , do: 1
374+
308375 defp price_per_ticket ( true ) , do: TicketType . price_for_member ( )
309376 defp price_per_ticket ( false ) , do: TicketType . price_for_non_member ( )
310377end
0 commit comments