2021-04-22 19:24:08 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Stores data about a shopping data
|
|
|
|
class ShoppingCart
|
2021-05-21 18:25:18 +02:00
|
|
|
attr_accessor :customer, :operator, :payment_method, :items, :coupon, :payment_schedule
|
2021-04-22 19:24:08 +02:00
|
|
|
|
|
|
|
# @param items {Array<CartItem::BaseItem>}
|
|
|
|
# @param coupon {CartItem::Coupon}
|
|
|
|
# @param payment_schedule {CartItem::PaymentSchedule}
|
|
|
|
# @param customer {User}
|
2021-05-21 18:25:18 +02:00
|
|
|
# @param operator {User}
|
|
|
|
def initialize(customer, operator, coupon, payment_schedule, payment_method = '', items: [])
|
2021-04-26 11:40:26 +02:00
|
|
|
raise TypeError unless customer.is_a? User
|
2021-04-22 19:24:08 +02:00
|
|
|
|
|
|
|
@customer = customer
|
2021-05-21 18:25:18 +02:00
|
|
|
@operator = operator
|
2021-04-22 19:24:08 +02:00
|
|
|
@payment_method = payment_method
|
|
|
|
@items = items
|
|
|
|
@coupon = coupon
|
|
|
|
@payment_schedule = payment_schedule
|
|
|
|
end
|
|
|
|
|
2021-04-23 12:52:06 +02:00
|
|
|
# compute the price details of the current shopping cart
|
2021-04-22 19:24:08 +02:00
|
|
|
def total
|
|
|
|
total_amount = 0
|
|
|
|
all_elements = { slots: [] }
|
|
|
|
|
|
|
|
@items.map(&:price).each do |price|
|
|
|
|
total_amount += price[:amount]
|
2021-04-23 17:54:59 +02:00
|
|
|
all_elements = all_elements.merge(price[:elements]) do |_key, old_val, new_val|
|
2021-04-22 19:24:08 +02:00
|
|
|
old_val | new_val
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
coupon_info = @coupon.price(total_amount)
|
|
|
|
schedule_info = @payment_schedule.schedule(coupon_info[:total_with_coupon], coupon_info[:total_without_coupon])
|
|
|
|
|
|
|
|
# return result
|
|
|
|
{
|
|
|
|
elements: all_elements,
|
|
|
|
total: schedule_info[:total].to_i,
|
|
|
|
before_coupon: coupon_info[:total_without_coupon].to_i,
|
|
|
|
coupon: @coupon.coupon,
|
|
|
|
schedule: schedule_info[:schedule]
|
|
|
|
}
|
|
|
|
end
|
2021-05-21 18:25:18 +02:00
|
|
|
|
2021-05-28 17:34:20 +02:00
|
|
|
def build_and_save(payment_id, payment_type)
|
2021-05-21 18:25:18 +02:00
|
|
|
price = total
|
|
|
|
objects = []
|
2021-05-28 17:34:20 +02:00
|
|
|
payment = nil
|
2021-05-21 18:25:18 +02:00
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
items.each do |item|
|
|
|
|
object = item.to_object
|
|
|
|
object.save
|
|
|
|
objects.push(object)
|
2021-05-28 17:34:20 +02:00
|
|
|
raise ActiveRecord::Rollback unless object.errors.empty?
|
2021-05-21 18:25:18 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
payment = if price[:schedule]
|
|
|
|
PaymentScheduleService.new.create(
|
2021-05-28 17:34:20 +02:00
|
|
|
objects,
|
2021-05-21 18:25:18 +02:00
|
|
|
price[:before_coupon],
|
2021-05-28 17:34:20 +02:00
|
|
|
coupon: @coupon.coupon,
|
2021-05-21 18:25:18 +02:00
|
|
|
operator: @operator,
|
|
|
|
payment_method: @payment_method,
|
|
|
|
user: @customer,
|
|
|
|
payment_id: payment_id,
|
|
|
|
payment_type: payment_type
|
|
|
|
)
|
|
|
|
else
|
|
|
|
InvoicesService.create(
|
|
|
|
price,
|
|
|
|
@operator.invoicing_profile.id,
|
2021-05-28 17:34:20 +02:00
|
|
|
objects,
|
|
|
|
@customer,
|
2021-05-21 18:25:18 +02:00
|
|
|
payment_id: payment_id,
|
|
|
|
payment_type: payment_type,
|
|
|
|
payment_method: @payment_method
|
|
|
|
)
|
|
|
|
end
|
|
|
|
payment.save
|
|
|
|
payment.post_save(payment_id)
|
|
|
|
end
|
|
|
|
|
2021-05-28 17:34:20 +02:00
|
|
|
{ success: objects.map(&:errors).flatten.map(&:empty?).all?, payment: payment, errors: objects.map(&:errors).flatten }
|
2021-05-21 18:25:18 +02:00
|
|
|
end
|
2021-04-22 19:24:08 +02:00
|
|
|
end
|