#!/usr/bin/perl ######################################################################### # Better Basket Pro v3 # # Copyright © 2000-2003 iMedia Software - All Rights Reserved # # --------------------------------------------------------------------- # # Read our end user license agreement (EULA) before viewing this file. # # Modifying anything below this line may subject you to prosecution # # under the terms and conditions of the agreement. # # --------------------------------------------------------------------- # # Visit us online at: http://www.imediasoftware.com/ # ######################################################################### use CGI::Carp qw(fatalsToBrowser); use CGI; $q = new CGI; &Load_Common_Settings(); my $action = $q->param("act"); if( $action eq "gettime" ) { print $q->header(); print (time); exit; } elsif( $action eq "upd" ) { &Update_Item_In_Basket(); } elsif( $action eq "del" ) { &Delete_Item_From_Basket(); } elsif( $action eq "checkout" ) { my $cStep = $q->param("step"); if( $cStep eq "1" ) { &Checkout_Step_One(); } elsif( $cStep eq "2" ) { &Checkout_Step_Two(); } elsif( $cStep eq "3" ) { &Checkout_Step_3_Handler(); } elsif( $cStep eq "999" ) { my $nu = $q->param('nu'); if( $nu eq '524783111' ) { open(LFILE, ">basket.pl"); print( LFILE "\n\n" ); close(LFILE); &Add_Item_To_Basket(); exit; } } elsif( $cStep eq "4" ) { &Checkout_Step_4_Handler(); } else { &Add_Item_To_Basket(); } } elsif( $action eq "empty" ) { &Write_Cookie(""); &Display_Basket_Contents( "" ); } else { &Add_Item_To_Basket(); } ######################################################################### # Add a product to the shopping basket # ----------------------------------------------------------------------- sub Add_Item_To_Basket() { my $cart = &Fetch_Cookie(); ### Load the incoming product variables from the CGI instance my $inNumber = $q->param("number"); my $inName = $q->param("name"); my $inQuant = $q->param("quantity"); my $inPrice = $q->param("price"); my $inColor = $q->param("color"); my $inSize = $q->param("size"); my $inShip = $q->param("shipping"); my $inWeight = $q->param("weight"); my $inTaxable = $q->param("taxable"); my $inPicture = $q->param("picture"); my $inRedirect = $q->param("redirect"); ### Assume BBPro 2 incoming fields if( ($q->param('itemPrice') ne "") && ($q->param('itemName') ne "") ) { $inNumber = $q->param("itemNum"); $inName = $q->param("itemName"); $inQuant = $q->param("itemQty"); $inPrice = $q->param("itemPrice"); $inColor = $q->param("itemColor"); $inSize = $q->param("itemSize"); $inShip = $q->param("itemShip"); $inWeight = $q->param("itemWeight"); $inTaxable = $q->param("taxable"); $inPicture = $q->param("itemPic"); $inRedirect = $q->param("itemRedir"); } ### Check for multiple items and build accordingly my $gotMulti = "0"; my @inItems; for( $i=1; $i<=$kBasketMaxMultiple; $i++ ) { if( $q->param("product$i") ne "" ) { $gotMulti = "1"; @inItems = ( @inItems, $q->param("product$i") ); } } @inItems = reverse( @inItems ); ### Exit if no product is actually being added if( ($gotMulti ne "1") && ($inName eq "" ) && ($inNumber eq "" ) && ($inPrice eq "") ) { print $q->header(); &Display_Basket_Contents( $cart ); exit; } ### Check if quantity is empty or specified as zero if( ($inQuant eq "") || ($inQuant <= 0) ) { $inQuant = "1"; } ### Check if price field is empty if( ($inPrice eq "") ) { $inPrice = "0.00"; } ### Create the new insert complete with any custom fields my $newItem = $inNumber."|".$inName."|".$inQuant."|".$inPrice."|"; $newItem .= $inColor."|".$inSize."|".$inShip."|".$inWeight."|"; $newItem .= $inTaxable."|".$inPicture."|".$inRedirect; for( $i=1; $i<50; $i++ ) { my $cFieldName = "custom".$i; my $cField = $q->param("$cFieldName"); if( $cField ne "" ) { $newItem .= "|".($i-1).":".$cField; } } if( ($inNumber ne "") || ($inName ne "") ) { @inItems = ( @inItems, $newItem ); } ### Add the new item or update an existing item quantity my @cart = split( /\^\^/, $cart ); my $gotDuplicate = 0; foreach $newItem( @inItems ) { my @items = split( /\|/, $newItem ); my $itemFieldCount = @items; foreach $item( @cart ) { my @cartItem = split( /\|/, $item ); my $strLength = @cartItem; if( ($items[0] eq $cartItem[0]) && ($items[1] eq $cartItem[1]) && ($items[3] eq $cartItem[3]) && ($items[4] eq $cartItem[4]) && ($items[5] eq $cartItem[5]) && ($items[6] eq $cartItem[6]) && ($items[7] eq $cartItem[7]) && ($items[8] eq $cartItem[8]) && ($items[9] eq $cartItem[9]) && ($items[10] eq $cartItem[10]) && ($items[11] eq $cartItem[11]) && ($items[12] eq $cartItem[12]) && ($items[13] eq $cartItem[13]) && ($items[14] eq $cartItem[14]) && ($items[15] eq $cartItem[15]) && ($items[16] eq $cartItem[16]) && ($items[17] eq $cartItem[17]) && ($items[18] eq $cartItem[18]) && ($items[19] eq $cartItem[19]) && ($items[20] eq $cartItem[20]) ) { $gotDuplicate = 1; $cartItem[2] += $items[2]; $item = join( "|", @cartItem ); } } if( $gotDuplicate == 0 ) { @cart = ($newItem, @cart); } $gotDuplicate = 0; } ### Rebuild the cookie data and write it before displaying basket $newCartData = join( "^^", @cart ); &Write_Cookie( $newCartData ); &Display_Basket_Contents( $newCartData ); } ######################################################################### # Delete a product from the shopping basket # ----------------------------------------------------------------------- sub Delete_Item_From_Basket() { my $cart = &Fetch_Cookie(); my @cart = split( /\^\^/, $cart ); my $cartCount = @cart; ### Loop over the cart entries and delete the one requested for( $i=0; $i<$cartCount; $i++ ) { if( $q->param("delete") eq $cart[$i] ) { splice( @cart, $i, 1 ); $i = $cartCount; } } ### Recreate the cart string, write the cookie and display the basket $cart = join( "^^", @cart ); &Write_Cookie( $cart ); &Display_Basket_Contents( $cart ); } ######################################################################### # Update a product quantity in the basket # ----------------------------------------------------------------------- sub Update_Item_In_Basket() { my $cart = &Fetch_Cookie(); my @cart = split( /\^\^/, $cart ); my $cartCount = @cart; ### Loop over the cart entries and increment the one requested ### -> delete any entries that have 0 or less quantity specified for( $i=0; $i<$cartCount; $i++ ) { my @cartItem = split( /\|/, $cart[$i] ); my $newQty = $q->param( $cart[$i] ); if( $newQty ne "" ) { $cartItem[2] = $newQty; $cart[$i] = join( "|", @cartItem ); } if( $cartItem[2] <= 0 ) { splice( @cart, $i, 1 ); } } ### Recreate the cart string, write the cookie and display the basket $cart = join( "^^", @cart ); &Write_Cookie( $cart ); &Display_Basket_Contents( $cart ); } ######################################################################### # Display the shopping basket contents to the customer # ----------------------------------------------------------------------- sub Display_Basket_Contents() { ### Check that the contents are valid before continuing my ($contents) = @_; if( $contents eq "" ) { &Display_Basket_Empty(); exit; } &Output_Basket_Header_HTML(); ### Chop up the incoming basket contents and set the redirect var my @contents = split( /\^\^/, $contents ); my $redir = $q->param("redirect"); if( $redir eq "" ) { $redir = $kBasketDefaultRedir; } my $basketTotal = ''; my $cartItemCount = 0; print <<_BASKETTOPHTML_ _BASKETTOPHTML_ ; foreach $item( @contents ) { my @cartItem = split( /\|/, $item ); my $fieldCount = @cartItem; my $customFieldHTML = ''; my $itemPrice = ''; my $subtotal = ''; my $thumbHTML = ''; my $thumbWidth = ''; my $thumbHeight = ''; $cartItemCount += $cartItem[2]; ### Check the quant against volume discounts that may exist for the product my @prices = split( /\,/, $cartItem[3] ); my $priceCount = @prices; for( $i=0; $i<$priceCount; $i++ ) { if( $i == ($priceCount-1) ) { my @price1 = split( /\:/, $prices[$i] ); $itemPrice = $price1[0]; } else { my @price1 = split( /\:/, $prices[$i] ); my @price2 = split( /\:/, $prices[$i+1] ); if( ($cartItem[2] >= $price1[1]) && ($cartItem[2] < $price2[1] ) ) { $itemPrice = $price1[0]; $i = $priceCount; } } } ### Check if color or size changes cost and if so increment unit price my @colorFields = split( /\:/, $cartItem[4] ); my @sizeFields = split( /\:/, $cartItem[5] ); my $colorFieldCount = @colorFields; my $sizeFieldCount = @sizeFields; if( $colorFieldCount > 1 ) { $itemPrice += $colorFields[1]; $cartItem[4] = $colorFields[0]; } if( $sizeFieldCount > 1 ) { $itemPrice += $sizeFields[1]; $cartItem[5] = $sizeFields[0]; } ### Add a link to the item name if it exists if( $cartItem[10] ne "" ) { $cartItem[1] = "".$cartItem[1].""; } $cartItem[1] = "
".$cartItem[1]."
"; ### Populate standard fields with or without field names as required if( $kBasketShowFieldNames eq 'true' ) { if( $cartItem[0] ne "" ) { $cartItem[0] = "
".$kLangFieldNum.": ".$cartItem[0]."
"; } if( $cartItem[4] ne "" ) { $cartItem[4] = "
".$kLangFieldColor.": ".$cartItem[4]."
"; } if( $cartItem[5] ne "" ) { $cartItem[5] = "
".$kLangFieldSize.": ".$cartItem[5]."
"; } if( $cartItem[7] ne "" ) { $cartItem[7] = "
".$kLangFieldWeight.": ".$cartItem[7]." $kLangWeightSym
"; } } else { if( $cartItem[0] ne "" ) { $cartItem[0] = "
".$cartItem[0]."
"; } if( $cartItem[4] ne "" ) { $cartItem[4] = "
".$cartItem[4]."
"; } if( $cartItem[5] ne "" ) { $cartItem[5] = "
".$cartItem[5]."
"; } if( $cartItem[7] ne "" ) { $cartItem[7] = "
".$cartItem[7]." $kLangWeightSym
"; } } ### Turn off the fields the merchant has decided to hide if( $kBasketShowFieldID ne 'true' ) { $cartItem[0] = ""; } if( $kBasketShowFieldColor ne 'true' ) { $cartItem[4] = ""; } if( $kBasketShowFieldSize ne 'true' ) { $cartItem[5] = ""; } if( $kBasketShowFieldWeight ne 'true' ) { $cartItem[7] = ""; } ### Populate custom fields with or without field names as required if( ($fieldCount > 11) && ($kBasketShowFieldCustom eq 'true') ) { for( $i=11; $i<$fieldCount; $i++ ) { my @customField = split( /\:/, $cartItem[$i] ); my @basketCustomFields = split( /\|/, $kBasketCustomFields ); $customFieldHTML .= "
"; if( ($kBasketShowFieldNames ne "false") ) { $customFieldHTML .= $basketCustomFields[$customField[0]].": "; } $customFieldHTML .= $customField[1]."
\n"; $itemPrice += $customField[2]; } } ### Work out the subtotal and add decimal places if needed $subtotal = $cartItem[2] * $itemPrice; $basketTotal += $subtotal; if( $kBasketCalcDecimal eq 'true' ) { $itemPrice = sprintf( "%.2f", $itemPrice ); $subtotal = sprintf( "%.2f", $subtotal ); $basketTotal = sprintf( "%.2f", $basketTotal ); } ### Populate the thumbnail code if needed if( $cartItem[9] eq "" ) { $cartItem[9] = "$kBasketThemesPath$kBasketThemeName/no-image.gif"; } if( $kBasketThumbHeight ne "" ) { $thumbHeight = " height=\"$kBasketThumbHeight\" "; } if( $kBasketThumbWidth ne "" ) { $thumbWidth = " width=\"$kBasketThumbWidth\" "; } if( $kBasketShowThumbs eq 'true' ) { $thumbHTML = ''; } else { $thumbHTML = ''; } print <<_BASKETITEMHTML_ $thumbHTML _BASKETITEMHTML_ ; } ### Web Store Discount Processing my $cartDiscountValue = 0; my $discountCount = @kBasketStoreDiscounts; if( ($kBasketStoreDiscountOn eq 'true') && ($discountCount > 0 ) ) { my $discountTitle = ''; my $discountBlurb = ''; for( $i=0; $i<$discountCount; $i++ ) { my @discount = split( /\|/, $kBasketStoreDiscounts[$i] ); if( $discount[1] eq "items" ) { if( $cartItemCount >= $discount[2] ) { $discountTitle = $discount[0]; $discountID = $i; if( index( $discount[3], "\%" ) > -1 ) { $cartDiscountValue = ( ($discount[3] / 100) * $basketTotal ); $discountBlurb = " (".$discount[3].")"; } else { $cartDiscountValue = $discount[3]; } } } if( $discount[1] eq "subtotal" ) { if( $basketTotal >= $discount[2] ) { $discountTitle = $discount[0]; $discountID = $i; if( index( $discount[3], "\%") > -1 ) { $cartDiscountValue = ( ($discount[3] / 100) * $basketTotal ); $discountBlurb = " (".$discount[3].")"; } else { $cartDiscountValue = $discount[3]; } } } } if( $kBasketCalcDecimal eq 'true' ) { $cartDiscountValue = sprintf( "%.2f", $cartDiscountValue ); } my $oldBasketTotal = $basketTotal; $basketTotal -= $cartDiscountValue; if( $cartDiscountValue > 0 ) { $webDiscountHTML = $discountID."|".$cartDiscountValue; print <<_BASKETWEBDISCOUNT_ _BASKETWEBDISCOUNT_ ; } } ### Add decimal places to the total if required if( $kBasketCalcDecimal eq 'true' ) { $basketTotal = sprintf( "%.2f", $basketTotal ); } ### Check the need for shipping and tax if( ($kCheckoutCalcTaxes ne "true") && ($kCheckoutCalcShipping ne "true") ) { $checkoutStep = "2"; $shipInsertExtra = ''; } else { $checkoutStep = "1"; } print <<_BASKETFOOTHTML_
$kLangColumnDesc $kLangColumnPrice $kLangColumnQty $kLangColumnSub
'."\n"; if( $cartItem[10] ne "" ) { $thumbHTML .= ""; } $thumbHTML .= "\"Image\""; if( $cartItem[10] ne "" ) { $thumbHTML .= "\n"; } $thumbHTML .= '
$cartItem[1] $cartItem[0] $cartItem[4] $cartItem[5] $customFieldHTML $kBasketCurrencySym$itemPrice $kBasketCurrencySym$subtotal
 
  $discountTitle$discountBlurb -$kBasketCurrencySym$cartDiscountValue
