Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
38671be
setting up file structures
yieknee Mar 2, 2020
77c0390
initialized rooms and wrote test
yieknee Mar 2, 2020
ddde6bf
write initial reservations test and code
yieknee Mar 3, 2020
4c84844
add more initialize tests for reservation
yieknee Mar 3, 2020
776f0e5
changed calendar filename to daterange and rooms file to room
yieknee Mar 3, 2020
0d10b72
change calendar_test.rb to daterange_test.rb
yieknee Mar 3, 2020
4048b4f
fixed various bugs from changing filenames
yieknee Mar 3, 2020
d17df05
refactored code that shows all rooms
yieknee Mar 3, 2020
d2b0176
add find room method
yieknee Mar 3, 2020
e3b8311
changed date parse to date.new
yieknee Mar 4, 2020
10cb24b
change return of overlap test to true or false
yieknee Mar 4, 2020
159864a
write nights and add reservation methods
yieknee Mar 4, 2020
83b3034
add available rooms for given date range method
yieknee Mar 4, 2020
2ae449a
write code and tests to find reservation given a room and date range
yieknee Mar 4, 2020
0fc5509
refactor find_reservations_with method an tests
yieknee Mar 4, 2020
0add42f
write total cost method
yieknee Mar 4, 2020
e628002
raised exception for no available rooms and write test
yieknee Mar 4, 2020
4731ffa
start scaffolding for wave 3
yieknee Mar 4, 2020
6172d57
add hotel block class and test, remove id from reservations
yieknee Mar 4, 2020
2e4bef5
add psuedo code for wave 3
yieknee Mar 5, 2020
0af6916
rewrite available room method and prep for writing blockmethods
yieknee Mar 5, 2020
ccc6cba
add extra validation for date range
yieknee Mar 5, 2020
72aba3b
add hotelblock tests and dry up test code
yieknee Mar 6, 2020
7ff3e3f
write request block method
yieknee Mar 6, 2020
a43b155
write change block status and change block availability methods
yieknee Mar 6, 2020
f7d7db6
refactor available rooms method to account for rooms in block
yieknee Mar 7, 2020
67e8b5b
write check block status method
yieknee Mar 8, 2020
c877a90
write add reservation to room in block method
yieknee Mar 8, 2020
4cacc0b
final working code
yieknee Mar 9, 2020
585309c
add refactor text file
yieknee Mar 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/No_Available_Room_Error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class NoAvailableRoomError < StandardError
end
30 changes: 30 additions & 0 deletions lib/date_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'date'

module Hotel
class DateRange
attr_reader :start_date, :end_date, :range

def initialize(start_date:, end_date:)
raise ArgumentError.new("start and end dates must be Date objects") if start_date.class != Date && end_date.class != Date
@start_date = start_date
@end_date = end_date
@range = (@start_date .. @end_date).to_a
raise ArgumentError.new("End date can not be before start date") if @end_date < @start_date
raise ArgumentError.new("Reservation can not be before today") if @end_date < Date.today || @start_date < Date.today

end

def overlap?(date_range)
# if the array of the combined arrays is empty, there is no overlap, so return false
# if the array is not empty, return true
overlap = (self.range & date_range.range).empty? || (date_range.start_date >= self.end_date) || (date_range.end_date <= self.start_date) ? false : true
return overlap
end

def nights
return @range.count - 1
end


end
Comment on lines +4 to +29

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A thought you might enjoy chewing on: how would your code change if class DateRange < Range?

end
101 changes: 101 additions & 0 deletions lib/front_desk.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
require_relative 'room'
require_relative 'date_range'
require_relative 'reservations'
require_relative 'hotel_block'
require_relative 'no_available_room_error'

module Hotel
class FrontDesk
attr_accessor :rooms, :reservations, :hotel_blocks

def initialize
@rooms = []

(1..20).each do |room_num|
new_room = Room.new(room_number: room_num, cost: 200)
@rooms << new_room
end
@reservations = []
@hotel_blocks = []
end

def add_reservation(date_range)
available_rooms = check_block_status(date_range)

raise NoAvailableRoomError.new("there are no available rooms for that date")if available_rooms.empty? == true

chosen_room = available_rooms[0]
new_reservation = Hotel::Reservation.new(date_range: date_range, room: chosen_room)
@reservations << new_reservation
chosen_room.add_room_reservation(new_reservation)
return new_reservation
end

def available_rooms(date_range)
available_rooms = @rooms.reject do |room|
room.reservations.any?{|reservation| reservation.date_range.overlap?(date_range) == true}
end
return available_rooms

end

def find_reservation_with(room: nil, date_range:)
res_w_given_date = @reservations.select {|reservation| (reservation.date_range == date_range && reservation.room == room) || reservation.date_range == date_range }
return res_w_given_date
end

def total_cost(reservation)
if reservation.block_reservation == false
total_cost = reservation.date_range.nights * reservation.room.cost
else
total_cost = reservation.date_range.nights * reservation.room.cost * (1-reservation.room.discount_cost)
end
return total_cost
end

def check_block_status(date_range)
available_rooms = available_rooms(date_range)
@hotel_blocks.each do |hotel_block|
if hotel_block.date_range.overlap?(date_range) == true
hotel_block.rooms.each do |block_room|
available_rooms.delete(block_room)
end
end
end
return available_rooms
end

def request_block(block_count, date_range, discount_cost)
available_rooms = check_block_status(date_range)
raise NoAvailableRoomError.new("Not enough available rooms to fulfill block") if available_rooms.count < block_count

hotel_block = Hotel::HotelBlock.new(block_count: block_count, date_range: date_range, discount_cost: discount_cost)

