/****************************************************************************** name: void listReservationsGaps description: The inverse of listReservations -- instead of listing when the room is reserved, it lists the gaps between reservations, to display when the room is NOT reserved parameters: n/a returns: n/a ******************************************************************************/ void Rom::listReservationsGaps() { int availableFrom = tid.hent_dato(), nextArrival = 0; Reservasjon* temp = nullptr; for(int i = 1; i <= Reservations->no_of_elements(); i++) { temp = (Reservasjon*) Reservations->remove_no(i); Reservations->add(temp); if(temp->getArrival() <= availableFrom && temp->getDeparture() > tid.hent_dato()) availableFrom = temp->getDeparture(); else if(temp->getDeparture() < availableFrom) availableFrom = tid.hent_dato(); else if(temp->getArrival() > availableFrom) nextArrival = temp->getArrival(); if(nextArrival > availableFrom) cout << "\nRoom #" << temp->getRoomID() << " is available from " << availableFrom << "-" << nextArrival; availableFrom = temp->getDeparture(); } if(((availableFrom > 0 && nextArrival == 0) ||( availableFrom > 0 && nextArrival < availableFrom) && temp != nullptr)) { cout << "\nRoom #" << temp->getRoomID() << " is available from " << availableFrom; cin.get(); } }
/****************************************************************************** name: void editReservation(string, int) description: Edit a reservation. If possible, you can change the arrival and/or departure date. parameters: (string) name, (int) date returns: n/a ******************************************************************************/ void Rom::editReservation(string name, int date) { extern Timer tid; int todaysDate = tid.hent_dato(); int newDate; char userCommand; for (int i = 1; i <= Reservations->no_of_elements(); i++) { Reservasjon * temp = (Reservasjon *) Reservations->remove_no(i); if (temp->getArrival() == date && temp->sameNameAsReservation(name)) { if (temp->getInUse() == 0) { cout << "\nAvailable choices:"; cout << "\n\t 1) Change arrival date"; cout << "\n\t 2) Change departure date"; cout << "\n\t Q) QUIT"; userCommand = readCommand(); switch(userCommand) { case '1': { do { // Gir "kunde" den allerede registrerte datoen, i // tilfellet ikke ledig i andre tidsperioder. // (For å hindre en loop man ikke kommer seg ut av) cout << "Arrival date already registered: " << temp->getArrival() << "\n"; cout << "\nEnter the new arrival date: "; cin >> newDate; cin.ignore(); // Check if room is reserved between the new date and deparature. } while (this->isReserved(newDate, tid.forskjell_datoer(newDate, date))); temp->setArrival(newDate); cout << "\nNotice: Arrival date has been updated.\n"; cin.get(); break; } case '2': { do { // Gir "kunde" den allerede registrerte datoen, // i tilfellet ikke ledig i andre tidsperioder. // (For å hindre en loop man ikke kommer seg ut av) cout << "The departure date already registered: " << temp->getDeparture() << "\n"; cout << "\nEnter the new departure date: "; cin >> newDate; cin.ignore(); } while (this->isReserved( temp->getArrival(), tid.forskjell_datoer(temp->getArrival(), newDate)) ); temp->setDeparture(newDate); cout << "\nNotice: Departure date has been updated.\n"; cin.get(); break; } } } else if(temp->getInUse() == 1) { cout << "\nAvailable choices:"; cout << "\n\t 1) Change departure date"; cout << "\n\t Q) QUIT"; userCommand = readCommand(); } else { cout << "Error: Can't change arrival date. This person has already checked in.\n"; cout << "Press any key to continue"; cin.get(); } }
Reservasjon* Rom::reservationByDate(int date, int action) { extern Hotell* hotellet; for (int i = 1; i <= Reservations->no_of_elements(); i++) { Reservasjon* temp = (Reservasjon*) Reservations->remove_no(i); // If this method was called with action CHECKOUT and departure date is the provided date for the reservation, // or action was checkin and arrival date is the date of this reservation, then return the reservation if ((action == CHECKOUT) || (action == CHECKIN && temp->getArrival() == date)) { // If action is checkout, destroy reservation, and create a temporary reservation object with errorcode // "reservation has been pruned" to be returned if(action == CHECKOUT && temp->getDeparture() == date) { temp->display(); if(readChar("Confirm checkout?",'y','n')=='y') { // Get filename, subtract file ending and apply new filename std::string hotellHst = hotellet->getFilename().substr(0, hotellet->getFilename().size()-4); hotellHst += ".hst"; // ... aaaand output! std::ofstream o(hotellHst.c_str(), std::ios::out|ios::app); temp->writeDataToFile(o); Reservations->destroy(temp->getRoomID()); temp = new Reservasjon(reservationHasBeenPruned); } // Otherwise, put it back in the list else Reservations->add(temp); } // If action is checkout, and a reservation on the room is current, but departure on reservation is not today, // ask if we want to check him out earlier than planned, and if so, call this method with his/her planned // departure date else if(action == CHECKOUT && temp->getDeparture() >= date && temp->getArrival() <= date) { std::cout << "\nGuest in room " << temp->getRoomID() << " is not meant to check out until " << temp->getDeparture(); if(readChar("\nCheck out anyways?",'y','n') == 'y') { Reservations->add(temp); return reservationByDate(temp->getDeparture(), CHECKOUT); } } // If action is check in, ask for confirmation to check in, and display information about the reservation else if(action == CHECKIN && readChar("Check-in?",'y','n') == 'y') { temp->display(); temp->setCheckin(); Reservations->add(temp); } // Otherwise, put it back in our list else { Reservations->add(temp); } return temp; } // If the method was called with NOOP action, as in NO OPeration, display the data without modifying it; essentially the same as // checkin, except it ONLY displays data about the reservation, and date may be any date within the time period of the reservation, // as opposed to requiring a specific checkin date. It does however require guests to be checked in. else if (action == NOOP && temp->getDeparture() >= date && temp->getArrival() <= date && temp->getInUse() == true) { //temp->display(roomNumber); Reservations->add(temp); return temp; } } // If no matching reservation was found, return a new reservations object, with // roomID containing the errorcode return new Reservasjon(reservationDoesNotExist); }
/****************************************************************************** name: isReserved() description: Checks if the room is booked on (or between) certain dates parameters: int date, int nights return: (bool) 0 = room is not reserved 1 = room is reserved ******************************************************************************/ bool Rom::isReserved(int date, int nights) { // If we have no reservations at all, there's no need to check ... if(Reservations->is_empty()) return false; // We use a tm timestruct to make SURE our dates are correct when iterating later on... struct tm time; int correctedTime; // Lets set up that time struct... time.tm_year = date / 10000; time.tm_mon = (date % (time.tm_year * 10000)) / 100; time.tm_mday = (date % (time.tm_year * 10000)) % 100; time.tm_hour = 12; time.tm_min = 0; time.tm_sec = 0; mktime(&time); // Loop through the list from end to beginning for(int i = Reservations->no_of_elements(); i > 0; i--) { // ... and remove each element, one at the time ... Reservasjon* r = (Reservasjon*) Reservations->remove_no(i); // Now, if nights-parameter is set, we must check the status of the room // for several days ... if(nights > 0) { // Increment date by 1 ... for(int k=1; k<=nights; k++) { // Increment tm_mday, then run mktime to correct potentially invalid values time.tm_mday++; mktime(&time); // ... and now, format that to YYYYMMDD :) correctedTime = (time.tm_year * 10000) + (time.tm_mon * 100) + time.tm_mday; // If this new time value is a value between the arrival and departure value of the reservation, // that would imply the room is already booked on that day ... if(correctedTime >= r->getArrival() && correctedTime <= r->getDeparture()) { // ... and put our reservation back in the list... Reservations->add(r); // If it's booked, just return -- no point in continuing return true; } } } else if(date >= r->getArrival() && date <= r->getDeparture()) { // ... and put our reservation back in the list... Reservations->add(r); // If it's booked, just return -- no point in continuing return true; } } return false; }