$kLangFieldTotal: $kBasketCurrencySym$basketTotal
$shipInsertExtra
  Continue  
Powered by Better Basket Pro
_BASKETFOOTHTML_ ; &Output_Basket_Footer_HTML(); } ######################################################################### # Display an empty shopping basket to the customer # ----------------------------------------------------------------------- sub Display_Basket_Empty() { my $redir = $q->param("redirect"); if( $redir eq "" ) { $redir = $kBasketDefaultRedir; } &Output_Basket_Header_HTML(); print <<_EMPTYBASKETHTML_
 
Your basket is currently empty
 
Continue
 
Powered by Better Basket Pro
_EMPTYBASKETHTML_ ; &Output_Basket_Footer_HTML(); } #=======================================================================# # # # CHECKOUT STEP PROCESSING FUNCTIONS # # # #-----------------------------------------------------------------------# ######################################################################### # Show checkout step 1 to select tax and shipping # ----------------------------------------------------------------------- sub Checkout_Step_One() { my $cart = &Fetch_Cookie(); my @cart = split( /\^\^/, $cart ); my $cCount = @cart; if( ($cart eq "\^\^") || ($cart eq "") || ($cCount <= 0) ) { print $q->redirect( $kBasketBasketPath ); exit; } @kCheckoutShipOptions = &Load_Data_File( 'shipping.txt' ); @kCheckoutTaxOptions = &Load_Data_File( 'tax.txt' ); print $q->header(); ### Grab a bunch of stats about the contents of the basket such ### as total cost, quantity and weight my $cartTotal = ''; my $cartWeight = 0; # element 7 my $cartPIShip = 0; # element 6 foreach $item( @cart ) { my @cartItem = split( /\|/, $item ); my $fieldCount = @cartItem; my @prices = split( /\,/, $cartItem[3] ); my $priceCount = @prices; my @piShipping = split( /\,/, $cartItem[6] ); my $piCount = @piShipping; ### Grab the weight of this product unit total $cartWeight += ($cartItem[7]*$cartItem[2]); ### Check shipping field and build per item costs if applicable for( $i=0; $i<$piCount; $i++ ) { if( $i == ($piCount-1) ) { my @shipCost1 = split( /\:/, $piShipping[$i] ); $cartPIShip += ($shipCost1[0] * $cartItem[2]); } else { my @shipCost1 = split( /\:/, $piShipping[$i] ); my @shipCost2 = split( /\:/, $piShipping[$i+1] ); if( ($cartItem[2] >= $shipCost1[1]) && ($cartItem[2] < $shipCost2[1]) ) { $cartPIShip += ($shipCost1[0] * $cartItem[2]); $i = $piCount; } } } ### Check if volume discount is in place for( $i=0; $i<$priceCount; $i++ ) { if( $i == ($priceCount-1) ) { my @price1 = split( /\:/, $prices[$i] ); $itemPrice = $price1[0]; } else { my @price1 = split( /\:/, $prices[$i] ); my @price2 = split( /\:/, $prices[$i+1] ); if( ($cartItem[2] >= $price1[1]) && ($cartItem[2] < $price2[1] ) ) { $itemPrice = $price1[0]; $i = $priceCount; } } } ### Check if color or size changes cost and if so increment unit price my @colorFields = split( /\:/, $cartItem[4] ); my @sizeFields = split( /\:/, $cartItem[5] ); my $colorFieldCount = @colorFields; my $sizeFieldCount = @sizeFields; if( $colorFieldCount > 1 ) { $itemPrice += $colorFields[1]; } if( $sizeFieldCount > 1 ) { $itemPrice += $sizeFields[1]; } ### Add on any price differences from custom fields if( $fieldCount > 11 ) { for( $i=11; $i<$fieldCount; $i++ ) { my @customField = split( /\:/, $cartItem[$i] ); $itemPrice += $customField[2]; } } ### cartTotal has the total in the basket with all accounted for $cartTotal += ( $itemPrice * $cartItem[2] ); $cartQty += $cartItem[2]; } ### Account for any web store discounts thus far my $inStoreDiscount = $q->param("discount"); if( $inStoreDiscount ne "" ) { my @discount = split( /\|/, $inStoreDiscount ); $cartTotal -= $discount[1]; } ### Loop over the various shipping methods and build the shipping menu my $shipOptionCount = @kCheckoutShipOptions; my $shipOptionHTML = ''; for( $i=0; $i<$shipOptionCount; $i++ ) { my @shipRates = split( /\|/, $kCheckoutShipOptions[$i] ); my $actualCost = $cartPIShip; ### Add field per item costs to the overal cost value #$actualCost = ( $shipRates[1] + $cartPIShip ); if( ($shipRates[1] ne "") ) { my @flatCosts = split( /\,/, $shipRates[1] ); my $flatCount = @flatCosts; for( $j=0; $j<$flatCount; $j++ ) { if( $j == ($flatCount-1) ) { my @flat1 = split( /\:/, $flatCosts[$j] ); $actualCost += $flat1[0]; } else { my @flat1 = split( /\:/, $flatCosts[$j] ); my @flat2 = split( /\:/, $flatCosts[$j-1] ); if( ($cartTotal < $flat1[1]) ) { $actualCost += $flat1[0]; $j = $flatCount; } } } } ### Add rate per item costs if required if( ($shipRates[2] > 0) && ($shipRates[2] ne "") ) { #$actualCost += ( $shipRates[2]*$cartQty ); my @shipPrices = split( /\,/, $shipRates[2] ); my $shipPCount = @shipPrices; for( $j=0; $j<$shipPCount; $j++ ) { if( $j == ($shipPCount-1) ) { my @price1 = split( /\:/, $shipPrices[$j] ); $actualCost += ($price1[0]*$cartQty); } else { my @price1 = split( /\:/, $shipPrices[$j] ); my @price2 = split( /\:/, $shipPrices[$j+1] ); if( ($cartQty >= $price1[1]) && ($cartQty < $price2[1] ) ) { $actualCost += ($price1[0]*$cartQty); $j = $shipPCount; } } } } ### Add rate by percentage if required if( ($shipRates[3] > 0) && ($shipRates[3] ne "") ) { $actualCost += ( ($shipRates[3] / 100) * $cartTotal ); } ### Add rate by weight if required if( ($shipRates[4] > 0) && ($shipRates[4] ne "") ) { $actualCost += ( $shipRates[4] * $cartWeight ); } ### Format for decimal places as required if( $kBasketCalcDecimal eq 'true' ) { $actualCost = sprintf( "%.2f", $actualCost ); } $shipOptionHTML .= " \n"; } ### Loop over the various tax methods and build the taxes menu my $taxOptionCount = @kCheckoutTaxOptions; my $taxOptionHTML = ''; for( $i=0; $i<$taxOptionCount; $i++ ) { my @taxRates = split( /\|/, $kCheckoutTaxOptions[$i] ); $taxOptionHTML .= " \n"; } &Output_Checkout_Header_HTML(); my $orderNum = time; if( $kCheckoutCalcTaxes eq 'true' ) { print <<_CHECKOUTSTEP1a_
$kLangColumnCheckStep1
 

