Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
94cb11e
Add coverage directory to .gitignore file
cojenco Mar 2, 2020
0b568c4
Added SimpleCov into test helper
cojenco Mar 2, 2020
f3ed103
Setup files and gems. Started DateRange class and tests.
cojenco Mar 3, 2020
6cd1e66
Revised DateRange tests using more of Date.today
cojenco Mar 3, 2020
8f69ba5
Added DateRange#count_nights method and tests.
cojenco Mar 3, 2020
7f9a473
Added DateRange#include method and tests.
cojenco Mar 3, 2020
d6abc6e
Added DateRange#overlapping method and tests. Revised #including meth…
cojenco Mar 3, 2020
1d16a53
Created Reservation#initialize and #get_price methods and tests.
cojenco Mar 3, 2020
255b4a8
Added Room#initialize method and tests
cojenco Mar 3, 2020
2e1e6b5
Added @rooms to SystemCoordinator constructor. Revised Room construct…
cojenco Mar 3, 2020
c35d83e
Revised Room@cost to be a Float, and changed corresponding tests.
cojenco Mar 3, 2020
326034f
Revised Reservation class to pass in date_range as parameter. Revised…
cojenco Mar 3, 2020
205f236
Added back Reservation#get_price tests.
cojenco Mar 3, 2020
543b708
Added DateRange#include_date method to pass in specific date instead …
cojenco Mar 3, 2020
17d6682
Added SystemCoordinator#find_reservation_by_date method and @reservat…
cojenco Mar 4, 2020
9026b3e
Added @bookings to Room and updated tests
cojenco Mar 4, 2020
81831db
Added Room#add_booking_to_room method and tests.
cojenco Mar 4, 2020
1c4c686
Added SystemCoordinator#find_reservations_room_date method and tests.
cojenco Mar 4, 2020
f5d36d4
Added SystemCoordinator#find_availabile_rooms method and tests.
cojenco Mar 4, 2020
f074a79
Added SystemCoordinator#make_reservation method and tests initial ver…
cojenco Mar 4, 2020
4baafe9
Added SystemCoordinator#find_room method and tests.
cojenco Mar 4, 2020
83984e0
Revised SystemCoordinator#make_reservation method to push reservating…
cojenco Mar 4, 2020
a3bdc8f
Added SystemCoordinator#list_rooms method and tests.
cojenco Mar 4, 2020
b4ae83e
Added more tests for #make_reservation and cleaned up draft.
cojenco Mar 4, 2020
e008545
Deleted @reservations container. Only Room holds its reservations. Wh…
cojenco Mar 5, 2020
86d90f6
Switched #get_price from Reservation to Room class. Revised tests.
cojenco Mar 5, 2020
9667db6
Added SystemCoordinator#build_rooms method for the constructor. Added…
cojenco Mar 5, 2020
eb2d44d
Revised @cost to be attr_accessor in Room class.
cojenco Mar 5, 2020
d85a9d3
Formatting and adding comments.
cojenco Mar 5, 2020
e8b9edb
Added tests for SystemCoordinator.
cojenco Mar 6, 2020
c997c2c
Created a NoAvailabilityError class and yet to implement.
cojenco Mar 6, 2020
8a8177c
Added Block class and test file and updated test helper.
cojenco Mar 6, 2020
a427012
Initial version for Wave2. Design thoughts and psuedocode starting Wa…
cojenco Mar 6, 2020
36551ca
Added comments.
cojenco Mar 6, 2020
c65c308
Revised Reservation to be superclass. Added @cost instance variable a…
cojenco Mar 6, 2020
1b63121
Block class inherits from Reservation. Built constructor and tests.
cojenco Mar 6, 2020
ee8f691
Added #exactly_matching method and tests.
cojenco Mar 6, 2020
2f46e39
Renamed block_id and restored back to original naming.
cojenco Mar 6, 2020
9929095
Revised methods to integrate the Block class and concept. Revised tests.
cojenco Mar 6, 2020
d1a89b5
Added Room#is_available method and tests.
cojenco Mar 7, 2020
bd2940f
Added #make_specific_block method and tests. Revised #find_available_…
cojenco Mar 7, 2020
434be2e
Cleaning up formatting and code.
cojenco Mar 7, 2020
b67560e
Added Room#change_rate method and tests.
cojenco Mar 8, 2020
8df9b3d
Fixed spelling typo. Revised #list_rooms methods to accomodate CLI.
cojenco Mar 8, 2020
ff0ac77
Added main.rb
cojenco Mar 8, 2020
b017ab5
Added Require_Relative and revised syntax to accomodate CLI.
cojenco Mar 8, 2020
def524f
Added small driver methods to the main.rb file.
cojenco Mar 8, 2020
24a9b36
Revised #list_rooms method for main and coordinator files.
cojenco Mar 9, 2020
5047dc8
Added refactors.txt
cojenco Mar 9, 2020
9f18e56
Revised #list_rooms method.
cojenco Mar 9, 2020
8c0c0cb
Clean up comments.
cojenco 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
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ build-iPhoneSimulator/

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
coverage
Binary file added lib/.DS_Store
Binary file not shown.
17 changes: 17 additions & 0 deletions lib/block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require_relative 'room'
require_relative 'date_range'
require_relative 'reservation'


