1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00
fab-manager/app/services/cart_service.rb

232 lines
10 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# Provides methods for working with cart items
class CartService
def initialize(operator)
@operator = operator
end
# For details about the expected hash format
# @see app/frontend/src/javascript/models/payment.ts > interface ShoppingCart
2023-03-14 11:54:41 +01:00
# @return [ShoppingCart]
def from_hash(cart_items)
2022-12-28 17:51:27 +01:00
cart_items.permit! if cart_items.is_a? ActionController::Parameters
@customer = customer(cart_items)
plan_info = plan(cart_items)
items = []
cart_items[:items].each do |item|
2022-12-28 17:51:27 +01:00
if ['subscription', :subscription].include?(item.keys.first) && plan_info[:new_subscription]
items.push(CartItem::Subscription.new(
plan: plan_info[:plan],
customer_profile: @customer.invoicing_profile,
start_at: item[:subscription][:start_at]
))
2021-06-09 18:48:51 +02:00
elsif ['reservation', :reservation].include?(item.keys.first)
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)
2022-12-28 17:51:27 +01:00
items.push(CartItem::PrepaidPack.new(
prepaid_pack: PrepaidPack.find(item[:prepaid_pack][:id]),
customer_profile: @customer.invoicing_profile
))
2021-10-12 14:07:35 +02:00
elsif ['free_extension', :free_extension].include?(item.keys.first)
2022-12-28 17:51:27 +01:00
items.push(CartItem::FreeExtension.new(
customer_profile: @customer.invoicing_profile,
subscription: plan_info[:subscription],
new_expiration_date: item[:free_extension][:end_at]
))
end
end
2022-12-28 17:51:27 +01:00
coupon = CartItem::Coupon.new(
customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
coupon: Coupon.find_by(code: cart_items[:coupon_code])
)
schedule = CartItem::PaymentSchedule.new(
2022-12-28 17:51:27 +01:00
plan: plan_info[:plan],
coupon: coupon,
requested: cart_items[:payment_schedule],
customer_profile: @customer.invoicing_profile,
start_at: plan_info[:subscription]&.start_at
)
ShoppingCart.new(
@customer,
@operator,
coupon,
schedule,
cart_items[:payment_method],
items: items
)
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
2022-12-28 17:51:27 +01:00
coupon = CartItem::Coupon.new(
customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
coupon: payment_schedule.coupon
)
schedule = CartItem::PaymentSchedule.new(
plan: plan,
coupon: coupon,
requested: true,
customer_profile: @customer.invoicing_profile,
start_at: 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
2022-12-28 17:51:27 +01:00
items.push(CartItem::Subscription.new(
plan: object.subscription.plan,
customer_profile: @customer.invoicing_profile,
start_at: 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
2022-12-28 17:51:27 +01:00
items.push(CartItem::PrepaidPack.new(
prepaid_pack_id: object.statistic_profile_prepaid_pack.prepaid_pack_id,
customer_profile: @customer.invoicing_profile
))
2021-10-14 18:20:10 +02:00
elsif object.object_type == OfferDay.name
2022-12-28 17:51:27 +01:00
items.push(CartItem::FreeExtension.new(
customer_profile: @customer.invoicing_profile,
subscription: object.offer_day.subscription,
new_expiration_date: 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
private
def plan(cart_items)
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) }
if cart_items[:items][index][:subscription][:plan_id]
new_plan_being_bought = true
plan = Plan.find(cart_items[:items][index][:subscription][:plan_id])
2022-12-28 17:51:27 +01:00
subscription = CartItem::Subscription.new(
plan: plan,
customer_profile: @customer.invoicing_profile,
start_at: cart_items[:items][index][:subscription][:start_at]
).to_object
plan
end
2021-04-26 11:40:26 +02:00
elsif @customer.subscribed_plan
subscription = @customer.subscription unless @customer.subscription.expired_at < Time.current
2021-04-26 11:40:26 +02:00
@customer.subscribed_plan
else
nil
end
2021-10-12 14:07:35 +02:00
{ plan: plan, subscription: subscription, new_subscription: new_plan_being_bought }
end
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
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])
case reservable
when Machine
2022-12-28 17:51:27 +01:00
CartItem::MachineReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item[:slots_reservations_attributes],
plan: plan_info[:plan],
2023-07-20 16:55:22 +02:00
new_subscription: plan_info[:new_subscription],
reservation_context_id: cart_item[:reservation_context_id])
when Training
2022-12-28 17:51:27 +01:00
CartItem::TrainingReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item[:slots_reservations_attributes],
plan: plan_info[:plan],
2023-07-20 16:55:22 +02:00
new_subscription: plan_info[:new_subscription],
reservation_context_id: cart_item[:reservation_context_id])
when Event
2022-12-28 17:51:27 +01:00
CartItem::EventReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
event: reservable,
cart_item_reservation_slots_attributes: cart_item[:slots_reservations_attributes],
normal_tickets: cart_item[:nb_reserve_places],
cart_item_event_reservation_tickets_attributes: cart_item[:tickets_attributes] || {},
cart_item_event_reservation_booking_users_attributes: cart_item[:booking_users_attributes] || {})
when Space
2022-12-28 17:51:27 +01:00
CartItem::SpaceReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item[:slots_reservations_attributes],
plan: plan_info[:plan],
2023-07-20 16:55:22 +02:00
new_subscription: plan_info[:new_subscription],
reservation_context_id: cart_item[:reservation_context_id])
else
Rails.logger.warn "the reservable #{reservable} is not implemented"
raise NotImplementedError
end
end
2021-06-04 18:26:20 +02:00
def reservable_from_payment_schedule_object(object, plan)
reservable = object.reservation.reservable
cart_item_reservation_slots = object.reservation.slots_reservations.map do |s|
{ slot_id: s.slot_id, slots_reservation_id: s.id, offered: s.offered }
end
2021-06-04 18:26:20 +02:00
case reservable
when Machine
2022-12-28 17:51:27 +01:00
CartItem::MachineReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item_reservation_slots,
2021-06-04 18:26:20 +02:00
plan: plan,
new_subscription: true)
when Training
2022-12-28 17:51:27 +01:00
CartItem::TrainingReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item_reservation_slots,
2021-06-04 18:26:20 +02:00
plan: plan,
new_subscription: true)
when Event
2022-12-28 17:51:27 +01:00
CartItem::EventReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
event: reservable,
cart_item_reservation_slots_attributes: cart_item_reservation_slots,
2021-06-04 18:26:20 +02:00
normal_tickets: object.reservation.nb_reserve_places,
2022-12-28 17:51:27 +01:00
cart_item_event_reservation_tickets_attributes: object.reservation.tickets)
2021-06-04 18:26:20 +02:00
when Space
2022-12-28 17:51:27 +01:00
CartItem::SpaceReservation.new(customer_profile: @customer.invoicing_profile,
operator_profile: @operator.invoicing_profile,
reservable: reservable,
cart_item_reservation_slots_attributes: cart_item_reservation_slots,
2021-06-04 18:26:20 +02:00
plan: plan,
new_subscription: true)
else
Rails.logger.warn "WARNING: the reservable #{reservable} is not implemented"
2021-06-04 18:26:20 +02:00
raise NotImplementedError
end
end
end