Package homework04

Source Code of homework04.WarehouseReport

/**
* @author drakebennion
* @date February 5, 2014
*/
package homework04;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

/**This program contains the methods and instance variables used to keep track of a series of
* warehouses and their respective inventories in order to determine what fooditems go in which inventory,
* when these items expire, etc...
*
* This is accomplished by taking each line of a file, which is given by WarehouseTest.java, and
* reading the first word: in the specific file format we require, this tells us an action. The
* processLine method decides which "sub-method" should be called in order to complete that action.
* As these "sub-methods" do their respective jobs, we are building up a set of warehouses,
* each with their own Inventory of fooditems. This program will also be able to determine
* which fooditems appear in every warehouse inventory, which don't appear in any inventory,
* and which date was the busiest for each warehouse.
*
*/
public class WarehouseReport
{
 
    //A calendar object to keep track of the effective date
    private GregorianCalendar effective;
    //And one to keep track of the first date
    private GregorianCalendar begin;
 
    //a map of UPC codes to corresponding fooditems
    private Map<String, FoodItem> map;
    //a map of upc codes to the name of the item
    private Map<String,String> namemap;
    //a map of a warehouse to its respective inventory
    private Map<String, Inventory<FoodItem>> foodmap;
   
    //a map to keep track of how many warehouses contain a certain item
    private Map<FoodItem, Integer> fullstock;
    private Map<FoodItem, Integer> nostock;
   
    //map will keep track of the number of transactions for each warehouse (and be reset every day)
    private Map<String, Integer> transaction;
    //map will keep track of the busiest day information for each warehouse.
    private Map<String, GregorianCalendar> busiest;
    //keep track of the highest number of transactions for each warehouse
    private Map<String, Integer> busiesttransactions;
 
   

    /**
     * Default constructor to set maps to be empty, and to set the date variables
     * to be today (dates that represent the moment they are called.)
     */
    public WarehouseReport()
    {
      effective=new GregorianCalendar();
      begin=new GregorianCalendar();
      map=new TreeMap<String,FoodItem>();
      foodmap=new TreeMap<String, Inventory<FoodItem>>();
      transaction=new TreeMap<String,Integer>();
      busiesttransactions=new TreeMap<String,Integer>();
      busiest=new TreeMap<String,GregorianCalendar>();
      namemap=new TreeMap<String,String>();
      fullstock=new TreeMap<FoodItem, Integer>();
      nostock=new TreeMap<FoodItem, Integer>();
    }
   
    /**
     * This method will read a line from a file, word by word, and decide
     * what each word is telling the program to do, by delegating each action to
     * a separate action method. However, some "filler words" are essentially
     * ignored by the method, though there are few of these.
     *
     * @param line--the line of the file to be read
     */
    public void processLine(String line)
    {
      //read through each word of the given line
      Scanner read=new Scanner(line);
     
      //while the line still has characters in it:
      while(read.hasNext())
      {
        //read the next word of the line
        String nextword=read.next();
       
        if(nextword.equals("FoodItem"))
        {
          //A fooditem is being processed--call the processFood method on the line
          processFood(line);
        }
        else if(nextword.equals("Warehouse"))
        {
          //A warehouse is being processed--call the processWarehouse method on the line
          processWarehouse(line);
         
        }
        else if(nextword.equals("Start"))
        {
          //A beginning date is being processed--call the processStart method on the line
          processStart(line);
        }
        else if(nextword.equals("Receive:"))
        {
          //A fooditem is being received--call the processReceive method on the line
          processReceive(line);
         
        }
        //A fooditem is being requested--call the processRequest method on the line
        else if(nextword.equals("Request:"))
        {
          processRequest(line);
        }
        else if(nextword.equals("Next"))
        {
          //The date should be incremented--call the processNext method on the line
          processNext(line);
        }
        else if(nextword.equals("End"))
        { 
          //The file has reached its end--after this, the program should terminate.
          //Before it terminates, we need to see if the final date was the busiest
          //date for any of our warehouses.
         
          //Create a date to represent this final date
          int tempday, tempyear, tempmonth;
          tempday=effective.get(Calendar.DAY_OF_MONTH);
          tempmonth=effective.get(Calendar.MONTH);
          tempyear=effective.get(Calendar.YEAR);
          GregorianCalendar temp=new GregorianCalendar(tempyear, tempmonth,tempday);
         
          //loop through all of the warehouses
          for(String s:transaction.keySet())
          {
            //If there were more total transactions here than any other day
            //for any warehouse, then that warehouse should have its busiest
            //day information updated.
            if(transaction.get(s)>=(busiesttransactions.get(s)))
              {
                busiesttransactions.put(s,transaction.get(s));
                busiest.put(s, temp);
              }
          }
         
          //Now terminate
          break;
        }
       
        else //otherwise, the word isn't indicating a command, and the method should go past it
          continue;
      }
    }
   
