Объедините массив часов магазина торговца, которые перекрываются, чтобы произвести один диапазон

У меня есть список часов магазина от продавца, который потенциально может перекрываться, хранится в AvailableHours модель. Модель имеет start_time и end_time хранится как TimeOfDay объект ( https://github.com/JackC/tod).

Я хочу перебрать список и сравнить часы работы магазина, чтобы я мог просто отобразить 1 магазинный час. Например, если магазин мог иметь часы Mon: 9am-2pm а также Mon: 10am-5pmЯ хотел бы отобразить Mon: 9am-5pm, Магазин также может иметь два раза за один день, то есть Fri: 9-5pm, 7pm-10pm, Я должен сделать это для каждого дня недели.

Проблема, с которой я сталкиваюсь, заключается в том, что моим кодом становится трудно управлять - я начал вводить множество вложенных if/else для ручной проверки (что кошмар!), Но мой вопрос таков:

Есть ли способ использовать ActiveRecord для создания хэша с объединенными временными диапазонами?

def ranges_overlap?(shift, current_shift)
  shift.include?(current_shift.beginning) || current_shift.include?(shift.beginning)
end

def merge_ranges(shift, current_shift)
  new_open_time = [shift.beginning, current_shift.beginning].min
  new_close_time = [shift.ending, current_shift.ending].max
  Shift.new(new_open_time, new_close_time)
end


def get_aggregate_merchant_hours 
  merchant = self
  day = nil
  shifts_array = []
  output_shift_array = []

  merchant_shifts = merchant_shifts = merchant.available_hours.order(day: :asc, open_time: :desc).map do |ah|
    merged_shift = nil
    show_output = false

    # if it's a new day
    if day.blank? || day != ah.day 
      output_shift_array = shifts_array
      shifts_array =  []        
      show_output = true if !day.blank?
      output_day = day
      day = ah.day
    end

    next if ah.open_time.blank? || ah.close_time.blank?
    open_time = ah.open_time
    close_time = ah.close_time

    current_shift = Shift.new(open_time, close_time)

    if !shifts_array.blank?
      #compare and merge
      shifts_array.each do |shift|
        merged_shift = merge_ranges(shift, current_shift) if ranges_overlap?(shift, current_shift)
      end
    end

    #replace old shift with merged shift
    if merged_shift

      delete_shift = shifts_array.find(beginning: current_shift.beginning, ending: current_shift.ending).first
      shifts_array.delete(delete_shift) if delete_shift

      shifts_array.push(merged_shift)
    else
      shifts_array.push(current_shift)
    end

    if show_output
      store_hours_string = ""
      if output_shift_array.blank?
        store_hours_string = "Closed"
      else
        output_shift_array.each do |shift|
          shift.beginning.strftime("%I:%M%p")
          shift.ending.strftime("%I:%M%p")
          if store_hours_string.blank?
            store_hours_string << "#{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
          else
            store_hours_string << ", #{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
          end
        end
      end
    "#{Date::DAYNAMES[output_day][0..2]}: #{store_hours_string}"

    end

  end

  #output last shift
  store_hours_string = ""
  if output_shift_array.blank?
    store_hours_string = "Closed"
  else
    output_shift_array.each do |shift|
      shift.beginning.strftime("%I:%M%p")
      shift.ending.strftime("%I:%M%p")
      if store_hours_string.blank?
        store_hours_string << "#{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
      else
        store_hours_string << ", #{shift.beginning.strftime("%I:%M%p").downcase} - #{shift.ending.strftime("%I:%M%p").downcase}"
      end
    end
  end
  merchant_shifts << "#{Date::DAYNAMES[day][0..2]}: #{store_hours_string}"


  merchant_shifts.compact

end

0 ответов

Другие вопросы по тегам