Advanced Configuration for Zen Cart Discounting Modules

THESE ARE ADVANCED INSTRUCTIONS. Do not attempt this sort of change unless you are a skilled programmer. I am available for hire to do customizations like this if you require help.

This page describes approaches to complex configurations for the following Zen Cart mods: The fact that many of my modules can be configured in code in their setup functions() means that you can write logic using built in Zen Cart functions to do specific things. I will provide a few examples:

Example 1: Using Better Together, with exceptions to a category wide discount

Suppose you have (master) category 10, and you want to give a 2-for-1 discount on every product in that category. The Better Together configuration is:

    function setup() { 
       $this->add_twoforone_cat(10);
    }


Now suppose you want to do the same thing, except for products 4 and 5.

    function setup() { 
         global $db; 
         $sql = "select products_id from " . TABLE_PRODUCTS . " where master_categories_id='10'";
         $prodlist = $db->Execute($sql);
         while (!$prodlist->EOF) { 
            $prod = (int)$prodlist->fields['products_id']; 
            if ($prod != 4 && $prod != 5) {
               $this->add_twoforone_prod($prod);
            }
            $prodlist->MoveNext();
         }
    }


Note the change from add_twoforone_cat with a category, to add_twoforone_prod with a specific product.

Example 2: Using Combination Discounts to create a category-wide 3-for-2

Suppose you have (master) category 10, and you want to give a 3-for-2 discount on every product in that category. Better Together has add_twoforone_prod, but there is no such configuration for Combination Discounts, it must be hand coded. configuration is:

    function setup() { 
         global $db; 
         $sql = "select products_id from " . TABLE_PRODUCTS . " where master_categories_id='10'";
         $prodlist = $db->Execute($sql);
         while (!$prodlist->EOF) { 
            $prod = (int)$prodlist->fields['products_id']; 
            $this->add_linkage(PROD,$prod, 2, PROD, $prod, 1, "%", 100); 
            $prodlist->MoveNext();
         }
    }


Example 3: Using Table Discounts to do per item discounting across a category

Suppose you have a master category 8, and you want to offer quantity discounting of this category, with 10% off on more than 10 items or 20% off on more than 20. The Table Discounts syntax is

    function setup() { 
       $this->add_table("Buy 10 items in category 8, get 10% off; buy 20, and get 20% off"); 
          $this->set_constraint(CAT, 8);
          $this->set_discount("%", 10, 10, 20, 20);
    }


Now suppose you want to do the same thing, but on a per item basis: buy 10 of any single item in category 8, get 10% off; buy 20, get 20% off.

    function setup() { 
         global $db; 
         $sql = "select products_id from " . TABLE_PRODUCTS . " where master_categories_id='8'";
         $prodlist = $db->Execute($sql);
         while (!$prodlist->EOF) { 
            $prod = (int)$prodlist->fields['products_id']; 
            $this->add_table("Buy 10, get 10% off, buy 20, get 20% off on " . zen_get_products_name($prod));
                  $this->set_constraint(PROD, $prod);
                  $this->set_discount("%", 10, 10, 20, 20);
            $prodlist->MoveNext();
         }
   }


Again, note the change from setting the constraint on a CAT basis to a PROD basis.

Example 4: Using Big Chooser to give buy-one-get-one for a group of products across multiple categories

Suppose products 2, 3, 5, 7, 11, 13, 17, 19 exist, are all Green Teas, but are not in a single category. If you want to offer a buy one, get one half off sale, then rather than coding 8 different discounts, you can use a foreach loop and do it in code:
    function setup() { 
        $list = array(22, 3, 5, 7, 11, 13, 17, 19);
        foreach ($list as $i) {
           $this->add_condition("Buy any Green Tea and get a second of same Tea for Half off", true);
           $this->set_constraint(PROD, $i, 1);
           $this->set_discount(PROD, $i, 1, "%", 50);
        }
    }


Example 5: Dealing with fractional quantities in Better Together, Combination Discounts and Big Chooser