    /**Reads through a line that starts with the word "Food", indicating a fooditem
     * is being processed.
     *
     * adds the upc code and the fooditem to our map<String, FoodItem>, and
     * adds the upc code with the name of the fooditem to the map<String, String>.
     *
     * @param line--the string to be read
     * @return none
     */
    public void processFood(String line)
    {
      //variables to store a fooditems information
      FoodItem food=null;
      String upc="";
      String name="";
      int shelf=0;
     
      //create a scanner to read through the line word by word
      Scanner read=new Scanner(line);
     
      //while there is still another word
      while(read.hasNext())
      {
        //The word following certain "buzzwords" (in this case,
        // Code, life or Name) will indicate different information
        //about the fooditem, so we store these words appropriately.
        String word=read.next();
        if(word.equals("Code:"))
          upc=read.next();
        else if(word.equals("life:"))
          shelf=Integer.valueOf(read.next());
        else if(word.equals("Name:"))
          {
            while(read.hasNext())
                name+=read.next()+" ";
          }
        else
          continue;
      }
      //create the new food item with the given information
      food=new FoodItem(name,upc,shelf);
     
      //add the fooditem to the upc->fooditem map
      map.put(upc, food);
      namemap.put(upc, name);
    }
   
    /**Reads through a line to process Warehouse information.
     * adds the warehouse name and its respective inventory to our
     * <String, Inventory<FoodItem> map.
     * Also sets the warehouse's transactions for today to 0 and sets today to be its
     * busiest day (each in its respective Map)
     *
     * @param line the line to be read
     * @return none
     */
    public void processWarehouse(String line)
    {
      //a variable to store the warehouse name
      String warehouse="";
      Scanner read=new Scanner(line);
      while(read.hasNext())
      {
        //similar process to the processFoodItem method above
        String word=read.next();
        if(word.equals("-"))
          while(read.hasNext())
            warehouse+=read.next()+" ";   
      }
     
      Inventory<FoodItem> winventory=new Inventory<FoodItem>();
      foodmap.put(warehouse, winventory);
      transaction.put(warehouse, 0);
      busiesttransactions.put(warehouse, 0);
    }
   
    /**Reads through a line to get the information about a current date.
     * Sets the instance variable "effective" to the beginning date (this will change)
     * and sets "beginning" to this date as well (this will remain the same)
     *
     * @param line
     * @return none
     */
    public void processStart(String line)
    {
      //A likewise similar process to the above two process methods
      Scanner read = new Scanner(line);
     
      String tempstring="";
     
      while(read.hasNext())
      {     
        if(read.next().equals("date:"))
        {
          //The date is read into a string
          tempstring=read.next();
         
          //The string is broken up into pieces, each piece corresponding to
          //the characters between the / character
          String[] holder=tempstring.split("/");
         
          //temporary variables to hold this information
          int tempmonth=0;
          int tempday=0;
          int tempyear=0;
         
          //reads the first two characters as an integer
          //needs to be decremented in order to be consistent with the GregorianCalendar--
          //0=January, 1=February...11=December.
          tempmonth=Integer.parseInt(holder[0])-1;
         
          //stores next two characters as day integer
          tempday=Integer.parseInt(holder[1]);
         
          //stores the next 4 characters as the year integer
          tempyear=Integer.parseInt(holder[2]);
         
          //GregorianCalendar objects constructed with these numbers
          begin=new GregorianCalendar(tempyear,tempmonth,tempday);
          effective=new GregorianCalendar(tempyear,tempmonth,tempday);
        }
      }
     
      //Set each warehouse to have its busiest day on the beginning date
      for(String s:foodmap.keySet())
        busiest.put(s, begin);
    }

