From 58142083d1055754a223628a5c09943d01c29bd8 Mon Sep 17 00:00:00 2001
From: Tyler Lemburg <lemburg@unl.edu>
Date: Thu, 29 Jun 2017 14:52:43 -0500
Subject: [PATCH] Make reserve pages respect resource hours in front of space
 hours if present

---
 models/resource.rb  | 51 ++++++++++++++++++++++++
 routes/resources.rb | 94 ++++++++-------------------------------------
 views/reserve.erb   |  2 +-
 3 files changed, 68 insertions(+), 79 deletions(-)

diff --git a/models/resource.rb b/models/resource.rb
index a0c590f..83faa81 100644
--- a/models/resource.rb
+++ b/models/resource.rb
@@ -4,10 +4,13 @@ require 'models/resource_authorization'
 require 'models/resource_class'
 require 'models/resource_field'
 require 'models/resource_field_data'
+require 'models/resource_hour'
+require 'models/space_hour'
 
 class Resource < ActiveRecord::Base
 	belongs_to :service_space
 	has_many :reservations, dependent: :destroy
+	has_many :resource_hours, dependent: :destroy
 	has_many :resource_approvers, dependent: :destroy
 	has_many :resource_authorizations, dependent: :destroy
 	belongs_to :resource_class
@@ -41,4 +44,52 @@ class Resource < ActiveRecord::Base
 	def add_hours_href
 		"/#{service_space.url_name}/admin/resources/#{id}/hours/create/"
 	end
+
+	def get_weeks_available_hours(date)
+		sunday = date.in_time_zone.week_start
+
+		# get the space's hours for the week
+		space_hours = SpaceHour.where(:service_space_id => service_space.id)
+			.where('effective_date < ?', (sunday+1.week+1.hour).midnight.utc.strftime('%Y-%m-%d %H:%M:%S'))
+			.order(:day_of_week, :effective_date => :desc, :id => :desc).all.to_a
+
+		space_hours_days = space_hours.group_by do |space_hour|
+			space_hour.day_of_week
+		end
+
+		resource_hours = ResourceHour.where(:resource_id => id)
+			.where('effective_date < ?', (sunday+1.week+1.hour).midnight.utc.strftime('%Y-%m-%d %H:%M:%S'))
+			.order(:day_of_week, :effective_date => :desc, :id => :desc).all.to_a
+
+		resource_hours_days = resource_hours.group_by do |resource_hour|
+			resource_hour.day_of_week
+		end
+
+		week_hours = {}
+		space_hours_days.each do |number_of_days, array|
+			this_day = (sunday + number_of_days.days + 1.hour).midnight
+
+			# find the correct hour record to use for this day
+			array.each do |space_hour|
+				if space_hour.effective_date.in_time_zone.midnight == this_day.in_time_zone.midnight || (!space_hour.one_off && space_hour.effective_date.in_time_zone.midnight <= this_day.in_time_zone.midnight)
+					week_hours[number_of_days] = space_hour
+					break
+				end
+			end
+		end
+
+		resource_hours_days.each do |number_of_days, array|
+			this_day = (sunday + number_of_days.days + 1.hour).midnight
+
+			# find the correct hour record to use for this day
+			array.each do |resource_hour|
+				if resource_hour.effective_date.in_time_zone.midnight == this_day.in_time_zone.midnight || (!resource_hour.one_off && resource_hour.effective_date.in_time_zone.midnight <= this_day.in_time_zone.midnight)
+					week_hours[number_of_days] = resource_hour
+					break
+				end
+			end
+		end
+
+		return week_hours
+	end
 end
\ No newline at end of file
diff --git a/routes/resources.rb b/routes/resources.rb
index f26bb7e..ef8e656 100644
--- a/routes/resources.rb
+++ b/routes/resources.rb
@@ -38,27 +38,7 @@ get '/:service_space_url_name/resources/:resource_id/calendar/?' do
 	# get the reservations for this week
 	reservations = Reservation.includes(:event, :user).where(:resource_id => resource.id).in_week(date).all
 
