-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHotel.java
408 lines (357 loc) · 11.5 KB
/
Hotel.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
import java.util.HashMap;
import java.util.ArrayList;
/**
* The Hotel class defines a hotel with a name, an array of rooms, and a base room price.
*/
public class Hotel {
/** Name of the hotel. */
private String name;
/**
* List of rooms in the hotel.
* Constraints: Must be between 1 - 50.
*/
private ArrayList<Room> rooms;
/**
* Number of standard rooms in the hotel.
*/
private int standardRoomCount;
/**
* Number of deluxe rooms in the hotel.
*/
private int deluxeRoomCount;
/**
* Number of executive rooms in the hotel.
*/
private int executiveRoomCount;
/**
* How much a room costs per night.
* All rooms in the hotel cost the same.
* Constraints: Must be >= 100.
*/
private double basePrice;
/**
* Date price modifier hashmap where the days are keys and the modifiers are the values
*/
private HashMap<Integer, Double> datePriceModifier;
/**
* Constructor that creates an empty hotel with only its name.
* @param name Name of hotel.
* @param standardRoomCount How many standard rooms are in the hotel.
* @param deluxeRoomCount How many deluxe rooms are in the hotel.
* @param executiveRoomCount How many executive rooms are in the hotel.
* @throws InvalidRoomCountException Exception that happens when there are too many or too little rooms.
*/
public Hotel(String name, int standardRoomCount, int deluxeRoomCount, int executiveRoomCount) throws InvalidRoomCountException {
int totalRoomCount = standardRoomCount + deluxeRoomCount + executiveRoomCount;
datePriceModifier = new HashMap<Integer, Double>();
if (totalRoomCount > 0 && totalRoomCount < 51) {
this.name = name;
// Create new ArrayList instance rooms.
rooms = new ArrayList<Room>(totalRoomCount);
// Default room base price is 1299 as per spec.
this.basePrice = 1299;
this.standardRoomCount = standardRoomCount;
this.deluxeRoomCount = deluxeRoomCount;
this.executiveRoomCount = executiveRoomCount;
// Initialize rooms when creating the hotel. Names go from 001, 002, ... 00n
for (int i = 0; i < this.standardRoomCount; i++) {
rooms.add(new StandardRoom(String.format("S%03d", i + 1), basePrice));
}
for (int i = 0; i < this.deluxeRoomCount; i++) {
rooms.add(new DeluxeRoom(String.format("D%03d", i + 1), basePrice));
}
for (int i = 0; i < this.executiveRoomCount; i++) {
rooms.add(new ExecutiveRoom(String.format("E%03d", i + 1), basePrice));
}
for(int i = 1; i <= 31; i++) {
datePriceModifier.put(i,1.0);
}
} else {
throw new InvalidRoomCountException();
}
}
/**
* Gets the name of the Hotel.
* @return Hotel name.
*/
public String getName() {
return name;
}
/**
* Gets the Room List.
* @return ArrayList containing the Room instances.
*/
public ArrayList<Room> getRooms() {
return rooms;
}
/**
* getRoom() takes a room name and searches the hotel for a room with that name.
* @param inputRoomName Name to search for.
* @return Room object with matching name. Returns null if no Room with a matching name was found.
*/
public Room getRoom(String inputRoomName) {
for (int i = 0; i < rooms.size(); i++) {
if (inputRoomName.equals(rooms.get(i).getName())) {
return rooms.get(i);
}
}
return null;
}
/**
* Secondary getRoom function that uses an index instead of a name to return a Room object.
* @param i index of the Room.
* @return Room object with matching index. Returns null if out of bounds.
*/
public Room getRoom(int i) {
if (i >= 0 && i < getRoomCount()) {
return rooms.get(i);
} else {
return null;
}
}
/**
* Gets the total count of Rooms in the Hotel.
* @return Number of Rooms that the Hotel has.
*/
public int getRoomCount() {
return rooms.size();
}
/**
* Returns the number of rooms in the hotel that are occupied in a specific timeframe.
* @param checkIn Date object describing the check in time.
* @param checkOut Date object describing the check out time. These will determine timeframe for checking.
* @return Number of occupied rooms.
*/
public int getBookedRoomCount(Date checkIn, Date checkOut) {
if (checkOut.isBefore(checkIn)) {
throw new IllegalArgumentException("Check-out date must be after check-in date.");
}
int count = 0;
for (int i = 0; i < this.rooms.size(); i++) {
if (!isRoomAvailable(getRoom(i).getName(), checkIn, checkOut)) {
count += 1;
}
}
return count;
}
/**
* Returns the number of rooms in the hotel that are available in a specific timeframe.
* @param checkIn Date object describing the check in time.
* @param checkOut Date object describing the check out time. These will determine timeframe for checking.
* @return Number of unoccupied (free) rooms.
*/
public int getAvailableRoomCount(Date checkIn, Date checkOut) {
if (checkOut.isBefore(checkIn)) {
throw new IllegalArgumentException("Check-out date must be after check-in date.");
}
int count = 0;
for (int i = 0; i < this.rooms.size(); i++) {
if (isRoomAvailable(getRoom(i).getName(), checkIn, checkOut)) {
count += 1;
}
}
return count;
}
/**
* Gets the base price per night for all Rooms in the Hotel.
* @return Base price per night. It is defaulted to 1299
*/
public double getBasePrice() {
return basePrice;
}
/**
* addRoom() adds a specified number of rooms to the hotel.
* @param count Number of rooms to add.
* @param type Type of Room as a string (Standard room, Deluxe room, Executive room)
* @throws InvalidRoomCountException Exception for invalid number of rooms. Hotels can have a maximum of 50 rooms as per specifications.
*/
public void addRoom(int count, String type) throws InvalidRoomCountException {
if (getRoomCount() + count > 50 || count < 1) {
throw new InvalidRoomCountException();
} else {
int lastRoomNumber;
for (int i = 0; i < count; i++) {
switch (type) {
case "Standard room":
standardRoomCount += 1;
lastRoomNumber = getLastRoomNumber(type);
rooms.add(new StandardRoom(String.format("S%03d", lastRoomNumber + 1), basePrice));
break;
case "Deluxe room":
deluxeRoomCount += 1;
lastRoomNumber = getLastRoomNumber(type);
rooms.add(new DeluxeRoom(String.format("D%03d", lastRoomNumber + 1), basePrice));
break;
case "Executive room":
executiveRoomCount += 1;
lastRoomNumber = getLastRoomNumber(type);
rooms.add(new ExecutiveRoom(String.format("E%03d", lastRoomNumber + 1), basePrice));
break;
}
}
}
}
/**
* getLastRoomNumber gets the last room number of a specific type of room
* @param type type of room as a String
* @return integer that represents the last room number
*/
public int getLastRoomNumber(String type) {
String name = "";
int number;
for(int i = 0; i < getRoomCount(); i++) {
switch(type) {
case "Standard room":
if(this.rooms.get(i) instanceof StandardRoom) {
name = this.rooms.get(i).getName().substring(1);
}
break;
case "Deluxe room":
if(this.rooms.get(i) instanceof DeluxeRoom) {
name = this.rooms.get(i).getName().substring(1);
}
break;
case "Executive room":
if(this.rooms.get(i) instanceof ExecutiveRoom) {
name = this.rooms.get(i).getName().substring(1);
}
break;
}
}
if(name.equals("")) {
number = 0;
}
else {
number = Integer.parseInt(name);
}
return number;
}
/**
* removeRoom() removes a room from the hotel.
* @param name Name of room to remove.
* @throws RoomNotFoundException Exception when a room with a given name is not found in the hotel.
* @throws InvalidRoomCountException Exception when the room being removed is the last in a hotel.
* @throws RoomIsOccupiedException Exception when the room is occupied.
*/
public void removeRoom(String name) throws RoomNotFoundException, InvalidRoomCountException, RoomIsOccupiedException {
if (rooms.size() == 1) {
throw new InvalidRoomCountException();
}
for (int i = 0; i < rooms.size(); i++) {
if (rooms.get(i).getName().equals(name)) {
if (rooms.get(i) instanceof StandardRoom) {
standardRoomCount -= 1;
} else if (rooms.get(i) instanceof DeluxeRoom) {
deluxeRoomCount -= 1;
} else {
executiveRoomCount -= 1;
}
if (rooms.get(i).getReservationCount() == 0) {
rooms.remove(i);
return;
} else {
throw new RoomIsOccupiedException();
}
}
}
throw new RoomNotFoundException("A room with that name was not found.");
}
/**
* isRoomAvailable() checks if a given room is available between the specified dates.
* @param roomName Name of room to check in to.
* @param checkInDate Check-in date of user.
* @param checkOutDate Check-out date of user.
* @return True if room is available. False otherwise.
*/
public boolean isRoomAvailable(String roomName, Date checkInDate, Date checkOutDate) {
boolean roomAvailable = true;
Room room = getRoom(roomName);
if(room.isOccupied(checkInDate, checkOutDate)) {
roomAvailable = false;
}
return roomAvailable;
}
/**
* Sets the name of the Hotel.
* @param name New name of Hotel.
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the new base price of the Hotel.
* @param basePrice New base price of the Hotel.
* @throws RoomIsOccupiedException Exception when attempting to modify a hotel with bookings.
* @throws InvalidBasePriceException Exception when attempting tot set a base price of less than 100.
*/
public void setBasePrice(double basePrice) throws RoomIsOccupiedException, InvalidBasePriceException {
for (int i = 0; i < getRoomCount(); i++) {
if (getRoom(i).getReservationCount() != 0) {
throw new RoomIsOccupiedException();
}
}
if (basePrice >= 100.0) {
this.basePrice = basePrice;
for (Room room : rooms) {
room.setRoomPrice(basePrice);
}
} else {
throw new InvalidBasePriceException();
}
}
/**
* Gets the total amount of earnings from all reservations in the Hotel.
* @return Total amount of Earnings based on the number of reservations and how long each reservation lasts.
*/
public double getTotalEarnings() {
double total = 0;
for(int i = 0; i < this.rooms.size(); i++) {
for(int j = 0; j < getRoom(i).getReservationCount(); j++) {
total += getRoom(i).getReservation(j).getTotalPrice();
}
}
return total;
}
/**
* isFull() checks if all of the rooms in the hotel are completely booked (from day 1 - 31).
* @return True if all rooms are completely booked. False otherwise.
*/
public boolean isFull() {
for (int i = 0; i < getRoomCount(); i++) {
if (!getRoom(i).isFull()) {
return false;
}
}
return true;
}
/**
* Gets the HashMap for the price modifiers with days as keys
* @return HashMap for the price modifiers with days as keys
*/
public HashMap<Integer, Double> getDatePriceModifiers() {
return this.datePriceModifier;
}
/**
* Gets the specific price modifer for a given day
* @param day day index to get the price modifier (day index starts at 1 for the first day).
* @return modifier which is a double
*/
public double getDatePriceModifier(int day) {
return this.datePriceModifier.get(day);
}
/**
* Sets the price modifier for a given day
* @param day day index to get the price modifier (day index starts at 1 for the first day).
* @param modifier new price modifier for the day.
* @return true if valid day was selected (1-31), false otherwise
*/
public boolean setDatePriceModifier(int day, double modifier) {
if(day >= 1 && day <= 31) {
this.datePriceModifier.put(day, modifier);
return true;
}
else {
return false;
}
}
}