# frozen_string_literal: true # API Controller for resources of type Availability class API::AvailabilitiesController < API::ApiController before_action :authenticate_user!, except: [:public] before_action :set_availability, only: %i[show update reservations lock] before_action :define_max_visibility, only: %i[machine trainings spaces] respond_to :json def index authorize Availability start_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:start]) end_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:end]).end_of_day @availabilities = Availability.includes(:machines, :tags, :trainings, :spaces) .where('start_at >= ? AND end_at <= ?', start_date, end_date) @availabilities = @availabilities.where.not(available_type: 'event') unless Setting.get('events_in_calendar') @availabilities = @availabilities.where.not(available_type: 'space') unless Setting.get('spaces_module') end def public start_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:start]) end_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:end]).end_of_day @reservations = Reservation.includes(:slots, :statistic_profile) .references(:slots) .where('slots.start_at >= ? AND slots.end_at <= ?', start_date, end_date) machine_ids = params[:m] || [] service = Availabilities::PublicAvailabilitiesService.new(current_user) @availabilities = service.public_availabilities( start_date, end_date, @reservations, machines: machine_ids, spaces: params[:s] ) @title_filter = { machine_ids: machine_ids.map(&:to_i) } @availabilities = filter_availabilites(@availabilities) end def show authorize Availability end def create authorize Availability @availability = Availability.new(availability_params) if @availability.save if params[:availability][:occurrences] service = Availabilities::CreateAvailabilitiesService.new service.create(@availability, params[:availability][:occurrences]) end render :show, status: :created, location: @availability else render json: @availability.errors, status: :unprocessable_entity end end def update authorize Availability if @availability.update(availability_params) render :show, status: :ok, location: @availability else render json: @availability.errors, status: :unprocessable_entity end end def destroy authorize Availability service = Availabilities::DeleteAvailabilitiesService.new res = service.delete(params[:id], params[:mode]) if res.all? { |r| r[:status] } render json: { deleted: res.length, details: res }, status: :ok else render json: { total: res.length, deleted: res.select { |r| r[:status] }.length, details: res }, status: :unprocessable_entity end end def machine @current_user_role = current_user.role service = Availabilities::AvailabilitiesService.new(current_user, other: @visi_max_other, year: @visi_max_year) @slots = service.machines(params[:machine_id], user) end def trainings service = Availabilities::AvailabilitiesService.new(current_user, other: @visi_max_other, year: @visi_max_year) @availabilities = service.trainings(params[:training_id], user) end def spaces @current_user_role = current_user.role service = Availabilities::AvailabilitiesService.new(current_user, other: @visi_max_other, year: @visi_max_year) @slots = service.spaces(params[:space_id], user) end def reservations authorize Availability @reservation_slots = @availability.slots.includes(reservations: [statistic_profile: [user: [:profile]]]).order('slots.start_at ASC') end def export_availabilities authorize :export export = Export.where(category: 'availabilities', export_type: 'index') .where('created_at > ?', Availability.maximum('updated_at')).last if export.nil? || !FileTest.exist?(export.file) @export = Export.new(category: 'availabilities', export_type: 'index', user: current_user) if @export.save render json: { export_id: @export.id }, status: :ok else render json: @export.errors, status: :unprocessable_entity end else send_file File.join(Rails.root, export.file), type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', disposition: 'attachment' end end def lock authorize @availability if @availability.update_attributes(lock: lock_params) render :show, status: :ok, location: @availability else render json: @availability.errors, status: :unprocessable_entity end end private def user if params[:member_id] User.find(params[:member_id]) else current_user end end def set_availability @availability = Availability.find(params[:id]) end def availability_params params.require(:availability).permit(:start_at, :end_at, :available_type, :machine_ids, :training_ids, :nb_total_places, :is_recurrent, :period, :nb_periods, :end_date, :slot_duration, machine_ids: [], training_ids: [], space_ids: [], tag_ids: [], plan_ids: [], machines_attributes: %i[id _destroy], plans_attributes: %i[id _destroy]) end def lock_params params.require(:lock) end def filter_availabilites(availabilities) availabilities_filtered = [] availabilities.to_ary.each do |a| # machine slot if !a.try(:available_type) availabilities_filtered << a else availabilities_filtered << a if filter_training?(a) availabilities_filtered << a if filter_space?(a) availabilities_filtered << a if filter_machine?(a) availabilities_filtered << a if filter_event?(a) end end availabilities_filtered.delete_if(&method(:remove_completed?)) end def filter_training?(availability) params[:t] && availability.available_type == 'training' && params[:t].include?(availability.trainings.first.id.to_s) end def filter_space?(availability) params[:s] && availability.available_type == 'space' && params[:s].include?(availability.spaces.first.id.to_s) end def filter_machine?(availability) params[:m] && availability.available_type == 'machines' && (params[:m].map(&:to_i) & availability.machine_ids).any? end def filter_event?(availability) params[:evt] && params[:evt] == 'true' && availability.available_type == 'event' end def remove_completed?(availability) params[:dispo] == 'false' && (availability.is_reserved || (availability.try(:completed?) && availability.completed?)) end def define_max_visibility @visi_max_year = Setting.get('visibility_yearly').to_i.months.since @visi_max_other = Setting.get('visibility_others').to_i.months.since end end