diff --git a/.gitignore b/.gitignore index 5e1422c9c..ce17d1737 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +coverage *.gem *.rbc /.config 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/admin.rb b/lib/admin.rb new file mode 100644 index 000000000..ec5237c85 --- /dev/null +++ b/lib/admin.rb @@ -0,0 +1,98 @@ +## would have to put number of rooms to be instantiated in the reservation parameters and adjust from there? + +require "pry" +require "date" + +module Hotel + class Administrator + + attr_reader :rooms + + def initialize() + @rooms = {} + @blocks = [] + + (1..20).each do |room_num| + @rooms[room_num] = [] + end + # binding.pry + + end + + + def make_reservation(requested_check_in, requested_check_out) + # def make_reservation(requested_check_in, requested_check_out, number_of_rooms = 1) + + available_rooms = see_available(requested_check_in, requested_check_out) #calls available rooms based on given dates + + if available_rooms.length == 0 + raise ArgumentError.new('No rooms available') + end + + # #Many cases (block rooms) + # (1..requested_rooms).each do | res_num | do + # @rooms[available_rooms[res_num]] << Reservation.new .... + + #Single case below + room = Hotel::Reservation.new({check_in: requested_check_in, check_out: requested_check_out}) #first available room is chosen and pushed to @rooms array for that room + @rooms[available_rooms[0]] << room + + return room + + end + + def block_room(requested_check_in, requested_check_out, room_amt) + available_rooms = see_available(requested_check_in, requested_check_out) + + if available_rooms.length < room_amt + raise ArgumentError.new('No rooms available') + end + + blocked_rooms = available_rooms[0, room_amt] + + block = Hotel::ReservationBlock.new({ + check_in: requested_check_in, + check_out: requested_check_out, + blocked_rooms: blocked_rooms + }) + + @blocks << block + + return block + end + + + def see_available(requested_check_in, requested_check_out) + parsed_req_in = DateTime.strptime(requested_check_in, "%d/%m/%Y") + parsed_req_out = DateTime.strptime(requested_check_out, "%d/%m/%Y") + + available_rooms = [] + + @rooms.each do |room_num, reservations| + reservations.each do |reservation| + + if parsed_req_in >= reservation.check_in && parsed_req_out <= reservation.check_out + next + + elsif parsed_req_in < reservation.check_in && parsed_req_out <= reservation.check_out + next + + elsif parsed_req_in >= reservation.check_in && parsed_req_out >= reservation.check_out + end # if conditional + + end + available_rooms << room_num + end + + @block_room.each do | + + + return available_rooms + end # see_available + + end # class + end # module + + + # mayo = Hotel::Administrator.new() + # mayo.make_reservation("05/05/2018", "05/10/2018") diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..7b861dd87 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,35 @@ + +require "pry" + +module Hotel + + class Reservation + COST = 200 + + attr_reader :check_in, :check_out #, :room_num + + def initialize(input) + @check_in = Reservation.parse_date(input[:check_in]) + @check_out = Reservation.parse_date(input[:check_out]) + end + + def self.parse_date(date) # self necessary for calling class + return DateTime.strptime(date, "%d/%m/%Y") + end + + def check_dates + if @check_in > @check_out + raise ArgumentError.new("Dates unavailable") + end + end + + + def get_stay_length + (@check_out - @check_in).to_i + end + + def total_cost + return (COST * (get_stay_length - 1)) + end + end # class +end # module diff --git a/lib/reservation_block.rb b/lib/reservation_block.rb new file mode 100644 index 000000000..bc974f6b9 --- /dev/null +++ b/lib/reservation_block.rb @@ -0,0 +1,19 @@ + +module Hotel + + class ReservationBlock < Reservation + + attr_reader :blocked_rooms + + DISCOUNT_RATE = 0.2 + + def initialize(input) + super(input) + @blocked_rooms = input[:blocked_rooms] + end + + def total_cost + return super * (1 - DISCOUNT_RATE) + end + end +end diff --git a/specs/admin_spec.rb b/specs/admin_spec.rb new file mode 100644 index 000000000..f9502f645 --- /dev/null +++ b/specs/admin_spec.rb @@ -0,0 +1,111 @@ +require_relative 'spec_helper' +require 'minitest/pride' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' + +require_relative '../lib/admin' + +describe "Admin" do + describe "Initialize" do + before do + @admin = Hotel::Administrator.new() + end + + it "initializes an Administrator" do + @admin.must_be_instance_of Hotel::Administrator + end + end + + describe "make reservations" do + before do + @admin = Hotel::Administrator.new() + end + + it "can make a reservation" do + @admin.make_reservation("24/12/2018", "25/12/2018") + + result = @admin.rooms[1] + + result.first.check_in.must_be_instance_of DateTime + result.first.check_out.must_be_instance_of DateTime + end + + end + + describe "establishes room structure on instantiation" do + before do + @admin = Hotel::Administrator.new() + end + it "establishes the base room structure" do + room_array = @rooms + + room_array.must_be_kind_of NilClass + # room_array.count.must_equal 20 + end + + it "has empty arrays upon instantiation" do + result = @admin.rooms[1] + result.must_be_kind_of Array + end + end + + + describe "creates reservation if dates are valid" do + before do + @admin = Hotel::Administrator.new() + end + + it "view available rooms for a given date range" do + available_room = @admin.see_available("24/12/2018", "25/12/2018") + available_room.must_equal (1..20).to_a + end + + it "returns an error if no rooms are available" do + + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + @admin.make_reservation("01/01/2018", "15/01/2018") + + proc { @admin.see_available}.must_raise ArgumentError + end + end # describe + + describe "block_room" do + before do + @admin = Hotel::Administrator.new + @admin.block_room("05/05/2018", "05/10/2018", 20) + end + + it "raise error if rooms are blocked within date range" do + proc { + @admin.make_reservation("05/05/2018", "05/10/2018") + }.must_raise ArgumentError + end + + it "won't throw error if the range is available" do + r = @admin.make_reservation("20/05/2018", "29/05/2018") + r.must_be_kind_of Hotel::Reservation + end + end + +end # Admin diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..d1c08a4be --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,44 @@ +require_relative 'spec_helper' +require 'minitest/pride' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' + +require_relative '../lib/admin' + +describe "Reservation" do + before do + @reserve1 = Hotel::Reservation.new({check_in: "30/10/2019", check_out: "30/10/2018"}) + end + + it "creates an instance of a reservation" do + @reserve1.must_be_instance_of Hotel::Reservation + end + + it "raises an error if an invalid date range provided" do + today = Time.now + check_out = today.strftime("%d/%m/%Y") + check_in = Date.parse("29/10/2019") + + proc {@reserve1.check_dates}.must_raise ArgumentError + end +end + +describe "checks the lenth of stay" do + + it "checks the duration of the reservation" do + reserve1 = Hotel::Reservation.new({check_in: "24/12/2018", check_out: "26/12/2018"}) + + reserve1.get_stay_length.must_equal(2) + end +end + +describe "returns the cost of the reservation" do + + it "gets the total cost of a stay " do + reserve1 = Hotel::Reservation.new({check_in: "24/12/2018", check_out: "26/12/2018"}) + + reserve1.total_cost.must_equal(200) + end + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..003c76b0f --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,11 @@ +require 'simplecov' +SimpleCov.start + +require 'minitest/autorun' +require 'minitest/reporters' +require_relative '../lib/admin' +require_relative '../lib/reservation' +require_relative '../lib/reservation_block' + + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new