#include <iostream>
#include <string>
#include <ctime>
using namespace std;
string hashPassword(string password, string salt) {
string result = password + salt;
for (int round = 0; round < 1000; round++) {
string temp = "";
for (int i = 0; i < (int)result.length(); i++) {
char c = (char)((result[i] ^ (round % 256) ^ (i % 256)) & 0xFF);
if (c < 32 || c > 126) c = (char)(((unsigned char)c % 95) + 32);
temp += c;
}
for (int i = 0; i < (int)result.length(); i++) {
temp[i % temp.length()] ^= result[i];
if (temp[i % temp.length()] < 32 || temp[i % temp.length()] > 126)
temp[i % temp.length()] = (char)(((unsigned char)temp[i % temp.length()] % 95) + 32);
}
result = temp;
}
if ((int)result.length() > 32) result = result.substr(0, 32);
return result;
}
string hashPass(string password, string username) {
return hashPassword(password, username + "DebtEase_Salt_2026");
}
struct Item {
string name;
int quantity;
double price;
};
struct BorrowSession {
string date;
string dueDate;
Item* items;
int itemCount;
int itemCap;
double total;
double paid;
};
struct Borrower {
string userID;
string username;
string passHash;
string fullName;
string contact;
int lenderIndex;
BorrowSession* sessions;
int sessionCount;
int sessionCap;
};
struct Lender {
string username;
string passHash;
string fullName;
string storeName;
string contact;
};
Lender* lenders = new Lender[2];
int lenderCount = 0;
int lenderCap = 2;
Borrower* borrowers = new Borrower[2];
int borrowerCount = 0;
int borrowerCap = 2;
void growLenders() {
lenderCap *= 2;
Lender* tmp = new Lender[lenderCap];
for (int i = 0; i < lenderCount; i++) tmp[i] = lenders[i];
delete[] lenders;
lenders = tmp;
}
void growBorrowers() {
borrowerCap *= 2;
Borrower* tmp = new Borrower[borrowerCap];
for (int i = 0; i < borrowerCount; i++) tmp[i] = borrowers[i];
delete[] borrowers;
borrowers = tmp;
}
void initSession(BorrowSession& s) {
s.itemCap = 4;
s.itemCount = 0;
s.total = 0;
s.paid = 0;
s.items = new Item[s.itemCap];
}
void addItemToSession(BorrowSession& s, Item item) {
if (s.itemCount == s.itemCap) {
s.itemCap *= 2;
Item* tmp = new Item[s.itemCap];
for (int i = 0; i < s.itemCount; i++) tmp[i] = s.items[i];
delete[] s.items;
s.items = tmp;
}
s.items[s.itemCount++] = item;
s.total += item.quantity * item.price;
}
void addSessionToBorrower(Borrower& b, BorrowSession s) {
if (b.sessionCount == b.sessionCap) {
b.sessionCap *= 2;
BorrowSession* tmp = new BorrowSession[b.sessionCap];
for (int i = 0; i < b.sessionCount; i++) tmp[i] = b.sessions[i];
delete[] b.sessions;
b.sessions = tmp;
}
b.sessions[b.sessionCount++] = s;
}
void initBorrower(Borrower& b) {
b.sessionCap = 4;
b.sessionCount = 0;
b.sessions = new BorrowSession[b.sessionCap];
}
void pressEnter() {
cout << "\n Press Enter to continue...";
cin.ignore();
cin.get();
}
string getDate() {
time_t now = time(0);
tm* t = localtime(&now);
string d = to_string(t->tm_mday);
string m = to_string(1 + t->tm_mon);
string y = to_string(1900 + t->tm_year);
if (d.length() == 1) d = "0" + d;
if (m.length() == 1) m = "0" + m;
return y + "-" + m + "-" + d;
}
string pad(string s, int w) {
while ((int)s.length() < w) s += " ";
if ((int)s.length() > w) s = s.substr(0, w);
return s;
}
string dbl(double v) {
if (v < 0) v = 0;
long whole = (long)v;
int cents = (int)((v - whole) * 100.0 + 0.5);
if (cents >= 100) { whole++; cents = 0; }
string c = to_string(cents);
if (c.length() == 1) c = "0" + c;
return to_string(whole) + "." + c;
}
string formatID(int n) {
string s = to_string(n);
while ((int)s.length() < 5) s = "0" + s;
return s;
}
double getBorrowerBalance(int bIdx) {
double total = 0, paid = 0;
for (int s = 0; s < borrowers[bIdx].sessionCount; s++) {
total += borrowers[bIdx].sessions[s].total;
paid += borrowers[bIdx].sessions[s].paid;
}
return total - paid;
}
string getNearestDue(int bIdx) {
string nearest = "";
for (int s = 0; s < borrowers[bIdx].sessionCount; s++) {
string d = borrowers[bIdx].sessions[s].dueDate;
if (nearest == "" || d < nearest) nearest = d;
}
return nearest == "" ? "N/A" : nearest;
}
bool usernameExists(string uname) {
for (int i = 0; i < lenderCount; i++)
if (lenders[i].username == uname) return true;
for (int i = 0; i < borrowerCount; i++)
if (borrowers[i].username == uname) return true;
return false;
}
bool userIDExists(string uid) {
for (int i = 0; i < borrowerCount; i++)
if (borrowers[i].userID == uid) return true;
return false;
}
string inputStr(string prompt) {
string val = "";
while (val == "") {
cout << prompt;
getline(cin, val);
if (val == "") cout << " [!] Cannot be empty. Try again.\n";
}
return val;
}
int inputInt(string prompt) {
string line = "";
while (true) {
cout << prompt;
getline(cin, line);
if (line == "") { cout << " INVALID INPUT!!! Try again.\n"; continue; }
bool isNum = true;
bool hasSign = (line[0] == '-');
int start = hasSign ? 1 : 0;
if (start >= (int)line.length()) isNum = false;
for (int i = start; i < (int)line.length() && isNum; i++)
if (line[i] < '0' || line[i] > '9') isNum = false;
if (!isNum) { cout << " INVALID INPUT!!! Try again.\n"; continue; }
return stoi(line);
}
}
double inputDbl(string prompt) {
string line = "";
while (true) {
cout << prompt;
getline(cin, line);
if (line == "") { cout << " INVALID INPUT!!! Try again.\n"; continue; }
bool ok = true; bool dotSeen = false;
for (int i = 0; i < (int)line.length() && ok; i++) {
if (line[i] == '.' && !dotSeen) { dotSeen = true; continue; }
if (line[i] < '0' || line[i] > '9') ok = false;
}
if (!ok) { cout << " INVALID INPUT!!! Try again.\n"; continue; }
return stod(line);
}
}
void printLine(int w) {
cout << " +";
for (int i = 0; i < w; i++) cout << "-";
cout << "+\n";
}
void printHeader(string title, int w) {
printLine(w);
int space = (w - (int)title.length()) / 2;
if (space < 0) space = 0;
cout << " |";
for (int i = 0; i < space; i++) cout << " ";
cout << title;
int rest = w - space - (int)title.length();
for (int i = 0; i < rest; i++) cout << " ";
cout << "|\n";
printLine(w);
}
void printRow(string left, int w) {
cout << " | " << pad(left, w - 2) << " |\n";
}
void displayBorrowerDetails(int bIdx) {
Borrower& b = borrowers[bIdx];
cout << "\n";
printHeader("BORROWER DETAILS", 64);
printRow("User ID : " + b.userID, 64);
printRow("Name : " + b.fullName, 64);
printRow("Username : " + b.username, 64);
printRow("Contact : " + b.contact, 64);
printLine(64);
if (b.sessionCount == 0) {
printRow("No borrow sessions yet.", 64);
printLine(64);
return;
}
double grandTotal = 0, grandPaid = 0;
for (int s = 0; s < b.sessionCount; s++) {
BorrowSession& ses = b.sessions[s];
cout << "\n";
printHeader("BORROW SESSION #" + to_string(s + 1), 64);
printRow("Date Borrowed : " + ses.date, 64);
printRow("Due Date : " + ses.dueDate, 64);
printLine(64);
cout << " | " << pad(" ITEM NAME", 24)
<< pad("QTY", 6)
<< pad("PRICE", 14)
<< pad("SUBTOTAL", 16) << " |\n";
printLine(64);
for (int i = 0; i < ses.itemCount; i++) {
double sub = ses.items[i].quantity * ses.items[i].price;
cout << " | " << pad(" " + ses.items[i].name, 24)
<< pad(to_string(ses.items[i].quantity), 6)
<< pad("P" + dbl(ses.items[i].price), 14)
<< pad("P" + dbl(sub), 16) << " |\n";
}
printLine(64);
double bal = ses.total - ses.paid;
printRow("Session Total : P" + dbl(ses.total), 64);
printRow("Amount Paid : P" + dbl(ses.paid), 64);
printRow("Remaining Bal : P" + dbl(bal), 64);
printLine(64);
grandTotal += ses.total;
grandPaid += ses.paid;
}
cout << "\n";
printHeader("GRAND SUMMARY", 64);
printRow("Total Borrowed : P" + dbl(grandTotal), 64);
printRow("Total Paid : P" + dbl(grandPaid), 64);
printRow("BALANCE OWED : P" + dbl(grandTotal - grandPaid), 64);
printLine(64);
}
void recalcSession(BorrowSession& ses) {
ses.total = 0;
for (int i = 0; i < ses.itemCount; i++)
ses.total += ses.items[i].quantity * ses.items[i].price;
}
void deleteItemFromSession(BorrowSession& ses) {
if (ses.itemCount == 0) {
cout << " No items to delete.\n";
pressEnter();
return;
}
bool back = false;
while (!back) {
cout << "\n";
printHeader("DELETE ITEM", 64);
cout << " | " << pad("#", 4) << pad("ITEM NAME", 24)
<< pad("QTY", 6) << pad("PRICE", 14) << pad("SUBTOTAL", 12) << " |\n";
printLine(64);
for (int i = 0; i < ses.itemCount; i++) {
double sub = ses.items[i].quantity * ses.items[i].price;
cout << " | " << pad("[" + to_string(i + 1) + "]", 4)
<< pad(ses.items[i].name, 24)
<< pad(to_string(ses.items[i].quantity), 6)
<< pad("P" + dbl(ses.items[i].price), 14)
<< pad("P" + dbl(sub), 12) << " |\n";
}
printLine(64);
cout << " [0] Back\n";
int choice = inputInt(" Select item number to DELETE: ");
if (choice == 0) { back = true; break; }
if (choice < 1 || choice > ses.itemCount) {
cout << " INVALID INPUT!!!\n"; continue;
}
string delName = ses.items[choice - 1].name;
for (int i = choice - 1; i < ses.itemCount - 1; i++)
ses.items[i] = ses.items[i + 1];
ses.itemCount--;
recalcSession(ses);
cout << " Item '" << delName << "' deleted.\n";
cout << " New Session Total: P" << dbl(ses.total) << "\n";
back = true;
}
}
void addBorrowSession(int bIdx) {
BorrowSession ses;
initSession(ses);
ses.date = getDate();
cout << "\n";
printHeader("ADD BORROW SESSION", 52);
printRow("Print [0] to cancel", 52);
printLine(52);
cout << " Date Borrowed : " << ses.date << "\n";
while (true) {
cout << " Due Date (YYYY-MM-DD): ";
string dd; getline(cin, dd);
if (dd == "0") {
cout << " Cancelled.\n"; pressEnter(); return;
}
if (dd.length() != 10 || dd[4] != '-' || dd[7] != '-') {
cout << " INVALID INPUT!!! Format must be YYYY-MM-DD\n"; continue;
}
ses.dueDate = dd;
break;
}
bool doneAdding = false;
while (!doneAdding) {
cout << "\n";
printHeader("ITEM LIST", 64);
if (ses.itemCount == 0) {
printRow(" (no items yet)", 64);
} else {
cout << " | " << pad("#", 4) << pad("ITEM NAME", 22)
<< pad("QTY", 6) << pad("PRICE", 14) << pad("SUBTOTAL", 14) << " |\n";
printLine(64);
for (int i = 0; i < ses.itemCount; i++) {
double sub = ses.items[i].quantity * ses.items[i].price;
cout << " | " << pad(to_string(i + 1), 4)
<< pad(ses.items[i].name, 22)
<< pad(to_string(ses.items[i].quantity), 6)
<< pad("P" + dbl(ses.items[i].price), 14)
<< pad("P" + dbl(sub), 14) << " |\n";
}
}
printLine(64);
cout << " Current Total: P" << dbl(ses.total) << "\n";
cout << "\n";
printHeader("ITEM OPTIONS", 40);
printRow("[1] Add Item", 40);
printRow("[2] Remove Item", 40);
printRow("[3] Save Session", 40);
printRow("[0] Cancel session", 40);
printLine(40);
int opt = inputInt(" Choice: ");
if (opt == 0) { cout << " Session discarded.\n"; pressEnter(); return; }
else if (opt == 1) {
Item item;
item.name = inputStr(" Item Name : ");
item.quantity = inputInt(" Quantity : ");
if (item.quantity <= 0) { cout << " INVALID INPUT!!!\n"; continue; }
item.price = inputDbl(" Price (P) : ");
if (item.price <= 0) { cout << " INVALID INPUT!!!\n"; continue; }
double sub = item.quantity * item.price;
cout << " Subtotal: P" << dbl(sub) << "\n";
addItemToSession(ses, item);
}
else if (opt == 2) deleteItemFromSession(ses);
else if (opt == 3) {
if (ses.itemCount == 0) {
cout << " Cannot save empty session. Add at least 1 item.\n"; continue;
}
doneAdding = true;
}
else cout << " INVALID INPUT!!!\n";
}
addSessionToBorrower(borrowers[bIdx], ses);
cout << "\n";
printHeader("SESSION SAVED", 52);
printRow("Date : " + ses.date, 52);
printRow("Due : " + ses.dueDate, 52);
printRow("Total : P" + dbl(ses.total), 52);
printLine(52);
pressEnter();
}
void addThingsToExisting(int bIdx) {
Borrower& b = borrowers[bIdx];
if (b.sessionCount == 0) {
cout << " No sessions found. Use 'Add New Borrow' instead.\n";
pressEnter(); return;
}
cout << "\n";
printHeader("SELECT SESSION TO ADD ITEMS", 52);
for (int s = 0; s < b.sessionCount; s++) {
cout << " | " << pad("[" + to_string(s + 1) + "] Due: "
+ b.sessions[s].dueDate
+ " Total: P" + dbl(b.sessions[s].total), 50) << " |\n";
}
printLine(52);
cout << " [0] Back\n";
int choice = inputInt(" Select session: ");
if (choice == 0) return;
if (choice < 1 || choice > b.sessionCount) {
cout << " INVALID INPUT!!!\n"; pressEnter(); return;
}
BorrowSession& ses = b.sessions[choice - 1];
bool done = false;
while (!done) {
cout << "\n";
printHeader("ADD / DELETE ITEMS", 40);
printRow("[1] Add Item", 40);
printRow("[2] Delete Item", 40);
printRow("[0] Back", 40);
printLine(40);
int opt = inputInt(" Choice: ");
if (opt == 0) done = true;
else if (opt == 1) {
Item item;
item.name = inputStr(" Item Name : ");
item.quantity = inputInt(" Quantity : ");
if (item.quantity <= 0) { cout << " INVALID INPUT!!!\n"; continue; }
item.price = inputDbl(" Price (P) : ");
if (item.price <= 0) { cout << " INVALID INPUT!!!\n"; continue; }
addItemToSession(ses, item);
cout << " Item added! New Total: P" << dbl(ses.total) << "\n";
}
else if (opt == 2) deleteItemFromSession(ses);
else cout << " INVALID INPUT!!!\n";
}
}
void payBorrowed(int bIdx) {
Borrower& b = borrowers[bIdx];
if (b.sessionCount == 0) {
cout << " No sessions found.\n"; pressEnter(); return;
}
bool back = false;
while (!back) {
cout << "\n";
printHeader("PAY BORROWED THINGS", 68);
cout << " | " << pad("#", 4) << pad("Due Date", 14)
<< pad("Total", 14) << pad("Paid", 14) << pad("Balance", 18) << " |\n";
printLine(68);
int active = 0;
for (int s = 0; s < b.sessionCount; s++) {
double bal = b.sessions[s].total - b.sessions[s].paid;
if (bal > 0.001) {
active++;
cout << " | " << pad("[" + to_string(s + 1) + "]", 4)
<< pad(b.sessions[s].dueDate, 14)
<< pad("P" + dbl(b.sessions[s].total), 14)
<< pad("P" + dbl(b.sessions[s].paid), 14)
<< pad("P" + dbl(bal), 18) << " |\n";
}
}
printLine(68);
if (active == 0) {
cout << " All sessions are FULLY PAID!\n";
pressEnter(); return;
}
cout << " [0] Back\n";
int choice = inputInt(" Select session to pay: ");
if (choice == 0) { back = true; break; }
if (choice < 1 || choice > b.sessionCount) {
cout << " INVALID INPUT!!!\n"; continue;
}
BorrowSession& ses = b.sessions[choice - 1];
double balance = ses.total - ses.paid;
if (balance <= 0.001) {
cout << " This session is already FULLY PAID.\n"; pressEnter(); continue;
}
cout << " Remaining Balance: P" << dbl(balance) << "\n";
double payment = inputDbl(" Enter payment amount: P");
if (payment <= 0) { cout << " INVALID INPUT!!!\n"; continue; }
if (payment > balance) {
cout << " Amount exceeds balance. Adjusted to P" << dbl(balance) << "\n";
payment = balance;
}
ses.paid += payment;
double newBal = ses.total - ses.paid;
cout << "\n";
printHeader("PAYMENT RECEIPT", 54);
printRow("Payment Made : P" + dbl(payment), 54);
printRow("Total Paid : P" + dbl(ses.paid), 54);
printRow("Remaining Bal : P" + dbl(newBal), 54);
printLine(54);
if (newBal <= 0.001) cout << " FULLY PAID! Great!\n";
else cout << " Partial payment recorded.\n";
pressEnter();
back = true;
}
}
void mergeSortDue(int* arr, int left, int right) {
if (left >= right) return;
int mid = (left + right) / 2;
mergeSortDue(arr, left, mid);
mergeSortDue(arr, mid + 1, right);
int n1 = mid - left + 1, n2 = right - mid;
int* L = new int[n1];
int* R = new int[n2];
for (int i = 0; i < n1; i++) L[i] = arr[left + i];
for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (getNearestDue(L[i]) <= getNearestDue(R[j])) arr[k++] = L[i++];
else arr[k++] = R[j++];
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
delete[] L; delete[] R;
}
void mergeSortBalance(int* arr, int left, int right) {
if (left >= right) return;
int mid = (left + right) / 2;
mergeSortBalance(arr, left, mid);
mergeSortBalance(arr, mid + 1, right);
int n1 = mid - left + 1, n2 = right - mid;
int* L = new int[n1];
int* R = new int[n2];
for (int i = 0; i < n1; i++) L[i] = arr[left + i];
for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (getBorrowerBalance(L[i]) >= getBorrowerBalance(R[j])) arr[k++] = L[i++];
else arr[k++] = R[j++];
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
delete[] L; delete[] R;
}
void sortByUsername(int* arr, int size) {
for (int i = 1; i < size; i++) {
int key = arr[i], j = i - 1;
while (j >= 0 && borrowers[arr[j]].username > borrowers[key].username) {
arr[j + 1] = arr[j]; j--;
}
arr[j + 1] = key;
}
}
int binarySearch(int* arr, int size, string target) {
int lo = 0, hi = size - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (borrowers[arr[mid]].username == target) return arr[mid];
else if (borrowers[arr[mid]].username < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}
int* getLenderBorrowers(int lenderIdx, int& count) {
count = 0;
for (int i = 0; i < borrowerCount; i++)
if (borrowers[i].lenderIndex == lenderIdx) count++;
if (count == 0) return nullptr;
int* arr = new int[count];
int k = 0;
for (int i = 0; i < borrowerCount; i++)
if (borrowers[i].lenderIndex == lenderIdx) arr[k++] = i;
return arr;
}
void borrowerActionMenu(int bIdx) {
bool back = false;
while (!back) {
cout << "\n";
printHeader(borrowers[bIdx].fullName + " - ACTIONS", 46);
printRow("[1] Add Things (New Borrow Session)", 46);
printRow("[2] Add Items to Existing Session", 46);
printRow("[3] Pay Borrowed Things", 46);
printRow("[4] View Full Details", 46);
printRow("[0] Back", 46);
printLine(46);
int c = inputInt(" Choice: ");
if (c == 0) back = true;
else if (c == 1) addBorrowSession(bIdx);
else if (c == 2) addThingsToExisting(bIdx);
else if (c == 3) payBorrowed(bIdx);
else if (c == 4) { displayBorrowerDetails(bIdx); pressEnter(); }
else cout << " INVALID INPUT!!!\n";
}
}
void seeDueDates(int lenderIdx) {
int count = 0;
int* arr = getLenderBorrowers(lenderIdx, count);
if (!arr || count == 0) {
cout << " No borrowers found.\n"; pressEnter();
if (arr) delete[] arr; return;
}
mergeSortDue(arr, 0, count - 1);
bool back = false;
while (!back) {
cout << "\n";
printHeader("DUE DATES (Earliest First - Merge Sorted)", 66);
cout << " | " << pad("#", 4) << pad("NAME", 22)
<< pad("NEAREST DUE", 16) << pad("BALANCE", 20) << " |\n";
printLine(66);
int shown = 0;
for (int i = 0; i < count; i++) {
if (borrowers[arr[i]].sessionCount == 0) continue;
shown++;
cout << " | " << pad("[" + to_string(i + 1) + "]", 4)
<< pad(borrowers[arr[i]].fullName, 22)
<< pad(getNearestDue(arr[i]), 16)
<< pad("P" + dbl(getBorrowerBalance(arr[i])), 20) << " |\n";
}
if (shown == 0) { printRow(" No active borrowers.", 66); }
printLine(66);
cout << " [0] Back\n";
int choice = inputInt(" Select borrower: ");
if (choice == 0) { back = true; break; }
if (choice < 1 || choice > count) { cout << " INVALID INPUT!!!\n"; continue; }
displayBorrowerDetails(arr[choice - 1]);
pressEnter();
back = true;
}
delete[] arr;
}
void seeAllBorrowers(int lenderIdx) {
int count = 0;
int* arr = getLenderBorrowers(lenderIdx, count);
if (!arr || count == 0) {
cout << " No borrowers registered.\n"; pressEnter();
if (arr) delete[] arr; return;
}
mergeSortBalance(arr, 0, count - 1);
bool back = false;
while (!back) {
cout << "\n";
printHeader("ALL BORROWERS (Biggest Balance First - Merge Sorted)", 66);
cout << " | " << pad("#", 4) << pad("ID", 8) << pad("NAME", 24)
<< pad("BALANCE", 26) << " |\n";
printLine(66);
for (int i = 0; i < count; i++) {
cout << " | " << pad("[" + to_string(i + 1) + "]", 4)
<< pad(borrowers[arr[i]].userID, 8)
<< pad(borrowers[arr[i]].fullName, 24)
<< pad("P" + dbl(getBorrowerBalance(arr[i])), 26) << " |\n";
}
printLine(66);
cout << " [0] Back\n";
int choice = inputInt(" Select borrower: ");
if (choice == 0) { back = true; break; }
if (choice < 1 || choice > count) { cout << " INVALID INPUT!!!\n"; continue; }
borrowerActionMenu(arr[choice - 1]);
back = true;
}
delete[] arr;
}
void searchBorrower(int lenderIdx) {
int count = 0;
int* arr = getLenderBorrowers(lenderIdx, count);
if (!arr || count == 0) {
cout << " No borrowers found.\n"; pressEnter();
if (arr) delete[] arr; return;
}
cout << "\n";
printHeader("SEARCH BORROWER", 54);
printRow("Search by User ID (e.g. 00001)", 54);
printRow(" or by Full Name (e.g. Juan Dela Cruz)", 54);
printLine(54);
string target = inputStr(" Enter User ID or Full Name: ");
for (int i = 1; i < count; i++) {
int key = arr[i], j = i - 1;
while (j >= 0 && borrowers[arr[j]].userID > borrowers[key].userID) {
arr[j + 1] = arr[j]; j--;
}
arr[j + 1] = key;
}
int result = -1;
int lo = 0, hi = count - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (borrowers[arr[mid]].userID == target) {
result = arr[mid]; break;
} else if (borrowers[arr[mid]].userID < target) lo = mid + 1;
else hi = mid - 1;
}
if (result == -1) {
for (int i = 0; i < count; i++) {
if (borrowers[arr[i]].fullName == target) {
result = arr[i]; break;
}
}
}
delete[] arr;
if (result == -1) {
cout << "\n Borrower not found.\n"; pressEnter(); return;
}
Borrower& b = borrowers[result];
cout << "\n";
printHeader("SEARCH RESULT", 64);
printRow("User ID : " + b.userID, 64);
printRow("Name : " + b.fullName, 64);
printRow("Username : " + b.username, 64);
printRow("Contact : " + b.contact, 64);
printLine(64);
if (b.sessionCount == 0) {
printRow("No borrow sessions yet.", 64);
printLine(64);
} else {
double grandTotal = 0, grandPaid = 0;
for (int s = 0; s < b.sessionCount; s++) {
BorrowSession& ses = b.sessions[s];
cout << "\n";
printHeader("BORROW SESSION #" + to_string(s + 1), 64);
printRow("Date Borrowed : " + ses.date, 64);
printRow("Due Date : " + ses.dueDate, 64);
printLine(64);
cout << " | " << pad(" ITEM NAME", 24)
<< pad("QTY", 6)
<< pad("PRICE", 14)
<< pad("SUBTOTAL", 16) << " |\n";
printLine(64);
for (int i = 0; i < ses.itemCount; i++) {
double sub = ses.items[i].quantity * ses.items[i].price;
cout << " | " << pad(" " + ses.items[i].name, 24)
<< pad(to_string(ses.items[i].quantity), 6)
<< pad("P" + dbl(ses.items[i].price), 14)
<< pad("P" + dbl(sub), 16) << " |\n";
}
printLine(64);
double bal = ses.total - ses.paid;
printRow("Session Total : P" + dbl(ses.total), 64);
printRow("Amount Paid : P" + dbl(ses.paid), 64);
printRow("Remaining Bal : P" + dbl(bal), 64);
printLine(64);
grandTotal += ses.total;
grandPaid += ses.paid;
}
cout << "\n";
printHeader("GRAND SUMMARY", 64);
printRow("Total Borrowed : P" + dbl(grandTotal), 64);
printRow("Total Paid : P" + dbl(grandPaid), 64);
printRow("BALANCE OWED : P" + dbl(grandTotal - grandPaid), 64);
printLine(64);
}
pressEnter();
borrowerActionMenu(result);
}
void addNewBorrower(int lenderIdx) {
if (borrowerCount == borrowerCap) growBorrowers();
Borrower& b = borrowers[borrowerCount];
initBorrower(b);
b.lenderIndex = lenderIdx;
cout << "\n";
printHeader("REGISTER NEW BORROWER", 54);
while (true) {
string uid = formatID(borrowerCount + 1);
cout << " Auto User ID: " << uid << "\n";
cout << " Use this ID? (1=Yes / 0=Enter custom): ";
int opt = inputInt("");
if (opt == 1) { b.userID = uid; break; }
else if (opt == 0) {
string cid = inputStr(" Enter custom ID (e.g. 00010): ");
if (userIDExists(cid)) {
cout << " User ID already exists!\n"; continue;
}
b.userID = cid; break;
}
else cout << " INVALID INPUT!!!\n";
}
b.fullName = inputStr(" Full Name : ");
b.contact = inputStr(" Contact : ");
while (true) {
b.username = inputStr(" Username : ");
if (usernameExists(b.username)) {
cout << " Username already taken! Try another.\n";
} else break;
}
while (true) {
string p1 = inputStr(" Password : ");
string p2 = inputStr(" Confirm Pass: ");
if (p1 != p2) {
cout << " Passwords do not match! Try again.\n"; continue;
}
b.passHash = hashPass(p1, b.username);
break;
}
borrowerCount++;
cout << "\n";
printHeader("BORROWER ACCOUNT CREATED", 54);
printRow("User ID : " + b.userID, 54);
printRow("Username : " + b.username, 54);
printRow("Name : " + b.fullName, 54);
printLine(54);
cout << " Add first borrow session now? (1=Yes / 0=No): ";
int opt = inputInt("");
if (opt == 1) addBorrowSession(borrowerCount - 1);
else pressEnter();
}
void lenderDashboard(int idx) {
bool on = true;
while (on) {
cout << "\n";
printHeader("LENDER DASHBOARD - " + lenders[idx].storeName, 54);
printRow("Owner : " + lenders[idx].fullName, 54);
printLine(54);
printRow("[1] Add New Borrower", 54);
printRow("[2] See Due Dates", 54);
printRow("[3] See All Borrowers", 54);
printRow("[4] Search Borrower", 54);
printRow("[0] Logout", 54);
printLine(54);
int c = inputInt(" Choice: ");
if (c == 0) { on = false; cout << " Logged out successfully.\n"; pressEnter(); }
else if (c == 1) addNewBorrower(idx);
else if (c == 2) seeDueDates(idx);
else if (c == 3) seeAllBorrowers(idx);
else if (c == 4) searchBorrower(idx);
else cout << " INVALID INPUT!!!\n";
}
}
void borrowerDashboard(int bIdx) {
displayBorrowerDetails(bIdx);
pressEnter();
}
void lenderLogin() {
bool back = false;
while (!back) {
cout << "\n";
printHeader("LENDER LOGIN", 44);
printRow("Press [0] to Cancel", 44);
printLine(44);
cout << " Username: ";
string u; getline(cin, u);
if (u == "0") { back = true; break; }
if (u == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Password: ";
string p; getline(cin, p);
if (p == "") { cout << " INVALID INPUT!!!\n"; continue; }
string hashed = hashPass(p, u);
bool found = false;
for (int i = 0; i < lenderCount; i++) {
if (lenders[i].username == u && lenders[i].passHash == hashed) {
cout << " Welcome, " << lenders[i].fullName << "!\n";
pressEnter();
lenderDashboard(i);
found = true;
back = true;
break;
}
}
if (!found && !back) {
cout << " Invalid username or password.\n";
}
}
}
void lenderRegister() {
bool back = false;
while (!back) {
cout << "\n";
printHeader("LENDER REGISTRATION", 54);
printRow("Press [0] to Cancel", 54);
printLine(54);
cout << " Full Name: ";
string fn; getline(cin, fn);
if (fn == "0") { back = true; break; }
if (fn == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Store Name: ";
string sn; getline(cin, sn);
if (sn == "0") { back = true; break; }
if (sn == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Contact: ";
string ct; getline(cin, ct);
if (ct == "0") { back = true; break; }
if (ct == "") { cout << " INVALID INPUT!!!\n"; continue; }
string uname = "";
while (true) {
cout << " Username: ";
getline(cin, uname);
if (uname == "0") { back = true; break; }
if (uname == "") { cout << " INVALID INPUT!!!\n"; continue; }
if (usernameExists(uname)) {
cout << " Username already taken! Try another.\n"; continue;
}
break;
}
if (back) break;
string passHash = "";
while (true) {
cout << " Password: ";
string p1; getline(cin, p1);
if (p1 == "0") { back = true; break; }
if (p1 == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Confirm : ";
string p2; getline(cin, p2);
if (p2 == "") { cout << " INVALID INPUT!!!\n"; continue; }
if (p1 != p2) { cout << " Passwords do not match!\n"; continue; }
passHash = hashPass(p1, uname);
break;
}
if (back) break;
if (lenderCount == lenderCap) growLenders();
lenders[lenderCount].fullName = fn;
lenders[lenderCount].storeName = sn;
lenders[lenderCount].contact = ct;
lenders[lenderCount].username = uname;
lenders[lenderCount].passHash = passHash;
lenderCount++;
cout << "\n Registration successful! You may now log in.\n";
pressEnter();
back = true;
}
}
void borrowerLogin() {
bool back = false;
while (!back) {
cout << "\n";
printHeader("BORROWER LOGIN", 44);
printRow("Press [0] to Cancel", 44);
printLine(44);
cout << " User ID: ";
string uid; getline(cin, uid);
if (uid == "0") { back = true; break; }
if (uid == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Username : ";
string u; getline(cin, u);
if (u == "") { cout << " INVALID INPUT!!!\n"; continue; }
cout << " Password : ";
string p; getline(cin, p);
if (p == "") { cout << " INVALID INPUT!!!\n"; continue; }
string hashed = hashPass(p, u);
bool found = false;
for (int i = 0; i < borrowerCount; i++) {
if (borrowers[i].userID == uid &&
borrowers[i].username == u &&
borrowers[i].passHash == hashed) {
cout << " Welcome, " << borrowers[i].fullName << "!\n";
pressEnter();
borrowerDashboard(i);
found = true;
back = true;
break;
}
}
if (!found && !back) {
cout << " Invalid User ID, username, or password.\n";
}
}
}
void lenderMenu() {
bool back = false;
while (!back) {
cout << "\n";
printHeader("DEBTEASE - LENDER PORTAL", 44);
printRow("[1] Login", 44);
printRow("[2] Register", 44);
printRow("[0] Back", 44);
printLine(44);
int c = inputInt(" Choice: ");
if (c == 0) back = true;
else if (c == 1) lenderLogin();
else if (c == 2) lenderRegister();
else cout << " INVALID INPUT!!!\n";
}
}
void borrowerMenu() {
bool back = false;
while (!back) {
cout << "\n";
printHeader("DEBTEASE - BORROWER PORTAL", 44);
printRow("[1] Login", 44);
printRow("[0] Back", 44);
printLine(44);
int c = inputInt(" Choice: ");
if (c == 0) back = true;
else if (c == 1) borrowerLogin();
else cout << " INVALID INPUT!!!\n";
}
}
int main() {
bool running = true;
while (running) {
cout << "\n";
printHeader("DEBTEASE - DEBT MANAGEMENT SYSTEM", 54);
printRow(" Localized Sari-Sari Store Ledger", 54);
printLine(54);
printRow("[1] Lender (Store Owner)", 54);
printRow("[2] Borrower (Customer)", 54);
printRow("[0] Exit", 54);
printLine(54);
int c = inputInt(" Choice: ");
if (c == 0) {
running = false;
cout << "\n Thank you for using DebtEase. Goodbye!\n";
}
else if (c == 1) lenderMenu();
else if (c == 2) borrowerMenu();
else cout << " INVALID INPUT!!!\n";
}
delete[] lenders;
delete[] borrowers;
return 0;
}