Saturday, January 7, 2017

Programming Challenge 6.14 - Order Status

/* Order Status - The Middletown Wholesale Copper Wire Company sells
   spools of copper wiring for $100 each. This program displays the
   status of an order. The following function is used:
  
   * getShippingData()

   Shipping and handling is normally $10 per spool. If there are any
   special charges, the program asks for the special charges per spool.

   The gathered data is passed as arguments to the following function:

   * displayOrderStatus()

   The shipping and handling parameter in the second function has the
   default argument 10.0.

   Input validation: No numbers less than 1 are accepted for spools
   ordered. No number less than 0 for spools in stock or shipping and
   handling charges are accepted. */

#include "Utility.h"

/* Prototypes: Get shipping data, Display order status */
void getShippingData(int &, int &, double &);
void displayOrderStatus(int, int, double, double = 10.0);

int main()
{
   /* Constants: Process Order, Display Order Status, Quit */
   const int PROCESS_ORDER = 1,
             DISPLAY_ORDER_STATUS = 2,
             QUIT = 3;

   /* Variables: Menu selection, Spools ordered, Spools in stock */
   int menuSelection = 0,
       numSpoolsOrdered = 0,
       numSpoolsInStock = 0;

   /* Variable: Special shipping charges */
   double numSpecialCharges = 0.0;

   /* Show the menu while menuSelection is not Quit
      Call: getshippingData, displayOrderStatus */
   do
   {
      /* Display: Menu */
      cout << "\t\tKANBAN Shipping Order Processing System\n"
           << "\t\t---------------------------------------\n\n"
           << "(1) Enter Shipping Data\n"
           << "(2) Display Order Status\n"
           << "(3) Quit\n"
           << "\nYour choice: ";
      cin >> menuSelection;

      /* Validate: The menu selection, if it is invalid, the user is
                   asked to select a valid menu item */
      while (menuSelection < 1 || menuSelection > 3)
      {
         cout << "\nPlease select a valid menu item. Valid items are\n"
              << "(1), (2), or (3) to quit.\n"
              << "\nYour choice: ";
         cin >> menuSelection;

         /* Call: catchInifiniteLopp */
         catchInfiniteLoop();
      }

      if (menuSelection != QUIT)
      {
         switch (menuSelection)
         {
            case PROCESS_ORDER:
                 getShippingData(numSpoolsOrdered, numSpoolsInStock,
                                 numSpecialCharges);
               cout << endl;
               break;

            case DISPLAY_ORDER_STATUS:
                 displayOrderStatus(numSpoolsOrdered, numSpoolsInStock,
                                    numSpecialCharges);
               cout << endl;
               break;
         }
      }

      if (menuSelection == QUIT)
      {
         cout << "\nExiting KANBAN Shipping Menu ... Press enter to exit\n";
         cin.ignore();
      }

   } while (menuSelection != QUIT);
  
   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: getShippingData

   This function asks for the number of spools ordered, the
   number of spools in stock, and determines whether there
   are special shipping and handling charges.
   ********************************************************** */

void getShippingData(int &numSpoolsOrdered, int &numSpoolsInStock,
                       double &numSpecialCharges)
{
   char extraShippingCharges = ' ';
  
   /* Get: Number of spools in ordered */
   cout << "\nHow many spools are ordered for shipping? ";
   cin >> numSpoolsOrdered;

   /* Validate: Input */
   while (numSpoolsOrdered < 1)
   {
      cout << "\nThe number you entered was invalid. Please enter a\n"
           << "positive number, at least 1.\n"
           << "How many spools are ordered for shipping? ";
      cin >> numSpoolsOrdered;

      /* Call: catchInifiniteLopp */
      catchInfiniteLoop();
   }

   /* Get: Number of spools in stock */
   cout << "How many spools are currently in stock? ";
   cin >> numSpoolsInStock;

   /* Validate: Input */
   while (numSpoolsInStock < 0)
   {
      cout << "The number of spools in stock can not be 0 or negative.\n"
           << "How many spools are currently in stock? ";
      cin >> numSpoolsInStock;
   
      /* Call: catchInifiniteLopp */
      catchInfiniteLoop();
   }

   /* Get: Special charges if there are any */
   cout << "\nAre there any special charges for this order (Y/N)? ";
   cin >> extraShippingCharges;

   /* Determine whether there are any special charges
      Get: Special charges */
   if (extraShippingCharges == 'Y' || extraShippingCharges == 'y')
   {
      cout << "\nSpecial Charges: $ ";
      cin >> numSpecialCharges;

      /* Validate: Input */
      while (numSpecialCharges < 0)
      {
         cout << "The number you entered was invalid. Please enter\n"
              << "a positive value for special charges: $";
         cin >> numSpecialCharges;

         /* Call: catchInifiniteLopp */
         catchInfiniteLoop();
      }
   }
}

/* **********************************************************
   Definition: displayOrderStatus

   Passed to it by getShippingData, this function accepts
   three arguments:

   * The number of spools ordered
   * The number of spools in stock
   * The special shipping and handling charges (if any)

   . It displays:
  
   * The number of spools ready to ship from current stock
   * The number of spools on backorder (if the number ordered
     is greater than what is in stock)
   * The subtotal of the portion ready to ship (the number of
     spoolsready to ship times $100)
   * The total shipping costs

   The default value for statusSpecialCharges is 10.0
   ********************************************************** */

void displayOrderStatus(int spgOrdered, int spgInStock,
   double spgSpecialCharges, double spgCharges)
{
   /* Constant: Shipping cost per unit */
   const double SPG_COST_PER_UNIT = 100.00;

   /* Variable: Status of backorder */
   int spgBackorder = 0;

   /* Variable: Backorder Cost subtotal, Regular shipping subtotal cost,
                Total Shipping Cost */
   double spgSubtotal = 0.0,
          spgTotal = 0.0;

   /* Determine whether there is a backorder, and if there is, the number
      of spools in backorder. The size of the order, the charges, the
      subtotal and total cost of the order is calculated (both with and
      without special charges). Else the order total is calculated (again
      with and without special charges), the number of spools in stock,
      the size of the order, the special charges (if any), and the total
      cost */
   if (spgOrdered > spgInStock)
   {
      /* Calculate: Size of backorder, Backorder Default charges, Regular
                    full stock charges */
      spgBackorder = (spgOrdered - spgInStock);
      spgSubtotal = (spgOrdered - spgBackorder) * SPG_COST_PER_UNIT;

      /* Determine whether there are any Special charges, if there are
         the cost is calculated with special charges, or if there aren't
         any, without */
      if (spgSpecialCharges)
      {
         spgTotal = (spgOrdered - spgBackorder) * SPG_COST_PER_UNIT +
                    (spgOrdered - spgBackorder) * spgCharges +
                     spgSpecialCharges;
      }
      else
      {
         spgTotal = (spgOrdered - spgBackorder) * SPG_COST_PER_UNIT +
                    (spgOrdered - spgBackorder) * spgCharges;
      }
   }

   else if (spgOrdered < spgInStock)
   {
      /* Calculate the subtotal */
      spgSubtotal = (spgOrdered * SPG_COST_PER_UNIT);

      /* Determine whether there are any special charges for a regular
         full stock order, if so they are calculated and added to the
         total shipping cost */
      if (spgSpecialCharges)
      {
         spgTotal = (spgOrdered * SPG_COST_PER_UNIT) +
                    (spgOrdered * spgCharges) + spgSpecialCharges;
      }
      else
      {
         spgTotal = (spgOrdered * SPG_COST_PER_UNIT) +
                    (spgOrdered * spgCharges);
      }   
   }
  
   /* Set up: Numeric output format */
   cout << fixed << showpoint << setprecision(2);

   /* Display: Order summary, If the order is greater than the number
      of items in stock, the header message will change accordingly */
   spgOrdered > spgInStock ?
      (cout << "\n\t\tShipping Order #149-P-15-3295 - [Part.]\n"
            << "\t\t---------------------------------------\n\n") :
      (cout << "\n\t\tShipping Order #149-N-15-3295 - [Comp.]\n"
            << "\t\t---------------------------------------\n\n");

   cout << "Spools Ordered:\t" << setw(39) << right << spgOrdered
        << "\nSpools In Stock:\t"
        << setw(31) << right << spgInStock << endl;

   /* If the order is greater than the number of items in stock,
      message the number of backorder items is displayed, else
      it is replaced by --- */
   spgOrdered > spgInStock ? 
   (cout << "Spools In Backorder:"
         << setw(35) << right << spgBackorder << endl) :
   (cout << "Spools In Backorder:" << setw(36) << right << "---\n");

   spgOrdered > spgInStock ?
   (cout << "Spools Ready For Shipping:"
         << setw(29) << right << spgInStock << endl) :
   (cout << "Spools Ready For Shipping:"
         << setw(29) << right << spgOrdered << endl);

   cout << "\n\t\tShipping And Handling Cost Information\n"
        << "\t\t---------------------------------------\n\n"
        << "Charge Per Unit:" << setw(30) << right << "$ "
        << setw(9) << right << SPG_COST_PER_UNIT
        << "\nS&H Per Unit:" << setw(33) << right
        << "$ " << setw(9) << right << spgCharges;

   cout << "\n\n\t\tShipping Cost: Subtotal & Total\n"
        << "\t\t---------------------------------------\n"
        << "\nSpecial Charges:" << setw(30) << right
        << "$ " << setw(9) << right << spgSpecialCharges
        << "\nOrder Subtotal:" << setw(31) << right
        << "$ " << setw(9) << right << spgSubtotal
        << "\nOrder Total:" << setw(34) << right
        << "$ " << setw(9) << right << spgTotal << endl;
}

No comments:

Post a Comment