mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-29 10:24:20 +01:00
142 lines
5.6 KiB
Ruby
142 lines
5.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Provides helper methods for Availability resources and properties
|
|
class Availabilities::AvailabilitiesService
|
|
|
|
def initialize(current_user, maximum_visibility = {})
|
|
@current_user = current_user
|
|
@maximum_visibility = maximum_visibility
|
|
@service = Availabilities::StatusService.new(current_user.admin? ? 'admin' : 'user')
|
|
end
|
|
|
|
# list all slots for the given machine, with reservations info, relatives to the given user
|
|
def machines(machine_id, user)
|
|
machine = Machine.friendly.find(machine_id)
|
|
reservations = reservations(machine)
|
|
availabilities = availabilities(machine, 'machines', user)
|
|
|
|
slots = []
|
|
availabilities.each do |a|
|
|
((a.end_at - a.start_at) / ApplicationHelper::SLOT_DURATION.minutes).to_i.times do |i|
|
|
next unless (a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes) > Time.now
|
|
|
|
slot = Slot.new(
|
|
start_at: a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes,
|
|
end_at: a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes + ApplicationHelper::SLOT_DURATION.minutes,
|
|
availability_id: a.id,
|
|
availability: a,
|
|
machine: machine,
|
|
title: ''
|
|
)
|
|
slot = @service.machine_reserved_status(slot, reservations, @current_user)
|
|
slots << slot
|
|
end
|
|
end
|
|
slots
|
|
end
|
|
|
|
# list all slots for the given space, with reservations info, relatives to the given user
|
|
def spaces(space_id, user)
|
|
space = Space.friendly.find(space_id)
|
|
reservations = reservations(space)
|
|
availabilities = availabilities(space, 'space', user)
|
|
|
|
slots = []
|
|
availabilities.each do |a|
|
|
((a.end_at - a.start_at) / ApplicationHelper::SLOT_DURATION.minutes).to_i.times do |i|
|
|
next unless (a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes) > Time.now
|
|
|
|
slot = Slot.new(
|
|
start_at: a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes,
|
|
end_at: a.start_at + (i * ApplicationHelper::SLOT_DURATION).minutes + ApplicationHelper::SLOT_DURATION.minutes,
|
|
availability_id: a.id,
|
|
availability: a,
|
|
space: space,
|
|
title: ''
|
|
)
|
|
slot = @service.space_reserved_status(slot, reservations, user)
|
|
slots << slot
|
|
end
|
|
end
|
|
slots.each do |s|
|
|
s.title = I18n.t('availabilities.not_available') if s.complete? && !s.is_reserved
|
|
end
|
|
slots
|
|
end
|
|
|
|
# list all slots for the given training, with reservations info, relatives to the given user
|
|
def trainings(training_id, user)
|
|
# first, we get the already-made reservations
|
|
reservations = user.reservations.where("reservable_type = 'Training'")
|
|
reservations = reservations.where('reservable_id = :id', id: training_id.to_i) if training_id.is_number?
|
|
reservations = reservations.joins(:slots).where('slots.start_at > ?', Time.now)
|
|
|
|
# visible availabilities depends on multiple parameters
|
|
availabilities = training_availabilities(training_id, user)
|
|
|
|
# finally, we merge the availabilities with the reservations
|
|
availabilities.each do |a|
|
|
a = @service.training_event_reserved_status(a, reservations, user)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def subscription_year?(user)
|
|
user.subscription && user.subscription.plan.interval == 'year' && user.subscription.expired_at >= Time.now
|
|
end
|
|
|
|
# member must have validated at least 1 training and must have a valid yearly subscription.
|
|
def show_extended_slots?(user)
|
|
user.trainings.size.positive? && subscription_year?(user)
|
|
end
|
|
|
|
def reservations(reservable)
|
|
Reservation.where('reservable_type = ? and reservable_id = ?', reservable.class.name, reservable.id)
|
|
.includes(:slots, statistic_profile: [user: [:profile]])
|
|
.references(:slots, :user)
|
|
.where('slots.start_at > ?', Time.now)
|
|
end
|
|
|
|
def availabilities(reservable, type, user)
|
|
if user.admin?
|
|
reservable.availabilities
|
|
.includes(:tags)
|
|
.where('end_at > ? AND available_type = ?', Time.now, type)
|
|
.where(lock: false)
|
|
else
|
|
end_at = @maximum_visibility[:other]
|
|
end_at = @maximum_visibility[:year] if subscription_year?(user)
|
|
reservable.availabilities
|
|
.includes(:tags)
|
|
.where('end_at > ? AND end_at < ? AND available_type = ?', Time.now, end_at, type)
|
|
.where('availability_tags.tag_id' => user.tag_ids.concat([nil]))
|
|
.where(lock: false)
|
|
end
|
|
end
|
|
|
|
def training_availabilities(training_id, user)
|
|
availabilities = if training_id.is_number? || (training_id.length.positive? && training_id != 'all')
|
|
Training.friendly.find(training_id).availabilities
|
|
else
|
|
Availability.trainings
|
|
end
|
|
|
|
# who made the request?
|
|
# 1) an admin (he can see all future availabilities)
|
|
if @current_user.admin?
|
|
availabilities.includes(:tags, :slots, trainings: [:machines])
|
|
.where('availabilities.start_at > ?', Time.now)
|
|
.where(lock: false)
|
|
# 2) an user (he cannot see availabilities further than 1 (or 3) months)
|
|
else
|
|
end_at = @maximum_visibility[:other]
|
|
end_at = @maximum_visibility[:year] if show_extended_slots?(user)
|
|
availabilities.includes(:tags, :slots, :availability_tags, trainings: [:machines])
|
|
.where('availabilities.start_at > ? AND availabilities.start_at < ?', Time.now, end_at)
|
|
.where('availability_tags.tag_id' => user.tag_ids.concat([nil]))
|
|
.where(lock: false)
|
|
end
|
|
end
|
|
end
|