From 7e666b7d2eb75ed57f70a2a1207ba4b2601d6e52 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Tue, 5 Sep 2017 23:06:11 -0700 Subject: [PATCH 01/18] room.rb and room_spec.rb drafted --- Rakefile | 9 +++++++++ lib/.keep | 0 lib/reservation.rb | 3 +++ lib/room.rb | 37 +++++++++++++++++++++++++++++++++++++ specs/.keep | 0 specs/reservation_spec.rb | 31 +++++++++++++++++++++++++++++++ specs/room_spec.rb | 30 ++++++++++++++++++++++++++++++ specs/spec_helper.rb | 16 ++++++++++++++++ support/rooms.csv | 20 ++++++++++++++++++++ 9 files changed, 146 insertions(+) create mode 100644 Rakefile delete mode 100644 lib/.keep create mode 100644 lib/reservation.rb create mode 100644 lib/room.rb delete mode 100644 specs/.keep create mode 100644 specs/reservation_spec.rb create mode 100644 specs/room_spec.rb create mode 100644 specs/spec_helper.rb create mode 100644 support/rooms.csv diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..deb52f2cd --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib"] + t.warning = true + t.test_files = FileList['specs/*_spec.rb'] +end + +task default: :test diff --git a/lib/.keep b/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..73327bc98 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,3 @@ +# class Reservation +# def initialize +# end diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..38333f1ab --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,37 @@ +require 'csv' +require 'awesome_print' + +#info_hash{id: 1, cost: 200} +module Hotel + class Room + attr_accessor :id, :cost + + def initialize(id, cost) + @id = id + @cost = cost + #@all_rooms = [] this way can't work + end + + def self.all + room_info = CSV.read('./support/rooms.csv') + + all_rooms = [] + room_info.each do |row| + id = row[0] + cost = row[1] + all_rooms << Room.new(id, cost) + end + + return all_rooms + end + + end#of_Room_class +end#of_module_Hotel + +#TESTING +#ap Hotel::Room.all #will access the list of all of the rooms in the hotel + +#Jans-MBP:hotel janedrozo$ ruby lib/room.rb + +#SPEC TESTING +#Jans-MBP:hotel janedrozo$ rake diff --git a/specs/.keep b/specs/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..186bf0ceb --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,31 @@ +# require_relative 'spec_helper' +# describe "Reservation" do +# before do +# @reservation_test = Reservation.new +# end +# +# describe "initialize" do +# it "can create an instance of Reservation class" do +# @reservation_test.class.must_equal Reservation +# end +# +# # it "#id: can give correct room id number" do +# # @room_test.id.must_equal 1 +# # end +# # +# # it "#cost: can give correct cost" do +# # @room_test.cost.must_equal 200 +# # end +# # +# # it "#status: can give correct availability status" do +# # @room_test.status.must_equal :open +# # end +# end +# +# # describe "Reservation.all" do +# # it "returns a list of all reservations" do +# # all_reservations = Reservation.all +# # +# # end +# # end +# end diff --git a/specs/room_spec.rb b/specs/room_spec.rb new file mode 100644 index 000000000..92ee0a2dc --- /dev/null +++ b/specs/room_spec.rb @@ -0,0 +1,30 @@ +require_relative 'spec_helper' +require_relative '../lib/room' + +describe "Room" do + before do + @room_test = Hotel::Room.new(1, 200) + end + + describe "initialize" do + it "can create an instance of Room class" do + @room_test.class.must_equal Hotel::Room + end + + it "#id: can give correct room id number" do + @room_test.id.must_equal 1 + end + + it "#cost: can give correct cost" do + @room_test.cost.must_equal 200 + end + end + + describe "Room.all" do + it "returns a list of all room instances as an array" do + all_rooms = Hotel::Room.all + + all_rooms.all.must_be_kind_of Array + end + end +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..b4e95ebd3 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,16 @@ +require 'simplecov' +SimpleCov.start + +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +require_relative '../lib/room' +# require_relative '../lib/' +# require_relative '../lib/' + + + + + + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new diff --git a/support/rooms.csv b/support/rooms.csv new file mode 100644 index 000000000..e0c15c31c --- /dev/null +++ b/support/rooms.csv @@ -0,0 +1,20 @@ +1, 200 +2, 200 +3, 200 +4, 200 +5, 200 +6, 200 +7, 200 +8, 200 +9, 200 +10, 200 +11, 200 +12, 200 +13, 200 +14, 200 +15, 200 +16, 200 +17, 200 +18, 200 +19, 200 +20, 200 From 6ddbc3ea10d512dfbca558a7a7e4d044d66334e7 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Wed, 6 Sep 2017 18:48:59 -0700 Subject: [PATCH 02/18] Updated room cost to be float --- lib/hotel.rb | 18 ++++++++ lib/reservation.rb | 55 +++++++++++++++++++++++-- lib/room.rb | 6 +-- specs/hotel_spec.rb | 1 + specs/reservation_spec.rb | 87 +++++++++++++++++++++++++-------------- specs/room_spec.rb | 12 +++--- specs/spec_helper.rb | 4 +- support/rooms.csv | 40 +++++++++--------- 8 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 lib/hotel.rb create mode 100644 specs/hotel_spec.rb diff --git a/lib/hotel.rb b/lib/hotel.rb new file mode 100644 index 000000000..6aa74b6da --- /dev/null +++ b/lib/hotel.rb @@ -0,0 +1,18 @@ +# module BookingSystem +# class Hotel +# +# def initialize +# #a hotel will have a collection of reservations +# @all_reservations = {} #hash of dates to arrays of reservations +# end +# +# #make reservation for a given date range +# +# #access the list of reservations for a specific date +# +# +# +# +# +# end#of_Hotel_class +# end#of_module_BookingSystem diff --git a/lib/reservation.rb b/lib/reservation.rb index 73327bc98..6c637025f 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,3 +1,52 @@ -# class Reservation -# def initialize -# end +require 'date' +require_relative 'room' + +module BookingSystem + class Reservation + attr_reader :first_name, :last_name, :room_id, :room_rate, :reserv_id, :start_date, :end_date, :room_count, :total_cost + + def initialize(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count, total_cost) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") + # raise ArgumentError.new("start_date must be a string in the format: DD/MM/YYYY") if !start_date + @first_name = first_name + @last_name = last_name + @reserv_id = reserv_id #how am I going to generate a reserv_id? + @start_date = start_date + @end_date = end_date + @room_id = room_id + @room_rate = room_rate + @room_count = room_count + @total_cost = total_cost + end + + def get_total_cost + date_diff = end_date - start_date + total_cost = date_diff * room_rate + return total_cost + end + + end#of_Reservation_class +end#of_module_BookingSystem + +# module BookingSystem +# class Reservation +# attr_reader :first_name, :last_name, :reserv_id, :start_date, :end_date, :room_id, :total_cost +# +# def initialize(first_name, last_name, reserv_id, start_date, end_date, room_id, total_cost) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") +# # raise ArgumentError.new("start_date must be a string in the format: DD/MM/YYYY") if !start_date +# @first_name = first_name +# @last_name = last_name +# @reserv_id = reserv_id #how am I going to generate a reserv_id? +# @start_date = start_date +# @end_date = end_date +# @room_id = room_id #Booking::Room.id +# @total_cost = total_cost +# end +# +# def get_total_cost +# date_diff = end_date - start_date +# +# date_diff * +# end +# +# end#of_Reservation_class +# end#of_module_BookingSystem diff --git a/lib/room.rb b/lib/room.rb index 38333f1ab..b4680abb6 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -2,7 +2,7 @@ require 'awesome_print' #info_hash{id: 1, cost: 200} -module Hotel +module BookingSystem class Room attr_accessor :id, :cost @@ -25,8 +25,8 @@ def self.all return all_rooms end - end#of_Room_class -end#of_module_Hotel + end#of_Reservation_class +end#of_module_BookingSystem #TESTING #ap Hotel::Room.all #will access the list of all of the rooms in the hotel diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb new file mode 100644 index 000000000..ae9c220ea --- /dev/null +++ b/specs/hotel_spec.rb @@ -0,0 +1 @@ +require_relative 'spec_helper' diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 186bf0ceb..9cf86d1d5 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -1,31 +1,56 @@ -# require_relative 'spec_helper' -# describe "Reservation" do -# before do -# @reservation_test = Reservation.new -# end -# -# describe "initialize" do -# it "can create an instance of Reservation class" do -# @reservation_test.class.must_equal Reservation -# end -# -# # it "#id: can give correct room id number" do -# # @room_test.id.must_equal 1 -# # end -# # -# # it "#cost: can give correct cost" do -# # @room_test.cost.must_equal 200 -# # end -# # -# # it "#status: can give correct availability status" do -# # @room_test.status.must_equal :open -# # end -# end -# -# # describe "Reservation.all" do -# # it "returns a list of all reservations" do -# # all_reservations = Reservation.all -# # -# # end -# # end -# end +require 'date' +require_relative 'spec_helper' + + +describe "Reservation" do + before do + first_name = "Jane" + last_name = "Doe" + room_id = 1 + room_rate = 200.00 + reserv_id = 1221 + start_date = Date.parse("1/9/2017") + end_date = Date.parse("3/9/2017") + room_count = 1 + total_cost = 0 + @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count, total_cost) + end + + describe "#initialize" do + it "can create an instance of Reservation class" do + @reservation_test.class.must_equal BookingSystem::Reservation + end + + it "can take in reserver's identity info as arguments: first_name, last_name" do + #@reservation_test.must_respond_to(first_name) #? not sure why this gives an error + @reservation_test.first_name.must_equal("Jane") + @reservation_test.first_name.must_be_instance_of String + + @reservation_test.last_name.must_equal("Doe") + @reservation_test.last_name.must_be_instance_of String + end + + it "can take in room info as arguments: room_id, room_rate" do + @reservation_test.room_id.must_equal 1 + @reservation_test.room_id.must_be_instance_of Integer + + @reservation_test.room_rate.must_equal 200.00 + @reservation_test.room_rate.must_be_instance_of Float + end + + it "#reserv_id: can give correct reservation id number" do + @reservation_test.reserv_id.must_equal 1221 + end + + # it "#total_cost: can give correct cost" do + # @reservation_test.total_cost.must_equal 400 + # end + end + + # describe "#get_total_cost" do + # it "can calculate a total " do + # + # end + # end + +end#of_"Reservation" diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 92ee0a2dc..d8b4c744f 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -3,28 +3,30 @@ describe "Room" do before do - @room_test = Hotel::Room.new(1, 200) + @room_test = BookingSystem::Room.new(1, 200.00) end describe "initialize" do it "can create an instance of Room class" do - @room_test.class.must_equal Hotel::Room + @room_test.class.must_equal BookingSystem::Room end it "#id: can give correct room id number" do @room_test.id.must_equal 1 + @room_test.id.must_be_instance_of Integer end it "#cost: can give correct cost" do - @room_test.cost.must_equal 200 + @room_test.cost.must_equal 200.00 + @room_test.cost.must_be_instance_of Float end end describe "Room.all" do it "returns a list of all room instances as an array" do - all_rooms = Hotel::Room.all + all_rooms = BookingSystem::Room.all - all_rooms.all.must_be_kind_of Array + all_rooms.must_be_instance_of Array end end end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index b4e95ebd3..67a257eea 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -5,8 +5,8 @@ require 'minitest/autorun' require 'minitest/reporters' require_relative '../lib/room' -# require_relative '../lib/' -# require_relative '../lib/' +require_relative '../lib/reservation' +require_relative '../lib/hotel' diff --git a/support/rooms.csv b/support/rooms.csv index e0c15c31c..2ff747506 100644 --- a/support/rooms.csv +++ b/support/rooms.csv @@ -1,20 +1,20 @@ -1, 200 -2, 200 -3, 200 -4, 200 -5, 200 -6, 200 -7, 200 -8, 200 -9, 200 -10, 200 -11, 200 -12, 200 -13, 200 -14, 200 -15, 200 -16, 200 -17, 200 -18, 200 -19, 200 -20, 200 +1, 200.00 +2, 200.00 +3, 200.00 +4, 200.00 +5, 200.00 +6, 200.00 +7, 200.00 +8, 200.00 +9, 200.00 +10, 200.00 +11, 200.00 +12, 200.00 +13, 200.00 +14, 200.00 +15, 200.00 +16, 200.00 +17, 200.00 +18, 200.00 +19, 200.00 +20, 200.00 From 4a22df2864a7356c76311357113726298ee9d24b Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Wed, 6 Sep 2017 19:09:04 -0700 Subject: [PATCH 03/18] reservation_spec and .rb arguments updated --- specs/reservation_spec.rb | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 9cf86d1d5..5520b64d6 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -12,7 +12,7 @@ start_date = Date.parse("1/9/2017") end_date = Date.parse("3/9/2017") room_count = 1 - total_cost = 0 + total_cost = 400.00 @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count, total_cost) end @@ -38,13 +38,25 @@ @reservation_test.room_rate.must_be_instance_of Float end - it "#reserv_id: can give correct reservation id number" do + it "can take in reservation info as arguments: reserv_id, room_count, total_cost" do @reservation_test.reserv_id.must_equal 1221 + @reservation_test.reserv_id.must_be_instance_of Integer #arbitrarily deciding the id is an integer MAY NOT BE NECESSARY to include + + @reservation_test.room_count.must_equal 1 + @reservation_test.room_count.must_be_instance_of Integer + + @reservation_test.total_cost.must_equal 400.00 + @reservation_test.total_cost.must_be_instance_of Float + end + + it "can take in reservation date objects as arguments: start_date, end_date" do + @reservation_test.start_date.must_equal(Date.parse("1/9/2017")) + @reservation_test.start_date.must_be_instance_of Date + + @reservation_test.end_date.must_equal(Date.parse("3/9/2017")) + @reservation_test.end_date.must_be_instance_of Date end - # it "#total_cost: can give correct cost" do - # @reservation_test.total_cost.must_equal 400 - # end end # describe "#get_total_cost" do From 3414dbc5fbc03abd36627541e8712a90071b7082 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Thu, 7 Sep 2017 10:20:55 -0700 Subject: [PATCH 04/18] Reservation: get_total_cost and initialize arguments count --- lib/reservation.rb | 37 +++++++------------------------------ specs/reservation_spec.rb | 24 +++++++++++++----------- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 6c637025f..83307a2eb 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -5,7 +5,7 @@ module BookingSystem class Reservation attr_reader :first_name, :last_name, :room_id, :room_rate, :reserv_id, :start_date, :end_date, :room_count, :total_cost - def initialize(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count, total_cost) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") + def initialize(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") # raise ArgumentError.new("start_date must be a string in the format: DD/MM/YYYY") if !start_date @first_name = first_name @last_name = last_name @@ -15,38 +15,15 @@ def initialize(first_name, last_name, room_id, room_rate, reserv_id, start_date, @room_id = room_id @room_rate = room_rate @room_count = room_count - @total_cost = total_cost + + @total_cost = 0 end - def get_total_cost - date_diff = end_date - start_date - total_cost = date_diff * room_rate - return total_cost + def get_total_cost #(start_date, end_date, room_rate, room_count) would hotel use these as arguments to get total_cost? + date_diff = @end_date - @start_date + @total_cost = date_diff * (@room_rate * @room_count) + return @total_cost end end#of_Reservation_class end#of_module_BookingSystem - -# module BookingSystem -# class Reservation -# attr_reader :first_name, :last_name, :reserv_id, :start_date, :end_date, :room_id, :total_cost -# -# def initialize(first_name, last_name, reserv_id, start_date, end_date, room_id, total_cost) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") -# # raise ArgumentError.new("start_date must be a string in the format: DD/MM/YYYY") if !start_date -# @first_name = first_name -# @last_name = last_name -# @reserv_id = reserv_id #how am I going to generate a reserv_id? -# @start_date = start_date -# @end_date = end_date -# @room_id = room_id #Booking::Room.id -# @total_cost = total_cost -# end -# -# def get_total_cost -# date_diff = end_date - start_date -# -# date_diff * -# end -# -# end#of_Reservation_class -# end#of_module_BookingSystem diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 5520b64d6..0a106ac93 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -12,8 +12,8 @@ start_date = Date.parse("1/9/2017") end_date = Date.parse("3/9/2017") room_count = 1 - total_cost = 400.00 - @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count, total_cost) + + @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count) end describe "#initialize" do @@ -38,15 +38,12 @@ @reservation_test.room_rate.must_be_instance_of Float end - it "can take in reservation info as arguments: reserv_id, room_count, total_cost" do + it "can take in reservation info as arguments: reserv_id, room_count" do @reservation_test.reserv_id.must_equal 1221 @reservation_test.reserv_id.must_be_instance_of Integer #arbitrarily deciding the id is an integer MAY NOT BE NECESSARY to include @reservation_test.room_count.must_equal 1 @reservation_test.room_count.must_be_instance_of Integer - - @reservation_test.total_cost.must_equal 400.00 - @reservation_test.total_cost.must_be_instance_of Float end it "can take in reservation date objects as arguments: start_date, end_date" do @@ -59,10 +56,15 @@ end - # describe "#get_total_cost" do - # it "can calculate a total " do - # - # end - # end + describe "#get_total_cost" do + it "can calculate a total" do + + @reservation_test.get_total_cost.must_equal 400.00 + @reservation_test.get_total_cost.must_be_instance_of Float + + @reservation_test.total_cost.must_equal 400.00 + @reservation_test.total_cost.must_be_instance_of Float + end + end end#of_"Reservation" From 78f5993e5c7c1a59e15c3d7672fed404ca76a319 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Fri, 8 Sep 2017 10:17:37 -0700 Subject: [PATCH 05/18] Added Guest --- lib/guest.rb | 15 ++++++++++ lib/hotel.rb | 18 ------------ lib/hotel_admin.rb | 60 +++++++++++++++++++++++++++++++++++++++ lib/reservation.rb | 25 +++++++++------- specs/booking.rb | 13 +++++++++ specs/guest_spec.rb | 25 ++++++++++++++++ specs/hotel_spec.rb | 45 +++++++++++++++++++++++++++++ specs/reservation_spec.rb | 21 +++++++------- specs/spec_helper.rb | 4 ++- 9 files changed, 186 insertions(+), 40 deletions(-) create mode 100644 lib/guest.rb delete mode 100644 lib/hotel.rb create mode 100644 lib/hotel_admin.rb create mode 100644 specs/booking.rb create mode 100644 specs/guest_spec.rb diff --git a/lib/guest.rb b/lib/guest.rb new file mode 100644 index 000000000..8ee0603f0 --- /dev/null +++ b/lib/guest.rb @@ -0,0 +1,15 @@ +module BookingSystem + class Guest + + attr_reader :first_name, :last_name + + def initialize(first_name, last_name) + raise ArgumentError.new("first name must be a string") if !first_name.is_a? String + @first_name = first_name + + raise ArgumentError.new("last name must be a string") if !last_name.is_a? String + @last_name = last_name + end + + end#of_Guest_class +end#of_module_BookingSystem diff --git a/lib/hotel.rb b/lib/hotel.rb deleted file mode 100644 index 6aa74b6da..000000000 --- a/lib/hotel.rb +++ /dev/null @@ -1,18 +0,0 @@ -# module BookingSystem -# class Hotel -# -# def initialize -# #a hotel will have a collection of reservations -# @all_reservations = {} #hash of dates to arrays of reservations -# end -# -# #make reservation for a given date range -# -# #access the list of reservations for a specific date -# -# -# -# -# -# end#of_Hotel_class -# end#of_module_BookingSystem diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb new file mode 100644 index 000000000..6f0309516 --- /dev/null +++ b/lib/hotel_admin.rb @@ -0,0 +1,60 @@ +# [X]As an administrator, I can access the list of all of the rooms in the hotel +# As an administrator, I can reserve a room for a given date range +# As an administrator, I can access the list of reservations for a specific date +# [X] As an administrator, I can get the total cost for a given reservation + +module BookingSystem + class HotelAdmin + + attr_reader :hotel_rooms, :all_reservations + + def initialize + #hotel admin knows all collection of reservations + @all_reservations = [] + #hotel admin knows all rooms in hotel + @hotel_rooms = BookingSystem::Room.all + end + + def make_reservation(first_name, last_name, room_id, room_rate, start_date, end_date) + + # check if room is available based on date range + raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| + reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date + } + # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. + + reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + #check if date range for room is available + @all_reservations << reservation + end + + # private + + #def generate_reservation_ids + #end + + # def check_availability + # + # # checks all_reservations for a room id, start, and end date + # # see if room id is in reservation list + # # if room is in reservation, check to see the dates of the reservation + # # if the range of dates overlap (using the Date gem) (not including the final date of the existing reservation) + # # then return false + # # Otherwise, return true + # end + + + + + end#of_HotelAdmin_class +end#of_module_BookingSystem + +=begin +Date notes: + +< +source: https://stackoverflow.com/questions/3296539/comparision-of-date-in-ruby + +.between?(start_date, end_date) +source: https://stackoverflow.com/questions/4521921/how-to-know-if-todays-date-is-in-a-date-range +=end diff --git a/lib/reservation.rb b/lib/reservation.rb index 83307a2eb..4fd36a92c 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -3,27 +3,32 @@ module BookingSystem class Reservation - attr_reader :first_name, :last_name, :room_id, :room_rate, :reserv_id, :start_date, :end_date, :room_count, :total_cost + attr_reader :first_name, :last_name, :room_id, :room_rate, :start_date, :end_date, :total_cost, :date_range + + def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") - def initialize(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") - # raise ArgumentError.new("start_date must be a string in the format: DD/MM/YYYY") if !start_date @first_name = first_name @last_name = last_name - @reserv_id = reserv_id #how am I going to generate a reserv_id? - @start_date = start_date - @end_date = end_date + @room_id = room_id @room_rate = room_rate - @room_count = room_count - @total_cost = 0 + @start_date = start_date + @end_date = end_date + @date_range = make_date_range_array + @total_cost = get_total_cost #returns grand_total, the result of get_total_cost end def get_total_cost #(start_date, end_date, room_rate, room_count) would hotel use these as arguments to get total_cost? date_diff = @end_date - @start_date - @total_cost = date_diff * (@room_rate * @room_count) - return @total_cost + grand_total = date_diff * @room_rate + return grand_total + end + + def make_date_range_array + return (@start_date .. @end_date).map{|day| day} end + end#of_Reservation_class end#of_module_BookingSystem diff --git a/specs/booking.rb b/specs/booking.rb new file mode 100644 index 000000000..3fd5c73f5 --- /dev/null +++ b/specs/booking.rb @@ -0,0 +1,13 @@ +require 'date' +require_relative '../lib/room' +require_relative '../lib/reservation' +require_relative '../lib/hotel' + + +hotel = BookingSystem::HotelAdmin.new + +puts hotel.all_reservations + +hotel.make_reservation("Jane", "Doe", 1, 200.00, Date.parse("1/9/2017"), Date.parse("3/9/2017")) + +puts hotel.all_reservations diff --git a/specs/guest_spec.rb b/specs/guest_spec.rb new file mode 100644 index 000000000..3a5c99360 --- /dev/null +++ b/specs/guest_spec.rb @@ -0,0 +1,25 @@ +require_relative 'spec_helper' + +describe "Guest" do + before do + @guest_test = BookingSystem::Guest.new("Jane", "Doe") + end + + describe "initialize" do + it "can create an instance of Guess class" do + @guest_test.class.must_equal BookingSystem::Guest + end + + it "can access a guest's first name and last name" do + @guest_test.first_name.must_equal "Jane" + @guest_test.last_name.must_equal "Doe" + end + + it "ensures first name and last name are strings" do + proc { BookingSystem::Guest.new([], "Doe") }.must_raise ArgumentError + proc { BookingSystem::Guest.new("Jane", 2) }.must_raise ArgumentError + end + + end + +end#_of_"Guest" diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb index ae9c220ea..ad3027da2 100644 --- a/specs/hotel_spec.rb +++ b/specs/hotel_spec.rb @@ -1 +1,46 @@ require_relative 'spec_helper' + +describe "HotelAdmin" do + before do + @hotel_admin_test = BookingSystem::HotelAdmin.new + end + + describe "initialize" do + it "can create an instance of HotelAdmin class" do + @hotel_admin_test.class.must_equal BookingSystem::HotelAdmin + end + + it "can access list of all rooms in the hotel" do + @hotel_admin_test.hotel_rooms.must_be_instance_of Array + end + + it "can access list of all reservations in hotel" do + @hotel_admin_test.all_reservations.must_be_instance_of Array + end + end + + # describe "#make_reservation" do + # before do + # first_name = "Jane" + # last_name = "Doe" + # + # room_id = 1 + # room_rate = 200.00 + # + # start_date = Date.parse("1/9/2017") + # end_date = Date.parse("3/9/2017") + # + # + # @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date) + # + # end + # it "can reserve a room for a given date range" do + # + # end + # + # # it "makes a reservation and adds it to hotel's list of reservations" do + # # @hotel_test.make_reservation(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date).must + # # end + # + # end +end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 0a106ac93..c96e4ca04 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -6,14 +6,16 @@ before do first_name = "Jane" last_name = "Doe" + room_id = 1 room_rate = 200.00 - reserv_id = 1221 + + # reserv_id = 1221 start_date = Date.parse("1/9/2017") end_date = Date.parse("3/9/2017") - room_count = 1 - @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date, room_count) + + @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) end describe "#initialize" do @@ -29,7 +31,7 @@ @reservation_test.last_name.must_equal("Doe") @reservation_test.last_name.must_be_instance_of String end - + it "can take in room info as arguments: room_id, room_rate" do @reservation_test.room_id.must_equal 1 @reservation_test.room_id.must_be_instance_of Integer @@ -38,13 +40,10 @@ @reservation_test.room_rate.must_be_instance_of Float end - it "can take in reservation info as arguments: reserv_id, room_count" do - @reservation_test.reserv_id.must_equal 1221 - @reservation_test.reserv_id.must_be_instance_of Integer #arbitrarily deciding the id is an integer MAY NOT BE NECESSARY to include - - @reservation_test.room_count.must_equal 1 - @reservation_test.room_count.must_be_instance_of Integer - end + # it "can take in reservation info as arguments: reserv_id" do + # @reservation_test.reserv_id.must_equal 1221 + # @reservation_test.reserv_id.must_be_instance_of Integer #arbitrarily deciding the id is an integer MAY NOT BE NECESSARY to include + # end it "can take in reservation date objects as arguments: start_date, end_date" do @reservation_test.start_date.must_equal(Date.parse("1/9/2017")) diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 67a257eea..2c4a5d7fc 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -6,7 +6,9 @@ require 'minitest/reporters' require_relative '../lib/room' require_relative '../lib/reservation' -require_relative '../lib/hotel' +require_relative '../lib/guest' +require_relative '../lib/hotel_admin' + From 9fd74a922b4d98b62ade8d6fa4c969f7890e7c45 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Fri, 8 Sep 2017 14:02:00 -0700 Subject: [PATCH 06/18] comments update for reservation --- lib/hotel_admin.rb | 35 +++++++++-------- lib/reservation.rb | 32 ++++++++++++---- lib/room.rb | 9 ++--- specs/booking.rb | 26 ++++++------- specs/hotel_spec.rb | 81 ++++++++++++++++++++++++++------------- specs/reservation_spec.rb | 26 ++++++------- specs/room_spec.rb | 1 - specs/spec_helper.rb | 5 --- 8 files changed, 127 insertions(+), 88 deletions(-) diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 6f0309516..09943d517 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -3,35 +3,40 @@ # As an administrator, I can access the list of reservations for a specific date # [X] As an administrator, I can get the total cost for a given reservation +require 'date' +require 'date_range' +require_relative 'room' +require_relative 'Reservation' + module BookingSystem class HotelAdmin - attr_reader :hotel_rooms, :all_reservations + attr_reader :room_list, :reservation_list def initialize #hotel admin knows all collection of reservations - @all_reservations = [] + @reservation_list = [] #hotel admin knows all rooms in hotel - @hotel_rooms = BookingSystem::Room.all + @room_list = BookingSystem::Room.all end - def make_reservation(first_name, last_name, room_id, room_rate, start_date, end_date) - - # check if room is available based on date range - raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| - reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date - } - # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. + def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date) - reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) #check if date range for room is available - @all_reservations << reservation + reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + + @reservation_list << reservation end - # private + # def check_availability + # # check if room is available based on date range + # raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| + # reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date + # } + # # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. + # end - #def generate_reservation_ids - #end + # private # def check_availability # diff --git a/lib/reservation.rb b/lib/reservation.rb index 4fd36a92c..9016bbcee 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,11 +1,11 @@ require 'date' -require_relative 'room' +require 'date_range' module BookingSystem class Reservation attr_reader :first_name, :last_name, :room_id, :room_rate, :start_date, :end_date, :total_cost, :date_range - def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) #assuming dates are already entered as objects using Date.parse("DD/MM/YYYY") + def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) @first_name = first_name @last_name = last_name @@ -15,7 +15,7 @@ def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) @start_date = start_date @end_date = end_date - @date_range = make_date_range_array + @date_range = DateRange.new(start_date, end_date) @total_cost = get_total_cost #returns grand_total, the result of get_total_cost end @@ -25,10 +25,26 @@ def get_total_cost #(start_date, end_date, room_rate, room_count) would hotel us return grand_total end - def make_date_range_array - return (@start_date .. @end_date).map{|day| day} - end - - end#of_Reservation_class end#of_module_BookingSystem + + + + + + + + + + + +=begin +NOTES: + #DATE RANGE METHOD (VERSION1) + # def make_date_range_array + # return (@start_date .. @end_date).map{|day| day} + # end + #Modify: @date_range = make_date_range_array + + #OUTPUTS: an array of the date range +=end diff --git a/lib/room.rb b/lib/room.rb index b4680abb6..768e73fe2 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -1,7 +1,5 @@ require 'csv' -require 'awesome_print' -#info_hash{id: 1, cost: 200} module BookingSystem class Room attr_accessor :id, :cost @@ -9,11 +7,10 @@ class Room def initialize(id, cost) @id = id @cost = cost - #@all_rooms = [] this way can't work end def self.all - room_info = CSV.read('./support/rooms.csv') + room_info = CSV.read('./support/rooms.csv', converters: :numeric) all_rooms = [] room_info.each do |row| @@ -21,7 +18,7 @@ def self.all cost = row[1] all_rooms << Room.new(id, cost) end - + return all_rooms end @@ -29,7 +26,7 @@ def self.all end#of_module_BookingSystem #TESTING -#ap Hotel::Room.all #will access the list of all of the rooms in the hotel +# Hotel::Room.all #will access the list of all of the rooms in the hotel #Jans-MBP:hotel janedrozo$ ruby lib/room.rb diff --git a/specs/booking.rb b/specs/booking.rb index 3fd5c73f5..fe4ad72e0 100644 --- a/specs/booking.rb +++ b/specs/booking.rb @@ -1,13 +1,13 @@ -require 'date' -require_relative '../lib/room' -require_relative '../lib/reservation' -require_relative '../lib/hotel' - - -hotel = BookingSystem::HotelAdmin.new - -puts hotel.all_reservations - -hotel.make_reservation("Jane", "Doe", 1, 200.00, Date.parse("1/9/2017"), Date.parse("3/9/2017")) - -puts hotel.all_reservations +# require 'date' +# require_relative '../lib/room' +# require_relative '../lib/reservation' +# require_relative '../lib/hotel' +# +# +# hotel = BookingSystem::HotelAdmin.new +# +# puts hotel.all_reservations +# +# hotel.make_reservation("Jane", "Doe", 1, 200.00, Date.parse("1/9/2017"), Date.parse("3/9/2017")) +# +# puts hotel.all_reservations diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb index ad3027da2..ebe2801e4 100644 --- a/specs/hotel_spec.rb +++ b/specs/hotel_spec.rb @@ -1,4 +1,5 @@ require_relative 'spec_helper' +require 'date_range' describe "HotelAdmin" do before do @@ -11,36 +12,64 @@ end it "can access list of all rooms in the hotel" do - @hotel_admin_test.hotel_rooms.must_be_instance_of Array + @hotel_admin_test.room_list.must_be_instance_of Array end it "can access list of all reservations in hotel" do - @hotel_admin_test.all_reservations.must_be_instance_of Array + @hotel_admin_test.reservation_list.must_be_instance_of Array end end - # describe "#make_reservation" do - # before do - # first_name = "Jane" - # last_name = "Doe" - # - # room_id = 1 - # room_rate = 200.00 - # - # start_date = Date.parse("1/9/2017") - # end_date = Date.parse("3/9/2017") - # - # - # @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date) - # - # end - # it "can reserve a room for a given date range" do - # - # end - # - # # it "makes a reservation and adds it to hotel's list of reservations" do - # # @hotel_test.make_reservation(first_name, last_name, room_id, room_rate, reserv_id, start_date, end_date).must - # # end - # - # end + describe "#reserve_room" do + + it "makes a reservation and adds it to hotel's list of reservations" do + first_name = "Jane" + last_name = "Doe" + + room_id = 1 + room_rate = 200.00 + + start_date = Date.parse("1/9/2017") + end_date = Date.parse("3/9/2017") + + reservation_made = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + + reservation_made = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + + @hotel_admin_test.reservation_list << reservation_made + + @hotel_admin_test.reservation_list.must_include reservation_made + end + + it "checks if room is available given the date range" do + reservation2 = BookingSystem::Reservation.new("J", "E", 2, 200.00, Date.parse("1/9/2017"), end_date = Date.parse("3/9/2017")) + + end + + end end + + + + + + + + + + + + + + + + + + + + + + + + +# diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index c96e4ca04..7a8ce1c94 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -10,10 +10,8 @@ room_id = 1 room_rate = 200.00 - # reserv_id = 1221 - start_date = Date.parse("1/9/2017") - end_date = Date.parse("3/9/2017") - + start_date = Date.new(2017, 9, 1) #Date.new(YYYY, M, D) + end_date = Date.new(2017, 9, 5) @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) end @@ -31,7 +29,7 @@ @reservation_test.last_name.must_equal("Doe") @reservation_test.last_name.must_be_instance_of String end - + it "can take in room info as arguments: room_id, room_rate" do @reservation_test.room_id.must_equal 1 @reservation_test.room_id.must_be_instance_of Integer @@ -40,28 +38,28 @@ @reservation_test.room_rate.must_be_instance_of Float end - # it "can take in reservation info as arguments: reserv_id" do - # @reservation_test.reserv_id.must_equal 1221 - # @reservation_test.reserv_id.must_be_instance_of Integer #arbitrarily deciding the id is an integer MAY NOT BE NECESSARY to include - # end - it "can take in reservation date objects as arguments: start_date, end_date" do - @reservation_test.start_date.must_equal(Date.parse("1/9/2017")) + @reservation_test.start_date.must_equal(Date.new(2017, 9, 1)) @reservation_test.start_date.must_be_instance_of Date - @reservation_test.end_date.must_equal(Date.parse("3/9/2017")) + @reservation_test.end_date.must_equal(Date.new(2017, 9, 5)) @reservation_test.end_date.must_be_instance_of Date end + it "#date_range: must return a DateRange object" do + @reservation_test.must_respond_to :date_range + @reservation_test.date_range.must_be_instance_of DateRange + end + end describe "#get_total_cost" do it "can calculate a total" do - @reservation_test.get_total_cost.must_equal 400.00 + @reservation_test.get_total_cost.must_equal 800.00 @reservation_test.get_total_cost.must_be_instance_of Float - @reservation_test.total_cost.must_equal 400.00 + @reservation_test.total_cost.must_equal 800.00 @reservation_test.total_cost.must_be_instance_of Float end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index d8b4c744f..e1369e53a 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -25,7 +25,6 @@ describe "Room.all" do it "returns a list of all room instances as an array" do all_rooms = BookingSystem::Room.all - all_rooms.must_be_instance_of Array end end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 2c4a5d7fc..ac2d6925c 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -10,9 +10,4 @@ require_relative '../lib/hotel_admin' - - - - - Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From 71c37a3b73ad8c4f952e5ae65a4ac235f4d5c14c Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 19:14:54 -0700 Subject: [PATCH 07/18] reserve room method and test revision --- lib/guest.rb => guest.rb | 0 specs/guest_spec.rb => guest_spec.rb | 0 lib/BookingSystem_Errors.rb | 2 + {specs => lib}/booking.rb | 0 lib/hotel_admin.rb | 52 ++++++++++++----- lib/reservation.rb | 25 +++++---- specs/hotel_admin_spec.rb | 83 ++++++++++++++++++++++++++++ specs/hotel_spec.rb | 75 ------------------------- specs/reservation_spec.rb | 12 ++++ specs/spec_helper.rb | 6 +- 10 files changed, 155 insertions(+), 100 deletions(-) rename lib/guest.rb => guest.rb (100%) rename specs/guest_spec.rb => guest_spec.rb (100%) create mode 100644 lib/BookingSystem_Errors.rb rename {specs => lib}/booking.rb (100%) create mode 100644 specs/hotel_admin_spec.rb delete mode 100644 specs/hotel_spec.rb diff --git a/lib/guest.rb b/guest.rb similarity index 100% rename from lib/guest.rb rename to guest.rb diff --git a/specs/guest_spec.rb b/guest_spec.rb similarity index 100% rename from specs/guest_spec.rb rename to guest_spec.rb diff --git a/lib/BookingSystem_Errors.rb b/lib/BookingSystem_Errors.rb new file mode 100644 index 000000000..9da50cf89 --- /dev/null +++ b/lib/BookingSystem_Errors.rb @@ -0,0 +1,2 @@ +class UnavailableRoomError < StandardError +end diff --git a/specs/booking.rb b/lib/booking.rb similarity index 100% rename from specs/booking.rb rename to lib/booking.rb diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 09943d517..0fc6496d4 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -1,12 +1,13 @@ -# [X]As an administrator, I can access the list of all of the rooms in the hotel -# As an administrator, I can reserve a room for a given date range -# As an administrator, I can access the list of reservations for a specific date +# [X] As an administrator, I can access the list of all of the rooms in the hotel +# [ ] As an administrator, I can reserve a room for a given date range +# [ ] As an administrator, I can access the list of reservations for a specific date # [X] As an administrator, I can get the total cost for a given reservation require 'date' require 'date_range' require_relative 'room' -require_relative 'Reservation' +require_relative 'reservation' +require_relative 'BookingSystem_Errors' module BookingSystem class HotelAdmin @@ -21,20 +22,22 @@ def initialize end def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date) + check_availability(room_id, start_date, end_date) - #check if date range for room is available reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) - @reservation_list << reservation end - # def check_availability - # # check if room is available based on date range - # raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| - # reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date - # } - # # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. - # end + def check_availability(room_id, start_date, end_date) + requested_range = DateRange.new(start_date, end_date) + + raise UnavailableRoomError.new("Date range conflicts with room requested")if @reservation_list.any? {|reservation| + reservation.room_id == room_id && reservation.date_range.include?(requested_range) && start_date < reservation.end_date + } + end + + + # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. # private @@ -54,6 +57,18 @@ def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date end#of_HotelAdmin_class end#of_module_BookingSystem + + + + + + + + + + + + =begin Date notes: @@ -62,4 +77,15 @@ def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date .between?(start_date, end_date) source: https://stackoverflow.com/questions/4521921/how-to-know-if-todays-date-is-in-a-date-range + + +VERSION1 +# def check_availability +# +# raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| +# reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date +# } +# # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. +# end + =end diff --git a/lib/reservation.rb b/lib/reservation.rb index 9016bbcee..c86219ba1 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -6,7 +6,6 @@ class Reservation attr_reader :first_name, :last_name, :room_id, :room_rate, :start_date, :end_date, :total_cost, :date_range def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) - @first_name = first_name @last_name = last_name @@ -15,16 +14,22 @@ def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) @start_date = start_date @end_date = end_date - @date_range = DateRange.new(start_date, end_date) - @total_cost = get_total_cost #returns grand_total, the result of get_total_cost + @date_range = get_date_range + @total_cost = get_total_cost end - def get_total_cost #(start_date, end_date, room_rate, room_count) would hotel use these as arguments to get total_cost? + def get_total_cost date_diff = @end_date - @start_date grand_total = date_diff * @room_rate return grand_total end + def get_date_range + raise ArgumentError.new("Invalid date range") if @end_date <= @start_date #if end_date is older or equal to start_date, raise error + range = DateRange.new(@start_date, @end_date) + return range + end + end#of_Reservation_class end#of_module_BookingSystem @@ -40,11 +45,11 @@ def get_total_cost #(start_date, end_date, room_rate, room_count) would hotel us =begin NOTES: - #DATE RANGE METHOD (VERSION1) - # def make_date_range_array - # return (@start_date .. @end_date).map{|day| day} - # end - #Modify: @date_range = make_date_range_array +#DATE RANGE METHOD (VERSION1) +# def make_date_range_array +# return (@start_date .. @end_date).map{|day| day} +# end +#Modify: @date_range = make_date_range_array - #OUTPUTS: an array of the date range +#OUTPUTS: an array of the date range =end diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb new file mode 100644 index 000000000..397aa3725 --- /dev/null +++ b/specs/hotel_admin_spec.rb @@ -0,0 +1,83 @@ +require_relative 'spec_helper' +require 'date_range' + +describe "HotelAdmin" do + before do + @hotel_admin_test = BookingSystem::HotelAdmin.new + end + + describe "initialize" do + it "can create an instance of HotelAdmin class" do + @hotel_admin_test.class.must_equal BookingSystem::HotelAdmin + end + + it "can access list of all rooms in the hotel" do + @hotel_admin_test.room_list.must_be_instance_of Array + end + + it "can access list of all reservations in hotel" do + @hotel_admin_test.reservation_list.must_be_instance_of Array + end + end + + describe "#reserve_room" do + before do + @first_name = "Jane" + @last_name = "Doe" + @room_id = 1 + @room_rate = 200.00 + @start_date = Date.new(2017, 9, 1) + @end_date = Date.new(2017, 9, 5) + + @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) + end + + it "ensures that reservation is added to all_reservations" do + @hotel_admin_test.reservation_list.any? { |reservation| + reservation.first_name == @first_name && + reservation.last_name == @last_name && + reservation.room_id == @room_id && + reservation.room_rate == @room_rate && + reservation.start_date == @start_date && + reservation.end_date == @end_date + }.must_equal true + end + + it "makes a reservation and adds it to hotel's list of reservations" do + @hotel_admin_test.reservation_list.length.must_equal 1 + end + + it "raises an error if another reservation requests an unavailable room and date range" do + proc {@hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date)}.must_raise UnavailableRoomError + end + + it do + end + + end +end#of_"HotelAdmin" + + + + + + + + + + + + + + + + + + + + + + + + +# diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb deleted file mode 100644 index ebe2801e4..000000000 --- a/specs/hotel_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -require_relative 'spec_helper' -require 'date_range' - -describe "HotelAdmin" do - before do - @hotel_admin_test = BookingSystem::HotelAdmin.new - end - - describe "initialize" do - it "can create an instance of HotelAdmin class" do - @hotel_admin_test.class.must_equal BookingSystem::HotelAdmin - end - - it "can access list of all rooms in the hotel" do - @hotel_admin_test.room_list.must_be_instance_of Array - end - - it "can access list of all reservations in hotel" do - @hotel_admin_test.reservation_list.must_be_instance_of Array - end - end - - describe "#reserve_room" do - - it "makes a reservation and adds it to hotel's list of reservations" do - first_name = "Jane" - last_name = "Doe" - - room_id = 1 - room_rate = 200.00 - - start_date = Date.parse("1/9/2017") - end_date = Date.parse("3/9/2017") - - reservation_made = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) - - reservation_made = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) - - @hotel_admin_test.reservation_list << reservation_made - - @hotel_admin_test.reservation_list.must_include reservation_made - end - - it "checks if room is available given the date range" do - reservation2 = BookingSystem::Reservation.new("J", "E", 2, 200.00, Date.parse("1/9/2017"), end_date = Date.parse("3/9/2017")) - - end - - end -end - - - - - - - - - - - - - - - - - - - - - - - - -# diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 7a8ce1c94..7925699c9 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -51,6 +51,18 @@ @reservation_test.date_range.must_be_instance_of DateRange end + it "raises an error if date range is invalid" do + first_name = "Jane" + last_name = "Doe" + + room_id = 1 + room_rate = 200.00 + + start_date = Date.new(2017, 9, 1) + end_date = Date.new(2015, 9, 5) + + proc {BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date)}.must_raise ArgumentError + end end describe "#get_total_cost" do diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index ac2d6925c..8a87e096f 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -4,10 +4,12 @@ require 'minitest' require 'minitest/autorun' require 'minitest/reporters' +require_relative '../lib/BookingSystem_Errors' require_relative '../lib/room' -require_relative '../lib/reservation' -require_relative '../lib/guest' require_relative '../lib/hotel_admin' +require_relative '../lib/reservation' +# require_relative '../lib/guest' + Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From 32f99c117ecb3cabb84e7d5a4815d2bc3f2ede97 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 19:34:41 -0700 Subject: [PATCH 08/18] reserve_room/specs and exceptions updated --- lib/BookingSystem_Errors.rb | 3 +++ lib/hotel_admin.rb | 25 ++++++------------------- specs/hotel_admin_spec.rb | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/BookingSystem_Errors.rb b/lib/BookingSystem_Errors.rb index 9da50cf89..1dfec8d1e 100644 --- a/lib/BookingSystem_Errors.rb +++ b/lib/BookingSystem_Errors.rb @@ -1,2 +1,5 @@ class UnavailableRoomError < StandardError end + +class InvalidDateRangeError < StandardError +end diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 0fc6496d4..c910433be 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -1,5 +1,5 @@ # [X] As an administrator, I can access the list of all of the rooms in the hotel -# [ ] As an administrator, I can reserve a room for a given date range +# [X] As an administrator, I can reserve a room for a given date range # [ ] As an administrator, I can access the list of reservations for a specific date # [X] As an administrator, I can get the total cost for a given reservation @@ -22,6 +22,7 @@ def initialize end def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date) + check_availability(room_id, start_date, end_date) reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) @@ -29,31 +30,17 @@ def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date end def check_availability(room_id, start_date, end_date) + + raise InvalidDateRangeError.new("Date range conflicts with room requested")if end_date < start_date + requested_range = DateRange.new(start_date, end_date) - raise UnavailableRoomError.new("Date range conflicts with room requested")if @reservation_list.any? {|reservation| + raise UnavailableRoomError.new("Room is unavailable")if @reservation_list.any? {|reservation| reservation.room_id == room_id && reservation.date_range.include?(requested_range) && start_date < reservation.end_date } end - # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. - - # private - - # def check_availability - # - # # checks all_reservations for a room id, start, and end date - # # see if room id is in reservation list - # # if room is in reservation, check to see the dates of the reservation - # # if the range of dates overlap (using the Date gem) (not including the final date of the existing reservation) - # # then return false - # # Otherwise, return true - # end - - - - end#of_HotelAdmin_class end#of_module_BookingSystem diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index 397aa3725..2dc2a5dc6 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -47,13 +47,23 @@ @hotel_admin_test.reservation_list.length.must_equal 1 end - it "raises an error if another reservation requests an unavailable room and date range" do - proc {@hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date)}.must_raise UnavailableRoomError + it "raises an error for an invalid date range" do + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2015, 9, 5)) }.must_raise InvalidDateRangeError end - it do + it "raises an error if another reservation requests an unavailable room because of dates overlapping" do + #this should raise an error because the same reservation was booked in the before block + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) }.must_raise UnavailableRoomError + + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 2)) }.must_raise UnavailableRoomError + end + + it "will allow booking for a room if requested start_date is on the end_date of a previous booking" do + @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) + @hotel_admin_test.reservation_list.length.must_equal 2 end + end end#of_"HotelAdmin" From 9e54690801c37ec2bdde17f9ece906529dcd4a7b Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 20:32:30 -0700 Subject: [PATCH 09/18] raised InvalidDateErrors for reservation --- lib/BookingSystem_Errors.rb | 3 +++ lib/hotel_admin.rb | 18 ++++++++++++++++-- lib/reservation.rb | 4 ++++ specs/hotel_admin_spec.rb | 33 +++++++++++++++++++++++---------- specs/reservation_spec.rb | 4 ++++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/lib/BookingSystem_Errors.rb b/lib/BookingSystem_Errors.rb index 1dfec8d1e..206d7e006 100644 --- a/lib/BookingSystem_Errors.rb +++ b/lib/BookingSystem_Errors.rb @@ -3,3 +3,6 @@ class UnavailableRoomError < StandardError class InvalidDateRangeError < StandardError end + +class InvalidDateError Date: Sun, 10 Sep 2017 21:51:54 -0700 Subject: [PATCH 10/18] W2 rb and specs updated and reviewed --- lib/hotel_admin.rb | 58 ++++++++++++++++++++++++++++++--------- lib/reservation.rb | 4 +-- specs/hotel_admin_spec.rb | 24 ++++++++++++++-- specs/reservation_spec.rb | 21 ++++++-------- 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 2486f3f2d..9c8a9fbc4 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -2,8 +2,8 @@ # [X] As an administrator, I can get the total cost for a given reservation # [X] As an administrator, I can reserve a room for a given date range # [X] As an administrator, I can reserve an available room for a given date range -# [ ] As an administrator, I can access the list of reservations for a specific date -# [] As an administrator, I can view a list of rooms that are not reserved for a given date range +# [X] As an administrator, I can access the list of reservations for a specific date +# [X] As an administrator, I can view a list of rooms that are not reserved for a given date range require 'date' @@ -54,6 +54,25 @@ def find_reservations_by_date(specific_date) return reservations_on_date end + def rooms_available_for_date_range(date_range) + + raise InvalidDateRangeError.new("Range must be a DateRange object") if !date_range.is_a? DateRange + + unavailable_room_ids = [] + + @reservation_list.each do |reservation| + if reservation.date_range.include?(date_range) + unavailable_room_ids << reservation.room_id + end + end + + available_rooms = @room_list.reject { |room| unavailable_room_ids.include?(room.id) } + + return available_rooms + end + + + end#of_HotelAdmin_class end#of_module_BookingSystem @@ -68,6 +87,30 @@ def find_reservations_by_date(specific_date) +# REFACTORED METHODS: +# def rooms_available_for_date_range(date_range) +# raise InvalidDateRangeError.new("Range must be a DateRange object") if !date_range.is_a? DateRange +# +# unavailable_room_ids = [] +# +# @reservation_list.each do |reservation| +# if reservation.date_range.include?(date_range) +# unavailable_room_ids << reservation.room_id +# end +# end +# +# available_rooms = [] +# +# @room_list.each do |room| +# if unavailable_room_ids.include?(room.id) == false +# available_rooms << room +# end +# end +# +# return available_rooms +# end + + =begin @@ -78,15 +121,4 @@ def find_reservations_by_date(specific_date) .between?(start_date, end_date) source: https://stackoverflow.com/questions/4521921/how-to-know-if-todays-date-is-in-a-date-range - - -VERSION1 -# def check_availability -# -# raise ArgumentError.new("Dates conflict with room requested") if @all_reservations.any? { |reservation| -# reservation.room_id == room_id && start_date.between?(reservation.start_date, reservation.end_date) && start_date < reservation.end_date -# } -# # If the new reservation's start date exists in between the existing reservation's start and end dates, and does not land on its end date, then we reject the reservation. -# end - =end diff --git a/lib/reservation.rb b/lib/reservation.rb index b488433df..dc9db240d 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -17,7 +17,7 @@ def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) raise InvalidDateError.new("End date is not a valid date object") if !end_date.is_a? Date @end_date = end_date - + @date_range = get_date_range @total_cost = get_total_cost end @@ -29,7 +29,7 @@ def get_total_cost end def get_date_range - raise ArgumentError.new("Invalid date range") if @end_date <= @start_date #if end_date is older or equal to start_date, raise error + raise InvalidDateRangeError.new("Invalid date range") if @end_date <= @start_date #if end_date is older or equal to start_date, raise error range = DateRange.new(@start_date, @end_date) return range end diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index a183154e3..471ef5e44 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -64,9 +64,8 @@ end describe "#find_reservations_by_date" do - before do - #including initial reservation: @hotel_admin_test.reserve_room(@first_name, @last_name, 1, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + #include: @hotel_admin_test.reserve_room(@first_name, @last_name, 1, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) @hotel_admin_test.reserve_room(@first_name, @last_name, 1, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) @hotel_admin_test.reserve_room(@first_name, @last_name, 2, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) @hotel_admin_test.reserve_room(@first_name, @last_name, 3, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) @@ -78,6 +77,27 @@ @hotel_admin_test.find_reservations_by_date(Date.new(2017, 9, 5)).length.must_equal 5 end end + + describe "#rooms_available_for_date_range" do + before do + #include: @hotel_admin_test.reserve_room(@first_name, @last_name, 1, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @hotel_admin_test.reserve_room(@first_name, @last_name, 2, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @hotel_admin_test.reserve_room(@first_name, @last_name, 3, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @hotel_admin_test.reserve_room(@first_name, @last_name, 4, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + end + + it "ensures given date range argument is a DateRange object" do + proc { @hotel_admin_test.rooms_available_for_date_range("range") }.must_raise InvalidDateRangeError + end + + it "provides list of rooms available for a given date range " do + start_date = Date.new(2017, 9, 1) + end_date = Date.new(2017, 9, 5) + range = DateRange.new(start_date, end_date) + @hotel_admin_test.rooms_available_for_date_range(range).must_be_instance_of Array + @hotel_admin_test.rooms_available_for_date_range(range).length.must_equal(16) + end + end end#of_"HotelAdmin" diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 88723a6cb..49e415892 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -4,16 +4,16 @@ describe "Reservation" do before do - first_name = "Jane" - last_name = "Doe" + @first_name = "Jane" + @last_name = "Doe" - room_id = 1 - room_rate = 200.00 + @room_id = 1 + @room_rate = 200.00 - start_date = Date.new(2017, 9, 1) #Date.new(YYYY, M, D) - end_date = Date.new(2017, 9, 5) + @start_date = Date.new(2017, 9, 1) #Date.new(YYYY, M, D) + @end_date = Date.new(2017, 9, 5) - @reservation_test = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + @reservation_test = BookingSystem::Reservation.new(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) end describe "#initialize" do @@ -56,16 +56,11 @@ end it "raises an error if date range is invalid" do - first_name = "Jane" - last_name = "Doe" - - room_id = 1 - room_rate = 200.00 start_date = Date.new(2017, 9, 1) end_date = Date.new(2015, 9, 5) - proc {BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date)}.must_raise ArgumentError + proc {BookingSystem::Reservation.new(@first_name, @last_name, @room_id, @room_rate, start_date, end_date)}.must_raise InvalidDateRangeError end end From 5d9d076a481e16eafa6fbe1ca947154df984a30b Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 22:07:47 -0700 Subject: [PATCH 11/18] back up --- .DS_Store | Bin 0 -> 6148 bytes lib/booking.rb | 13 ------------- specs/spec_helper.rb | 1 - 3 files changed, 14 deletions(-) create mode 100644 .DS_Store delete mode 100644 lib/booking.rb diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1ad899dbcdc748036dd701eacb0ec11e243703d4 GIT binary patch literal 6148 zcmeHKyJ`bL3>+mc4$`I(2Sbbi#2M3J zT*oXyY@Q(Y!ZDE|1kgGlC+ZoQs7@HV6)|Fx!@~RZ=JlH_u58Z)4k@C?#6Xc7@{2$qaAbO f?f5y0vab1>=e=-D3_9~cC+cUwb&*MdzgFN1-fR_w literal 0 HcmV?d00001 diff --git a/lib/booking.rb b/lib/booking.rb deleted file mode 100644 index fe4ad72e0..000000000 --- a/lib/booking.rb +++ /dev/null @@ -1,13 +0,0 @@ -# require 'date' -# require_relative '../lib/room' -# require_relative '../lib/reservation' -# require_relative '../lib/hotel' -# -# -# hotel = BookingSystem::HotelAdmin.new -# -# puts hotel.all_reservations -# -# hotel.make_reservation("Jane", "Doe", 1, 200.00, Date.parse("1/9/2017"), Date.parse("3/9/2017")) -# -# puts hotel.all_reservations diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 8a87e096f..0d4923a7c 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -8,7 +8,6 @@ require_relative '../lib/room' require_relative '../lib/hotel_admin' require_relative '../lib/reservation' -# require_relative '../lib/guest' From ffee5673e2c4e4d57ee856faa66c7a5141352ac7 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 23:36:33 -0700 Subject: [PATCH 12/18] added block_id with default value nil --- lib/BookingSystem_Errors.rb | 3 +++ lib/block.rb | 27 +++++++++++++++++++++++++ lib/hotel_admin.rb | 6 ++++++ lib/reservation.rb | 2 +- specs/block_spec.rb | 40 +++++++++++++++++++++++++++++++++++++ specs/hotel_admin_spec.rb | 25 +++++++++++++++++++++++ specs/reservation_spec.rb | 4 +++- specs/spec_helper.rb | 1 + 8 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 lib/block.rb create mode 100644 specs/block_spec.rb diff --git a/lib/BookingSystem_Errors.rb b/lib/BookingSystem_Errors.rb index 206d7e006..9fced9b35 100644 --- a/lib/BookingSystem_Errors.rb +++ b/lib/BookingSystem_Errors.rb @@ -6,3 +6,6 @@ class InvalidDateRangeError < StandardError class InvalidDateError 5 + @rooms_array = rooms_array + + raise ArgumentError.new("Room rate discount must be a float") if !discount_room_rate.is_a? Float + @discount_room_rate = discount_room_rate + end + + end#of_Block_class +end#of_module_BookingSystem diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 9c8a9fbc4..6ada7f72d 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -5,6 +5,12 @@ # [X] As an administrator, I can access the list of reservations for a specific date # [X] As an administrator, I can view a list of rooms that are not reserved for a given date range +# [] As an administrator, I can create a block of rooms +# [] To create a block you need a date range, collection of rooms and a discounted room rate +# [] The collection of rooms should only include rooms that are available for the given date range +# [] If a room is set aside in a block, it can't be reserved by the general public, nor can it be included in another block +# [] As an administrator, I can check whether a given block (needs block_id) has any rooms available +# [] As an administrator, I can reserve a room from within a block of rooms require 'date' require 'date_range' diff --git a/lib/reservation.rb b/lib/reservation.rb index dc9db240d..fd91116b5 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -5,7 +5,7 @@ module BookingSystem class Reservation attr_reader :first_name, :last_name, :room_id, :room_rate, :start_date, :end_date, :total_cost, :date_range - def initialize(first_name, last_name, room_id, room_rate, start_date, end_date) + def initialize(first_name, last_name, room_id, room_rate, start_date, end_date, block_id = nil) @first_name = first_name @last_name = last_name diff --git a/specs/block_spec.rb b/specs/block_spec.rb new file mode 100644 index 000000000..49be8f2b7 --- /dev/null +++ b/specs/block_spec.rb @@ -0,0 +1,40 @@ +require_relative 'spec_helper' +require 'date_range' + +describe "Block Class" do + + describe "#initialize" do + before do + @block_id = "Block1" + @date_range = DateRange.new(Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @rooms_array = [1, 2, 3, 4, 5] + @discount_room_rate = 0.20 + + @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate) + end + + it "can create a block of rooms using a date range, collection of rooms and a discounted room rate" do + @block.must_be_instance_of BookingSystem::Block + end + + it "ensures block_id argument is a String" do + proc { BookingSystem::Block.new(12345, @date_range, @rooms_array, @discount_room_rate) }.must_raise ArgumentError + end + + it "ensures date range argument is a DateRange object" do + proc { BookingSystem::Block.new(@block_id, "date_range", @rooms_array, @discount_room_rate) }.must_raise InvalidDateRangeError + end + + it "ensures collection of rooms argument is an array" do + proc { BookingSystem::Block.new(@block_id, @date_range, "rooms_array", @discount_room_rate) }.must_raise ArgumentError + end + + it "ensures collection of rooms argument array length cannot be greater than 5" do + proc { BookingSystem::Block.new(@block_id, @date_range, [1, 2, 3, 4, 5, 6], @discount_room_rate) }.must_raise BlockError + end + + it "ensures room discount argument is a float" do + proc { BookingSystem::Block.new(@block_id, @date_range, @rooms_array, "discount_room_rate") }.must_raise ArgumentError + end + end +end#of_"Block Class" diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index 471ef5e44..a453bc593 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -98,6 +98,31 @@ @hotel_admin_test.rooms_available_for_date_range(range).length.must_equal(16) end end + + describe "#reserve_block" do + before do + @hotel_admin_test = BookingSystem::HotelAdmin.new + + @block_id = "Block1" + @date_range = DateRange.new(Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @rooms_array = [ + BookingSystem::Room.new(1, 200.00), + BookingSystem::Room.new(2, 200.00), + BookingSystem::Room.new(3, 200.00), + BookingSystem::Room.new(4, 200.00), + BookingSystem::Room.new(5, 200.00)] + @discount_room_rate = 0.20 + + + @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate) + end + # + # it "makes a block reservation and adds it to hotel's list of block reservations" do + # @hotel_admin_test.block_reservation_list.length.must_equal 1 + # end + + end + end#of_"HotelAdmin" diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 49e415892..6fd284c37 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -13,7 +13,9 @@ @start_date = Date.new(2017, 9, 1) #Date.new(YYYY, M, D) @end_date = Date.new(2017, 9, 5) - @reservation_test = BookingSystem::Reservation.new(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) + @block_id = "Block1" + + @reservation_test = BookingSystem::Reservation.new(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date, @block_id) end describe "#initialize" do diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 0d4923a7c..98ed1de41 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -4,6 +4,7 @@ require 'minitest' require 'minitest/autorun' require 'minitest/reporters' +require_relative '../lib/block' require_relative '../lib/BookingSystem_Errors' require_relative '../lib/room' require_relative '../lib/hotel_admin' From 9582bb37c31cf710dd06b64319ffa000b38ce08b Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sun, 10 Sep 2017 23:46:56 -0700 Subject: [PATCH 13/18] reserve_block --- lib/hotel_admin.rb | 21 ++++++++++++++------- specs/hotel_admin_spec.rb | 8 ++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 6ada7f72d..d78bb6703 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -21,34 +21,41 @@ module BookingSystem class HotelAdmin - attr_reader :room_list, :reservation_list + attr_reader :room_list, :reservation_list, :block_reservation_list def initialize - #hotel admin knows all collection of reservations + #hotel admin knows all reservations (non-block and block) @reservation_list = [] + @block_reservation_list = [] #hotel admin knows all rooms in hotel @room_list = BookingSystem::Room.all end - def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date) + def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date, block_id = nil) - check_availability(room_id, start_date, end_date) + check_availability(room_id, start_date, end_date, block_id) - reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date) + reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date, block_id) @reservation_list << reservation end - def check_availability(room_id, start_date, end_date) + def check_availability(room_id, start_date, end_date, block_id) raise InvalidDateRangeError.new("Date range conflicts with room requested")if end_date <= start_date - requested_range = DateRange.new(start_date, end_date) + # if block_id == nil + # + # + # end + raise UnavailableRoomError.new("Room is unavailable")if @reservation_list.any? {|reservation| reservation.room_id == room_id && reservation.date_range.include?(requested_range) && start_date < reservation.end_date } end + + def find_reservations_by_date(specific_date) reservations_on_date = [] @reservation_list.each do |reservation| diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index a453bc593..041bca523 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -24,9 +24,13 @@ @hotel_admin_test.room_list.must_be_instance_of Array end - it "can access list of all reservations in hotel" do + it "can access list of all (non-block) reservations in hotel" do @hotel_admin_test.reservation_list.must_be_instance_of Array end + + it "can access list of block reservations in hotel" do + @hotel_admin_test.block_reservation_list.must_be_instance_of Array + end end describe "#reserve_room" do @@ -116,7 +120,7 @@ @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate) end - # + # it "makes a block reservation and adds it to hotel's list of block reservations" do # @hotel_admin_test.block_reservation_list.length.must_equal 1 # end From 5f29e401f1a88f07acdf675622e774494f3b3a7d Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Mon, 11 Sep 2017 01:20:25 -0700 Subject: [PATCH 14/18] reserve block and room revision --- lib/block.rb | 5 ++ lib/hotel_admin.rb | 43 ++++++++----- specs/block_spec.rb | 7 ++- specs/hotel_admin_spec.rb | 123 ++++++++++++++++++++++---------------- 4 files changed, 108 insertions(+), 70 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index a239c12d3..f1799f3b8 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -23,5 +23,10 @@ def initialize(block_id, date_range, rooms_array, discount_room_rate) @discount_room_rate = discount_room_rate end + def list_room_ids + room_ids = @rooms_array.map { |room| room.id } + return room_ids + end + end#of_Block_class end#of_module_BookingSystem diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index d78bb6703..8faf11e4d 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -21,41 +21,52 @@ module BookingSystem class HotelAdmin - attr_reader :room_list, :reservation_list, :block_reservation_list + attr_reader :room_list, :reservation_list, :block_list def initialize #hotel admin knows all reservations (non-block and block) @reservation_list = [] - @block_reservation_list = [] + @block_list = [] #hotel admin knows all rooms in hotel @room_list = BookingSystem::Room.all end def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date, block_id = nil) - check_availability(room_id, start_date, end_date, block_id) + raise InvalidDateRangeError.new("Date range conflicts with room requested") if end_date <= start_date + requested_range = DateRange.new(start_date, end_date) + + if block_id.nil? #if a room doesn't have a block_id, blacklist all rooms that are blocked + raise UnavailableRoomError.new("Room is unavailable") if @block_list.any? do |block| + block.date_range.overlaps?(requested_range) && block.rooms_array.any? { |room| room.id == room_id } + end + end + + raise UnavailableRoomError.new("Room is unavailable") if @reservation_list.any? {|reservation| + reservation.room_id == room_id && reservation.date_range.overlaps?(requested_range) && start_date < reservation.end_date + } reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date, block_id) @reservation_list << reservation end - def check_availability(room_id, start_date, end_date, block_id) - raise InvalidDateRangeError.new("Date range conflicts with room requested")if end_date <= start_date - requested_range = DateRange.new(start_date, end_date) + def reserve_block(block_id, date_range, rooms_array, discount_room_rate) - # if block_id == nil - # - # - # end + if @block_list.any? { |block| block.date_range.overlaps?(date_range) } + @block_list.each do |block| + rooms_array.each do |room| + if block.list_room_ids.include?(room.id) + raise UnavailableRoomError.new("Room is unavailable") + end + end + end + end - raise UnavailableRoomError.new("Room is unavailable")if @reservation_list.any? {|reservation| - reservation.room_id == room_id && reservation.date_range.include?(requested_range) && start_date < reservation.end_date - } + block = BookingSystem::Block.new(block_id, date_range, rooms_array, discount_room_rate) + @block_list << block end - - def find_reservations_by_date(specific_date) reservations_on_date = [] @reservation_list.each do |reservation| @@ -74,7 +85,7 @@ def rooms_available_for_date_range(date_range) unavailable_room_ids = [] @reservation_list.each do |reservation| - if reservation.date_range.include?(date_range) + if reservation.date_range.overlaps?(date_range) unavailable_room_ids << reservation.room_id end end diff --git a/specs/block_spec.rb b/specs/block_spec.rb index 49be8f2b7..ce7e806cf 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -7,7 +7,12 @@ before do @block_id = "Block1" @date_range = DateRange.new(Date.new(2017, 9, 1), Date.new(2017, 9, 5)) - @rooms_array = [1, 2, 3, 4, 5] + @rooms_array = [ + BookingSystem::Room.new(1, 200.00), + BookingSystem::Room.new(2, 200.00), + BookingSystem::Room.new(3, 200.00), + BookingSystem::Room.new(4, 200.00), + BookingSystem::Room.new(5, 200.00)] @discount_room_rate = 0.20 @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate) diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index 041bca523..2b2da8343 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -28,42 +28,8 @@ @hotel_admin_test.reservation_list.must_be_instance_of Array end - it "can access list of block reservations in hotel" do - @hotel_admin_test.block_reservation_list.must_be_instance_of Array - end - end - - describe "#reserve_room" do - - it "ensures that reservation is added to all_reservations" do - @hotel_admin_test.reservation_list.any? { |reservation| - reservation.first_name == @first_name && - reservation.last_name == @last_name && - reservation.room_id == @room_id && - reservation.room_rate == @room_rate && - reservation.start_date == @start_date && - reservation.end_date == @end_date - }.must_equal true - end - - it "makes a reservation and adds it to hotel's list of reservations" do - @hotel_admin_test.reservation_list.length.must_equal 1 - end - - it "raises an error for an invalid date range" do - proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2015, 9, 5)) }.must_raise InvalidDateRangeError - end - - it "raises an error if another reservation requests an unavailable room because of dates overlapping" do - #this should raise an error because the same reservation was booked in the before block - proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) }.must_raise UnavailableRoomError - - proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 2)) }.must_raise UnavailableRoomError - end - - it "will allow booking for a room if requested start_date is on the end_date of a previous booking" do - @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) - @hotel_admin_test.reservation_list.length.must_equal 2 + it "can access list of blocks in hotel" do + @hotel_admin_test.block_list.must_be_instance_of Array end end @@ -103,31 +69,82 @@ end end - describe "#reserve_block" do + describe "#reserve_room" do before do - @hotel_admin_test = BookingSystem::HotelAdmin.new - @block_id = "Block1" @date_range = DateRange.new(Date.new(2017, 9, 1), Date.new(2017, 9, 5)) @rooms_array = [ - BookingSystem::Room.new(1, 200.00), - BookingSystem::Room.new(2, 200.00), - BookingSystem::Room.new(3, 200.00), - BookingSystem::Room.new(4, 200.00), - BookingSystem::Room.new(5, 200.00)] - @discount_room_rate = 0.20 - + BookingSystem::Room.new(10, 200.00), + BookingSystem::Room.new(11, 200.00), + BookingSystem::Room.new(12, 200.00), + BookingSystem::Room.new(13, 200.00), + BookingSystem::Room.new(14, 200.00)] + @discount_room_rate = 0.20 + + @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate) + end + + it "ensures that reservation is added to all_reservations" do + @hotel_admin_test.reservation_list.any? { |reservation| + reservation.first_name == @first_name && + reservation.last_name == @last_name && + reservation.room_id == @room_id && + reservation.room_rate == @room_rate && + reservation.start_date == @start_date && + reservation.end_date == @end_date + }.must_equal true + end + + it "makes a reservation and adds it to hotel's list of reservations" do + @hotel_admin_test.reservation_list.length.must_equal 1 + end + + it "raises an error for an invalid date range" do + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2015, 9, 5)) }.must_raise InvalidDateRangeError + end + + it "raises an error if another reservation requests an unavailable room because of dates overlapping" do + #this should raise an error because the same reservation was booked in the before block + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, @start_date, @end_date) }.must_raise UnavailableRoomError + + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 2)) }.must_raise UnavailableRoomError + end + + # it "cannot reserve a room that's in a block with same date range and room id" do + # proc { @hotel_admin_test.reserve_room(@first_name, @last_name, 10, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) }.must_raise UnavailableRoomError + # end + + it "will allow booking for a room if requested start_date is on the end_date of a previous booking" do + @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) + @hotel_admin_test.reservation_list.length.must_equal 2 + end - @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate) end - # it "makes a block reservation and adds it to hotel's list of block reservations" do - # @hotel_admin_test.block_reservation_list.length.must_equal 1 - # end + describe "#reserve_block" do + before do + @hotel_admin_test = BookingSystem::HotelAdmin.new - end + @block_id = "Block1" + @date_range = DateRange.new(Date.new(2017, 9, 1), Date.new(2017, 9, 5)) + @rooms_array = [ + BookingSystem::Room.new(1, 200.00), + BookingSystem::Room.new(2, 200.00), + BookingSystem::Room.new(3, 200.00), + BookingSystem::Room.new(4, 200.00), + BookingSystem::Room.new(5, 200.00)] + @discount_room_rate = 0.20 + + @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate) + end + + it "makes a block reservation and adds it to hotel's list of block reservations" do + @hotel_admin_test.block_list.length.must_equal 1 + end + + end -end#of_"HotelAdmin" + end#of_"HotelAdmin" @@ -152,4 +169,4 @@ -# + # From 4e1fbc7180980f2f95606212809dfabe2916a893 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Mon, 11 Sep 2017 01:40:03 -0700 Subject: [PATCH 15/18] comments update --- lib/hotel_admin.rb | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 8faf11e4d..172efbd77 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -1,17 +1,3 @@ -# [X] As an administrator, I can access the list of all of the rooms in the hotel -# [X] As an administrator, I can get the total cost for a given reservation -# [X] As an administrator, I can reserve a room for a given date range -# [X] As an administrator, I can reserve an available room for a given date range -# [X] As an administrator, I can access the list of reservations for a specific date -# [X] As an administrator, I can view a list of rooms that are not reserved for a given date range - -# [] As an administrator, I can create a block of rooms -# [] To create a block you need a date range, collection of rooms and a discounted room rate -# [] The collection of rooms should only include rooms that are available for the given date range -# [] If a room is set aside in a block, it can't be reserved by the general public, nor can it be included in another block -# [] As an administrator, I can check whether a given block (needs block_id) has any rooms available -# [] As an administrator, I can reserve a room from within a block of rooms - require 'date' require 'date_range' require_relative 'room' From 8e1219e19d12fa2a507b153632cca276d643365f Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Thu, 28 Sep 2017 20:25:37 -0700 Subject: [PATCH 16/18] design-activity.md responses --- .DS_Store | Bin 6148 -> 6148 bytes design-activity.md | 79 ++++++++++++++++++++++++++++++++++++++ specs/hotel_admin_spec.rb | 6 +-- 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 design-activity.md diff --git a/.DS_Store b/.DS_Store index 1ad899dbcdc748036dd701eacb0ec11e243703d4..1a69ece39929f67266e74dae84c505b9a3fe8b8b 100644 GIT binary patch delta 371 zcmZoMXfc=|#>B)qu~2NHo}wrd0|Nsi1A_nqLlHwFLpnohQh9N~#*NDvCmV>c)N?Q- zGvqUrF{C2PCgtQO0d;*%D#*z!E-^5;!N|nS!pg?Z!O6+Z!^y+X6C0e7UmjeNSW;T- zlvorE;sqp@WF#dP#S6#;XQreAS>c%}B^e>9d9FFBWvO}oMLvlosSu?h`T03O1t4wp zZC-aNwf)s*+k)Z)XgLQ8X5!t{zv4I5u DF!E#W delta 88 zcmZoMXfc=|#>CJzu~2NHo}wrt0|NsP3otMgF(fjiGo+RU7v)VXRA*$|tjPR~Wpe=Y nRHn`B9Q+(WEt?&gzcWwf7t!Se={f+!43lkmq<iEMW!!jSdt> diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..f506655d7 --- /dev/null +++ b/design-activity.md @@ -0,0 +1,79 @@ +# Hotel Revisited + +## Prompts: Responses + +* What classes does each implementation include? Are the lists the same? + +While both implementations A & B have the following classes: CartEntry, ShoppingCart, their list of classes are not the same. Implementation A's CartEntry class uses attr accessors for its unit_price and quantity, so its Order class can access those values when calculating the total price for each entry in the cart. Implementation B on the other hand does not use attr accessors and instead, has a price calculation method for each class such that: CartEntry has a price method to calculate each price per cart entry, the ShoppingCart has a price method to sum all cart entries in the cart (subtotal), and Order has a total_price method that adds SALES_TAX to the ShoppingCart's subtotal. + +* Write down a sentence to describe each class. + * CartEntry defines the state (unit_price and quantity) and behavior (price in implementation B) of each cart entry requested. + * ShoppingCart defines the ShoppingCart object that's initialized as an array to store cart entries for one order. + * Order creates an order (initialized as an instance of a ShoppingCart) and handles total_price calculation (using the SALES_TAX). + +* How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. + +The classes relate to each in that an instance of an Order is made up of an instance of a ShoppingCart (called cart), where the cart is an array that stores any number of CartEntry instances. + +* What data does each class store? How (if at all) does this differ between the two implementations? +* What methods does each class have? How (if at all) does this differ between the two implementations? + + * Implementation A: + CartEntry: unit_price and quantity (with attr accessors) + ShoppingCart: entries (array - with attr accessors) + Order: SALES_TAX, total_price method + + * Implementation B: + CartEntry: unit_price, quantity, CartEntry price method + ShoppingCart: entries (array - no attr accessors), ShoppingCart subtotal price method + Order: SALES_TAX, total_price method + + * Differences: + - Implementation A delegates all price calculation to the Order class, while B has some level of price calculated within each class. + - Implementation A makes use of attr accessors (interestingly rather than attr readers) and only uses one pricing method (total_price) in the Order class. Conversely, B does not us any attr accessors (I'm assuming to limit users ability to manipulate CartEntry data) and implements a price method for both CartEntry and ShoppingCart to access each objects' prices. + +* Consider the Order#total_price method. In each implementation: + * Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order? + A does not delegate the price computation responsibility to "lower level" classes; it is all retained in Order. B does delegate price computation to ShoppingCart and CartEntry so that its Order class only deals with adding the SALES_TAX to the ShoppingCart price. + + * Does total_price directly manipulate the instance variables of other classes? + A's total_price directly references the instance variables for the ShoppingCart (entries) and CartEntry (unit_price and quantity), but it takes their values and stores it in the variable sum. So in that way, while it is not directly changing the variables, there is potential to manipulate them because they are being accessed using attr accessors. B only references the ShoppingCart price (using the price method), so this implementation does not directly manipulate any instance variables. + +* If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + +Implementation B would be easier to change because you could add additional code in CartEntry to account for cheaper cost when buying items in bulk. + +* Which implementation better adheres to the single responsibility principle? + +Implementation B appears to better adhere to the single responsibility principle because its classes (particularly Order and its total_price method) have less dependencies on its other classes. For example, it doesn't know/reference nearly as many objects and instance variables as A does in its total_price method. This is ideal because it reduces the potential for bugs and makes the code more adaptable. + +Furthermore, before considering how we'd modify the code to consider bulk items, I thought A good in that it appeared DRY because it was consolidating and delegating all price calculations in Order (so you could just update price calculations all in one place), but now that I've had to also consider buying items in bulk and potential areas of price changes, it makes sense to break up the price calculation responsibilities. + +* Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? +Implementation B is more loosely coupled because its Order class does not reference and knows less about the other classes (e.g. it doesn't reference any CartEntry objects like A). + + + + + + + + + + + + + + + + + + + + + + + + + +######## diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index 2b2da8343..40dccd8d9 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -110,9 +110,9 @@ proc { @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 2)) }.must_raise UnavailableRoomError end - # it "cannot reserve a room that's in a block with same date range and room id" do - # proc { @hotel_admin_test.reserve_room(@first_name, @last_name, 10, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) }.must_raise UnavailableRoomError - # end + it "cannot reserve a room that's in a block with same date range and room id" do + proc { @hotel_admin_test.reserve_room(@first_name, @last_name, 10, @room_rate, Date.new(2017, 9, 1), Date.new(2017, 9, 5)) }.must_raise UnavailableRoomError + end it "will allow booking for a room if requested start_date is on the end_date of a previous booking" do @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) From b6b3a0fd06e52241f564745469af876fbff9ac53 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Thu, 28 Sep 2017 23:16:02 -0700 Subject: [PATCH 17/18] revised hotel_admin rb and spec to check for existing reservation overlaps --- lib/block.rb | 8 +++++++- lib/hotel_admin.rb | 9 +++++---- lib/test.rb | 4 ++++ 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 lib/test.rb diff --git a/lib/block.rb b/lib/block.rb index f1799f3b8..64513a54b 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -8,7 +8,13 @@ class Block attr_reader :block_id, :date_range, :rooms_array, :discount_room_rate - def initialize(block_id, date_range, rooms_array, discount_room_rate) + def initialize(block_id, date_range, rooms_array, discount_room_rate, reservation_list) + raise UnavailableRoomError.new("Room is unavailable") if reservation_list.any? {|reservation| + rooms_array.include?(reservation.room_id) && + # !(reservation.start_date >= date_range.last || reservation.end_date <= date_range.first) + reservation.date_range.overlaps?(date_range) && date_range.first < reservation.end_date + } + raise ArgumentError.new("Block ID must be a string") if !block_id.is_a? String @block_id = block_id diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 172efbd77..33ccb940c 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -19,7 +19,6 @@ def initialize def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date, block_id = nil) - raise InvalidDateRangeError.new("Date range conflicts with room requested") if end_date <= start_date requested_range = DateRange.new(start_date, end_date) if block_id.nil? #if a room doesn't have a block_id, blacklist all rooms that are blocked @@ -30,14 +29,16 @@ def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date raise UnavailableRoomError.new("Room is unavailable") if @reservation_list.any? {|reservation| reservation.room_id == room_id && reservation.date_range.overlaps?(requested_range) && start_date < reservation.end_date + # reservation.room_id == room_id && + # !(reservation.start_date >= end_date || reservation.end_date <= start_date) } reservation = BookingSystem::Reservation.new(first_name, last_name, room_id, room_rate, start_date, end_date, block_id) @reservation_list << reservation end - - def reserve_block(block_id, date_range, rooms_array, discount_room_rate) + # Hotel Revisted Changes + def reserve_block(block_id, date_range, rooms_array, discount_room_rate, reservation_list) if @block_list.any? { |block| block.date_range.overlaps?(date_range) } @block_list.each do |block| @@ -49,7 +50,7 @@ def reserve_block(block_id, date_range, rooms_array, discount_room_rate) end end - block = BookingSystem::Block.new(block_id, date_range, rooms_array, discount_room_rate) + block = BookingSystem::Block.new(block_id, date_range, rooms_array, discount_room_rate, @reservation_list) @block_list << block end diff --git a/lib/test.rb b/lib/test.rb new file mode 100644 index 000000000..08d20f531 --- /dev/null +++ b/lib/test.rb @@ -0,0 +1,4 @@ +require 'date' +require 'date_range' + +puts (Date.new(2012, 01, 01)..Date.new(2012, 01, 30)).last From 0541e8046c7a8cc07e916947cc5308bac0b8f761 Mon Sep 17 00:00:00 2001 From: Jan Edrozo Date: Sat, 30 Sep 2017 22:51:04 -0700 Subject: [PATCH 18/18] Revisiting Hotel Activity and decoupling changes updated --- design-activity.md | 5 ++++- lib/block.rb | 4 +++- lib/hotel_admin.rb | 6 ++---- lib/reservation.rb | 1 + lib/test.rb | 4 ---- specs/block_spec.rb | 13 +++++++------ specs/hotel_admin_spec.rb | 15 +++++++++------ 7 files changed, 26 insertions(+), 22 deletions(-) delete mode 100644 lib/test.rb diff --git a/design-activity.md b/design-activity.md index f506655d7..cb63f1a7b 100644 --- a/design-activity.md +++ b/design-activity.md @@ -50,9 +50,12 @@ Implementation B appears to better adhere to the single responsibility principle Furthermore, before considering how we'd modify the code to consider bulk items, I thought A good in that it appeared DRY because it was consolidating and delegating all price calculations in Order (so you could just update price calculations all in one place), but now that I've had to also consider buying items in bulk and potential areas of price changes, it makes sense to break up the price calculation responsibilities. * Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? -Implementation B is more loosely coupled because its Order class does not reference and knows less about the other classes (e.g. it doesn't reference any CartEntry objects like A). +Implementation B is more loosely coupled because its Order class does not reference and knows less about the other classes (e.g. it doesn't reference any CartEntry objects like A). +## Revisiting Hotel Activity: + +HotelAdmin is currently tightly coupled with my block and reservation classes. For example, I had date validation for reservations made in both my HotelAdmin and Reservation. I've changed it so now only my Reservation class handles date validation. Previously, I'd also planned for the HotelAdmin class to check if a block would conflict with an existing reservation before attempting to create the block. To decouple this area of logic, now the HotelAdmin class just creates a block while the block class performs the validation to decide if there is a conflict with an existing reservation. diff --git a/lib/block.rb b/lib/block.rb index 64513a54b..6d51f6350 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -9,9 +9,11 @@ class Block attr_reader :block_id, :date_range, :rooms_array, :discount_room_rate def initialize(block_id, date_range, rooms_array, discount_room_rate, reservation_list) + + #Hotel Revisted Changes: Checks the reservation for any date range that would overlap with the block_id's date_range and throws an error if it detects an overlap raise UnavailableRoomError.new("Room is unavailable") if reservation_list.any? {|reservation| rooms_array.include?(reservation.room_id) && - # !(reservation.start_date >= date_range.last || reservation.end_date <= date_range.first) + #overlaps? same as: !(reservation.start_date >= date_range.last || reservation.end_date <= date_range.first) reservation.date_range.overlaps?(date_range) && date_range.first < reservation.end_date } diff --git a/lib/hotel_admin.rb b/lib/hotel_admin.rb index 33ccb940c..14059240f 100644 --- a/lib/hotel_admin.rb +++ b/lib/hotel_admin.rb @@ -29,6 +29,7 @@ def reserve_room(first_name, last_name, room_id, room_rate, start_date, end_date raise UnavailableRoomError.new("Room is unavailable") if @reservation_list.any? {|reservation| reservation.room_id == room_id && reservation.date_range.overlaps?(requested_range) && start_date < reservation.end_date + #overlaps? same as: # reservation.room_id == room_id && # !(reservation.start_date >= end_date || reservation.end_date <= start_date) } @@ -50,7 +51,7 @@ def reserve_block(block_id, date_range, rooms_array, discount_room_rate, reserva end end - block = BookingSystem::Block.new(block_id, date_range, rooms_array, discount_room_rate, @reservation_list) + block = BookingSystem::Block.new(block_id, date_range, rooms_array, discount_room_rate, reservation_list) @block_list << block end @@ -82,9 +83,6 @@ def rooms_available_for_date_range(date_range) return available_rooms end - - - end#of_HotelAdmin_class end#of_module_BookingSystem diff --git a/lib/reservation.rb b/lib/reservation.rb index fd91116b5..b6a304b99 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -6,6 +6,7 @@ class Reservation attr_reader :first_name, :last_name, :room_id, :room_rate, :start_date, :end_date, :total_cost, :date_range def initialize(first_name, last_name, room_id, room_rate, start_date, end_date, block_id = nil) + @first_name = first_name @last_name = last_name diff --git a/lib/test.rb b/lib/test.rb deleted file mode 100644 index 08d20f531..000000000 --- a/lib/test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'date' -require 'date_range' - -puts (Date.new(2012, 01, 01)..Date.new(2012, 01, 30)).last diff --git a/specs/block_spec.rb b/specs/block_spec.rb index ce7e806cf..99bd1e578 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -14,8 +14,9 @@ BookingSystem::Room.new(4, 200.00), BookingSystem::Room.new(5, 200.00)] @discount_room_rate = 0.20 + @reservation_list = [] - @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate) + @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate, @reservation_list) end it "can create a block of rooms using a date range, collection of rooms and a discounted room rate" do @@ -23,23 +24,23 @@ end it "ensures block_id argument is a String" do - proc { BookingSystem::Block.new(12345, @date_range, @rooms_array, @discount_room_rate) }.must_raise ArgumentError + proc { BookingSystem::Block.new(12345, @date_range, @rooms_array, @discount_room_rate, @reservation_list) }.must_raise ArgumentError end it "ensures date range argument is a DateRange object" do - proc { BookingSystem::Block.new(@block_id, "date_range", @rooms_array, @discount_room_rate) }.must_raise InvalidDateRangeError + proc { BookingSystem::Block.new(@block_id, "date_range", @rooms_array, @discount_room_rate, @reservation_list) }.must_raise InvalidDateRangeError end it "ensures collection of rooms argument is an array" do - proc { BookingSystem::Block.new(@block_id, @date_range, "rooms_array", @discount_room_rate) }.must_raise ArgumentError + proc { BookingSystem::Block.new(@block_id, @date_range, "rooms_array", @discount_room_rate, @reservation_list) }.must_raise ArgumentError end it "ensures collection of rooms argument array length cannot be greater than 5" do - proc { BookingSystem::Block.new(@block_id, @date_range, [1, 2, 3, 4, 5, 6], @discount_room_rate) }.must_raise BlockError + proc { BookingSystem::Block.new(@block_id, @date_range, [1, 2, 3, 4, 5, 6], @discount_room_rate, @reservation_list) }.must_raise BlockError end it "ensures room discount argument is a float" do - proc { BookingSystem::Block.new(@block_id, @date_range, @rooms_array, "discount_room_rate") }.must_raise ArgumentError + proc { BookingSystem::Block.new(@block_id, @date_range, @rooms_array, "discount_room_rate", @reservation_list) }.must_raise ArgumentError end end end#of_"Block Class" diff --git a/specs/hotel_admin_spec.rb b/specs/hotel_admin_spec.rb index 40dccd8d9..041ad1257 100644 --- a/specs/hotel_admin_spec.rb +++ b/specs/hotel_admin_spec.rb @@ -79,10 +79,13 @@ BookingSystem::Room.new(12, 200.00), BookingSystem::Room.new(13, 200.00), BookingSystem::Room.new(14, 200.00)] - @discount_room_rate = 0.20 + @discount_room_rate = 0.20 - @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate) - end + #Hotel Revisted Changes + @hotel_admin_test.reservation_list << BookingSystem::Reservation.new("Jane", "Doe", 10, 200.00, Date.new(2017, 9, 1), Date.new(2017, 9, 5), "Block1") + + @block = BookingSystem::Block.new(@block_id, @date_range, @rooms_array, @discount_room_rate, @hotel_admin_test.reservation_list) + end it "ensures that reservation is added to all_reservations" do @hotel_admin_test.reservation_list.any? { |reservation| @@ -96,7 +99,7 @@ end it "makes a reservation and adds it to hotel's list of reservations" do - @hotel_admin_test.reservation_list.length.must_equal 1 + @hotel_admin_test.reservation_list.length.must_equal 2 end it "raises an error for an invalid date range" do @@ -116,7 +119,7 @@ it "will allow booking for a room if requested start_date is on the end_date of a previous booking" do @hotel_admin_test.reserve_room(@first_name, @last_name, @room_id, @room_rate, Date.new(2017, 9, 5), Date.new(2017, 9, 6)) - @hotel_admin_test.reservation_list.length.must_equal 2 + @hotel_admin_test.reservation_list.length.must_equal 3 end end @@ -135,7 +138,7 @@ BookingSystem::Room.new(5, 200.00)] @discount_room_rate = 0.20 - @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate) + @hotel_admin_test.reserve_block(@block_id, @date_range, @rooms_array, @discount_room_rate, @hotel_admin_test.reservation_list) end it "makes a block reservation and adds it to hotel's list of block reservations" do