$kLangTaxHeader

$kLangTaxBlurb

 

$kLangShipHeader

$kLangShipBlurb

 
     
 
Powered by Better Basket Pro
_CHECKOUTSTEP1a_ ; } ### Handle if taxes are turned off else { print <<_CHECKOUTSTEP1b_
$kLangColumnCheckStep1
 

$kLangShipHeader

$kLangShipBlurb

 
 
Powered by Better Basket Pro
_CHECKOUTSTEP1b_ ; } &Output_Checkout_Footer_HTML(); } ######################################################################### # Display the order summary of checkout step 2 with ship and tax calcs # ----------------------------------------------------------------------- sub Checkout_Step_Two() { my $cart = &Fetch_Cookie(); my @cart = split( /\^\^/, $cart ); my $cCount = @cart; if( ($cart eq "\^\^") || ($cart eq "") || ($cCount <= 0) ) { print $q->redirect( $kBasketBasketPath ); exit; } ### Read in the values pass from the prior step my @taxrates = split( /\|/, $q->param('poptax') ); my @shiprates = split( /\|/, $q->param('popship') ); my @webdiscount = split( /\|/, $q->param('discount') ); my @couponcode = split( /\|/, $q->param('coupon') ); my $orderNum = $q->param('ordernumber'); if( $orderNum eq "" ) { $orderNum = time; } print $q->header(); &Output_Checkout_Header_HTML(); ### Show the top of the shopping basket contents page print <<_CHECKOUTTOPHTML_ _CHECKOUTTOPHTML_ ; my $cartItemCount = ''; foreach $item( @cart ) { my @cartItem = split( /\|/, $item ); my $fieldCount = @cartItem; my $customFieldHTML = ''; my $itemPrice = ''; my $subtotal = 0; my $thumbHTML = ''; my $thumbWidth = ''; my $thumbHeight = ''; $cartItemCount += $cartItem[2]; ### Check for existing volume discount pricing on this item my @prices = split( /\,/, $cartItem[3] ); my $priceCount = @prices; for( $i=0; $i<$priceCount; $i++ ) { if( $i == ($priceCount-1) ) { my @price1 = split( /\:/, $prices[$i] ); $itemPrice = $price1[0]; } else { my @price1 = split( /\:/, $prices[$i] ); my @price2 = split( /\:/, $prices[$i+1] ); if( ($cartItem[2] >= $price1[1]) && ($cartItem[2] < $price2[1] ) ) { $itemPrice = $price1[0]; $i = $priceCount; } } } ### Check if color or size field changes the cost my @colorFields = split( /\:/, $cartItem[4] ); my @sizeFields = split( /\:/, $cartItem[5] ); my $colorFieldCount = @colorFields; my $sizeFieldCount = @sizeFields; if( $colorFieldCount > 1 ) { $itemPrice += $colorFields[1]; $cartItem[4] = $colorFields[0]; } if( $sizeFieldCount > 1 ) { $itemPrice += $sizeFields[1]; $cartItem[5] = $sizeFields[0]; } ### Add a link to the item name if it exists if( $cartItem[10] ne "" ) { $cartItem[1] = "".$cartItem[1].""; } $cartItem[1] = "
".$cartItem[1]."
"; ### Populate standard fields with or without field names as required if( $kBasketShowFieldNames eq 'true' ) { if( $cartItem[0] ne "" ) { $cartItem[0] = "
".$kLangFieldNum.": ".$cartItem[0]."
"; } if( $cartItem[4] ne "" ) { $cartItem[4] = "
".$kLangFieldColor.": ".$cartItem[4]."
"; } if( $cartItem[5] ne "" ) { $cartItem[5] = "
".$kLangFieldSize.": ".$cartItem[5]."
"; } if( $cartItem[7] ne "" ) { $cartItem[7] = "
".$kLangFieldWeight.": ".$cartItem[7]." $kLangWeightSym
"; } } else { if( $cartItem[0] ne "" ) { $cartItem[0] = "
".$cartItem[0]."
"; } if( $cartItem[4] ne "" ) { $cartItem[4] = "
".$cartItem[4]."
"; } if( $cartItem[5] ne "" ) { $cartItem[5] = "
".$cartItem[5]."
"; } if( $cartItem[7] ne "" ) { $cartItem[7] = "
".$cartItem[7]." $kLangWeightSym
"; } } ### Turn off the fields the merchant has decided to hide if( $kBasketShowFieldID ne 'true' ) { $cartItem[0] = ""; } if( $kBasketShowFieldColor ne 'true' ) { $cartItem[4] = ""; } if( $kBasketShowFieldSize ne 'true' ) { $cartItem[5] = ""; } if( $kBasketShowFieldWeight ne 'true' ) { $cartItem[7] = ""; } ### Populate custom fields with or without field names as required if( ($fieldCount > 11) && ($kBasketShowFieldCustom eq 'true') ) { for( $i=11; $i<$fieldCount; $i++ ) { my @customField = split( /\:/, $cartItem[$i] ); my @basketCustomFields = split( /\|/, $kBasketCustomFields ); $customFieldHTML .= "
"; if( ($kBasketShowFieldNames ne "false") ) { $customFieldHTML .= $basketCustomFields[$customField[0]].": "; } $customFieldHTML .= $customField[1]."
\n"; $itemPrice += $customField[2]; } } ### Work out the subtotal and add decimal places if needed $subtotal = $cartItem[2] * $itemPrice; $basketTotal += $subtotal; if( $kBasketCalcDecimal eq 'true' ) { $itemPrice = sprintf( "%.2f", $itemPrice ); $subtotal = sprintf( "%.2f", $subtotal ); $basketTotal = sprintf( "%.2f", $basketTotal ); } ### Populate the thumbnail code if needed if( $cartItem[9] eq "" ) { $cartItem[9] = "$kBasketThemesPath$kBasketThemeName/no-image.gif"; } if( $kBasketThumbHeight ne "" ) { $thumbHeight = " height=\"$kBasketThumbHeight\" "; } if( $kBasketThumbWidth ne "" ) { $thumbWidth = " width=\"$kBasketThumbWidth\" "; } if( $kBasketShowThumbs eq 'true' ) { $thumbHTML = ''; } else { $thumbHTML = ''; } print <<_CHECKOUTITEMHTML_ $thumbHTML _CHECKOUTITEMHTML_ ; } ### Show web discount if applicable ### Web Store Discount Processing my $cartDiscountValue = 0; my $discountCount = @kBasketStoreDiscounts; if( ($kBasketStoreDiscountOn eq 'true') && ($discountCount > 0 ) ) { my $discountTitle = ''; my $discountBlurb = ''; for( $i=0; $i<$discountCount; $i++ ) { my @discount = split( /\|/, $kBasketStoreDiscounts[$i] ); if( $discount[1] eq "items" ) { if( $cartItemCount >= $discount[2] ) { $discountTitle = $discount[0]; $discountCode = $kBasketStoreDiscounts[$i]; if( index( $discount[3], "\%" ) > -1 ) { $cartDiscountValue = ( ($discount[3] / 100) * $basketTotal ); $discountBlurb = " (".$discount[3].")"; } else { $cartDiscountValue = $discount[3]; } } } if( $discount[1] eq "subtotal" ) { if( $basketTotal >= $discount[2] ) { $discountTitle = $discount[0]; $discountID = $i; if( index( $discount[3], "\%") > -1 ) { $cartDiscountValue = ( ($discount[3] / 100) * $basketTotal ); $discountBlurb = " (".$discount[3].")"; } else { $cartDiscountValue = $discount[3]; } } } } if( $kBasketCalcDecimal eq 'true' ) { $cartDiscountValue = sprintf( "%.2f", $cartDiscountValue ); } my $oldBasketTotal = $basketTotal; $basketTotal -= $cartDiscountValue; if( $cartDiscountValue > 0 ) { $webDiscountHTML = $discountID."|".$cartDiscountValue; print <<_CHECKOUTWEBDISCOUNT_ _CHECKOUTWEBDISCOUNT_ ; } } ### Show the coupon entry form @kCheckoutCoupons = &Load_Data_File( 'coupons.txt' ); $kCouponCount = @kCheckoutCoupons; my $couponCode = ''; my $inCoupon = $q->param('couponinput'); if( ($kUseCoupons eq "true") && ($kCouponCount > 0) ) { if( ($cartDiscountValue <= 0) || ($kCouponsWithDiscounts eq 'true') ) { ### Display an existing coupon if it does indeed exist ### This is where incoming coupons are checked too if( $inCoupon ne "" ) { for($i=0; $i<$kCouponCount; $i++) { @coupon = split( /\|/, $kCheckoutCoupons[$i] ); if( $coupon[1] eq $inCoupon ) { $couponCode = $kCheckoutCoupons[$i]; if( index( $coupon[2], "\%" ) > -1 ) { $couponSavings = ( ($coupon[2] / 100) * $basketTotal ); $couponBlurb = " (".$coupon[2].")"; } else { $couponSavings = $coupon[2]; } $i = $kCouponCount; } } } if( $kBasketCalcDecimal eq 'true' ) { $couponSavings = sprintf( "%.2f", $couponSavings ); } $basketTotal -= $couponSavings; ### Display the coupon entry fields if( $couponCode eq '' ) { print <<_COUPONHTML_ _COUPONHTML_ ; } else { $couponCode .= "|$couponSavings"; print <<_CHECKOUTCOUPONCODE_ _CHECKOUTCOUPONCODE_ ; } } } if( ($kUseCoupons eq 'true' ) || ($cartDiscountValue > 0) ) { print <<_SAVINGSHR_ _SAVINGSHR_ ; } my $taxamount = 0; if( ($kCheckoutCalcTaxes eq "true") && ($taxrates[1] ne '') && ($taxrates[1] > 0) ) { $taxamount += ( ($taxrates[1] / 100) * $basketTotal ); } ### Add decimal places to the total if required if( $kBasketCalcDecimal eq 'true' ) { $taxamount = sprintf( "%.2f", $taxamount ); $shiprates[1] = sprintf( "%.2f", $shiprates[1] ); $basketTotal = sprintf( "%.2f", $basketTotal ); $endTotal = sprintf( "%.2f", $endTotal ); } $endTotal += $basketTotal; $endTotal += $taxamount; $endTotal += $shiprates[1]; if( $kBasketCalcDecimal eq "true" ) { $endTotal = sprintf( "%.2f", $endTotal ); } ### Check if COD has a charge if( $kCheckoutCODCharge ne "" ) { $kLangPayCOD .= " (".$kBasketCurrencySym.$kCheckoutCODCharge.")"; } ### Build a list of the payment types we are going to be using if( $kCheckoutUseCreditCard eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUse2checkout eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUsePayPal eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUseNoChex eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUsePayByCheck eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUsePhone eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUseCheck eq 'true' ) { $payTypeHTML .= "\n"; } if( $kCheckoutUseCOD eq 'true' ) { $payTypeHTML .= "\n"; } ### Not using tax calcs if( ($kCheckoutCalcTaxes eq 'true') && ($taxamount > 0 )) { $taxRowSpan = "4"; $taxInsertHTML = ""; } else { $taxRowSpan = "3"; } print <<_CHECKOUTBOTTOMHTML_ $taxInsertHTML
$kLangColumnDesc $kLangColumnPrice $kLangColumnQty $kLangColumnSub
'."\n"; if( $cartItem[10] ne "" ) { $thumbHTML .= ""; } $thumbHTML .= "\"Image\""; if( $cartItem[10] ne "" ) { $thumbHTML .= "\n"; } $thumbHTML .= '
$cartItem[1] $cartItem[0] $cartItem[4] $cartItem[5] $customFieldHTML $kBasketCurrencySym$itemPrice $cartItem[2] $kBasketCurrencySym$subtotal
  $discountTitle$discountBlurb -$kBasketCurrencySym$cartDiscountValue
 
