1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00
fab-manager/app/services/prepaid_pack_service.rb
2023-03-13 14:19:52 +01:00

88 lines
3.7 KiB
Ruby

# frozen_string_literal: true
# Provides methods for PrepaidPack
class PrepaidPackService
class << self
# @param filters [Hash{Symbol=>Integer,String}]
# @option filters [Integer] :group_id
# @option filters [Integer] :priceable_id
# @option filters [String] :priceable_type 'Machine' | 'Space'
# @return [ActiveRecord::Relation<PrepaidPack>]
def list(filters)
packs = PrepaidPack.where(nil)
packs = packs.where(group_id: filters[:group_id]) if filters[:group_id].present?
packs = packs.where(priceable_id: filters[:priceable_id]) if filters[:priceable_id].present?
packs = packs.where(priceable_type: filters[:priceable_type]) if filters[:priceable_type].present?
if filters[:disabled].present?
state = filters[:disabled] == 'false' ? [nil, false] : true
packs = packs.where(disabled: state)
end
packs
end
# return the not expired packs for the given item bought by the given user
# @param user [User]
# @param priceable [Machine,Space,NilClass]
# @return [ActiveRecord::Relation<StatisticProfilePrepaidPack>]
def user_packs(user, priceable = nil)
sppp = StatisticProfilePrepaidPack.includes(:prepaid_pack)
.references(:prepaid_packs)
.where(statistic_profile_id: user.statistic_profile.id)
.where('expires_at > ? OR expires_at IS NULL', Time.current)
.where('minutes_used < prepaid_packs.minutes')
unless priceable.nil?
sppp = sppp.where(prepaid_packs: { priceable_id: priceable.id })
.where(prepaid_packs: { priceable_type: priceable.class.name })
end
sppp
end
# subtract the number of used prepaid minutes from the user's count
# @param user [User]
# @param reservation [Reservation]
def update_user_minutes(user, reservation)
# total number of minutes available in user's packs
available_minutes = minutes_available(user, reservation.reservable)
return if available_minutes.zero?
# total number of minutes in the reservation's slots
slots_minutes = reservation.slots.map do |slot|
(slot.end_at.to_time - slot.start_at.to_time) / 60.0
end
reservation_minutes = slots_minutes.reduce(:+) || 0
# total number of prepaid minutes used by this reservation
consumed = reservation_minutes
consumed = available_minutes if reservation_minutes > available_minutes
# subtract the consumed minutes for user's current packs
packs = user_packs(user, reservation.reservable).order(minutes_used: :desc)
packs.each do |pack|
pack_available = pack.prepaid_pack.minutes - pack.minutes_used
remaining = consumed > pack_available ? 0 : pack_available - consumed
pack.update(minutes_used: pack.prepaid_pack.minutes - remaining)
pack_consumed = consumed > pack_available ? pack_available : consumed
consumed -= pack_consumed
PrepaidPackReservation.create!(statistic_profile_prepaid_pack: pack, reservation: reservation, consumed_minutes: pack_consumed)
end
end
# Total number of prepaid minutes available
# @param user [User]
# @param priceable [Machine,Space,NilClass]
def minutes_available(user, priceable)
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
total_used = user_packs.map(&:minutes_used).reduce(:+) || 0
total_available - total_used
end
end
end