/*********************************** ** Author: Steven Scott ** Filename: pex6.cpp ** Date: Nov 19, 2007 ** Purpose: Keep track of inventory ** levels for a company using linked ** lists. ***********************************/ #include #include #include using namespace std; /***************************** ** Struct for pending items. *****************************/ struct pendingItem { int pending; string customer; pendingItem *nextItem; }; /***************************************** ** Define named constants ******************************************/ const int maxWidgets = 500; const int minWarning = static_cast(maxWidgets * 0.1); const int pendingLimit = 100; const char cList = 'L'; const char cReq = 'R'; const char cShip = 'S'; const char cQuit = 'Q'; const char cHelp = 'H'; /*********************************************** ** Ok, now tell me if you recommend this now? ** Define functions for later use. ***********************************************/ /*********************************** ** Function: drawMenu() ** Description: Draws the help menu. ***********************************/ void drawMenu(); /*********************************** ** Function: getCmdAndParse() (Happy?) ** Description: Takes users input, ** calls whichever function they requested. ***********************************/ bool getCmdAndParse(int &widgets, int &accepted, int &returned, int &sent, int &maxpending, int &pending, list &pendingList); /*********************************** ** Function: listInv() ** Description: Prints inventory ** and pending levels. ***********************************/ void listInv(int widgets, list &pendingList); /*********************************** ** Function: recvShip() ** Description: Recieves a shipment. ** Asking for amount, and customer, ** fills pending, returns unneeded. ***********************************/ void recvShip(int &accepted, int &pending, int &sent, int &widgets, int &returned, list &pendingList); /*********************************** ** Function: request() ** Description: Take and fill to ability ** a customers request, add rest to pending ***********************************/ void request(list &pendingList, int &sent, int &widgets, int &maxpending, int &pending); /*********************************** ** Function: cmdLoop() ** Description: Run every command loop, ** prints out if the user is low on stock. ***********************************/ void cmdLoop(int widgets); /*********************************** ** Function: quit() ** Description: Exit program. Print out ** final values. ***********************************/ void quit(int accepted, int returned, int sent, int maxpending, int widgets, list &pendingList); /*********************************** ** Function: getPosInt() ** Description: Gets a users input, ** only accepts positive integers. ***********************************/ int getPosInt(string q); /*********************************** ** Function: printPending() ** Description: Prints the current list ** of pending transactions. ***********************************/ void printPending(list &pendingList); /*********************************** ** Function: getString() ** Description: Gets a string from ** the user ***********************************/ string getString(string q); int main() { // Initialize variables with 0 values. int widgets = 0; int accepted = 0; int returned = 0; int sent = 0; int maxpending = 0; int pending = 0; // Create the list for pending items. list pendingList; // Draw the help menu drawMenu(); // Loop through the commands until getCmd returns false (Quit) while (getCmdAndParse(widgets, accepted, returned, sent, maxpending, pending, pendingList)) cmdLoop(widgets); return 0; } /*********************************** ** Function: drawMenu() ** Description: Draws the help menu. ***********************************/ void drawMenu() { cout << string(38, '-') << endl; cout << "Choose from following commands:\n"; cout << cList << " --- list the current inventory level;\n"; cout << cReq << " --- handle a request from the customer;\n"; cout << cShip << " --- handle a shipment from the supplier;\n"; cout << cQuit << " --- terminate the program;\n"; cout << cHelp << " --- display this help message.\n"; cout << string(38, '-') << endl; } /*********************************** ** Function: getCmdAndParse() (Happy?) ** Description: Takes users input, ** calls whichever function they requested. ***********************************/ bool getCmdAndParse(int &widgets, int &accepted, int &returned, int &sent, int &maxpending, int &pending, list &pendingList) { string tmp = getString("\nEnter your choice: "); char cmd = tmp[0]; switch (toupper(cmd)) { case cList: // Call list inv function listInv(widgets, pendingList); break; case cReq: request(pendingList, sent, widgets, maxpending, pending); // Call request function break; case cShip: // Call shipment function recvShip(accepted, pending, sent, widgets, returned, pendingList); break; case cHelp: // Draw the menu drawMenu(); break; case cQuit: quit (accepted, returned, sent, maxpending, widgets, pendingList); // Call quit status function return false; break; default: cout << "--- Invalid command.\n"; break; } return true; } /*********************************** ** Function: listInv() ** Description: Prints inventory ** and pending levels. ***********************************/ void listInv(int widgets, list &pendingList) { cout << "--- Number of widgets in inventory: " << widgets << endl; printPending(pendingList); } /*********************************** ** Function: recvShip() ** Description: Recieves a shipment. ** Asking for amount, and customer, ** fills pending, returns unneeded. ***********************************/ void recvShip(int &accepted, int &pending, int &sent, int &widgets, int &returned, list &pendingList) { int amt; amt = getPosInt("Enter the shipment amount: "); accepted += amt; // If there is a pending list, make sure to fill it. if (pendingList.size() > 0) { // Create an iterator to the first element. No need to increase it. list::iterator iter = pendingList.begin(); while (pendingList.size() > 0) { // Loop through, removing pending items while we have the widgets. if (amt >= iter->pending) { cout << "--- " << iter->pending << " widgets have been sent to " << iter->customer << ".\n"; sent += iter->pending; amt -= iter->pending; pending -= iter->pending; iter = pendingList.erase(iter); } else if (amt > 0) { // If we can partially fill an order, do it. cout << "--- " << amt << " widgets have been sent to " << iter->customer << ".\n"; iter->pending -= amt; pending -= pending; sent += amt; amt = 0; break; } else { break; } } } // Once done pending list, check if there's anything left to recieve if (amt > 0) { // See if it will fill up the inventory or not if (widgets + amt <= maxWidgets) { cout << "--- " << amt << " widgets have been stored.\n"; widgets += amt; } else { // Figure out how much to decline int dec = amt - (maxWidgets - widgets); returned += dec; accepted -= dec; amt -= dec; widgets += amt; if (amt > 0) cout << "--- " << amt << " widgets have been stored.\n"; cout << "--- " << dec << " widgets have been sent " << "back due to lack of storage space.\n"; } } } /*********************************** ** Function: request() ** Description: Take and fill to ability ** a customers request, add rest to pending ***********************************/ void request(list &pendingList, int &sent, int &widgets, int &maxpending, int &pending) { int amt; string cust; // Get customer name and amount. cust = getString("Enter the name of the customer: "); amt = getPosInt("Enter the request amount: "); if (amt <= widgets) { // There's enough widgets to fill order, do so. widgets -= amt; sent += amt; cout << "--- " << amt << " widgets have been sent to " << cust << ".\n"; } else { if (widgets > 0) { // If there's widgets, fill request to ability. sent += widgets; cout << "--- " << widgets << " widgets have been sent to " << cust << ".\n"; amt -= widgets; widgets = 0; } // Add unfilled to a new pendingItem. Add that to pendingList pendingItem *pend = new pendingItem; pend->customer = cust; pend->pending = amt; pendingList.push_back(*pend); pending += amt; if (pending > maxpending) maxpending = pending; cout << "--- " << amt << " widgets requested by " << cust << " have been entered into a pending list.\n"; } } /*********************************** ** Function: quit() ** Description: Exit program. Print out ** final values. ***********************************/ void quit(int accepted, int returned, int sent, int maxpending, int widgets, list &pendingList) { // Print out the list of pending items. printPending(pendingList); // Print out other stats. cout << endl << "==== Statistics ====\n\n"; cout << "Widgets accepted from supplier:" << setw(8) << accepted << endl; cout << "Widgets returned to supplier :" << setw(8) << returned << endl; cout << "Widgets sent to customers :" << setw(8) << sent << endl; cout << "Maximum widgets pending :" << setw(8) << maxpending << endl; cout << "Number of widgets in inventory:" << setw(8) << widgets << "\n\n"; cout << "==== End of run ====" << endl; // Clear the pending list and free the memory. pendingList.clear(); delete(&pendingList); } /*********************************** ** Function: getPosInt() ** Description: Gets a users input, ** only accepts positive integers. ***********************************/ int getPosInt(string q) { int amt = 0; // Loop until a valid answer while (cout << q) { cin >> amt; // If there is something wrong, clear cin for proper useage. if (cin.fail()) { cin.clear(); cin.ignore(numeric_limits::max(),'\n'); amt = 0; } if (amt <= 0) cout << "The amount must be a positive number.\n"; else break; } // Clear cin so that getline doesn't complain cin.ignore(numeric_limits::max(),'\n'); return amt; } /*********************************** ** Function: cmdLoop() ** Description: Run every command loop, ** prints out if the user is low on stock. ***********************************/ void cmdLoop(int widgets) { // If inventory is too low, print out a warning. if (widgets < minWarning) { cout << "\n!!! Warning! The current inventory level is too low."; cout << "\n!!! Order a new shipment ASAP.\n\n"; } } /*********************************** ** Function: printPending() ** Description: Prints the current list ** of pending transactions. ***********************************/ void printPending(list &pendingList) { cout << "--------------------" << endl; // If there is a pending list, print it. if (pendingList.size() > 0) { cout << "--- Number of requests pending:" << setw(11) << pendingList.size() << endl; // Loop from the beginning to the end of the pending list and print. list::const_iterator iter; for (iter = pendingList.begin(); iter != pendingList.end(); iter++) { cout << "--- " << iter->pending; cout << " widgets need to be sent to "; cout << iter->customer << ".\n"; } } else // Else, print that there is none. cout << "--- No pending requests.\n"; cout << "--------------------" << endl; } /*********************************** ** Function: getString() ** Description: Gets a string from ** the user ***********************************/ string getString(string q) { string a; cout << q; getline( cin, a ); return a; }