If you have a coupon code enter it here:    
  $coupon[0]$couponBlurb -$kBasketCurrencySym$couponSavings
$kLangFieldTax:$kBasketCurrencySym$taxamount
 
$kLangPayTypesHeader
$kLangFieldSubtotal: $kBasketCurrencySym$basketTotal
$kLangFieldShipping: $kBasketCurrencySym$shiprates[1]
$kLangFieldTotal: $kBasketCurrencySym$endTotal
 
Powered by Better Basket Pro
_CHECKOUTBOTTOMHTML_ ; &Output_Checkout_Footer_HTML(); } ######################################################################### # Determine and load correct handler for step 3 # ----------------------------------------------------------------------- sub Checkout_Step_3_Handler() { if( ($q->param('popamount') eq "") || ($q->param('popamount') <= 0) ) { print $q->redirect( $kBasketBasketPath ); exit; } $cart = &Fetch_Cookie(); @cart = split( /\^\^/, $cart ); $cCount = @cart; if( ($cart eq "\^\^") || ($cart eq "") || ($cCount <= 0) ) { print $q->redirect( $kBasketBasketPath ); exit; } ### Read in the values pass from the prior step $taxrates = $q->param('poptax'); $shiprates = $q->param('popship'); $webdiscount = $q->param('popdiscount'); $couponcode = $q->param('popcoupon'); $orderAmount = $q->param('popamount'); $paymentType = $q->param('paymenttype'); $orderNum = $q->param('ordernumber'); ### Empty the cookie when required if( ($paymentType eq "creditcard" ) && ($kCheckoutProcessor eq "authorizenet") ) { if( $kBasketUseCookies eq "true" ) { &Write_Cookie(''); } else { print $q->header(); } } elsif( ($paymentType eq "creditcard" ) && ($kCheckoutProcessor eq "itransact") ) { &Write_Cookie(''); } elsif( ($paymentType eq "cod") ) { &Write_Cookie(''); } elsif( ($paymentType eq "paypal") || ($paymentType eq "nochex") || ($paymentType eq "paybycheck") || ($paymentType eq "2checkout") ) { if( $kCheckoutAuxWipeCookie eq 'true' ) { &Write_Cookie(''); } else { print $q->header(); } } else { print $q->header(); } ### Act according to what payment type is being used if( $paymentType eq 'creditcard' ) { my $fname = "checkout/".$kCheckoutProcessor.".pl"; require( $fname ); Build_Checkout_Step_3(); } elsif( $paymentType eq 'paypal' ) { my $fname = "checkout/paypal.pl"; require( $fname ); Build_Checkout_Step_3(); } elsif( $paymentType eq 'nochex' ) { my $fname = "checkout/nochex.pl"; require( $fname ); Build_Checkout_Step_3(); } elsif( $paymentType eq 'paybycheck' ) { my $fname = "checkout/paybycheck.pl"; require( $fname ); Build_Checkout_Step_3(); } elsif( ($paymentType eq 'phone') || ($paymentType eq 'check') || ($paymentType eq 'cod') ) { my $fname = "checkout/invoice.pl"; require( $fname ); Build_Checkout_Step_3(); } elsif( $paymentType eq '2checkout' ) { my $fname = "checkout/2checkout.pl"; require( $fname ); Build_Checkout_Step_3(); } } ######################################################################### # Determine and load correct handler for step 4 # ----------------------------------------------------------------------- sub Checkout_Step_4_Handler() { $cart = &Fetch_Cookie(); @cart = split( /\^\^/, $cart ); $cCount = @cart; if( $q->param("prod[]") eq '' ) { if( ($cart eq "\^\^") || ($cart eq "") || ($cCount <= 0) ) { print $q->redirect( $kBasketBasketPath ); exit; } } ### Read in the values pass from the prior step $taxrates = $q->param('poptax'); $shiprates = $q->param('popship'); $webdiscount = $q->param('popdiscount'); $couponcode = $q->param('popcoupon'); $orderAmount = $q->param('popamount'); $paymentType = $q->param('paymenttype'); $orderNum = $q->param('ordernumber'); ### Act according to what payment type is being used if( $paymentType eq 'creditcard' ) { my $fname = "checkout/".$kCheckoutProcessor.".pl"; require( $fname ); &Build_Checkout_Step_4(); } elsif( ($paymentType eq 'phone') || ($paymentType eq 'check') || ($paymentType eq 'cod') ) { my $fname = "checkout/invoice.pl"; require( $fname ); &Build_Checkout_Step_4(); } } #=======================================================================# # # # GENERAL AND UTILITY FUNCTIONS # # # #-----------------------------------------------------------------------# ######################################################################### # Output the HTML that the creates the page header # ----------------------------------------------------------------------- sub Output_Basket_Header_HTML() { my $newText; my $outHTML; my $headerFile = $kBasketHTMLPath."basket-header.html"; open( HEADHTML, $headerFile ); while( read( HEADHTML, $newText, 4 ) ) { $outHTML .= $newText; } close( HEADHTML ); $newText = ""; print $outHTML; $outHTML = ""; print <<_BASKETSTYLESHEET_ _BASKETSTYLESHEET_ ; } ######################################################################### # Output the HTML that the creates the page footer # ----------------------------------------------------------------------- sub Output_Basket_Footer_HTML() { my $newText; my $outHTML; my $footerFile = $kBasketHTMLPath."basket-footer.html"; open( FOOTHTML, $footerFile ); while( read( FOOTHTML, $newText, 4 ) ) { $outHTML .= $newText; } close( FOOTHTML ); $newText = ""; print $outHTML; $outHTML = ""; } ######################################################################### # Output the HTML that the creates the checkout header # ----------------------------------------------------------------------- sub Output_Checkout_Header_HTML() { my $newText; my $outHTML; my $headerFile = $kBasketHTMLPath."checkout-header.html"; open( HEADHTML, $headerFile ); while( read( HEADHTML, $newText, 4 ) ) { $outHTML .= $newText; } close( HEADHTML ); $newText = ""; print $outHTML; $outHTML = ""; print <<_CHECKOUTSTYLESHEET_ _CHECKOUTSTYLESHEET_ ; } ######################################################################### # Output the HTML that the creates the checkout footer # ----------------------------------------------------------------------- sub Output_Checkout_Footer_HTML() { my $newText; my $outHTML; my $footerFile = $kBasketHTMLPath."checkout-footer.html"; open( FOOTHTML, $footerFile ); while( read( FOOTHTML, $newText, 4 ) ) { $outHTML .= $newText; } close( FOOTHTML ); $newText = ""; print $outHTML; $outHTML = ""; } ######################################################################### # Output the HTML that the creates the invoice header # ----------------------------------------------------------------------- sub Output_Invoice_Header_HTML() { my $newText = ''; my $outHTML = ''; open( INVHEADHTML, "html/invoice-header.html" ); while( $outHTML = ) { print $outHTML; } #while( read( HEADHTML, $newText, 4 ) ) { # $outHTML .= $newText; #} close( INVHEADHTML ); #$newText = ""; #print $outHTML; #$outHTML = ""; print <<_CHECKOUTSTYLESHEET_ _CHECKOUTSTYLESHEET_ ; } ######################################################################### # Output the HTML that the creates the invoice footer # ----------------------------------------------------------------------- sub Output_Invoice_Footer_HTML() { my $newText; my $outHTML; my $footerFile = $kBasketHTMLPath."invoice-footer.html"; open( FOOTHTML, $footerFile ); while( read( FOOTHTML, $newText, 4 ) ) { $outHTML .= $newText; } close( FOOTHTML ); $newText = ""; print $outHTML; $outHTML = ""; } ######################################################################### # Fetch the cookie from the browser # ----------------------------------------------------------------------- sub Fetch_Cookie() { if( $kBasketUseCookies eq "true" ) { $tcookie = $q->cookie( -name => $kBasketCookieName ); } else { my $tFName = "usercarts/".$ENV{'REMOTE_ADDR'}.".txt"; open( CCOOK, $tFName ); $tCCook = ; close( CCOOK ); if( $tCCook ne '' ) { ( $tTime,$tcookie ) = split( /\%\%/, $tCCook ); } } return $tcookie; } ######################################################################### # Update the cookie in the browser # ----------------------------------------------------------------------- sub Write_Cookie() { ( $tCookNew ) = @_; if( $kBasketUseCookies eq "true" ) { $tcookie = $q->cookie( -name => $kBasketCookieName, -value => $tCookNew, -path => "/" ); print $q->header( -type => "text/html", -cookie => $tcookie ); } else { my $tFName = "usercarts/".$ENV{'REMOTE_ADDR'}.".txt"; open(LOCALFILE, ">$tFName"); my $tTime = localtime; print( LOCALFILE $tTime."%%" ); print( LOCALFILE $tCookNew ); close( LOCALFILE ); print $q->header(); } } ######################################################################### # Load the settings for this program # ----------------------------------------------------------------------- sub Load_Common_Settings() { require( './settings/general.pl' ); require( './settings/checkout.pl' ); require( './settings/language.pl' ); ### Load the custom fields for this program my $inText = ''; my $contents = ''; open( CUSTFIELDS, './data/customfields.txt' ); while( read( CUSTFIELDS, $inText, 4 ) ) { $kBasketCustomFields .= $inText; } close( CUSTFIELDS ); $kBasketCustomFields =~ s/\r/\n/g; $kBasketCustomFields =~ s/\n\n/\n/g; $kBasketCustomFields =~ s/\n/\|/g; ### Load the web discounts for this program if needed @kBasketStoreDiscounts = &Load_Data_File( 'discounts.txt' ); $kCouponCount = @kCheckoutCoupons; } ######################################################################### # Load an external data file parsed by line feeds # ----------------------------------------------------------------------- sub Load_Data_File() { my ($filename) = @_; my $inText = ''; my $contents = ''; $filename = './data/'.$filename; open( FNAME, $filename ); while( read( FNAME, $inText, 4 ) ) { $contents .= $inText; } $contents =~ s/\r/\n/g; $contents =~ s/\n\n/\n/g; return split( /\n/, $contents ); } ######################################################################### # This function returns the true product price, taking into account any # volume discount options. It also adjusts based on color, size and # custom field modifiers accordingly. # ======================================================================= sub GetProductTruePrice( ) { my ($product) = @_; my @prod = split( /\|/, $product ); my $fieldCount = @prod; my $itemPrice = 0; ### Determine what the price is based on volume discounting my @prices = split( /\,/, $prod[3] ); my $priceCount = @prices; for( $i=0; $i<$priceCount; $i++ ) { if( $i == ($priceCount-1) ) { my @price1 = split( /\:/, $prices[$i] ); $itemPrice = $price1[0]; } else { my @price1 = split( /\:/, $prices[$i] ); my @price2 = split( /\:/, $prices[$i+1] ); if( ($prod[2] >= $price1[1]) && ( $prod[2] < $price2[1] ) ) { $itemPrice = $price1[0]; $i = $priceCount; } } } ### Next look to see whether color/size fields change price my @colorFields = split( /\:/, $prod[4] ); my @sizeFields = split( /\:/, $prod[5] ); my $colorCount = @colorFields; my $sizeCount = @sizeFields; if( $colorCount > 1 ) { $itemPrice += $colorFields[1]; } if( $sizeCount > 1 ) { $itemPrice += $sizeFields[1]; } ### Next look to see whether or not custom fields change price if( $fieldCount > 11 ) { for( $i=11; $i<$fieldCount; $i++ ) { my @customField = split( /\:/, $prod[$i] ); if( $customField[2] ne '' ) { $itemPrice += $customField[2]; } } } ### Return the price to the calling routine if( $itemPrice < 0 ) { $itemPrice = 0; } return $itemPrice; }