mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-29 10:24:20 +01:00
82 lines
2.8 KiB
Ruby
82 lines
2.8 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
MINUTES_PER_HOUR = 60.0
|
||
|
SECONDS_PER_MINUTE = 60.0
|
||
|
|
||
|
GET_SLOT_PRICE_DEFAULT_OPTS = { has_credits: false, elements: nil, is_division: true }.freeze
|
||
|
|
||
|
# A generic reservation added to the shopping cart
|
||
|
class CartItem::Reservation < CartItem::BaseItem
|
||
|
def initialize(customer, operator, reservable, slots)
|
||
|
@customer = customer
|
||
|
@operator = operator
|
||
|
@reservable = reservable
|
||
|
@slots = slots
|
||
|
end
|
||
|
|
||
|
def price
|
||
|
base_amount = @reservable.prices.find_by(group_id: @customer.group_id, plan_id: @plan.try(:id)).amount
|
||
|
is_privileged = @operator.admin? || (@operator.manager? && @operator.id != @customer.id)
|
||
|
|
||
|
elements = { slots: [] }
|
||
|
amount = 0
|
||
|
|
||
|
hours_available = credits
|
||
|
@slots.each_with_index do |slot, index|
|
||
|
amount += get_slot_price(base_amount, slot, is_privileged, elements: elements, has_credits: (index < hours_available))
|
||
|
end
|
||
|
|
||
|
{ elements: elements, amount: amount }
|
||
|
end
|
||
|
|
||
|
protected
|
||
|
|
||
|
def credits
|
||
|
0
|
||
|
end
|
||
|
|
||
|
##
|
||
|
# Compute the price of a single slot, according to the base price and the ability for an admin
|
||
|
# to offer the slot.
|
||
|
# @param hourly_rate {Number} base price of a slot
|
||
|
# @param slot {Hash} Slot object
|
||
|
# @param is_privileged {Boolean} true if the current user has a privileged role (admin or manager)
|
||
|
# @param [options] {Hash} optional parameters, allowing the following options:
|
||
|
# - elements {Array} if provided the resulting price will be append into elements.slots
|
||
|
# - has_credits {Boolean} true if the user still has credits for the given slot, false if not provided
|
||
|
# - is_division {boolean} false if the slot covers a full availability, true if it is a subdivision (default)
|
||
|
# @return {Number} price of the slot
|
||
|
##
|
||
|
def get_slot_price(hourly_rate, slot, is_privileged, options = {})
|
||
|
options = GET_SLOT_PRICE_DEFAULT_OPTS.merge(options)
|
||
|
|
||
|
slot_rate = options[:has_credits] || (slot[:offered] && is_privileged) ? 0 : hourly_rate
|
||
|
real_price = if options[:is_division]
|
||
|
(slot_rate / MINUTES_PER_HOUR) * ((slot[:end_at].to_time - slot[:start_at].to_time) / SECONDS_PER_MINUTE)
|
||
|
else
|
||
|
slot_rate
|
||
|
end
|
||
|
|
||
|
unless options[:elements].nil?
|
||
|
options[:elements][:slots].push(
|
||
|
start_at: slot[:start_at],
|
||
|
price: real_price,
|
||
|
promo: (slot_rate != hourly_rate)
|
||
|
)
|
||
|
end
|
||
|
real_price
|
||
|
end
|
||
|
|
||
|
##
|
||
|
# Compute the number of remaining hours in the users current credits (for machine or space)
|
||
|
##
|
||
|
def credits_hours(credits, new_plan_being_bought = false)
|
||
|
hours_available = credits.hours
|
||
|
unless new_plan_being_bought
|
||
|
user_credit = @customer.users_credits.find_by(credit_id: credits.id)
|
||
|
hours_available = credits.hours - user_credit.hours_used if user_credit
|
||
|
end
|
||
|
hours_available
|
||
|
end
|
||
|
end
|