Catalog Script: order.cgi

This script enters customer shipping and billing information into database.

#!/usr/local/bin/perl
# order.cgi
# online order-entry system for catalog demo

use lib './modules';
use DBI;
use CGI::Pretty qw/:standard/;
use Catalog;
use ShoppingCart;

use strict;

use constant DB           => 'dbi:mysql:perl_conference';
use constant SHIPPING     => '10.50';
use constant stylesheet   => '/stylesheets/catalog.css';

# open database
my $db = DBI->connect(DB,undef,undef,{PrintError=>0}) || die $DBI::errstr;
my $cart    = ShoppingCart->new($db) || exit 0;
my $catalog = Catalog->new($db)      || die "Couldn't create catalog";

# CGI parameters:
# $catalog           number of this item
# "confirm"          confirm order
# "update"           update quantities on order form

# items on the customer/order info form
my %labels = (
	      'name'      => 'Full Name (required)',
	      'address1'  => 'Address line 1 (required)',
	      'address2'  => 'Address line 2',
	      'city'      => 'City (required)',
	      'state'     => 'State/Province (required)',
	      'country'   => 'Country (required)',
	      'zip'       => 'Zip Code (required)',
	      'telephone' => 'Daytime Phone (required)',
	      'ccno'      => 'Credit Card MC/Visa/Amex (required)',
	      'expires'   => 'Expiration date (required)'
	      );

# process any last-minute changes to the shopping cart
process_cart($cart);

# If there's nothing to order, then return to catalog main page?
unless (keys %{$cart->fetch}) {
    print redirect($cart->rewrite_url('catalog.cgi'));
    exit 0;
}

# start the HTML document
print header();
print start_html(-style => {src => stylesheet},
	       -title => 'Kool Kitchen Koncepts Order Form'),
      h1('Order from Kool Kitchen Koncepts'),
      p("Our one-klick order form makes ordering kwick and easy!");

# If the "confirm" parameter is present, then try to place the order.
# The ShoppingCart will do all the hard stuff.
my $confirmation;
if (param('confirm')) {
    my $order_data = CGI::Vars();  # magic CGI.pm function (recent addition)
    $confirmation = $cart->place_order($order_data);
    print $@ unless $confirmation; # couldn't confirm so give error message
}

# If there's a confirmation number, then we've placed the order successfully,
# so we print it.
if ($confirmation) {
    print_confirmation($confirmation,$cart);
} 
# otherwise we display the shopping cart and customer/order info form.
else { 
    print start_form;
    display_shopping_cart($catalog,$cart);
    display_order_form();
    print end_form;
}

bottom_boilerplate($cart);
$db->disconnect;
exit 0;

# This is called to print the order confirmation number.
sub print_confirmation {
    my ($confirmation_id,$cart) = @_;
    print h2('Your order has been entered'),
          h3("Confirmation \# $confirmation_id"),
          p('Please keep this number for your records.');
}

# This is called to display the shopping cart and current totals.
sub display_shopping_cart {
    my ($catalog,$cart) = @_;
    my $items = $cart->fetch;

    my (@rows,$total);
    for my $catno (keys %$items) {
	my $info = $catalog->info($catno);
	my $left = $cart->items_left($catno);
	my $backordered = $left >= 0 ? '' 
                                     : strong({-class=>'alert'},
					      abs($left) . ' item(s) backordered');
	push(@rows,
	     td(
		[a({-href=>$cart->rewrite_url("catalog.cgi?catno=$catno")},$catno),
		 $info->{'name'} ] ).
	     td({-align=>'RIGHT'}, 
		[ textfield(-name=>$catno, -value=>$items->{$catno}, -size=>3),
		  $info->{'price'},
		  sprintf('%4.2f',$items->{$catno} * $info->{'price'}),
		 $backordered ]
		));
	$total += $items->{$catno} * $info->{'price'};
    }
    push(@rows,
	 td({-class=>'highlight',-align=>'RIGHT',-colspan=>4},'Shipping/Handling') .
	 td({-class=>'highlight',-align=>'RIGHT'},"\$",SHIPPING));
    push(@rows,
	 th({-align=>'RIGHT',-colspan=>4},'Total') .
	 th({-align=>'RIGHT'},"\$",sprintf('%4.2f',SHIPPING + $total)));

    print table({-width=>'100%'},
		TR(th(['Catalog','Name','Quantity', 'Price','Total Price','B.O.'])),
		TR(\@rows)),
          submit('Recalculate');
}

# This is called to display the customer/order information form.
sub display_order_form {
    my @rows;
    param(-name=>'country',-value=>'USA'); # default
    for my $field (qw(name address1 address2 city 
		      state country zip telephone ccno expires)) {
	push(@rows,
	     th({-align=>'RIGHT'},$labels{$field}) .
	     td(textfield(-name=>$field,-size=>40)));
    }
    print hr,
          h3('Shipping/Payment Information'),
          table(TR(\@rows)),
          submit(-name=>'confirm',-value=>'Confirm Order'),
          hr;
}

# This is called to update the contents of the shopping cart if any
# last-minute changes have been made.
sub process_cart {
    my $cart = shift;
    my $items = $cart->fetch;
    my $changed;
    foreach (keys %$items) {
	next unless defined param($_);
	$items->{$_} = param($_);
	$changed++;
    }
    $cart->store($items) if $changed;
}

sub bottom_boilerplate {
    my $cart = shift;
    print p(a({-href=>$cart->rewrite_url('catalog.cgi')},'Browse our katalog')),
          hr,'Copyright 1999 ',a({-href=>'/'},'Kool Kitchen Concepts');
}
  


<< Previous
Contents >> Next >>

Lincoln D. Stein, lstein@cshl.org
Cold Spring Harbor Laboratory
Last modified: Sun Apr 25 15:29:06 EDT 1999