module Hotel
class Block < Reservation
attr_reader :block

def initialize(date_range, room_id, cost = 200.00, block = 0)

super(date_range, room_id, cost)
@block = block

end
end
end
52 changes: 52 additions & 0 deletions lib/date_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'date'

module Hotel
class DateRange

attr_accessor :start_date, :end_date

# your library code should assume that it's receiving Date objects to start
def initialize(start_date, end_date)
raise ArgumentError.new("Please pass in Date class instances.") if !(start_date.is_a? Date) || !(end_date.is_a? Date)
raise ArgumentError.new("Live in the present! Dates should not be prior to today.") if start_date < Date.today

Choose a reason for hiding this comment

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

It's helpful to include the bad arguments in message of the ArgumentError:

Suggested change
raise ArgumentError.new("Live in the present! Dates should not be prior to today.") if start_date < Date.today
raise ArgumentError.new("Live in the present! Dates should not be prior to today. Bad start_date: #{start_date}") if start_date < Date.today

raise ArgumentError.new("End date should not be earlier than or the same day as start date.") if end_date <= start_date

@start_date = start_date
@end_date = end_date
end

def count_nights
nights = (@end_date - @start_date).to_i
return nights
Comment on lines +19 to +20

Choose a reason for hiding this comment

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

You don't need to assign to a variable before returning:

Suggested change
nights = (@end_date - @start_date).to_i
return nights
return (@end_date - @start_date).to_i

end

def include_date(date)
return true if date >= @start_date && date < @end_date
return false
Comment on lines +24 to +25

Choose a reason for hiding this comment

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

You can directly return the boolean condition:

Suggested change
return true if date >= @start_date && date < @end_date
return false
return date >= @start_date && date < @end_date

end

def overlapping(other_range)
if other_range.start_date < @end_date && @start_date < other_range.end_date
return true
else
return false
end
end

def exactly_matching(other_range)
if @start_date == other_range.start_date && @end_date == other_range.end_date
return true
else
return false
end
end

def including(other_range)
if other_range.start_date >= @start_date && other_range.end_date <= @end_date
return true
else
return false
end
end
end
end
3 changes: 3 additions & 0 deletions lib/no_availability_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class NoAvailabilityError < StandardError

Choose a reason for hiding this comment

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

Custom exception class! 🎉

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

module Hotel
class Reservation
attr_reader :id, :start_date, :end_date, :date_range, :room_id, :block
attr_accessor :cost

@@next_id = 1

Choose a reason for hiding this comment

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

Generally we advise against using a class variable. In this case it's not too bad but it would be preferable to have this stored in the SystemCoordinator.


def initialize(date_range, room_id, cost = 200.00)
@date_range = date_range
@start_date = date_range.start_date
@end_date = date_range.end_date

@room_id = room_id
@cost = cost

@id = @@next_id
@@next_id += 1
@block = -1

Choose a reason for hiding this comment

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

It looks like you're using -1 to signal that this isn't a block.

Generally speaking you should use nil to indicate the absence of something:

Suggested change
@block = -1
@block = nil

end

def get_total_price
total_price = date_range.count_nights * cost
return total_price
end
end
end
44 changes: 44 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require_relative 'reservation'

module Hotel
class Room
attr_reader :room_id,:bookings
attr_accessor :cost

def initialize(room_id, cost = 200.00, bookings = nil)
raise ArgumentError if !room_id.is_a? Integer
raise ArgumentError if room_id < 1
@room_id = room_id
@cost = cost
@bookings = bookings || []
end

def add_booking_to_room(new_reservation)
@bookings << new_reservation
end

def get_price(reservation)
price = reservation.date_range.count_nights * cost
return price
end

def is_available(given_range)
return true if bookings.empty?

bookings.each do |item|
if item.block >= 0 #item.class == Hotel::Block
return false if item.date_range.overlapping(given_range) && item.date_range.exactly_matching(given_range)== false #it is not an exact match #method

Choose a reason for hiding this comment

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

Instead of comparing to false you should use !:

Suggested change
return false if item.date_range.overlapping(given_range) && item.date_range.exactly_matching(given_range)== false #it is not an exact match #method
return false if item.date_range.overlapping(given_range) && !item.date_range.exactly_matching(given_range) #it is not an exact match #method

elsif item.block < 0 #item.class == Hotel::Reservation
return false if item.date_range.overlapping(given_range)
end
end

return true
end

def change_rate(new_rate)
raise ArgumentError if !new_rate.is_a?(Numeric) || new_rate.to_f < 0
@cost = new_rate.to_f
end
end
end
174 changes: 174 additions & 0 deletions lib/system_coordinator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
require_relative 'room'
require_relative 'date_range'
require_relative 'reservation'
require_relative 'block'
require_relative 'no_availability_error'