    /**Reads through a line to process information about an item being received
     * in an inventory. Updates the inventory of the corresponding warehouse.
     * Also updates the transaction information for the respective warehouse.
     *
     * @param line--string to read
     * @return --none
     */
    public void processReceive(String line)
    {
      //variables to hold the receiving information
      String receivingupc="";
      int quantity=0;
      String warehouse="";
     
      Scanner read=new Scanner(line);
     
      //the next word will be Receive, so ignore it
      read.next();
      //The next few inputs will be important, so store them
      receivingupc=read.next();
      quantity=Integer.valueOf(read.next());
      while(read.hasNext())
        warehouse+=read.next()+" ";
     
      //retrieve the fooditem stored at the received upc code
      FoodItem food=map.get(receivingupc);
      //calculate the fooditem's expiration date (uses a method inside FoodItem.java
      GregorianCalendar expires=food.getExpirationDate(effective);
     
      //add the fooditem with the calculated expiration date and the given quantity
      //to the proper warehouse
      foodmap.get(warehouse).addItem(food,expires,quantity);
     
      //update transaction information for this warehouse
      int gettransaction=transaction.get(warehouse);
      gettransaction+=quantity;
      transaction.put(warehouse,gettransaction);
    }

    /**Reads through a line to process information about an item being Requested
     * in an inventory (meaning the item is to be removed). Updates the inventory
     *  of the corresponding warehouse.
     * Also updates the transaction information for the respective warehouse.
     *
     * @param line--string to read
     * @return --none
     */
    public void processRequest(String line)
    {
      //variables to store request info
      String requestupc="";
      int quantity=0;
      String warehouse="";
     
      Scanner read=new Scanner(line);
     
      //store the info
      read.next();
      requestupc=read.next();
      quantity=Integer.valueOf(read.next());
      while(read.hasNext())
        warehouse+=read.next()+" ";
     
      //update transaction information
      int gettransaction=transaction.get(warehouse);
      gettransaction+=quantity;
      transaction.put(warehouse,gettransaction);
     
      //Create a temporary GregorianCalendar object to start at the beginning
      //a new object must be created, because saying temp=begin would make
      //temp and begin reference the same object--then whenever one changes, the
      //other must also change...we don't want that.
      int tempday, tempyear, tempmonth;
      tempday=begin.get(Calendar.DAY_OF_MONTH);
      tempmonth=begin.get(Calendar.MONTH);
      tempyear=begin.get(Calendar.YEAR);
      GregorianCalendar temp=new GregorianCalendar(tempyear, tempmonth, tempday);
   
      //Get the requested food item
      FoodItem food=map.get(requestupc);
     
      //removing was a bit of a tricky situation, but here's what I think works:
     
      //starting from the first date, loop through the dates until we get to the last
      //possible expiration date of the food item: the items shelf life+the current date.
      //While we're still working before that date, and while our quantity to be removed
      //is >0, continue looping and removing, as described below:
      while((temp.compareTo(food.getExpirationDate(effective))<=0)&&quantity>0)
        {
          //If the inventory has enough of the requested fooditem, then
          //remove it, and make our removing quantity zero--then the loop
          //is exited.
          if((foodmap.get(warehouse)).getQuantity(food, temp)>=quantity)
            {
              (foodmap.get(warehouse)).removeItem(food,temp,quantity);
              quantity=0;
            }
          //Otherwise, figure out how many we can remove, remove them, and
          //change the quantity we want to remove accordingly.
          else
         
            int tempremovequantity=(foodmap.get(warehouse)).getQuantity(food, temp);
            (foodmap.get(warehouse)).removeItem(food,temp,tempremovequantity);
            quantity-=tempremovequantity;
          }
          //Then increment the date by one day. Then this loop will only exit once
          //either 1. The request is entirely satisfied
          //or     2. There are not enough fooditems currently in the inventory to
          //          satisfy the request. Then the request is simply dropped.
          temp.add(Calendar.DAY_OF_MONTH,1);
        } //hope that all makes sense!
    }
   
    /**processes the "next" command--increments the date by one and
     * removes expired items from their respective inventories
     * Also resets each warehouse's transaction map info, and updates
     * the busiest date info for each warehouse.
     *
     * @param line to be read
     * @return none
     */
    private void processNext(String line)
    { 
      //need to create a GregorianCalendar to represent the effective date so we
      //can update the busiest day info--using effective means the date inside the
      //busiest day map will change whenever effective date changes, which we
      //don't want.
      int tempday, tempyear, tempmonth;
      tempday=effective.get(Calendar.DAY_OF_MONTH);
      tempmonth=effective.get(Calendar.MONTH); //System.out.println(tempmonth);
      tempyear=effective.get(Calendar.YEAR);
      GregorianCalendar temp=new GregorianCalendar(tempyear, tempmonth,tempday);

      //for every warehouse
      for(String s:transaction.keySet())
      {
        //If the current days transaction were more than the currently busiest days,
        //update busiest day to the current day. Also update the busiest day number of transactions.
        if(transaction.get(s)>=(busiesttransactions.get(s)))
          {
            busiesttransactions.put(s,transaction.get(s));
            busiest.put(s, temp);
          }
        //reset the transaction map for each warehouse
        transaction.put(s, 0);
      }
     
      //increment the date
      effective.add(Calendar.DAY_OF_MONTH, 1);
      //remove any now-expired fooditems
      for(Inventory<FoodItem> food:foodmap.values())
        food.removeExpired(effective);
    }
   
    /*Prints to console what fooditems make an appearance in every warehouse.
     *
     *
     * @param--none
     * @return--none, but prints to console
     */
    public void printFullStock()
    {
      //loop through every fooditem in our map to decide how many warehouses contain it:
      for(FoodItem f:map.values())
      { 
        //let the number of warehouses that contain that item be zero
        int warehousescontaining=0;
       
        //for each warehouse's inventory, if the fooditem is inside that inventory,
        //increment the number of warehouses that do hold the item.
        for(Inventory<FoodItem> food:foodmap.values())
        {
          if((food.getItems().contains(f)))
              warehousescontaining++;
        }
        //This map keeps track of how many inventories contain each fooditem
        fullstock.put(f,warehousescontaining);
      }
      //This is the number of warehouses we have in our map
      int warehousenumber=foodmap.size();
     
      //Then for every fooditem inside the fullstock map...
      for(FoodItem f:fullstock.keySet())
      {
        //...if the number of warehouses containing the fooditem is equal to the
        //number of warehouses we're keeping track of, then it must have a positive
        //quantity in every warehouse. Then output it's information to the console.
        if(fullstock.get(f).equals(warehousenumber))
          System.out.println(f.getUpcCode()+" "+namemap.get(f.getUpcCode()));
      }
    }
   
    /*Prints to console what fooditems aren't in any warehouse
     *
     *@param none
     *@return none, prints to console
     */
    public void printOutofStock()
    {
      //works very similarly to the Fullstock method above: instead, keep track of how many
      //warehouses do not contain the food item in question.
     
      //again, this is how many warehouses we have
      int warehousenumber=foodmap.size();
     
      //loop through every fooditem we have information for
      for(FoodItem f:map.values())
      {
        //Assume that every warehouse contains the item
        int warehousescontaining=warehousenumber;
        for(Inventory<FoodItem> food:foodmap.values())
        {
          //If the warehouse actually doesn't contain the item,
          //decrement the count of how many warehouses
          //do contain it.
          if(!(food.getItems().contains(f)))
              warehousescontaining--;
        }
        //put this information in our map
        nostock.put(f,warehousescontaining);
      }
     
      //for every fooditem...
      for(FoodItem f:nostock.keySet())
      {
        //If no warehouse holds the fooditem, the fooditems map value will be zero
        //then print its info to the console
        if(nostock.get(f).equals(0))
          System.out.println(f.getUpcCode()+" "+namemap.get(f.getUpcCode()));
      }
    }
   
    /**For each warehouse we have, prints the warehouse name, the busiest day
     * and the highest number of transactions that occurred for the warehouse.
     *
     * @param none
     * @return none, prints to the console
     */
    public void printBusyDays()
    {
      //simple enough, print out the information inside our busiest day map
      for(String s:busiest.keySet())
      {
        int busyday=busiest.get(s).get(Calendar.DAY_OF_MONTH);
        int busymonth=busiest.get(s).get(Calendar.MONTH)+1;
        int busyyear=busiest.get(s).get(Calendar.YEAR);
        //The month needs to be incremented to account for the GregorianCalendar month discrepancy
//        System.out.println(s+((busiest.get(s)).get(Calendar.MONTH)+1)+"/"+(busiest.get(s)).get(Calendar.DAY_OF_MONTH)
//            +"/"+(busiest.get(s)).get(Calendar.YEAR)+" "+busiesttransactions.get(s));
       
        System.out.print(s+(busymonth<10? "0":"")+busymonth+"/");
        System.out.print((busyday<10? "0":"")+busyday+"/");
        System.out.println(busyyear+" "+busiesttransactions.get(s));
       
       
        //need to print out date differently (updated 3/2/14)
        /*SimpleDateFormat ft = new SimpleDateFormat ("MM-dd-yyyy");
        Date t;

            try {
                t = ft.parse(busiest.get(s).toString());
                System.out.println(t);
            } catch (ParseException e) {
                System.out.println("Unparseable using " + ft);
            }
            */
      }
    }
}

 
TOP

Related Classes of homework04.WarehouseReport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.