# frozen_string_literal: true require './app/helpers/application_helper' # Provides helper methods for Events resources and properties class EventService class << self include ApplicationHelper def process_params(params) # handle dates & times (whole-day events or not, maybe during many days) range = EventService.date_range({ date: params[:start_date], time: params[:start_time] }, { date: params[:end_date], time: params[:end_time] }, params[:all_day] == 'true') params.merge!(availability_attributes: { id: params[:availability_id], start_at: range[:start_at], end_at: range[:end_at], available_type: 'event' }) .extract!(:start_date, :end_date, :start_time, :end_time, :all_day) # convert main price to centimes params[:amount] = to_centimes(params[:amount]) if params[:amount].present? # delete non-complete "other" prices and convert them to centimes unless params[:event_price_categories_attributes].nil? params[:event_price_categories_attributes].delete_if do |price_cat| price_cat[:price_category_id].empty? || price_cat[:amount].empty? end params[:event_price_categories_attributes].each do |price_cat| price_cat[:amount] = to_centimes(price_cat[:amount]) end end # return the resulting params object params end def date_range(starting, ending, all_day) start_date = Date.parse(starting[:date]) end_date = Date.parse(ending[:date]) start_time = starting[:time] ? Time.zone.parse(starting[:time]) : nil end_time = ending[:time] ? Time.zone.parse(ending[:time]) : nil if all_day || start_time.nil? || end_time.nil? start_at = Time.zone.local(start_date.year, start_date.month, start_date.day, 0, 0, 0) end_at = Time.zone.local(end_date.year, end_date.month, end_date.day, 23, 59, 59) else start_at = Time.zone.local(start_date.year, start_date.month, start_date.day, start_time.hour, start_time.min, start_time.sec) end_at = Time.zone.local(end_date.year, end_date.month, end_date.day, end_time.hour, end_time.min, end_time.sec) end { start_at: start_at, end_at: end_at } end # delete one or more events (if periodic) def delete(event_id, mode = 'single') results = [] event = Event.find(event_id) events = case mode when 'single' [event] when 'next' Event.includes(:availability) .where( 'availabilities.start_at >= ? AND events.recurrence_id = ?', event.availability.start_at, event.recurrence_id ) .references(:availabilities, :events) when 'all' Event.where(recurrence_id: event.recurrence_id) else [] end events.each do |e| method = e.destroyable? ? :destroy : :soft_destroy! # we use double negation because destroy can return either a boolean (false) or an Event (in case of delete success) ActiveRecord::Base.transaction do status = !!e.send(method) if status e.reservations.preload(:slots_reservations).map(&:slots_reservations).flatten.map do |slots_reservation| SlotsReservationsService.cancel(slots_reservation) end end results.push status: status, event: e # rubocop:disable Style/DoubleNegation end end results end end end