#!/usr/local/bin/perl #declare subroutines to be used sub StartOrder(); sub DispInventory(); sub Search(); sub Add(); sub Remove(); sub DispOrder(); sub Submit(); sub Menu(); $order_started = 0; #global flag set when StartOrder() called. #################MAIN################### if (@ARGV != 1){ die "Usage: $0 \n"; } open (INV, $ARGV[0]) || die "Error: Cannot open inventory file: $!\n"; #read inventory file. Store products in hash keyed by product number. foreach $product (){ ($code, $title, $price) = split(/\|/, $product); $price =~ s/\$//; #get rid of the dollar sign - it'd cause problems; chomp($price); #so would the new line; $code = uc($code); #make code all upper-case #create anonymous reference to hash, store as value to inventory hash $inventory{$code} = {title => $title, price => $price}; } close INV; #continuously present the user with the menu. Program exits when Submit #function is called while (1){ Menu; } #End of Main. Remainder of program called through subroutines ################SUBROUTINES############ ###MENU()### sub Menu(){ #present user with list of options, and take in user's selection. print "1) Begin Order\n"; print "2) Display Entire Inventory\n"; print "3) Search for Item in Inventory\n"; print "4) Add Item to Order\n"; print "5) Remove Item from Order\n"; print "6) Display current Order\n"; print "7) Submit Order and Exit Program\n\n"; print "Choose an option above: "; chomp ($choice = ); print "\n"; #call appropriate function. if ($choice == 1){ StartOrder; } elsif ($choice == 2){ DispInventory; } elsif ($choice == 3){ Search; } elsif ($choice == 4){ Add; } elsif ($choice == 5){ Remove; } elsif ($choice == 6){ DispOrder; } elsif ($choice == 7){ Submit; } else{ print "Sorry, that is not a valid option. Please try again.\n"; } }#End of Menu(); ###START ORDER### sub StartOrder(){ #make sure the order hasn't already been started. if ($order_started){ print "Error: Order has already been started\n"; return; } #set the global flag. $order_started = 1; #open the order file and declare the hash that will contain the order. open (ORDER, ">order.txt") || die "Error: Cannot open order file: $!\n"; print "Order Started. File is order.txt\n"; %order; }#End of StartOrder(); ###DISPLAY INVENTORY### sub DispInventory(){ #Go through inventory hash, print out title, product code, and price foreach $code (keys %inventory){ $title = $inventory{$code}->{title}; $price = $inventory{$code}->{price}; print "PRODUCT: $code\n"; print "\t$title\n"; print "\t\$$price\n"; } }#End of DispInventory(); ###ADD ITEM### sub Add(){ #Make sure we've started an order. if (!$order_started){ print "Sorry, you must begin an order before choosing this option\n"; return; } print "Enter the Product Code of the item you wish to order: "; chomp ($code = ); $code = uc($code); #make sure the product code is actually in the inventory. if (!exists ($inventory{$code})){ print "Sorry, no item exists with that product code\n"; return; } $title = $inventory{$code}->{title}; #Determine if product has already been ordered. if (exists($order{$code})){ print qq(You are currently ordering $order{$code} cop) . ($order{$code}==1 ? "y" : "ies") . qq(of "$title"\n); print "How many additional copies would you like to order?\n"; } else { print "How many copies of \"$title\" would you like to order?\n"; } #find out out many copies to add, add that many, print status msg. chomp ($num = ); $order{$code} += $num; print qq($num cop) . ($num == 1 ? "y" : "ies") . qq( of "$title" ha) . ($num == 1 ? "s" : "ve") . qq( been added to the order\n); }#end of Add(); ###REMOVE ITEM### sub Remove(){ #make sure an order has been started if (!$order_started){ print "Sorry, you must begin an order before choosing this option\n"; return; } print "Enter the Product Code of the item you wish to remove from the order: "; chomp ($code = ); $code = uc($code); #make sure this product code exists in the inventory if (!exists ($inventory{$code})){ print "Sorry, no item exists with that product code\n"; return; } $title = $inventory{$code}->{title}; #make sure order contains at least one copy of the product entered if (!exists ($order{$code})){ print "You are not currently ordering any copies of \"$title\"\n"; return; } #if only one copy ordered, remove entire entry in the hash if ($order{$code} == 1){ delete $order{$code}; print "\"$title\" has been removed from your order\n"; } #otherwise, ask how many to remove else { print "You are currently ordering $order{$code} copies of \"$title\"\n"; print "How many of them would you like to remove from your order?\n"; chomp ($num = ); #make sure the user's not being dumb... while ($num > $order{$code}){ print "You can't remove more copies than you have in your order\n"; print "How many copies do you wish to remove?\n"; chomp ($num = ); } #subtract correct number of copies from the order $order{$code} -= $num; #if we've removed them all, remove entire entry from hash if ($order{$code} == 0){ delete $order{$code}; print qq("$title" has been removed from your order\n); } else { print qq($num copies of "$title" have been removed from your order\n); } } }#end Remove() ###DISPLAY ORDER### sub DispOrder(){ #see if there's anything to display if (keys (%order) == 0){ print "Your order is currently empty\n"; return; } print "Your order contains the following item(s)\n\n"; #grand total is lexical variable - so it gets reset each time through my $grand_total = 0; #go through order, compute total for each item, #print title, code, and price of each item, #add to grand total. foreach $code (keys %order){ my $title = $inventory{$code}->{title}; my $price = $inventory{$code}->{price}; my $num = $order{$code}; $total = $price * $num; print "$num cop".($num == 1 ? "y" : "ies")." of \"$title\" ($code)\n"; print "at a price of \$$price each = \$$total\n\n"; $grand_total += $total; } print "Total order price = \$$grand_total\n"; }#End of DispOrder(); ###SUBMIT ORDER### sub Submit(){ #first, see if we have anything to submit if (!$order_started){ print "No order started. Nothing to submit!\n"; } elsif (keys %order == 0){ print "Your order is empty. Nothing to submit!\n"; }else{ #change the default output filehandle to be the order file, #then simply call the DisplayOrder function select ORDER; DispOrder(); select STDOUT; #make Standard out default filehandle again. print "Order submitted. Thank you, and have a nice day\n"; close ORDER; } exit; #exit the program. }#End of Submit(); ###Search for Item### sub Search(){ #make list of matching items local - get new copy each time search is run my @returns; #get query from the user print "Please enter a search query: \n"; chomp ($query = ); #determine which method of searching the user is using if ($query =~ /"(.*)"/){ #phrase search $term = $1; #search for whatever was in quotes exactly as is foreach $code (keys %inventory){ $title = $inventory{$code}->{title}; push (@returns, $code) if $title =~ /$term/i; } } elsif ($query =~ /^(\S+) and (\S+)$/i){ #AND search ($term1, $term2) = ($1, $2); #search for titles containing both terms, #make sure terms are bounded by word boundaries foreach $code (keys %inventory){ $title = $inventory{$code}->{title}; if (($title =~ /\b$term1\b/i) && ($title =~ /\b$term2\b/i)){ push (@returns, $code); } } } elsif ($query =~ /^(\S+) or (\S+)$/i){ #OR search ($term1, $term2) = ($1, $2); #same as AND search, replacing && with || foreach $code (keys %inventory){ $title = $inventory{$code}->{title}; if (($title =~ /\b$term1\b/i) || ($title =~ /\b$term2\b/i)){ push (@returns, $code); } } } elsif ($query =~ /^(\S+)$/){ #plain word search $term = $1; #search for titles containing term, bounded by word boundary foreach $code (keys %inventory){ $title = $inventory{$code}->{title}; push (@returns, $code) if $title =~ /\b$term\b/i; } } else { #User didn't follow correct format print "Sorry, that search format is not supported\n"; return; } #if anything was matched... if (@returns){ print "Here are the inventory items matching your query $query:\n"; #print matches in same format as display inventory function foreach $code (@returns){ $title = $inventory{$code}->{title}; $price = $inventory{$code}->{price}; print "PRODUCT: $code\n"; print "\t$title\n"; print "\t\$$price\n"; } } else { print "Sorry, your query $query returned no items\n"; } }