1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

[ongoing] compute per based on a hourly rate

This commit is contained in:
Sylvain 2020-05-05 17:56:47 +02:00
parent 34935cbc35
commit e6f8a34aa4
2 changed files with 37 additions and 15 deletions

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Raised when reserving on a locked availability
class LockedError < StandardError
end

View File

@ -1,5 +1,8 @@
# frozen_string_literal: true
MINUTES_PER_HOUR = 60
SECONDS_PER_MINUTE = 60
# Store customized price for various items (Machine, Space), depending on the group and on the plan
# Also provides a static helper method to compute the price details of a shopping cart
class Price < ApplicationRecord
@ -52,16 +55,16 @@ class Price < ApplicationRecord
if space_credit
hours_available = credits_hours(space_credit, user, new_plan_being_bought)
slots.each_with_index do |slot, index|
total_amount += get_slot_price(base_amount, slot, admin, all_elements, (index < hours_available))
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements, has_credits: (index < hours_available))
end
else
slots.each do |slot|
total_amount += get_slot_price(base_amount, slot, admin, all_elements)
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements)
end
end
else
slots.each do |slot|
total_amount += get_slot_price(base_amount, slot, admin, all_elements)
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements)
end
end
@ -83,7 +86,7 @@ class Price < ApplicationRecord
end
end
slots.each do |slot|
total_amount += get_slot_price(amount, slot, admin, all_elements)
total_amount += get_slot_price(amount, slot, admin, elements: all_elements, is_division: false)
end
# Event reservation
@ -93,7 +96,7 @@ class Price < ApplicationRecord
amount += ticket[:booked] * EventPriceCategory.find(ticket[:event_price_category_id]).amount
end
slots.each do |slot|
total_amount += get_slot_price(amount, slot, admin, all_elements)
total_amount += get_slot_price(amount, slot, admin, elements: all_elements, is_division: false)
end
# Space reservation
@ -105,16 +108,16 @@ class Price < ApplicationRecord
if space_credit
hours_available = credits_hours(space_credit, user, new_plan_being_bought)
slots.each_with_index do |slot, index|
total_amount += get_slot_price(base_amount, slot, admin, all_elements, (index < hours_available))
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements, has_credits: (index < hours_available))
end
else
slots.each do |slot|
total_amount += get_slot_price(base_amount, slot, admin, all_elements)
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements)
end
end
else
slots.each do |slot|
total_amount += get_slot_price(base_amount, slot, admin, all_elements)
total_amount += get_slot_price(base_amount, slot, admin, elements: all_elements)
end
end
@ -144,20 +147,37 @@ class Price < ApplicationRecord
private
GET_SLOT_PRICE_DEFAULT_OPTS = { has_credits: false, elements: nil, is_division: true }.freeze
##
# Compute the price of a single slot, according to the base price and the ability for an admin
# to offer the slot.
# @param base_amount {Number} base price of a slot
# @param hourly_rate {Number} base price of a slot
# @param slot {Hash} Slot object
# @param is_admin {Boolean} true if the current user has the 'admin' role
# @param [elements] {Array} optional, if provided the resulting price will be append into elements.slots
# @param [has_credits] {Boolean} true if the user still has credits for the given slot
# @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 an full availability, true if it is a subdivision (default)
# @return {Number} price of the slot
##
def get_slot_price(base_amount, slot, is_admin, elements = nil, has_credits = false)
ii_amount = has_credits || (slot[:offered] && is_admin) ? 0 : base_amount
elements[:slots].push(start_at: slot[:start_at], price: ii_amount, promo: (ii_amount != base_amount)) unless elements.nil?
ii_amount
def get_slot_price(hourly_rate, slot, is_admin, options = {})
options = GET_SLOT_PRICE_DEFAULT_OPTS.merge(options)
slot_rate = options[:has_credits] || (slot[:offered] && is_admin) ? 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
##