Skip to content

Instantly share code, notes, and snippets.

@apisandipas
Created January 22, 2023 05:04
Show Gist options
  • Save apisandipas/5e1d5905de5ebf1099e925805bd152d2 to your computer and use it in GitHub Desktop.
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
/**
* 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