1

我有一个商家的商店营业时间列表,这些营业时间可能会重叠存储在AvailableHours模型中。该模型将 astart_time和 aend_time存储为TimeOfDay对象(https://github.com/JackC/tod)。

我想遍历列表并比较商店营业时间,以便仅显示 1 个营业时间。例如,如果一家商店可以有几个小时Mon: 9am-2pmMon: 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
4

0 回答 0