Created
January 22, 2023 05:04
-
-
Save apisandipas/5e1d5905de5ebf1099e925805bd152d2 to your computer and use it in GitHub Desktop.
This is my submission for my Study.com C++ Assignment, Bryan Paronto , 2023-01-21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Study.com - Computer Sciece 102: Intro to C++ Coding Assignment | |
* Author: Bryan Paronto | |
* Date: 2023-01-21 | |
* | |
* The below is an implementation of a simple Employeee Management System. | |
* | |
* To try it out, I've hardcoded 1 user of each permission level. Login with the information below: | |
* | |
* Username Password | |
* Employee- bryan bryan | |
* HR - susan susan | |
* Manager - manager manager | |
* | |
* Compilation: I've compiled the following program with the command below: | |
* > g++ employee-mgmt ./main.cpp -lstdc++ | |
* | |
* It can then be ran by running `./employee-mgmt` in the command-line in any POSIX-compliant shell. | |
* | |
* */ | |
#include <cctype> | |
#include <cstdlib> | |
#include <iostream> | |
#include <string> | |
#include <algorithm> | |
#include <iomanip> | |
#include <vector> | |
#include <functional> | |
using namespace std; | |
/* | |
** Function Declarations | |
*/ | |
int generateUserId(); | |
void LOG(); | |
void showMainScreen(); | |
void showLoginScreen(); | |
void showMenuScreen(); | |
bool validateLogin(); | |
static bool isLoggedIn = false; | |
/* | |
* Utilities | |
**/ | |
// Generate dummy user IDs for demo purposes. | |
int generateUserId() { | |
static int userId = 0; | |
return userId++; | |
} | |
void LOG(string value){ | |
cout << "debug > " << value << endl; | |
} | |
/* | |
* Class Definitions | |
**/ | |
// Employee Base class | |
// - used for generic employees and as a Base class for employees with higher priveledges | |
class Employee { | |
public: | |
string userName; | |
string password; | |
string name; | |
string jobTitle; | |
int userId; | |
// Constructor, with an optinal userId field. | |
Employee(string userName, string name, string password, string jobTitle, int userId = generateUserId()){ | |
this->userName = userName; | |
this->name = name; | |
this->password = password; | |
this->jobTitle = jobTitle; | |
this->userId = userId; | |
} | |
// Displays menu for regular employees. Default actions and View Record and Quit to Login. | |
virtual void displayMenu() { | |
cout << "MENU OPTIONS: " << endl; | |
cout << "(a) View Employee Record" << endl; | |
cout << "(q) Quit to Login Screen" << endl; | |
char choice; | |
while(true) { | |
cout << "> "; | |
cin >> choice; | |
switch (choice) { | |
case 'a': | |
this->showOwnRecord(); | |
break; | |
case 'q': | |
this->quitToLoginScreen(); | |
break; | |
default: | |
cout << "Oops, invalid choice. Try again. " << endl; | |
cout << "You picked: " << choice << endl; | |
break; | |
} | |
} | |
} | |
virtual void showOwnRecord() { | |
cout << "------------" << endl; | |
cout << "EMPLOYEE RECORD" << endl; | |
cout << left << setw(12) << "NAME: " << this->name << endl; | |
cout << left << setw(12) << "JOB TITLE: " << this->jobTitle << endl; | |
cout << left << setw(12) << "USERNAME" << this->userName << endl; | |
cout << "------------" << endl; | |
cout << endl; | |
displayMenu(); | |
} | |
void quitToLoginScreen() { | |
cin.clear(); | |
cin.ignore(1000, '\n'); | |
cout << "Goodbye."; | |
cout << endl; | |
isLoggedIn = false; | |
showLoginScreen(); | |
} | |
}; | |
// A simple data wrapper to help us manager our Employee data in an abstracted manner. | |
class EmployeeDatabase { | |
private: | |
// Because our vector consists of differenct classes, we've wrapper it in a reference_wrapper, which allowed this functionality without object slicing. | |
vector<reference_wrapper<Employee>> employees; | |
public: | |
void addEmployee(Employee &employee) { | |
this->employees.push_back(employee); | |
} | |
vector<reference_wrapper<Employee>> getAllEmployees() { | |
return this->employees; | |
} | |
void removeEmployee(int id) { | |
// Employee a lamda function to assist with filtering for a matching employee by employee's userId. | |
auto it = find_if(employees.begin(), employees.end(), [&](reference_wrapper<Employee> employee) { return employee.get().userId == id; }); | |
if ( it != employees.end() ) { | |
employees.erase(it); | |
} | |
} | |
}; | |
// Instantiation of our Employee Database | |
static EmployeeDatabase db; | |
// Instantiation of a placeholder for our currenrtly logged in user. | |
static reference_wrapper<Employee> loggedInUser = *new Employee("", "", "" , ""); | |
// A Manager Employeee class which has extended permissions to view all Employeee Records. | |
class Manager: public Employee { | |
using Employee::Employee; | |
public: | |
void displayMenu() override { | |
cout << "MENU OPTIONS: " << endl; | |
cout << "(a) View Employee Record" << endl; | |
cout << "(b) View All Employee Records" << endl; | |
cout << "(q) Quit to Login Screen" << endl; | |
char choice; | |
while(true) { | |
cout << "> "; | |
cin >> choice; | |
switch (choice) { | |
case 'a': | |
this->showOwnRecord(); | |
break; | |
case 'b': | |
this->showSearchAndViewRecordScreen(); | |
break; | |
case 'q': | |
this->quitToLoginScreen(); | |
break; | |
default: | |
cout << "Oops, invalid choice. Try again. " << endl; | |
cout << "You picked: " << choice << endl; | |
break; | |
} | |
} | |
} | |
// View a list of all employee records as well as the individual details of each record. | |
void showSearchAndViewRecordScreen() { | |
cout << "------------" << endl; | |
cout << "ALL EMPLOYEE RECORDS" << endl; | |
cout << left << setw(6) << "ID" << setw(15) << "NAME" << setw(10) << "JOB TITLE" << endl; | |
for (const auto& employee : db.getAllEmployees()) { | |
string formattedId = "(" + to_string(employee.get().userId) + ")"; | |
cout << left << setw(6) << formattedId; | |
cout << setw(15) << employee.get().name << setw(10) << employee.get().jobTitle << endl; | |
} | |
cout << endl; | |
cout << "------------" << endl; | |
cout << "Enter User ID to view Employee Record. Press q to quit to login screen." << endl; | |
string employeeChoice; | |
while(true) { | |
cout << "> "; | |
cin >> employeeChoice; | |
if (employeeChoice == "q") { | |
this->quitToLoginScreen(); | |
} | |
for (const auto& employee : db.getAllEmployees()) { | |
if (to_string(employee.get().userId) == employeeChoice) { | |
cout << "------------" << endl; | |
cout << "EMPLOYEE RECORD" << endl; | |
cout << left << setw(12) << "NAME: " << employee.get().name << endl; | |
cout << left << setw(12) << "JOB TITLE: " << employee.get().jobTitle << endl; | |
cout << left << setw(12) << "USERNAME" << employee.get().userName << endl; | |
cout << "------------" << endl; | |
cout << endl; | |
break; | |
} | |
} | |
showSearchAndViewRecordScreen(); | |
} | |
} | |
}; | |
// A HumanResourcesEmployee Class, with extended permissions to allow for C.R.U.D (Create, Read, Update, Delete) of employee objects. | |
class HumanResourcesEmployee: public Employee { | |
using Employee::Employee; | |
public: | |
void displayMenu() override { | |
cout << "MENU OPTIONS: " << endl; | |
cout << "(a) View Employee Record" << endl; | |
cout << "(b) View All Employee Records" << endl; | |
cout << "(c) Add New Employee Record " << endl; | |
cout << "(d) Delete Employee Record" << endl; | |
cout << "(e) Edit Employee Record" << endl; | |
cout << "(q) Quit to Login Screen" << endl; | |
char choice; | |
while(true) { | |
cout << "> "; | |
cin >> choice; | |
switch (choice) { | |
case 'a': | |
this->showOwnRecord(); | |
break; | |
case 'b': | |
this->showSearchAndViewRecordScreen(); | |
break; | |
case 'c': | |
this->addRecordScreen(); | |
break; | |
case 'd': | |
this->deleteRecordScreen(); | |
break; | |
case 'e': | |
this->editRecordScreen(); | |
break; | |
case 'q': | |
this->quitToLoginScreen(); | |
break; | |
default: | |
cout << "Oops, invalid choice. Try again. " << endl; | |
cout << "You picked: " << choice << endl; | |
break; | |
} | |
} | |
} | |
void showSearchAndViewRecordScreen() { | |
cout << "------------" << endl; | |
cout << "ALL EMPLOYEE RECORDS" << endl; | |
cout << left << setw(6) << "ID" << setw(15) << "NAME" << setw(10) << "JOB TITLE" << endl; | |
for (const auto& employee : db.getAllEmployees()) { | |
string formattedId = "(" + to_string(employee.get().userId) + ")"; | |
cout << left << setw(6) << formattedId; | |
cout << setw(15) << employee.get().name << setw(10) << employee.get().jobTitle << endl; | |
} | |
cout << endl; | |
cout << "------------" << endl; | |
cout << "Enter User ID to view Employee Record. Press m to go back to Menu. Press q to quit to login screen." << endl; | |
string employeeChoice; | |
while(true) { | |
cout << "> "; | |
cin >> employeeChoice; | |
if (employeeChoice == "q") { | |
this->quitToLoginScreen(); | |
} | |
if (employeeChoice == "m") { | |
this->displayMenu(); | |
} | |
for (const auto& employee : db.getAllEmployees()) { | |
if (to_string(employee.get().userId) == employeeChoice) { | |
cout << "------------" << endl; | |
cout << "EMPLOYEE RECORD" << endl; | |
cout << left << setw(12) << "NAME: " << employee.get().name << endl; | |
cout << left << setw(12) << "JOB TITLE: " << employee.get().jobTitle << endl; | |
cout << left << setw(12) << "USERNAME" << employee.get().userName << endl; | |
cout << "------------" << endl; | |
cout << endl; | |
break; | |
} | |
} | |
showSearchAndViewRecordScreen(); | |
} | |
} | |
void addRecordScreen() { | |
string newName, newJobTitle, newUserName, newPassword; | |
cout << "ADD EMPLOYEE RECORD" << endl; | |
cout << "Enter new user's name: "; | |
cin.ignore(); | |
getline(cin, newName); | |
cout << "Enter user's Job Title: "; | |
getline(cin, newJobTitle); | |
cout << "Enter user's username: "; | |
getline(cin, newUserName); | |
cout << "Enter user's password: "; | |
getline(cin, newPassword); | |
if (cin.fail()) { | |
cin.clear(); | |
cin.ignore(1000, '\n'); | |
} else { | |
Employee newEmployee(newUserName, newName, newPassword, newJobTitle); | |
db.addEmployee(newEmployee); | |
cout << "Saved New Employee." << endl; | |
this->displayMenu(); | |
} | |
} | |
void deleteRecordScreen() { | |
cout << "------------" << endl; | |
cout << "DELETE EMPLOYEE RECORDS" << endl; | |
cout << left << setw(6) << "ID" << setw(15) << "NAME" << setw(10) << "JOB TITLE" << endl; | |
for (const auto& employee : db.getAllEmployees()) { | |
string formattedId = "(" + to_string(employee.get().userId) + ")"; | |
cout << left << setw(6) << formattedId; | |
cout << setw(15) << employee.get().name << setw(10) << employee.get().jobTitle << endl; | |
} | |
cout << endl; | |
cout << "------------" << endl; | |
cout << "Enter User ID to delete Employee Record. Press m to go back to Menu. Press q to quit to login screen." << endl; | |
string employeeChoice; | |
while(true) { | |
cout << "> "; | |
cin >> employeeChoice; | |
if (employeeChoice == "q") { | |
this->quitToLoginScreen(); | |
} | |
if (employeeChoice == "m") { | |
this->displayMenu(); | |
} | |
for (const auto& employee : db.getAllEmployees()) { | |
if (to_string(employee.get().userId) == employeeChoice) { | |
db.removeEmployee(employee.get().userId); | |
} | |
} | |
showSearchAndViewRecordScreen(); | |
} | |
} | |
void editRecordScreen(){ | |
cout << "------------" << endl; | |
cout << "ALL EMPLOYEE RECORDS" << endl; | |
cout << left << setw(6) << "ID" << setw(15) << "NAME" << setw(10) << "JOB TITLE" << endl; | |
for (const auto& employee : db.getAllEmployees()) { | |
string formattedId = "(" + to_string(employee.get().userId) + ")"; | |
cout << left << setw(6) << formattedId; | |
cout << setw(15) << employee.get().name << setw(10) << employee.get().jobTitle << endl; | |
} | |
cout << endl; | |
cout << "------------" << endl; | |
cout << "Enter User ID to update Employee Record. Press m to go back to Menu. Press q to quit to login screen." << endl; | |
string employeeChoice; | |
while(true) { | |
cout << "> "; | |
cin >> employeeChoice; | |
if (employeeChoice == "q") { | |
this->quitToLoginScreen(); | |
} | |
if (employeeChoice == "m") { | |
this->displayMenu(); | |
} | |
for (const auto& employee : db.getAllEmployees()) { | |
if (to_string(employee.get().userId) == employeeChoice) { | |
string oldUserName = employee.get().userName; | |
string oldName = employee.get().name; | |
string oldPassword = employee.get().password; | |
string oldJobTitle = employee.get().jobTitle; | |
int userId = employee.get().userId; | |
string newName, newJobTitle, newUserName, newPassword; | |
cout << "UPDATE EMPLOYEE RECORD" << endl; | |
cout << "Enter new user's name: "; | |
cin.ignore(); | |
getline(cin, newName); | |
cout << "Enter user's Job Title: "; | |
getline(cin, newJobTitle); | |
cout << "Enter user's username: "; | |
getline(cin, newUserName); | |
cout << "Enter user's password: "; | |
getline(cin, newPassword); | |
if (cin.fail()) { | |
cin.clear(); | |
cin.ignore(1000, '\n'); | |
} else { | |
if(newUserName.empty()) { | |
newUserName = oldUserName; | |
} | |
if(newName.empty()) { | |
newName = oldName; | |
} | |
if(newPassword.empty()) { | |
newPassword = oldPassword; | |
} | |
if(newJobTitle.empty()) { | |
newJobTitle = oldJobTitle; | |
} | |
// To simplify, remove the old employee object and add a new one with the same ID. | |
db.removeEmployee(userId); | |
Employee newEmployee(newUserName, newName, newPassword, newJobTitle, userId); | |
db.addEmployee(newEmployee); | |
cout << "Update Employee." << endl; | |
this->displayMenu(); | |
} | |
} | |
} | |
showSearchAndViewRecordScreen(); | |
} | |
} | |
}; | |
bool validateLogin(string userName, string password) { | |
for (const auto& employee : db.getAllEmployees()) { | |
if (employee.get().userName == userName && employee.get().password == password) { | |
isLoggedIn = true; | |
loggedInUser = employee.get(); | |
return true; | |
} | |
} | |
return false; | |
} | |
void showEmployeeMenu() { | |
loggedInUser.get().displayMenu(); | |
} | |
void showLoginScreen() { | |
string userName; | |
string password; | |
cout << "Welcome to the Employee Management System. Please login to continue." << endl; | |
cout << endl; | |
cout << endl; | |
while(true) { | |
cout << "Username: "; | |
getline(cin, userName); | |
if(!userName.empty()){ | |
break; | |
} else { | |
cout << "Invalid input. Please try again." << endl; | |
} | |
} | |
while(true) { | |
cout << "Password: "; | |
// Typically, we'd want to mask password input so as to not show on the screen. | |
getline(cin, password); | |
if(!password.empty()){ | |
break; | |
} else { | |
cout << "Invalid input. Please try again." << endl; | |
} | |
} | |
// Authenticate the User by username and password and allow them to see their respective employee menu according to their permissions level. | |
if (validateLogin(userName, password)){ | |
showEmployeeMenu(); | |
} else { | |
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl; | |
cout << "% Invalid login credentials entered. Please try again. %" << endl; | |
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl; | |
showLoginScreen(); | |
} | |
} | |
void showMainScreen() { | |
if (!isLoggedIn) { | |
showLoginScreen(); | |
} else { | |
showEmployeeMenu(); | |
} | |
} | |
int main() { | |
// Add example employees, these would typically be loaded from a database on program start. | |
Employee employee1("bryan", "Bryan Paronto", "bryan", "Software Engineer"); | |
db.addEmployee(employee1); | |
HumanResourcesEmployee hrPerson1("susan", "Susan Ross", "susan", "HR Personnel"); | |
db.addEmployee(hrPerson1); | |
Manager manager1("manager", "Gob Bluth", "manager", "CEO of Banana Stand"); | |
db.addEmployee(manager1); | |
// Start Program | |
showMainScreen(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment