2021-04-22 19:24:08 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Provides methods for working with cart items
|
|
|
|
class CartService
|
|
|
|
def initialize(operator)
|
|
|
|
@operator = operator
|
|
|
|
end
|
|
|
|
|
2021-04-23 12:52:06 +02:00
|
|
|
##
|
|
|
|
# For details about the expected hash format
|
2021-05-21 18:25:18 +02:00
|
|
|
# @see app/frontend/src/javascript/models/payment.ts > interface ShoppingCart
|
2021-04-23 12:52:06 +02:00
|
|
|
##
|
2021-04-22 19:24:08 +02:00
|
|
|
def from_hash(cart_items)
|
2021-04-23 17:54:59 +02:00
|
|
|
@customer = customer(cart_items)
|
2021-04-22 19:24:08 +02:00
|
|
|
plan_info = plan(cart_items)
|
|
|
|
|
2021-04-23 17:54:59 +02:00
|
|
|
items = []
|
2021-05-19 18:12:52 +02:00
|
|
|
cart_items[:items].each do |item|
|
2021-06-09 18:48:51 +02:00
|
|
|
if ['subscription', :subscription].include?(item.keys.first)
|
2021-10-15 17:31:01 +02:00
|
|
|
items.push(CartItem::Subscription.new(plan_info[:plan], @customer, item[:subscription][:start_at])) if plan_info[:new_subscription]
|
2021-06-09 18:48:51 +02:00
|
|
|
elsif ['reservation', :reservation].include?(item.keys.first)
|
2021-05-19 18:12:52 +02:00
|
|
|
items.push(reservable_from_hash(item[:reservation], plan_info))
|
2021-06-28 18:17:11 +02:00
|
|
|
elsif ['prepaid_pack', :prepaid_pack].include?(item.keys.first)
|
|
|
|
items.push(CartItem::PrepaidPack.new(PrepaidPack.find(item[:prepaid_pack][:id]), @customer))
|
2021-10-12 14:07:35 +02:00
|
|
|
elsif ['free_extension', :free_extension].include?(item.keys.first)
|
|
|
|
items.push(CartItem::FreeExtension.new(@customer, plan_info[:subscription], item[:free_extension][:end_at]))
|
2021-05-19 18:12:52 +02:00
|
|
|
end
|
|
|
|
end
|
2021-04-22 19:24:08 +02:00
|
|
|
|
|
|
|
coupon = CartItem::Coupon.new(@customer, @operator, cart_items[:coupon_code])
|
2022-07-13 16:28:43 +02:00
|
|
|
schedule = CartItem::PaymentSchedule.new(
|
|
|
|
plan_info[:plan], coupon, cart_items[:payment_schedule], @customer, plan_info[:subscription]&.start_at
|
|
|
|
)
|
2021-04-22 19:24:08 +02:00
|
|
|
|
|
|
|
ShoppingCart.new(
|
|
|
|
@customer,
|
2021-05-21 18:25:18 +02:00
|
|
|
@operator,
|
2021-04-22 19:24:08 +02:00
|
|
|
coupon,
|
2021-04-23 12:52:06 +02:00
|
|
|
schedule,
|
2021-04-22 19:24:08 +02:00
|
|
|
cart_items[:payment_method],
|
2021-04-23 12:52:06 +02:00
|
|
|
items: items
|
2021-04-22 19:24:08 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2021-06-04 18:26:20 +02:00
|
|
|
def from_payment_schedule(payment_schedule)
|
|
|
|
@customer = payment_schedule.user
|
2021-10-14 18:20:10 +02:00
|
|
|
subscription = payment_schedule.payment_schedule_objects.find { |pso| pso.object_type == Subscription.name }&.subscription
|
|
|
|
plan = subscription&.plan
|
2021-06-04 18:26:20 +02:00
|
|
|
|
|
|
|
coupon = CartItem::Coupon.new(@customer, @operator, payment_schedule.coupon&.code)
|
2021-10-14 18:20:10 +02:00
|
|
|
schedule = CartItem::PaymentSchedule.new(plan, coupon, true, @customer, subscription.start_at)
|
2021-06-04 18:26:20 +02:00
|
|
|
|
|
|
|
items = []
|
|
|
|
payment_schedule.payment_schedule_objects.each do |object|
|
2021-06-28 18:17:11 +02:00
|
|
|
if object.object_type == Subscription.name
|
2021-10-14 18:20:10 +02:00
|
|
|
items.push(CartItem::Subscription.new(object.subscription.plan, @customer, object.subscription.start_at))
|
2021-06-28 18:17:11 +02:00
|
|
|
elsif object.object_type == Reservation.name
|
2021-06-04 18:26:20 +02:00
|
|
|
items.push(reservable_from_payment_schedule_object(object, plan))
|
2021-06-28 18:17:11 +02:00
|
|
|
elsif object.object_type == PrepaidPack.name
|
|
|
|
items.push(CartItem::PrepaidPack.new(object.statistic_profile_prepaid_pack.prepaid_pack_id, @customer))
|
2021-10-14 18:20:10 +02:00
|
|
|
elsif object.object_type == OfferDay.name
|
|
|
|
items.push(CartItem::FreeExtension.new(@customer, object.offer_day.subscription, object.offer_day.end_date))
|
2021-06-04 18:26:20 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
ShoppingCart.new(
|
|
|
|
@customer,
|
|
|
|
@operator,
|
|
|
|
coupon,
|
|
|
|
schedule,
|
|
|
|
payment_schedule.payment_method,
|
|
|
|
items: items
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2021-04-22 19:24:08 +02:00
|
|
|
private
|
|
|
|
|
|
|
|
def plan(cart_items)
|
2021-05-19 18:12:52 +02:00
|
|
|
new_plan_being_bought = false
|
2021-10-12 14:07:35 +02:00
|
|
|
subscription = nil
|
2021-06-09 18:48:51 +02:00
|
|
|
plan = if cart_items[:items].any? { |item| ['subscription', :subscription].include?(item.keys.first) }
|
|
|
|
index = cart_items[:items].index { |item| ['subscription', :subscription].include?(item.keys.first) }
|
2021-05-19 18:12:52 +02:00
|
|
|
if cart_items[:items][index][:subscription][:plan_id]
|
|
|
|
new_plan_being_bought = true
|
2021-10-13 17:39:39 +02:00
|
|
|
plan = Plan.find(cart_items[:items][index][:subscription][:plan_id])
|
2021-10-14 18:20:10 +02:00
|
|
|
subscription = CartItem::Subscription.new(plan, @customer, cart_items[:items][index][:subscription][:start_at]).to_object
|
2021-10-13 17:39:39 +02:00
|
|
|
plan
|
2021-05-19 18:12:52 +02:00
|
|
|
end
|
2021-04-26 11:40:26 +02:00
|
|
|
elsif @customer.subscribed_plan
|
2021-10-12 14:07:35 +02:00
|
|
|
subscription = @customer.subscription unless @customer.subscription.expired_at < DateTime.current
|
2021-04-26 11:40:26 +02:00
|
|
|
@customer.subscribed_plan
|
2021-04-22 19:24:08 +02:00
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
2021-10-12 14:07:35 +02:00
|
|
|
{ plan: plan, subscription: subscription, new_subscription: new_plan_being_bought }
|
2021-04-22 19:24:08 +02:00
|
|
|
end
|
|
|
|
|
2021-04-23 17:54:59 +02:00
|
|
|
def customer(cart_items)
|
|
|
|
if @operator.admin? || (@operator.manager? && @operator.id != cart_items[:customer_id])
|
|
|
|
User.find(cart_items[:customer_id])
|
|
|
|
else
|
|
|
|
@operator
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-04-22 19:24:08 +02:00
|
|
|
def reservable_from_hash(cart_item, plan_info)
|
2021-04-28 16:22:22 +02:00
|
|
|
reservable = cart_item[:reservable_type]&.constantize&.find(cart_item[:reservable_id])
|
2021-04-22 19:24:08 +02:00
|
|
|
case reservable
|
|
|
|
when Machine
|
|
|
|
CartItem::MachineReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
cart_item[:slots_reservations_attributes],
|
2021-04-22 19:24:08 +02:00
|
|
|
plan: plan_info[:plan],
|
|
|
|
new_subscription: plan_info[:new_subscription])
|
|
|
|
when Training
|
|
|
|
CartItem::TrainingReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
cart_item[:slots_reservations_attributes],
|
2021-04-22 19:24:08 +02:00
|
|
|
plan: plan_info[:plan],
|
|
|
|
new_subscription: plan_info[:new_subscription])
|
|
|
|
when Event
|
|
|
|
CartItem::EventReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
cart_item[:slots_reservations_attributes],
|
2021-04-22 19:24:08 +02:00
|
|
|
normal_tickets: cart_item[:nb_reserve_places],
|
|
|
|
other_tickets: cart_item[:tickets_attributes])
|
|
|
|
when Space
|
|
|
|
CartItem::SpaceReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
cart_item[:slots_reservations_attributes],
|
2021-04-22 19:24:08 +02:00
|
|
|
plan: plan_info[:plan],
|
|
|
|
new_subscription: plan_info[:new_subscription])
|
|
|
|
else
|
2022-07-26 17:27:33 +02:00
|
|
|
Rails.logger.warn "the reservable #{reservable} is not implemented"
|
2021-04-22 19:24:08 +02:00
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
end
|
2021-06-04 18:26:20 +02:00
|
|
|
|
|
|
|
def reservable_from_payment_schedule_object(object, plan)
|
|
|
|
reservable = object.reservation.reservable
|
|
|
|
case reservable
|
|
|
|
when Machine
|
|
|
|
CartItem::MachineReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
object.reservation.slots_reservations,
|
2021-06-04 18:26:20 +02:00
|
|
|
plan: plan,
|
|
|
|
new_subscription: true)
|
|
|
|
when Training
|
|
|
|
CartItem::TrainingReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
object.reservation.slots_reservations,
|
2021-06-04 18:26:20 +02:00
|
|
|
plan: plan,
|
|
|
|
new_subscription: true)
|
|
|
|
when Event
|
|
|
|
CartItem::EventReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
object.reservation.slots_reservations,
|
2021-06-04 18:26:20 +02:00
|
|
|
normal_tickets: object.reservation.nb_reserve_places,
|
|
|
|
other_tickets: object.reservation.tickets)
|
|
|
|
when Space
|
|
|
|
CartItem::SpaceReservation.new(@customer,
|
|
|
|
@operator,
|
|
|
|
reservable,
|
2022-07-13 16:28:43 +02:00
|
|
|
object.reservation.slots_reservations,
|
2021-06-04 18:26:20 +02:00
|
|
|
plan: plan,
|
|
|
|
new_subscription: true)
|
|
|
|
else
|
2022-07-26 17:27:33 +02:00
|
|
|
Rails.logger.warn "WARNING: the reservable #{reservable} is not implemented"
|
2021-06-04 18:26:20 +02:00
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
end
|
2021-04-22 19:24:08 +02:00
|
|
|
end
|