1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-18 07:52:23 +01:00

compute the price based on custom durations

This commit is contained in:
Sylvain 2021-12-20 17:08:14 +01:00
parent 5ebc1017d2
commit d6b30875a4
3 changed files with 33 additions and 7 deletions

View File

@ -30,6 +30,6 @@ class API::PricesController < API::ApiController
private
def price_params
params.require(:price).permit(:amount)
params.require(:price).permit(:amount, :duration)
end
end

View File

@ -3,7 +3,7 @@
MINUTES_PER_HOUR = 60.0
SECONDS_PER_MINUTE = 60.0
GET_SLOT_PRICE_DEFAULT_OPTS = { has_credits: false, elements: nil, is_division: true, prepaid: { minutes: 0 } }.freeze
GET_SLOT_PRICE_DEFAULT_OPTS = { has_credits: false, elements: nil, is_division: true, prepaid: { minutes: 0 }, custom_duration: nil }.freeze
# A generic reservation added to the shopping cart
class CartItem::Reservation < CartItem::BaseItem
@ -16,7 +16,7 @@ class CartItem::Reservation < CartItem::BaseItem
end
def price
base_amount = @reservable.prices.find_by(group_id: @customer.group_id, plan_id: @plan.try(:id), duration: 60).amount
base_amount = get_hourly_rate
is_privileged = @operator.privileged? && @operator.id != @customer.id
prepaid = { minutes: PrepaidPackService.minutes_available(@customer, @reservable) }
@ -103,6 +103,35 @@ class CartItem::Reservation < CartItem::BaseItem
real_price
end
# We compute the hourly rate according to the prices of the current reservation
# If there are prices for durations longer than 1 hour, but shorter than the total duration,
# we use these prices before using the hourly rate.
# Eg. If the reservation is for 12 hours, and there are prices for 3 hours, 7 hours,
# and the base price (1 hours), we use the 7 hours price, then 3 hours price, and finally the base price.
# Then we divide the total price by the total duration to get the hourly rate.
def get_hourly_rate
total_duration = @slots.map { |slot| (slot[:end_at].to_time - slot[:start_at].to_time) / SECONDS_PER_MINUTE }.reduce(:+)
price = 0
remaining_duration = total_duration
while remaining_duration > 60
max_duration = @reservable.prices.where(group_id: @customer.group_id, plan_id: @plan.try(:id))
.where(Price.arel_table[:duration].lteq(remaining_duration))
.maximum(:duration)
max_duration_amount = @reservable.prices.find_by(group_id: @customer.group_id, plan_id: @plan.try(:id), duration: max_duration)
.amount
price += max_duration_amount
remaining_duration -= max_duration
end
# base price for the last hour or less
base_amount = @reservable.prices.find_by(group_id: @customer.group_id, plan_id: @plan.try(:id), duration: 60).amount
price += (base_amount / MINUTES_PER_HOUR) * remaining_duration
price / (total_duration / MINUTES_PER_HOUR)
end
##
# Compute the number of remaining hours in the users current credits (for machine or space)
##

View File

@ -61,10 +61,7 @@ class PrepaidPackService
## Total number of prepaid minutes available
def minutes_available(user, priceable)
is_pack_only_for_subscription = Setting.find_by(name: "pack_only_for_subscription")&.value
if is_pack_only_for_subscription == 'true' && !user.subscribed_plan
return 0
end
return 0 if Setting.get('pack_only_for_subscription') && !user.subscribed_plan
user_packs = user_packs(user, priceable)
total_available = user_packs.map { |up| up.prepaid_pack.minutes }.reduce(:+) || 0