Some shops, such as those selling cloth or weighed goods, find it advantageous to set Admin->Configuration->Stock->Product Quantity Decimals to 2 instead of 0, and set the per product minimums to a fractional value. But my discount modules assume any quantity in the cart is at least 1 (i.e. it suffices to meet the condition in a linkage). To overcome this, simply round the quantity of each item in the cart to an integer value, and skip over the items which round to 0.

Here's the change for Better Together. In the function calculate_deductions(), change

       // Build discount list 
       for ($i=0, $n=sizeof($products); $i<$n; $i++) {
            $discountable_products[$i] = $products[$i]; 
       }

to
       // Build discount list 
       for ($i=0, $n=sizeof($products); $i<$n; $i++) {
            $products[$i]['quantity'] = (int)$products[$i]['quantity'];
            if ($products[$i]['quantity'] == 0) continue; 
            $discountable_products[] = $products[$i]; 
       }


Here's the change for Combination Discounts. In the function calculate_deductions(), change

       $products = array();
       for ($i = 0; $i < sizeof($all_products); $i++) { 
           for ($j = 0; $j < $all_products[$i]['quantity']; $j++) {
               $newprod = array(); 
               $newprod['price'] = $all_products[$i]['price']; 
               $newprod['final_price'] = $all_products[$i]['final_price']; 
               $newprod['id'] = $all_products[$i]['id']; 
               $newprod['category'] = $all_products[$i]['category']; 
               $newprod['quantity'] = 1; 
               $products[] = $newprod; 
           }
       }

to
       $products = array();
       for ($i = 0; $i < sizeof($all_products); $i++) { 
           $all_products[$i]['quantity'] = (int)$all_products[$i]['quantity'];

           if ($all_products[$i]['quantity'] == 0) continue; 
           for ($j = 0; $j < $all_products[$i]['quantity']; $j++) {
               $newprod = array(); 
               $newprod['price'] = $all_products[$i]['price']; 
               $newprod['final_price'] = $all_products[$i]['final_price']; 
               $newprod['id'] = $all_products[$i]['id']; 
               $newprod['category'] = $all_products[$i]['category']; 
               $newprod['quantity'] = 1; 
               $products[] = $newprod; 
           }
       }


Here's the change for Big Chooser. In the function calculate_deductions(), change

       for ($i = 0; $i < sizeof($all_products); $i++) { 
          $newprod = array(); 
          $newprod['price'] = $all_products[$i]['price']; 
          $newprod['final_price'] = $all_products[$i]['final_price']; 
          $newprod['id'] = $all_products[$i]['id']; 
          $newprod['category'] = $all_products[$i]['category']; 
          $newprod['quantity'] = $all_products[$i]['quantity'];
          $newprod['attributes'] = $all_products[$i]['attributes'];
          $newprod['manuf'] = zen_get_products_manufacturers_id($all_products[$i]['id']);
          $products[] = $newprod; 
       }

to
       for ($i = 0; $i < sizeof($all_products); $i++) { 
          $newprod = array(); 
          $newprod['price'] = $all_products[$i]['price']; 
          $newprod['final_price'] = $all_products[$i]['final_price']; 
          $newprod['id'] = $all_products[$i]['id']; 
          $newprod['category'] = $all_products[$i]['category']; 
          $all_products[$i]['quantity'] = (int) $all_products[$i]['quantity'];
          if ($all_products[$i]['quantity'] == 0) continue; 
          $newprod['quantity'] = $all_products[$i]['quantity'];
          $newprod['attributes'] = $all_products[$i]['attributes'];
          $newprod['manuf'] = zen_get_products_manufacturers_id($all_products[$i]['id']);
          $products[] = $newprod; 
       }




Certificates of appreciation most welcome!
If the information you learned reading this site is helping your store make more money, please consider making a donation. Thank you!


Want more Zen Cart?     Tips and Tricks     Contributions     Extensions     Custom Software     Newsletter

Terms | Privacy | SiteMap | Newsletter | Contact Me | Contents © 2003-2011 That Software Guy, Inc.
Zen Cart Project Home Page | Zen Cart Forum | Zen Cart™ is © Zen Ventures, LLC.