diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..475aa56fa --- /dev/null +++ b/design-activity.md @@ -0,0 +1,73 @@ +What classes does each implementation include? Are the lists the same? +Write down a sentence to describe each class. + + Implementation A + CartEntry class: initializes unit price and quantity variables + ShoppingCart class: initializes an array of entries + Order class: initializes a new shopping cart, calculates total price using cart entries and uses the unit price and quantity of each cart entry. + + + Implementation B + CartEntry class: initializes unit price and quantity variables, calculates the price of each cart entry + ShoppingCart class: initializes an array of entries, calculates price (cart total) using the sum of prices for all cart entries + Order class: initializes a new shopping cart, calculates total price, by adding sales tax and shopping cart price. + + The two implementations have the same list of classes. But the classes do different things, in implementation B. Calculations for prices and done within individual classes unlike A which does all the calculations in the Order class. + +How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. + + ShoppingCart is populated with an array of CartEntry instances, it also calls the CartEntry method price and used in defining ShoppingCart#price. + + Order is populated with an instance of ShoppingCart. It has a method total price that calls the ShoppingCart#price method. + + +What data does each class store? How (if at all) does this differ between the two implementations? + + + CartEntry contains two integers variables (I'm assuming unit price and quantity will be integers). The class does not store data, it creates a CartEntry. + + ShoppingCart has an array stored in the @entires variable that stores instances of CartEntry. + + Order contains the @cart variable which is an instance of ShoppingCart. The class does not store any data + +What methods does each class have? How (if at all) does this differ between the two implementations? + + Implementation A + CartEntry has no methods + ShoppingCart has no methods + Order has total_price method + + Implementation B + CartEntry has a price method + ShoppingCart has a price method + Order has a total_price method + + +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? + + Implementation A + The price logic is retained in Order + + Implementation B + The price logic is delegated to lower level classes + +Does total_price directly manipulate the instance variables of other classes? + + total_price does not directly manipulate the instance variables of other classes. + +If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + + Implementation B will be easier to modify because it is loosely couple. + +Which implementation better adheres to the single responsibility principle? + + Implementation B + + +Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? + + Implementation B is more loosely coupled because classes are responsible for their prices unlike in Implementation A. + +I think it would lessen dependencies if each room does not know about all the reservations it has. I made it like this as a way to check if a room is available for a given date range. If I can think of a better design for how rooms are available, rooms won't need to know reservations. + diff --git a/lib/block_reservation.rb b/lib/block_reservation.rb new file mode 100644 index 000000000..261096f59 --- /dev/null +++ b/lib/block_reservation.rb @@ -0,0 +1,48 @@ +class BlockReservation + def initialize(number of rooms, start_time, end_time, rate) + number of rooms = integer + rate = integer + start_time - Time object + end_time - Time object + + id = integer - how will this be generated + block_reservations = [{}] + rooms - [array of room intance to accomate blocks] + cost - integer + #client -hash of client details + end + + + # def make_block_reservation(start_time, end_time) + # find room with stauts == avaible + # reservarions_list << BlockReservation.new(reservation_data) + # end + + def self.all + + block_reservations << all + returns list of all block reservations + end + + def list_block_reservations_by_date(date) + check block_reservations for reservation with start_time == date + end + + + def reservation_cost + cost == difference in days between end_time start_time * rate + end + + +end + +block_reservation_data = { + number_of_rooms: 1, + rate: 150.00, + start_time: 03-23-2019, + end_time: 03-26-2019, + rooms: room, + cost: 0 +} + +BlockRevservation.new(block_reservation_data) diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..63dc8ff47 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,36 @@ +class Reservation + attr_reader :check_in, :check_out, :cost, :date_range, :room + def initialize(check_in, check_out, room) + @check_in = check_in + @check_out = check_out + @date_range = check_out..check_in + @cost = reservation_cost + @room = room + + raise ArgumentError if check_in >= check_out + + # @block_reservation = block_reservation + # @id = id + # @client = client + end + + def nights + nights = check_out - check_in + return nights + end + + def reservation_cost + cost = nights * 200 + return cost + end + + def during?(check_out, check_in) + @date_range.include?(check_out) + end + + # def make_block_reservation(number of rooms, start_time, end_time, rate) + # raise error of number of rooms > 5 + # assign 1 - 5 availble rooms to reservation + # cost = calculates using discouted cost + # end +end diff --git a/lib/reservation_manager.rb b/lib/reservation_manager.rb new file mode 100644 index 000000000..3a94fa54c --- /dev/null +++ b/lib/reservation_manager.rb @@ -0,0 +1,57 @@ +require 'date' +class ReservationManager + attr_reader :reservations, :rooms + # attr_accessor + def initialize(reservations = [], rooms = []) + @reservations = reservations + @rooms = generate_rooms + # @block_reservations = block_reservations + end + + def generate_rooms + rooms = 20.times.map do |number| + Room.new(number) + end + return rooms + end + + def make_reservation(check_in = Date.new(check_in), check_out = Date.new(check_out)) + room = rooms_available(check_in, check_out).first + reservation = Reservation.new(check_in, check_out, room) + @reservations << reservation + room.reserve(reservation) + return reservation + end + + def rooms_available(check_in, check_out) + free_rooms = @rooms.select do |room| + room.available?(check_in, check_out) + end + return free_rooms + end + +# rethinking design +# def rooms_available(check_in, check_out) +# free_rooms = @rooms.select do |room| +# room.room_availble?(check_in, check_out) +# end +# return free_rooms +# end + + def find_reservation(check_out, check_in) + @reservations.each do |reservation| + return reservation if reservation.during?(check_out, check_in) + return "Reservation not found" + end + end + + # def list_reservations(check_out, check_in) + # end + + # def reserve_block + # end + + # def cancel_reservations + # end + +end diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..c6db0c906 --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,28 @@ +class Room + # This class seems to mostly serve as a a container for reservations, which might be better served as a feature of your Hotel class. + attr_reader :room_number, :dates + attr_accessor :status, :reservations + def initialize(room_number, status = :available, reservations = []) + @room_number = room_number + @status = status # valid_status = [:available, :reserved, :blocked] + @reservations = reservations + # rethinking design + @dates_range = check_in..check_out + + raise ArgumentError if room_number > 20 + end + + def reserve(reservation) + @reservations << reservation + end + + def available?(check_in, check_out) + @reservations.each do |reservation| + reservation.during?(check_in, check_out) + end + end + + def room_availble?(check_in, check_out) + @date_range.include?(check_out) + end +end diff --git a/spec/reservation_manager_spec.rb b/spec/reservation_manager_spec.rb new file mode 100644 index 000000000..fdf5e0e3f --- /dev/null +++ b/spec/reservation_manager_spec.rb @@ -0,0 +1,112 @@ +require_relative 'spec_helper' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +require 'pry' +require 'date' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +require_relative '../lib/reservation_manager.rb' +require_relative '../lib/room.rb' +require_relative '../lib/reservation.rb' + +describe "ReservationManagers Class" do + + describe "Initializer" do + before do + @reservation_manager = ReservationManager.new + end + + it "returns an instance of ReservationManager" do + expect(@reservation_manager).must_be_kind_of ReservationManager + end + + it "initializes the correct data structure" do + expect(@reservation_manager.rooms).must_be_kind_of Array + expect(@reservation_manager.reservations).must_be_kind_of Array + end + + it "creates 20 rooms on initiation" do + expect(@reservation_manager.rooms.length).must_equal 20 + end + end + + describe "ReservationManager#make_reservation" do + before do + @reservation_manager = ReservationManager.new + end + + it "creates a reservation" do + reservation = @reservation_manager.make_reservation(2018923, 2018926) + + expect(reservation).must_be_kind_of Reservation + reservation.check_in.must_equal 2018923 + + reservation_1 = @reservation_manager.make_reservation(2018910, 2018911) + + end + # + # it "adds reservation to list of reservarions made" do + # + # @reservation_manager.make_reservation(2018923, 2018926) + # expect(@reservation_manager.reservations.length).must_equal 1 + # end + end + + # TODO: + # That you can make a reservation + # That if you have a reservation in a date range, the next room is selected. + # If all rooms are booked, an error is produced. + # If a reservation ends on the new booking date, the room can be reserved. + + # describe "Hotel#find_reservation(date)" do + # it "find a reservation using the date" do + # hotel = Hotel.new + # hotel.make_reservation(2018923, 2018926) + # reservation_2 = hotel.make_reservation(20181023, 20181028) + # + # expect(hotel.find_reservation(2018923)).must_be_kind_of Reservation + # expect(hotel.find_reservation(20181023)).must_equal reservation_2 + # end + # + # it "finds the correct reservation using the date" do + # hotel = Hotel.new + # hotel.make_reservation(2018923, 2018926) + # reservation_2 = hotel.make_reservation(20181023, 20181028) + # + # expect(hotel.find_reservation(2018923)).must_be_kind_of Reservation + # expect(hotel.find_reservation(20181023)).must_equal reservation_2 + # end + # end + + # describe "Hotel#list_rooms_available(start_date, end_date)" do + # before do + # @hotel = Hotel.new + # @hotel.make_reservation(2018923, 2018926) + # reservation_2 = @hotel.make_reservation(20181023, 20181028) + # end + # + # it "finds room dates" do + # binding.pry + # expect(@hotel.list_rooms_available(2018923, 201892)) + # end + # end + # describe "Hotel#find_available_rooms(check_in, check_out)" do + # before do + # hotel = Hotel.new + # reservation_1 = hotel.make_reservation(2018923, 2018926) + # reservation_2 = hotel.make_reservation(2018923, 2018928) + # reservation_3 = hotel.make_reservation(2018925, 2018101) + # binding.pry + # end + # + # it "returns all rooms that are availble for given dates" do + # # binding.pry + # expect(hotel.find_available_rooms(2018923, 2018926)) + # end + # # + # end + + +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb new file mode 100644 index 000000000..fc123eab2 --- /dev/null +++ b/spec/reservation_spec.rb @@ -0,0 +1,37 @@ +require_relative 'spec_helper' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +require 'pry' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +require_relative '../lib/room.rb' +require_relative '../lib/reservation.rb' +require_relative '../lib/hotel.rb' + + +describe "Reservation Class" do + describe "initializer" do + before do + room = Room.new(2) + @reservation = Reservation.new(2018923, 2018926, room) + end + + it "returns an instance of Reservation" do + expect(@reservation).must_be_kind_of Reservation + end + + it "raises error when given invalid dates" do + room = Room.new(2) + expect {(Reservation.new(2018926, 2018923, room))}.must_raise ArgumentError + end + + it "calculates the reservation cost correctly" do + expect(@reservation.cost).must_equal 600 + end + + end + # TODO: Test for nights and during? methods + +end diff --git a/spec/room_spec.rb b/spec/room_spec.rb new file mode 100644 index 000000000..0e15b7414 --- /dev/null +++ b/spec/room_spec.rb @@ -0,0 +1,18 @@ +require_relative 'spec_helper' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +require_relative '../lib/room.rb' +require_relative '../lib/reservation.rb' + + +describe "Room" do + it "returns an instance of Room" do + new_room = Room.new(13) + expect(new_room).must_be_kind_of Room + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4d1e3fdc8..19448e311 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,12 @@ +require 'simplecov' +SimpleCov.start require 'minitest' require 'minitest/autorun' require 'minitest/reporters' -# Add simplecov + Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +require_relative '../lib/room.rb' +require_relative '../lib/reservation.rb' # Require_relative your lib files here!