x = 0
until x == block_count do
available_room = available_rooms[x]
available_room.change_cost(discount_cost)
hotel_block.rooms << available_room
x += 1
end
@hotel_blocks << hotel_block
return hotel_block
end

def available_rooms_in_block(hotel_block)
available_rooms = hotel_block.rooms.select{|room| room.reservations.empty? == true || room.reservations.any?{|reservation| reservation.date_range.overlap?(hotel_block.date_range) == false}}
return available_rooms
end

def add_reservation_to_room_in_block(hotel_block)
available_rooms = available_rooms_in_block(hotel_block)
raise NoAvailableRoomError.new("there are no available rooms left in this block")if available_rooms.empty? == true
chosen_room = available_rooms[0]
new_reservation = Hotel::Reservation.new(date_range: hotel_block.date_range, room: chosen_room)
new_reservation.block_reservation = true
@reservations << new_reservation
chosen_room.add_room_reservation(new_reservation)
return new_reservation
end
Comment on lines +56 to +99

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least a couple of these methods probably belong to HotelBlock

end
end
19 changes: 19 additions & 0 deletions lib/hotel_block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Hotel
class HotelBlock
attr_reader :block_count, :date_range, :discount_cost
attr_accessor :rooms

def initialize(block_count:, date_range:, discount_cost:)
@block_count = block_count # I interpreted the user story "collection of rooms" to mean I can pass it a
#count and the count determines how many rooms to request for the block.
@date_range = date_range
@discount_cost = discount_cost
@rooms = []

raise ArgumentError.new("Block count must be an integer between 2 and 5 inclusive") if @block_count.between?(2,5) == false

end

end

Comment on lines +2 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to get suspicious when a class only has initialize as a method. Usually, this means that another class is managing the data that belongs to this class.

end
14 changes: 14 additions & 0 deletions lib/reservations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

module Hotel
class Reservation
attr_reader :date_range, :room
attr_accessor :block_reservation

def initialize(date_range:, room: nil)
@date_range = date_range
@room = room
@block_reservation = block_reservation
end

end
end
28 changes: 28 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

module Hotel
class Room
attr_reader :room_number
attr_accessor :cost, :reservations, :discount_cost

def initialize(room_number:, cost:, reservations: nil)
@room_number = room_number

raise ArgumentError.new("There are only 20 rooms") if room_number < 1 || room_number > 20

@cost = 200
@reservations = reservations || []
@discount_cost = 0

end

def add_room_reservation(reservation)
@reservations << reservation
end

def change_cost(discount_cost)
self.discount_cost = discount_cost
return self
end

end
end
6 changes: 6 additions & 0 deletions refactors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Possible Refactors:
1. Only tracking reservation in either my front desk or my rooms, but not both
2. Refactor my block check status so that time and space are not O(n**2)
3. Write more test that cover more edge cases for the methods in my front desk
4. Don't track discount cost in my rooms
a. figure out a better way to account for discount costs for rooms in block
63 changes: 63 additions & 0 deletions test/daterange_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require_relative 'test_helper'

describe "DateRange" do
before do
@start_date = Date.today + 2
@end_date = Date.today + 6
@date_range = Hotel::DateRange.new(start_date: @start_date, end_date: @end_date)
end

describe "initialize DateRange" do

it "creates a DateRange object" do
expect(@date_range).must_be_instance_of Hotel::DateRange
end

it "raises ArgumentError if end date is before start date" do
expect{Hotel::DateRange.new(start_date: Date.today + 6, end_date: Date.today + 2)}.must_raise ArgumentError
end

it "raises ArgumentError if end date and start date are not Date objects" do
expect{Hotel::DateRange.new(start_date: "March 4, 2020", end_date: "March 2, 2020")}.must_raise ArgumentError
end

it "creates a range of the start and end dates" do
expect(@date_range.range).must_equal (@start_date..@end_date).to_a
end
end

describe "overlap?" do

it "returns true if there is overlap between date ranges" do
date_range2 = Hotel::DateRange.new(start_date: Date.today + 2, end_date: Date.today + 4)
date_range3 = Hotel::DateRange.new(start_date: Date.today + 3, end_date: Date.today + 6)
date_range4 = Hotel::DateRange.new(start_date: Date.today + 1, end_date: Date.today + 9)
date_range5 = Hotel::DateRange.new(start_date: Date.today + 1, end_date: Date.today + 6)
expect(@date_range.overlap?(date_range2)).must_equal true
expect(@date_range.overlap?(date_range3)).must_equal true
expect(@date_range.overlap?(date_range4)).must_equal true
expect(@date_range.overlap?(date_range5)).must_equal true
end

it "returns false if the date is not within the range" do
date_range2 = Hotel::DateRange.new(start_date: Date.today + 6, end_date: Date.today + 9)
date_range3 = Hotel::DateRange.new(start_date: Date.today + 7, end_date: Date.today + 13)
date_range4 = Hotel::DateRange.new(start_date: Date.today + 1, end_date: Date.today + 2)
date_range5 = Hotel::DateRange.new(start_date: Date.today + 19, end_date: Date.today + 20)
date_range5 = Hotel::DateRange.new(start_date: Date.today , end_date: Date.today + 1)
expect(@date_range.overlap?(date_range2)).must_equal false
expect(@date_range.overlap?(date_range3)).must_equal false
expect(@date_range.overlap?(date_range4)).must_equal false
expect(@date_range.overlap?(date_range5)).must_equal false
end
Comment on lines +31 to +52

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would give these date ranges more explicit names, so that others can check your work more easily.


end

describe "nights" do

it "calculates the number of nights booked" do
expect(@date_range.nights).must_equal 4
end
end

end
Loading