1

AvailableHoursモデルに保存されている可能性のある販売業者の営業時間のリストがあります。モデルにはstart_timeとがオブジェクトend_timeとして保存されていTimeOfDayます ( https://github.com/JackC/tod )。

リストを繰り返し処理し、店舗の営業時間を比較して、1 店舗の営業時間を表示したいと考えています。たとえば、店舗の営業時間がMon: 9am-2pmMon: 10am-5pmである場合、 を表示したいと思いますMon: 9am-5pm。店舗は 1 日に 2 回、つまり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