-	# get the space's hours for the week
-	hours = SpaceHour.where(:service_space_id => @space.id)
-		.where('effective_date < ?', (sunday+1.week+1.hour).midnight.utc.strftime('%Y-%m-%d %H:%M:%S'))
-		.order(:day_of_week, :effective_date => :desc, :id => :desc).all.to_a
-
-	hours_days = hours.group_by do |space_hour|
-		space_hour.day_of_week
-	end
-
-	week_hours = {}
-	hours_days.each do |number_of_days, array|
-		this_day = (sunday + number_of_days.days + 1.hour).midnight
-
-		# find the correct hour record to use for this day
-		array.each do |space_hour|
-			if space_hour.effective_date.in_time_zone.midnight == this_day.in_time_zone.midnight || (!space_hour.one_off && space_hour.effective_date.in_time_zone.midnight <= this_day.in_time_zone.midnight)
-				week_hours[number_of_days] = space_hour
-				break
-			end
-		end
-	end
+	week_hours = resource.get_weeks_available_hours(date)
 
 	erb :resource_calendar, :layout => :fixed, :locals => {
 		:date => date,
@@ -84,17 +64,9 @@ get '/:service_space_url_name/resources/:resource_id/reserve/?' do
 	end
 
 	date = params[:date].nil? ? Time.now.midnight.in_time_zone : Time.parse(params[:date]).midnight.in_time_zone
-	# get the studio's hours for this day
-	# is there a one_off
-	space_hour = SpaceHour.where(:service_space_id => @space.id)
-		.where('effective_date = ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-		.where(:day_of_week => date.wday).where(:one_off => true).first
-	if space_hour.nil?
-		space_hour = SpaceHour.where(:service_space_id => @space.id)
-			.where('effective_date <= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-			.where(:day_of_week => date.wday).where(:one_off => false)
-			.order(:effective_date => :desc, :id => :desc).first
-	end
+	
+	week_hours = resource.get_weeks_available_hours(date)
+	space_hour = week_hours[date.in_time_zone.wday]
 
 	available_start_times = []
 	# calculate the available start times for reservation
@@ -158,17 +130,9 @@ post '/:service_space_url_name/resources/:resource_id/reserve/?' do
 
 	date = start_time.midnight
 	# validate that the requested time slot falls within the open hours of the day
-	# get the studio's hours for this day
-	# is there a one_off
-	space_hour = SpaceHour.where(:service_space_id => @space.id)
-		.where('effective_date = ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-		.where(:day_of_week => date.wday).where(:one_off => true).first
-	if space_hour.nil?
-		space_hour = SpaceHour.where(:service_space_id => @space.id)
-			.where('effective_date <= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-			.where(:day_of_week => date.wday).where(:one_off => false)
-			.order(:effective_date => :desc, :id => :desc).first
-	end
+	
+	week_hours = resource.get_weeks_available_hours(date)
+	space_hour = week_hours[date.in_time_zone.wday]
 
 	unless space_hour.nil?
 		# figure out where the closed sections need to be
@@ -335,18 +299,9 @@ post '/:service_space_url_name/resources/:resource_id/reserve/?' do
 			new_end = new_start + params[:length].to_i.minutes
 
 			date = new_start.midnight
-			# validate that the requested time slot falls within the open hours of the day
-			# get the studio's hours for this day
-			# is there a one_off
-			space_hour = SpaceHour.where(:service_space_id => @space.id)
-				.where('effective_date = ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-				.where(:day_of_week => date.wday).where(:one_off => true).first
-			if space_hour.nil?
-				space_hour = SpaceHour.where(:service_space_id => @space.id)
-					.where('effective_date <= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-					.where(:day_of_week => date.wday).where(:one_off => false)
-					.order(:effective_date => :desc, :id => :desc).first
-			end
+			
+			week_hours = resource.get_weeks_available_hours(date)
+			space_hour = week_hours[date.in_time_zone.wday]
 
 			unless space_hour.nil?
 				# figure out where the closed sections need to be
@@ -461,17 +416,9 @@ get '/:service_space_url_name/resources/:resource_id/edit_reservation/:reservati
 	end
 
 	date = params[:date].nil? ? reservation.start_time.in_time_zone.midnight : Time.parse(params[:date]).midnight.in_time_zone
-	# get the studio's hours for this day
-	# is there a one_off
-	space_hour = SpaceHour.where(:service_space_id => @space.id)
-		.where('effective_date = ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-		.where(:day_of_week => date.wday).where(:one_off => true).first
-	if space_hour.nil?
-		space_hour = SpaceHour.where(:service_space_id => @space.id)
-			.where('effective_date <= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-			.where(:day_of_week => date.wday).where(:one_off => false)
-			.order(:effective_date => :desc, :id => :desc).first
-	end
+	
+	week_hours = resource.get_weeks_available_hours(date)
+	space_hour = week_hours[date.in_time_zone.wday]
 
 	available_start_times = []
 	# calculate the available start times for reservation
@@ -538,18 +485,9 @@ post '/:service_space_url_name/resources/:resource_id/edit_reservation/:reservat
 	end_time = start_time + params[:length].to_i.minutes
 
 	date = start_time.midnight
-	# validate that the requested time slot falls within the open hours of the day
-	# get the studio's hours for this day
-	# is there a one_off
-	space_hour = SpaceHour.where(:service_space_id => @space.id)
-		.where('effective_date = ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-		.where(:day_of_week => date.wday).where(:one_off => true).first
-	if space_hour.nil?
-		space_hour = SpaceHour.where(:service_space_id => @space.id)
-			.where('effective_date <= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S'))
-			.where(:day_of_week => date.wday).where(:one_off => false)
-			.order(:effective_date => :desc, :id => :desc).first
-	end
+	
+	week_hours = resource.get_weeks_available_hours(date)
+	space_hour = week_hours[date.in_time_zone.wday]
 
 	unless space_hour.nil?
 		# figure out where the closed sections need to be
diff --git a/views/reserve.erb b/views/reserve.erb
index 567967b..305b467 100644
--- a/views/reserve.erb
+++ b/views/reserve.erb
@@ -33,7 +33,7 @@ EIGHT_PM_MINUTES = 1200 # end time of calendar
                 <div class="time-chart">
                     <% (12..39).each do |j| %>
                         <div class="calendar-half-hour">
-                            <label><%= "#{(j / 2) % 12 + (j==24?12:0)} #{j>=24?'PM':'AM'}" if j % 2 == 0 %></label>
+                            <label><%= "#{(j / 2) % 12 + (j==24?12:0)} #{j>=24? 'PM': 'AM'}" if j % 2 == 0 %></label>
                         </div>
                     <% end %>
                 </div>
-- 
GitLab