module Hotel
class SystemCoordinator
attr_reader :rooms

@@next_block = 1

Choose a reason for hiding this comment

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

This definitely doesn't need to be a class variable since there will only be one SystemCoordinator instantiated.


def initialize(room_quantity = 20)
@rooms = [] # Array.new(quantity){|i| Hotel::Room.new(i+1)}
build_rooms(room_quantity)
end

def build_rooms(room_quantity)
room_quantity.times do
@rooms << Hotel::Room.new(@rooms.length + 1)
end
end

def list_rooms
return rooms
end
Comment on lines +24 to +26

Choose a reason for hiding this comment

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

You don't need both a list_rooms method and an attr_reader on rooms, you should pick one.



def find_reservations_by_date(date)
reservations_by_date = []

rooms.each do |room|
room.bookings.each do |reservation|
reservations_by_date << reservation if reservation.date_range.include_date(date)
end
end

return reservations_by_date
end


def find_reservations_room_date(room_id, date_range)
selected_room = find_room(room_id)
reservations_room_date = selected_room.bookings.reject{|reservation|false == reservation.date_range.overlapping(date_range)}

Choose a reason for hiding this comment

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

This can be simplified using select:

Suggested change
reservations_room_date = selected_room.bookings.reject{|reservation|false == reservation.date_range.overlapping(date_range)}
reservations_room_date = selected_room.bookings.select {|reservation| reservation.date_range.overlapping(date_range)}

return reservations_room_date
end


def find_reservations_range(given_range)
reservations_range = []

rooms.each do |room|
room.bookings.each do |reservation|
reservations_range << reservation if reservation.date_range.overlapping(given_range)
end
end

return reservations_range
end


def find_available_rooms(given_range)
available_rooms = []

rooms.each do |room|
if room.bookings.empty?
available_rooms << room
else
status = true
room.bookings.each do |item|
if item.block >= 0 #item.class == Hotel::Block
status = false if item.date_range.overlapping(given_range) && false == item.date_range.exactly_matching(given_range) #it is not an exact match #method
elsif item.block < 0 #item.class == Hotel::Reservation
status = false if item.date_range.overlapping(given_range)
end
end
available_rooms << room if true == status

Choose a reason for hiding this comment

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

You don't need to compare to true here since status is a boolean value:

Suggested change
available_rooms << room if true == status
available_rooms << room if status

end
end

raise NoAvailabilityError.new "No Availability. Please try another date range." if available_rooms == []
return available_rooms
end


def make_reservation(start_date, end_date)
range_created = Hotel::DateRange.new(start_date,end_date)
available_rooms = find_available_rooms(range_created)

chosen_room = available_rooms.shift
new_reservation = Hotel::Reservation.new(range_created, chosen_room.room_id)

chosen_room.add_booking_to_room(new_reservation)

return new_reservation
end


def find_block_rooms(given_range)
available_rooms = rooms.reject do |room|
room.bookings.any? do |reservation| #returns true if there are overlapping reservations
reservation.date_range.overlapping(given_range) == true
end
end
return available_rooms
end


def make_specific_block(date_range, roomid_array, cost)
room_array = roomid_array.map{|id| find_room(id)}
raise ArgumentError.new "Maximum 5 rooms for a hotel block." if room_array.length > 5 || room_array.length == 0
rooms_in_block = []

room_array.each do |room|
if room.is_available(date_range) == false

Choose a reason for hiding this comment

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

This can be clarified using an unless:

Suggested change
if room.is_available(date_range) == false
unless room.is_available(date_range)

raise NoAvailabilityError.new "Room#{room.room_id} is not available for this given date range."
end
end

room_array.each do |room|
room_block = Hotel::Block.new(date_range,room.room_id, cost, @@next_block)
room.add_booking_to_room(room_block)
rooms_in_block << room_block
end

@@next_block += 1

return rooms_in_block
end


def make_block(date_range, room_quantity, cost)
raise ArgumentError.new "Maximum 5 rooms for a hotel block." if room_quantity > 5
available_rooms = find_block_rooms(date_range)
raise NoAvailabilityError.new "No availability. Please try another date range." if available_rooms.length < room_quantity

rooms_in_block = []

room_quantity.times do |i|
chosen_room = available_rooms[i]
room_id = chosen_room.room_id
room_block = Hotel::Block.new(date_range,room_id, cost, @@next_block)
chosen_room.add_booking_to_room(room_block)
rooms_in_block << room_block
end

@@next_block += 1
return rooms_in_block
end


def find_room(given_room_id)
room_found = rooms.find{|room|room.room_id == given_room_id}
return room_found
end


def check_block_availability(block_id)
rooms_in_block = []
blocks = []
rooms.each do |room|
room.bookings.each do |item|
if item.block > 0 && item.block == block_id
blocks << item
rooms_in_block << room
end
end
end

date_range = blocks[0].date_range
rooms_in_block.any?{|room|room.is_available(date_range)} #returns true or false
end
end
end
Loading