ALL IN, CLEAR NALANG AT KULAY
unknown
c_cpp
a year ago
49 kB
8
Indexable
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <cmath>
#include <limits>
#include <algorithm>
#include <set>
#include <sstream>
#include <fstream>
// Required for std::find_if and std::remove
using namespace std;
struct Book {
int id;
string title;
int copies;
// Define an equality operator to compare books by their ID
bool operator == (const Book& other) const {
return id == other.id;
}
};
struct BorrowedBookDetails {
string title;
string dateBorrow;
string dateReturn;
};
struct Borrower {
int id;
string lastName, firstName, middleInitial;
vector<BorrowedBookDetails> borrowedBooks; // Stores multiple borrowed books
int overdueFee = 0;
};
vector<Book> fictionBooks;
vector<Book> nonFictionBooks;
vector<Book> scienceBooks;
vector<Book> mysteryBooks;
vector<Book> romanceBooks;
vector<Book> biographyBooks;
vector<Book> historyBooks;
vector<Book> technologyBooks;
vector<Book> childrenBooks;
vector<Book> artBooks;
vector<Borrower> borrowers;
set<int> uniqueBookIDs;
set<int> uniqueBorrowerIDs;
const string BOOKS_FILE = "books.txt";
const string BORROWERS_FILE = "borrowers.txt";
void displayMainMenu();
void displayAddMenu();
void addBook();
void displayMenu();
void displayBooks();
void displaySearchMenu();
void searchBook();
void addBorrower();
void viewBorrowers();
void searchBorrower();
void borrowBook();
void displayBorrowedDetails(const Borrower& borrower);
void returnBook();
void displayTableHeader();
void displayTable(const vector<Book>& books, const string& header);
void displayBorrowerTableHeader();
void displayBorrowerTable(const Borrower& borrower);
int calculateOverdueFee(const string& borrowDate, const string& returnDate);
void saveBooks();
void loadBooks();
void saveBorrowers();
void loadBorrowers();
bool isValidDate(const string& date) {
if (date.size() != 10 || date[4] != '-' || date[7] != '-') {
return false;
}
int year, month, day;
if (sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3) {
return false;
}
if (year < 1900 || year > 2100 || month < 1 || month > 12 || day < 1 || day > 31) {
return false;
}
if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
return false;
}
if (month == 2) {
bool isLeap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
if (day > (isLeap ? 29 : 28)) {
return false;
}
}
return true;
}
int main() {
loadBooks(); // Load books at the start
loadBorrowers();
displayMainMenu();
borrowBook();
return 0;
}
void saveBooks() {
ofstream outFile(BOOKS_FILE);
if (outFile.is_open()) {
for (const auto& book : fictionBooks) {
outFile << "Fiction," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : nonFictionBooks) {
outFile << "NonFiction," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : scienceBooks) {
outFile << "Science Fiction & Fantasy," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : mysteryBooks) {
outFile << "Mystery & Thriller," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : romanceBooks) {
outFile << "Romance," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : biographyBooks) {
outFile << "Biography & Autobiography," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : historyBooks) {
outFile << "History," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : technologyBooks) {
outFile << "Science & Technology," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : childrenBooks) {
outFile << "Children's Book," << book.id << "," << book.title << "," << book.copies << endl;
}
for (const auto& book : artBooks) {
outFile << "Art & Design," << book.id << "," << book.title << "," << book.copies << endl;
}
outFile.close();
} else {
cout << "Error opening books file for writing.\n";
}
}
void loadBooks() {
ifstream inFile(BOOKS_FILE);
if (inFile.is_open()) {
string line;
while (getline(inFile, line)) {
stringstream ss(line);
string category;
Book book;
getline(ss, category, ',');
ss >> book.id;
ss.ignore(); // Ignore the comma
getline(ss, book.title, ',');
ss >> book.copies;
// Add book to the appropriate category
if (category == "Fiction") fictionBooks.push_back(book);
else if (category == "NonFiction") nonFictionBooks.push_back(book);
else if (category == "Science Fiction & Fantasy") scienceBooks.push_back(book);
else if (category == "Mystery & Thriller") mysteryBooks.push_back(book);
else if (category == "Romance") romanceBooks.push_back(book);
else if (category == "Biography & Autobiography") biographyBooks.push_back(book);
else if (category == "History") historyBooks.push_back(book);
else if (category == "Science & Technology") scienceBooks.push_back(book);
else if (category == "Children's Book") childrenBooks.push_back(book);
else if (category == "Art & Design") artBooks.push_back(book);
}
inFile.close();
} else {
cout << "Error opening books file for reading.\n";
}
}
void saveBorrowers() {
ofstream outFile(BORROWERS_FILE);
if (outFile.is_open()) {
for (const auto& borrower : borrowers) {
outFile << borrower.id << "," << borrower.lastName << "," << borrower.firstName << ","
<< borrower.middleInitial << ",";
// Save borrowed book details
for (const auto& book : borrower.borrowedBooks) {
outFile << book.title << "," << book.dateBorrow << "," << book.dateReturn << ",";
}
outFile << borrower.overdueFee << endl;
}
outFile.close();
} else {
cout << "Error opening borrowers file for writing.\n";
}
}
void loadBorrowers() {
ifstream inFile(BORROWERS_FILE);
if (inFile.is_open()) {
string line;
while (getline(inFile, line)) {
stringstream ss(line);
Borrower borrower;
string borrowedBookTitle, dateBorrow, dateReturn;
ss >> borrower.id;
ss.ignore(); // Ignore the comma
getline(ss, borrower.lastName, ',');
getline(ss, borrower.firstName, ',');
getline(ss, borrower.middleInitial, ',');
// Read borrowed book details
while (getline(ss, borrowedBookTitle, ',')) {
if (borrowedBookTitle.empty()) break; // Stop if no more books
getline(ss, dateBorrow, ',');
getline(ss, dateReturn, ',');
borrower.borrowedBooks.push_back({borrowedBookTitle, dateBorrow, dateReturn});
}
ss >> borrower.overdueFee;
borrowers.push_back(borrower);
uniqueBorrowerIDs.insert(borrower.id); // Ensure unique IDs
}
inFile.close();
} else {
cout << "Error opening borrowers file for reading.\n";
}
}
void displayMainMenu() {
int choice;
do {
cout <<" ________ __ __ ______ __ ______ __ ______ "<<endl;
cout <<" /\\ ____\\ /\\ \\_\\ \\ /\\ ___\\ /\\ \\ /\\ ___\\ /\\ \\ /\\ ___\\ "<<endl;
cout <<" \\ \\____ \\ \\ \\ __ \\ \\ \\ __\\ \\ \\ \\____ \\ \\ __\\ \\ \\ \\ \\ \\ __\\ "<<endl;
cout <<" \\/\\_______\\ \\ \\_\\ \\_\\ \\ \\_____\\ \\ \\_____\\ \\ \\_\\ \\ \\_\\ \\ \\_____\\ "<<endl;
cout <<" \\/_______/ \\/_/\\/_/ \\/_____/ \\/_____/ \\/_/ \\/_/ \\/_____/ "<<endl;
cout << "\n==== Library Book Borrowing System ====\n";
cout << "[1] Add Menu\n";
cout << "[2] Display Menu\n";
cout << "[3] Search Menu\n";
cout << "[4] Borrow Book\n";
cout << "[5] Return Book\n";
cout << "[6] Exit\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
displayAddMenu();
break;
case 2:
displayMenu();
break;
case 3:
displaySearchMenu();
break;
case 4:
borrowBook();
break;
case 5:
returnBook();
break;
case 6:
char confirm;
cout << "Are you sure you want to exit the system? (Y/N): ";
cin >> confirm;
saveBooks();
saveBorrowers();
if (confirm == 'Y' || confirm == 'y') {
cout << "Exiting system. Goodbye!\n";
exit(0);
} else {
choice = 0; // Reset the choice to prevent exiting
}
break;
default: cout << "Invalid choice. Please try again.\n";
}
} while (choice != 6);
}
void displayTableHeader() {
cout << "---------------------------------------------------\n";
cout << "| ID | Title | Copies |\n";
cout << "---------------------------------------------------\n";
}
void displayTable(const vector<Book>& books, const string& header = "") {
for (const auto& book : books) {
cout << "| " << setw(10) << book.id << " | "
<< setw(25) << left << book.title.substr(0, 25) << "| "
<< setw(7) << right << book.copies << " |\n";
}
cout << "---------------------------------------------------\n";
}
void displayAddMenu() {
int choice;
do {
cout << "\n==== Add Menu ====\n";
cout << "[1] Add Book\n";
cout << "[2] Add Borrower\n";
cout << "[3] Return to Main Menu\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
addBook();
break;
case 2:
addBorrower();
break;
case 3:
return; // Return to the main menu
default:
cout << "Invalid choice. Please try again.\n";
}
} while (choice != 3);
}
void addBook() {
int category;
// Clear the screen at the start
system("CLS"); // Use "clear" for Unix/Linux systems
cout << "\nSELECT BOOK CATEGORY:\n";
cout << "[1] Fiction\n";
cout << "[2] Non-Fiction\n";
cout << "[3] Science Fiction & Fantasy\n";
cout << "[4] Mystery & Thriller\n";
cout << "[5] Romance\n";
cout << "[6] Biography & Autobiography\n";
cout << "[7] History\n";
cout << "[8] Science & Technology\n";
cout << "[9] Children's Book\n";
cout << "[10] Art & Design\n";
cout << "Enter category: ";
cin >> category;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (category < 1 || category > 10) {
cout << "Invalid category. Please enter a number between 1 and 10.\n";
return;
}
Book newBook;
cout << "Enter Book ID: ";
cin >> newBook.id;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (uniqueBookIDs.find(newBook.id) != uniqueBookIDs.end()) {
cout << "Error: Book ID must be unique. Book not added.\n";
return;
}
cout << "Enter Book Title: ";
getline(cin, newBook.title);
cout << "Enter Number of Copies: ";
string copiesInput;
getline(cin, copiesInput);
if (!copiesInput.empty()) {
newBook.copies = stoi(copiesInput);
} else {
cout << "Invalid number of copies. Please enter a valid number.\n";
return;
}
// Add the book to the respective category
switch (category) {
case 1: fictionBooks.push_back(newBook); break;
case 2: nonFictionBooks.push_back(newBook); break;
case 3: scienceBooks.push_back(newBook); break;
case 4: mysteryBooks.push_back(newBook); break;
case 5: romanceBooks.push_back(newBook); break;
case 6: biographyBooks.push_back(newBook); break;
case 7: historyBooks.push_back(newBook); break;
case 8: technologyBooks.push_back(newBook); break;
case 9: childrenBooks.push_back(newBook); break;
case 10: artBooks.push_back(newBook); break;
default:
cout << "Invalid category. Book not added.\n";
return;
}
uniqueBookIDs.insert(newBook.id);
// Display the recently added book
cout << "\nBOOK ADDED SUCCESSFULLY!\n";
cout << "Recently Added Book Details:\n";
displayTableHeader();
displayTable({newBook});
// Clear input buffer and screen after displaying the book
cin.clear();
cout << "\nPress Enter to return to the main menu...";
cin.get(); // Wait for the user to press Enter
system("CLS"); // Use "clear" for Unix/Linux systems
displayMainMenu();
}
void displayCategoryBooks(vector<Book>* books, const string& categoryName) {
cout << "\nCategory: " << categoryName << "\n";
if (books->empty()) {
cout << "No books available in this category.\n";
} else {
// Call the displayTable function to display the table
displayTableHeader();
displayTable(*books);
}
// Clear input buffer
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Pause before returning
cout << "\nPress Enter to return to the previous menu...";
cin.get();
system("CLS"); // Use "clear" for Unix/Linux systems
}
void displayMenu() {
int displayChoice;
do {
system("CLS"); // Clear the screen
cout << "\n==== Display Menu ====\n";
cout << "[1] Display Books\n";
cout << "[2] View Borrowers\n";
cout << "[3] Back to Main Menu\n";
cout << "Enter your choice: ";
cin >> displayChoice;
switch (displayChoice) {
case 1:
displayBooks();
break;
case 2:
viewBorrowers();
break;
case 3:
return; // Return to the main menu
default:
cout << "Invalid choice. Please try again.\n";
}
} while (displayChoice != 3);
}
void displayBooks() {
system("CLS"); // Clear the screen
int category;
cout << "\nSelect Book Category:\n";
cout << "[1] Fiction\n";
cout << "[2] Non-Fiction\n";
cout << "[3] Science Fiction & Fantasy\n";
cout << "[4] Mystery & Thriller\n";
cout << "[5] Romance\n";
cout << "[6] Biography & Autobiography\n";
cout << "[7] History\n";
cout << "[8] Science & Technology\n";
cout << "[9] Children's Book\n";
cout << "[10] Art & Design\n";
cout << "[11] Display all books\n";
cout << "Enter category: ";
cin >> category;
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please enter a valid number.\n";
return;
}
vector<pair<vector<Book>*, string>> categories = {
{&fictionBooks, "Fiction"},
{&nonFictionBooks, "Non-Fiction"},
{&scienceBooks, "Science Fiction & Fantasy"},
{&mysteryBooks, "Mystery & Thriller"},
{&romanceBooks, "Romance"},
{&biographyBooks, "Biography & Autobiography"},
{&historyBooks, "History"},
{&technologyBooks, "Science & Technology"},
{&childrenBooks, "Children's Book"},
{&artBooks, "Art & Design"},
};
if (category >= 1 && category <= 10) {
displayCategoryBooks(categories[category - 1].first, categories[category - 1].second);
} else if (category == 11) {
vector<Book> allBooks;
for (const auto& cat : categories) {
allBooks.insert(allBooks.end(), cat.first->begin(), cat.first->end());
}
cout << "\nDisplaying all books:\n";
if (allBooks.empty()) {
cout << "No books available to display.\n";
} else {
displayTableHeader();
displayTable(allBooks);
}
// Pause before returning
cout << "\nPress Enter to return to the menu...";
cin.ignore();
cin.get();
system("CLS");
} else {
cout << "Invalid category.\n";
}
}
void searchBook() {
system("CLS"); // Use "clear" for Unix/Linux systems
int choice;
int bookID;
cout << "Enter Book ID: ";
cin >> bookID;
// Function to find and manage books
auto findAndManageBook = [&](vector<Book>& books) -> bool {
auto it = find_if(books.begin(), books.end(), [bookID](const Book& book) {
return book.id == bookID;
});
if (it != books.end()) {
cout << "\nBook Found:\n";
displayTableHeader();
// Display the found book details
vector<Book> foundBook = {*it}; // Create a vector with the found book
displayTable(foundBook); // Display the book in table format
cout << "[1] Edit\n";
cout << "[2] Delete\n";
cout << "[3] Go Back to Main Menu\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1: {
// Ask which part of the book the user wants to edit
int editChoice;
cout << "\nWhat would you like to edit?\n";
cout << "[1] Title\n";
cout << "[2] Number of Copies\n";
cout << "[3] Both Title and Copies\n";
cout << "Enter your choice: ";
cin >> editChoice;
if (editChoice == 1) {
cout << "Enter new title: ";
cin.ignore(); // Clear input buffer
getline(cin, it->title);
cout << "Book title updated successfully.\n";
}
else if (editChoice == 2) {
cout << "Enter new number of copies: ";
cin >> it->copies;
cout << "Number of copies updated successfully.\n";
}
else if (editChoice == 3) {
cout << "Enter new title: ";
cin.ignore(); // Clear input buffer
getline(cin, it->title);
cout << "Enter new number of copies: ";
cin >> it->copies;
cout << "Book updated successfully.\n";
}
else {
cout << "Invalid choice. Returning to Main Menu.\n";
}
// Display the updated book details in a tabular format
cout << "\nUpdated Book:\n";
displayTableHeader(); // Display the table header
vector<Book> updatedBook = {*it}; // Create a vector with the updated book
displayTable(updatedBook); // Display the updated book in table format
// Pause before returning to the search menu
cout << "\nPress Enter to return to the Search Menu...";
cin.ignore();
cin.get();
break;
}
case 2:
char confirm;
cout << "Are you sure you want to delete this book? (y/n): ";
cin >> confirm;
if (confirm == 'y' || confirm == 'Y') {
books.erase(it); // Remove the book from the list
cout << "Book deleted successfully.\n";
} else {
cout << "Book deletion canceled.\n";
}
// Pause before returning to the search menu
cout << "\nPress Enter to return to the Search Menu...";
cin.ignore();
cin.get();
break;
case 3:
cout << "Returning to Search Menu.\n";
return true;
default:
cout << "Invalid choice. Returning to Main Menu.\n";
}
return true;
}
return false;
};
// Search in fictionBooks and nonFictionBooks
if (!findAndManageBook(fictionBooks) && !findAndManageBook(nonFictionBooks) && !findAndManageBook(scienceBooks) && !findAndManageBook(mysteryBooks ) && !findAndManageBook(romanceBooks) && !findAndManageBook(biographyBooks) && !findAndManageBook(historyBooks) && !findAndManageBook(technologyBooks) && !findAndManageBook(childrenBooks) && !findAndManageBook(artBooks)) {
cout << "Book not found.\n";
// Pause before returning to the search menu
cout << "\nPress Enter to return to the Search Menu...";
cin.ignore();
cin.get();
}
}
void displaySearchMenu() {
int choice;
do {
system("CLS"); // Clear the screen
cout << "==== Search Menu ====\n";
cout << "[1] Search Book\n";
cout << "[2] Search Borrower\n";
cout << "[3] Return to Main Menu\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
searchBook();
break;
case 2:
searchBorrower();
break;
case 3:
cout << "Returning to Main Menu.\n";
return;
default:
cout << "Invalid choice. Please try again.\n";
}
} while (choice != 3);
}
void searchBorrower() {
int borrowerID;
cout << "Enter Borrower ID to search: ";
cin >> borrowerID;
// Find borrower by ID
auto it = find_if(borrowers.begin(), borrowers.end(), [borrowerID](const Borrower& b) {
return b.id == borrowerID;
});
if (it != borrowers.end()) {
// Display borrower details
cout << "\nBorrower Found:\n";
cout << setw(10) << "ID" << setw(20) << "Name" << endl;
cout << setw(10) << it->id
<< setw(20) << it->lastName + ", " + it->firstName + " " + it->middleInitial + "." << endl;
// Provide options
int choice;
cout << "\n[1] View Borrowed Books\n";
cout << "[2] Return to Main Menu\n";
cout << "Enter your choice: ";
cin >> choice;
if (choice == 1) {
if (it->borrowedBooks.empty()) {
cout << "No borrowed books.\n";
} else {
cout << "\nBorrowed Books:\n";
cout << setw(20) << "Book Title" << setw(20) << "Borrowed Date" << setw(20) << "Date Returned" << endl;
for (const auto& book : it->borrowedBooks) {
cout << setw(20) << book.title
<< setw(20) << book.dateBorrow
<< setw(20) << (book.dateReturn.empty() ? "Not Returned" : book.dateReturn) << endl;
}
}
// Wait for user input to continue
cout << "\nPress any key to return to the menu...\n";
cin.ignore();
cin.get();
} else if (choice == 2) {
return; // Go back to main menu
} else {
cout << "Invalid choice. Returning to main menu.\n";
}
} else {
cout << "Borrower with ID " << borrowerID << " not found.\n";
}
}
void addBorrower() {
Borrower newBorrower;
cout << "Enter Borrower ID: ";
cin >> newBorrower.id;
// Check if the ID is unique
if (uniqueBorrowerIDs.find(newBorrower.id) != uniqueBorrowerIDs.end()) {
cout << "Error: Borrower ID must be unique. Borrower not added.\n";
return;
}
cin.ignore(); // Clear the input buffer
cout << "Enter Last Name: ";
getline(cin, newBorrower.lastName);
cout << "Enter First Name: ";
getline(cin, newBorrower.firstName);
cout << "Enter Middle Initial: ";
getline(cin, newBorrower.middleInitial);
borrowers.push_back(newBorrower);
uniqueBorrowerIDs.insert(newBorrower.id); // Add the ID to the unique set
cout << "Borrower added successfully!\n";
// Display the recently added borrower in table format
displayBorrowerTableHeader();
displayBorrowerTable(newBorrower);
}
void displayBorrowerTableHeader() {
cout << "------------------------------------------------------------------------------------------\n";
cout << "| ID | Full Name | Book | Borrowed Date | Return Date | Fee |\n";
cout << "------------------------------------------------------------------------------------------\n";
}
void displayBorrowerTable(const Borrower& borrower) {
if (borrower.borrowedBooks.empty()) {
// Display borrower details with no books borrowed
cout << "| " << left << setw(10) << borrower.id
<< "| " << setw(25) << borrower.firstName + " " + borrower.middleInitial + " " + borrower.lastName
<< "| " << setw(20) << "No books borrowed" // Indicating no books borrowed
<< "| " << setw(14) << "N/A" // No borrow date
<< "| " << setw(12) << "N/A" // No return date
<< "| " << setw(6) << borrower.overdueFee << " |\n";
} else {
for (const auto& bookDetails : borrower.borrowedBooks) {
cout << "| " << left << setw(10) << borrower.id
<< "| " << setw(25) << borrower.firstName + " " + borrower.middleInitial + " " + borrower.lastName
<< "| " << setw(20) << bookDetails.title
<< "| " << setw(14) << bookDetails.dateBorrow
<< "| " << setw(12) << bookDetails.dateReturn
<< "| " << setw(6) << borrower.overdueFee << " |\n";
}
}
cout << "------------------------------------------------------------------------------------------\n";
}
void viewBorrowers() {
system("CLS"); // Clear the screen for a clean display
cout << "\n==== List of Borrowers ====\n";
if (borrowers.empty()) {
cout << "No borrowers found.\n";
} else {
// Call displayBorrowerTableHeader to print the table header
displayBorrowerTableHeader();
// Print borrower details using displayBorrowerTable for each borrower in the list
for (const auto& borrower : borrowers) {
displayBorrowerTable(borrower);
}
}
// Pause to allow the user to see the output
cout << "\nPress Enter to return to the Display Menu...";
cin.ignore();
cin.get(); // Waits for the user to press Enter
}
void borrowFromCategory(Borrower& borrower, int bookID, const string& date) {
// Check each category
for (auto& book : fictionBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Fiction category!\n";
displayBorrowedDetails(borrower);
return;
}
}
// Repeat the check for other categories (Non-Fiction, Science, etc.)
for (auto& book : nonFictionBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Non-Fiction category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : scienceBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Science Fiction & Fantasy category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : mysteryBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Mystery & Thriller category! \n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : romanceBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Romance category!!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : biographyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Biography category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : historyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from History category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : technologyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Science & Technology category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : childrenBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Children's category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : artBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Art & Design!\n";
displayBorrowedDetails(borrower);
return;
}
}
}
void borrowBook() {
int borrowerID, bookID;
string date;
cout << "Enter Borrower ID: ";
cin >> borrowerID;
bool borrowerFound = false;
for (auto& borrower : borrowers) {
if (borrower.id == borrowerID) {
borrowerFound = true;
break;
}
}
if (!borrowerFound) {
cout << "Error: Borrower ID not found. Please enter a valid Borrower ID.\n";
return; // Exit the function if Borrower ID is invalid
}
cout << "Enter Book ID: ";
cin >> bookID;
bool bookFound = false;
for (auto& book : fictionBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
if (!bookFound) {
for (auto& book : nonFictionBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : scienceBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : mysteryBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : romanceBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : biographyBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : historyBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : technologyBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : childrenBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
for (auto& book : artBooks) {
if (book.id == bookID && book.copies > 0) {
bookFound = true;
break;
}
}
}
if (!bookFound) {
cout << "Error: Book ID not found or no copies available.\n";
return; // Exit the function if Book ID is invalid or no copies are available
}
cin.ignore();
cout << "Enter Date of Borrow (YYYY-MM-DD): ";
getline(cin, date);
if (!isValidDate(date)) {
cout << "Invalid date format. Please enter a valid date (YYYY-MM-DD).\n";
return;
}
for (auto& borrower : borrowers) {
if (borrower.id == borrowerID) {
// Check Fiction books
for (auto& book : fictionBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Fiction category!\n";
displayBorrowedDetails(borrower);
return;
}
}
// Repeat for other categories
for (auto& book : nonFictionBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Non-Fiction category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : scienceBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Science category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : mysteryBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Mystery category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : romanceBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Romance category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : biographyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Biography category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : historyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from History category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : technologyBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Technology category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : childrenBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Children category!\n";
displayBorrowedDetails(borrower);
return;
}
}
for (auto& book : artBooks) {
if (book.id == bookID && book.copies > 0) {
borrower.borrowedBooks.push_back({book.title, date, ""});
book.copies--;
cout << "Book borrowed successfully from Art category!\n";
displayBorrowedDetails(borrower);
return;
}
}
cout << "Book not found or no copies available in any category.\n";
return;
}
}
cout << "Borrowing failed. Borrower ID not found.\n";
}
// Function definition for displaying borrower details
void displayBorrowedDetails(const Borrower& borrower) {
cout << "---------------------------------------------------------------\n";
cout << "| Borrower Name | Book Title | Date Borrowed |\n";
cout << "---------------------------------------------------------------\n";
if (borrower.borrowedBooks.empty()) {
cout << "| " << left << setw(58) << "No books borrowed yet." << " |\n";
cout << "---------------------------------------------------------------\n";
} else {
// If there are borrowed books, print them
for (const auto& borrowedBook : borrower.borrowedBooks) {
cout << "| " << left << setw(20) << borrower.firstName + " " + borrower.middleInitial + " " + borrower.lastName
<< "| " << setw(20) << borrowedBook.title
<< "| " << setw(14) << borrowedBook.dateBorrow << " |\n";
}
cout << "---------------------------------------------------------------\n";
}
}
void returnBook() {
int borrowerID, bookID;
string returnDate;
// Input borrower and book IDs and the return date
cout << "Enter Borrower ID: ";
cin >> borrowerID;
cout << "Enter Book ID: ";
cin >> bookID;
cin.ignore();
cout << "Enter Date of Return (YYYY-MM-DD): ";
getline(cin, returnDate);
// Check if the borrower ID is valid
bool borrowerFound = false;
for (auto& borrower : borrowers) {
if (borrower.id == borrowerID) {
borrowerFound = true;
break;
}
}
if (!borrowerFound) {
cout << "Error: Borrower ID is not valid.\n";
return;
}
// Check if the book ID is valid in any book category
bool bookFound = false;
for (auto& category : {fictionBooks, nonFictionBooks, scienceBooks, mysteryBooks, romanceBooks,
biographyBooks, historyBooks, technologyBooks, childrenBooks, artBooks}) {
for (auto& book : category) {
if (book.id == bookID) {
bookFound = true;
break;
}
}
if (bookFound) {
break;
}
}
if (!bookFound) {
cout << "Error: Book ID is not valid or not found in the inventory.\n";
return;
}
// Iterate through the list of borrowers
for (auto& borrower : borrowers) {
if (borrower.id == borrowerID && !borrower.borrowedBooks.empty()) { // Check if the borrower exists and has borrowed books
bool bookFoundInBorrowedBooks = false;
// Find the book that matches the bookID in the borrower's list of borrowed books
for (auto& borrowedBook : borrower.borrowedBooks) {
if (borrowedBook.title == "") {
continue;
}
if (bookFoundInBorrowedBooks) break;
if (bookFoundInBorrowedBooks = borrowedBook.title == borrowedBook.title) {
int overdueFee = calculateOverdueFee(borrowedBook.dateBorrow, returnDate); // Calculate the overdue fee
borrowedBook.dateReturn = returnDate; // Set the return date
borrower.overdueFee = overdueFee; // Update the borrower's overdue fee
if (overdueFee == 0) {
// Case 1: On-time return
cout << "Book returned SUCCESSFULLY.\n";
displayBorrowerTableHeader();
// Display the borrower details using displayBorrowerTable
displayBorrowerTable(borrower);
} else {
// Case 2: Late return with fee
cout << "Book returned SUCCESSFULLY. But, you need to pay for not following the rules.\n";
cout << "\n--- E-Receipt ---\n";
cout << "Borrower's Name: " << borrower.firstName + " " + borrower.middleInitial + " " + borrower.lastName << "\n";
cout << "Book Title: " << borrowedBook.title << "\n";
cout << "Date Borrowed: " << borrowedBook.dateBorrow << "\n";
cout << "Date Returned: " << borrowedBook.dateReturn << "\n";
cout << "Overdue Fee: " << overdueFee << " pesos\n";
cout << "------------------\n";
}
// Return the book to inventory
for (auto& book : fictionBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : nonFictionBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : scienceBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copied
return;
}
}
for (auto& book : mysteryBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copied
return;
}
}
for (auto& book : romanceBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : biographyBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
borrowedBook.title = ""; // Clear the borrowed book record
return;
}
}
for (auto& book : historyBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : technologyBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : childrenBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
for (auto& book : artBooks) { // Repeat for all categories
if (book.id == bookID) {
book.copies++; // Increase the available copies
return;
}
}
cout << "Book not found in the library inventory.\n";
return;
}
}
}
}
// If borrower or book ID not found
cout << "Borrower ID or Book ID not found, or the borrower did not borrow any books.\n";
}
int daysSinceStartOfYear(int year, int month, int day) {
static const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int totalDays = 0;
// Add days of months in the same year
for (int i = 0; i < month - 1; ++i) {
totalDays += daysInMonth[i];
}
// Add the current month's days
totalDays += day;
// Handle leap years for February
if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
totalDays += 1; // Leap day
}
return totalDays;
}
int daysFromDate(const string& date) {
int year, month, day;
sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
// Calculate total days since 1900-01-01
int totalDays = (year - 1900) * 365 + (year - 1900) / 4 - (year - 1900) / 100 + (year - 1900) / 400;
totalDays += daysSinceStartOfYear(year, month, day);
return totalDays;
}
int calculateOverdueFee(const string& borrowDate, const string& returnDate) {
int borrowDays = daysFromDate(borrowDate);
int returnDays = daysFromDate(returnDate);
int daysBorrowed = returnDays - borrowDays;
int maxDays = 7;
int overdueDays = max(0, daysBorrowed - maxDays);
return overdueDays * 5; // Fee of 5 pesos per day
}
Editor is loading...
Leave a Comment