Jump to content

discount math on an array


turpentyne

Recommended Posts

Having to go into somebody else's code yet again! Gah! Originally the totaling page just subtracted a flat discount. But now the client wants to be able to subtract percentage discounts and 'per item' discounts. In the discount table I added a field to determine whether the discount chosen is to be applied as flat off total, flat per item, % off total, and % off each item. I also entered a field that can have a class id, in case this discount is only for that class. (the intention being that otherwise the discount is on anything)

 

I've got a session variable that generates something like : Array ( [217] => 1 [215] => 2 )

meaning 1 person in class #217, and 2 people in class 215.

 

$_SESSION['s_to_be_added'] = array_filter($_POST['participantqty']);

 

Then on the page I'm concerned with, I've been trying to write the script. I know I still need some math stuff figured out

But how do I take the array, do the math, and then generate an overall cost for the whole thing? and this is just  the discounting? I don't even have a clue how to work in delimiting it if there's a class id.. did any of that make sense?

 

<?php

// the above is the array I want to use to 
$passed_array = array_filter($_SESSION['s_to_be_added']);

// this is the discount 'code' the user entered.
$discount = mysql_escape_string($_POST['discount']);

// just a donation added after everything.
$donation = mysql_escape_string($_POST['donation']);

// finding the discount that matches the discount 'code' entered.
$query_selectAllItems_events = "SELECT discount_amount,discount_type,workshop_link_1 FROM tbl_discount where discount_value = '$discount'";

    $result_all_events = mysql_query($query_selectAllItems_events);
$numRows_all_events = mysql_num_rows($result_all_events);
$num=mysql_num_rows($result_all_events); 
$z_row = mysql_fetch_array($result_all_events);
        
        // this is just a number: 1, 20, 90 etc.
        $discount_amount = $z_row['discount_amount'];
        
        /*this is 1,2,3,4 - for each type of discount 1- flat 2- flat per item
        3- discount on all, 4- discount per item */
        $discount_type = $z_row['discount_type'];
        
        // the workshop id if the discount is onlyh for this workshop
        $discount_link_1 = $z_row['workshop_link_1'];
        
        // just a description
$discount_name = $z_row['discount_name'];

        
if ($discount_type ==1) {
            /* flat discount on total here */
            $total = mysql_escape_string($_POST['total']);

$final_total = ($total - $discount_amount);
$final_total = ($final_total + $donation);
        }
        
        elseif ($discount_type ==2)) {
            /*  discount per item total here */
$total = mysql_escape_string($_POST['total']);

$final_total = ($total - $discount_amount);
$final_total = ($final_total + $donation);
        
        }
        
        elseif ($discount_type ==3)) {
            /* percentage discount on total here */
$total = mysql_escape_string($_POST['total']);

$final_total = ($total * ($discount_amount/100));
$final_total = ($final_total + $donation);
        
        }
        
        elseif ($discount_type ==4)) {
            /* percentage discount per item here */
$total = mysql_escape_string($_POST['total']);

$final_total = ($total * ($discount_amount/100));
$final_total = ($final_total + $donation);
        
        }
        
        ?>

 

Link to comment
Share on other sites

I'm not too sure what you're asking?

Do you wanna be able to provide a different discount on each item, and then total the discounted values?

If you have an array of items, all with 30% off, you can just total the original price and take 30% off the total. You get the same result.

 

If you have an array of items and want to take different percentages off each one, then use a foreach loop?

foreach ($items as &$item){
    $item = $item['value'] * ((100-$item['discount'])/100)
}

Where $items is an array of items such as:

array ("tennis_ball" => array("value" => 10, "discount"=>5), "baseball_bat" => array("value" => 50, "discount"=>25))

Link to comment
Share on other sites

Hmmm.. I've worked a little more on this (very lengthy) script, trying to understand how i would do it - and how to explain it. I commented all through, hoping it helps make more sense of things?

 

The scenario is: Somebody picks a couple classes, putting one student in Workshop 217 at $200, and two students in Workshop 215 at $150 each.

 

On the next page they enter discount code "Irish". On the third page, the discount by that title is pulled from the database and it is subtracted from the registration, based on what discount_type it is. The possible scenarios are 1- off the total cost ($500), 2-off each class, 3- % off total, 4- % off each item. AND within each of these scenarios, the customer wants to have some of the discounts be workshop-specific.

 

Meaning, if they enter discount code "Scottish", the discount is 10% off on only workshop 217. Very confusing to me... There must be an easier way to do this... if what I've got below is even close to how to do it?

 

<?php

// the above is the array I want to use to 
//$passed_array = array_filter($_SESSION['s_to_be_added']);
$passed_array = Array ( [217] => 1 [215] => 2 );
// 217, 215 - workshop id - is also the value in workshop_link_1
// 1, 2 are number of students in each workshop.
// this is the discount 'code' the user entered.
$discount = mysql_escape_string($_POST['discount']);

// just a donation added after discount math is done.
$donation = mysql_escape_string($_POST['donation']);

// finding the discount that matches the discount 'code' the customer entered.
$query_selectAllItems_events = "SELECT discount_amount,discount_type,workshop_link_1 FROM tbl_discount where discount_value = '$discount'";

    $result_all_events = mysql_query($query_selectAllItems_events);
$numRows_all_events = mysql_num_rows($result_all_events);
$num=mysql_num_rows($result_all_events); 
$z_row = mysql_fetch_array($result_all_events);
        
        // this is just an integer 1-100 if discount, 1-whatever for actual dollar amount.
        $discount_amount = $z_row['discount_amount'];
        
        /*this is: 1,2,3,4 - for each type of discount 1- flat 2- flat per item
        3- discount on all, 4- discount per item */
        $discount_type = $z_row['discount_type'];
        
        // the workshop id - in database if the discount is intended only to be subtracted from that workshop. otherwise '0'
        $discount_link_1 = $z_row['workshop_link_1'];
        
        // just a description
$discount_name = $z_row['discount_name'];

        /* ///////////////////////////////////////////////////////////////////////// */ 
        
if (($discount_type ==1) && ($discount_link_1 ==0)) {
            /* flat discount on total here - regardless of workshop # */
            $total = mysql_escape_string($_POST['total']);

$final_total = ($total - $discount_amount);
$final_total = ($final_total + $donation);
        
        } elseif (($discount_type ==1) && ($discount_link_1 !== 0)) {
            /* flat discount on total here - SPECIFIC WORKSHOP # */
            foreach ($passed_array[] as $key => $value){
                if ($key == $discount_link_1){$final_total += $key - $discount_amount;}
                else {$final_total += $key;}
                
            }
            $total = mysql_escape_string($_POST['total']);

$final_total = ($total - $discount_amount);
$final_total = ($final_total + $donation);
        }
        
      /* ///////////////////////////////////////////////////////////////////////// */  
        
        elseif (($discount_type ==2) && ($discount_link_1 ==0)) {
            /*  discount per item total here - regardless of workshop # */
$total = mysql_escape_string($_POST['total']);
            foreach ($passed_array[] as $key => $value){
            // I want to take off discount on each item, and add sums to get final total using +=
            $final_total += $key - $discount_amount;   
            $final_total = ($final_total + $donation);
            }
        } elseif (($discount_type ==2) && ($discount_link_1 !==0)) {
            /*  discount per item total here - SPECIFIC WORKSHOP # */
$total = mysql_escape_string($_POST['total']);
            foreach ($passed_array[] as $key => $value){
            // I want to take off discount on each item, and add sums to get final total using +=
            $final_total += $key - $discount_amount;   
            $final_total = ($final_total + $donation);
            }
        }
        
        /* ///////////////////////////////////////////////////////////////////////// */
        
        elseif (($discount_type ==3) && ($discount_link_1 ==0)) {
            /* percentage discount on total here - regardless of workshop # */
$total = mysql_escape_string($_POST['total']);
$final_total = $total * ((100-discount_amount)/100);
//$final_total = ($total * ($discount_amount/100));
$final_total = ($final_total + $donation);
        
        }elseif (($discount_type ==3) && ($discount_link_1 !== 0)) {
            /* percentage discount on total here - SPECIFIC WORKSHOP #  */
$total = mysql_escape_string($_POST['total']);
$final_total = $total * ((100-discount_amount)/100);
//$final_total = ($total * ($discount_amount/100));
$final_total = ($final_total + $donation);
        
        }
        
      /* ///////////////////////////////////////////////////////////////////////// */
      
        elseif (($discount_type ==4) && ($discount_link_1 ==0)) {
            /* percentage discount per item here - regardless of workshop # */
 /*  discount per item total here */
$total = mysql_escape_string($_POST['total']);
            foreach ($passed_array[] as $key => $value){
            // I want to take off discount on each item, and add sums to get final total using +=
            $final_total = $total * ((100-discount_amount)/100);  
            $final_total = ($final_total + $donation);
        }
        
         elseif (($discount_type ==4) && ($discount_link_1 !==0)) {
            /* percentage discount per item here - SPECIFIC WORKSHOP # */
 /*  discount per item total here */
$total = mysql_escape_string($_POST['total']);
            foreach ($passed_array[] as $key => $value){
            // I want to take off discount on each item, and add sums to get final total using +=
            $final_total = $total * ((100-discount_amount)/100);  
            $final_total = ($final_total + $donation);
        }
        
        
        echo $final_total;
        ?>

Link to comment
Share on other sites

This is how I would do what I think you're trying to achieve:

 

Database

3 tables:

  • classes
  • discounts
  • active_discounts

 

classes would be contain all the possible classes a person can choose.

ID - Auto Incremented ID

Name - The name of the class.

Cost - The original cost.

 

discounts would contain all of the possible discounts that can be applied to a class.

ID - Auto Incremented ID

Name - Display name of discount

Code - The discount code

Value - The value of the discount.

Type - The type of discount (Percentage, Discount of each item, Discount off total)

I'm going to assume here, that only one discount can be used at one time. (So someone can't get a discount off one class, and then another discount off the total)

 

active_discounts would link the discounts to class table.

ID - Auto Incremented ID.

class_id - The ID of the class to apply the discount to.

discount_id - The ID of the discount to apply.

 

Now when someone submits the form, the PHP would be like this:

 

<?php

    $discount_code = "irish"; //The discount code, if entered.
    $selected_classes = array(56 => 1, 52 => 2); //How many of each class was selected. class_id => quantity
    // We'll build an array with information about each class, and what discount it can get.
    $classes = array();
    foreach ($selected_classes as $class => $quantity)
    {
        $result = mysql_query("SELECT * FROM `active_discounts` WHERE `code` = '{$discount_code} AND `class_id` = '{$class}'");
        if (mysql_num_rows($result) > 0)
        {
            $discount_row = mysql_fetch_assoc($result);
            $discount_type = $discount_row['type'];
            $discount_value = $discount_row['value'];
            $discount_name = $discount_row['name'];

            $result = mysql_query("SELECT * FROM `classes` WHERE `id` = '{$class}'");
            $class_row = mysql_fetch_assoc($result);
            $class_name = $class_row['name'];
            $class_cost = $class_row['cost'];

            $classes[$class]['name'] = $class_name;
            $classes[$class]['cost'] = $class_cost;
            $classes[$class]['discount_name'] = $discount_name;
            $classes[$class]['discount_type'] = $discount_type;
            $classes[$class]['discount_value'] = $discount_value;
            $classes[$class]['quantity'] = $quanity;
        }
        else
            break;
    }
    // We'll set some constants, to make the code more readible.
    define("OFF_TOTAL", 1);
    define("OFF_INDIVIDUAL", 2);
    define("PERC_TOTAL", 3);
    define("PERC_INDIVIDUAL", 4);
    // Now we loop through each class and take off any valid discounts
    $grand_total = 0;
    foreach ($classes as &$class)
    {
        if ($class['discount_type'] == OFF_INDIVIDUAL)
        {
            $total = $class['cost'] * $class['quantity'];
            $discount = $class['quanity'] * $class['discount_value'];
            $total = $total - $discount;
            $gand_total += $total;
        }
        if ($class['discount_type'] == PERC_INDIVIDUAL)
        {
            $total = $class['cost'] * $class['quantity'];
            $discount = ($class['value'] / 100) * $class['cost'];
            $total = $total - $discount;
            $gand_total += $total;
        }
        if ($class['discount_type'] == OFF_TOTAL)
        {
            $gand_total += $class['cost'] * $class['quantity'];
            $discount_type = OFF_TOTAL;
            $discount_value = $class['discount_value'];
        }
        if ($class['discount_type'] == PERC_TOTAL)
        {
            $gand_total += $class['cost'] * $class['quantity'];
            $discount_type = PERC_TOTAL;
            $discount = ($class['value'] / 100) * $class['cost'];
        }
    }

    if($discount_type == PERC_TOTAL){
        $discount = ($discount_value / 100) * $grand_total;
        $grand_total = $grand_total - $discount;
        
    }
    if($discount_type == OFF_TOTAL){
        $grand_total = $grand_total - $discount_value;
        
    }

Link to comment
Share on other sites

Wow... That's pretty much what I needed! Some quick questions on it though.

 

I see around line 10 the query to active_discounts. I'm assuming that what I need to do is after confirming mysql_num_rows($result) > 0

 

Something like this? Or maybe an inner join?

 

$result = mysql_query("SELECT * FROM `active_discounts` WHERE `code` = '{$discount_code} AND `class_id` = '{$class}'");
        if (mysql_num_rows($result) > 0)
        { 
              $result2 = mysql_query("SELECT * FROM `discounts` WHERE `code` = '{$discount_id} ");
            $discount_row = mysql_fetch_assoc($result);
            $discount_type = $discount_row['type'];
           //etc..?

 

(maybe I answered my own question: SELECT * FROM `active_discounts` JOIN tbl_discount ON active_discounts.disc_id = tbl_discount.discount_id WHERE `code` = etcetera.

 

 

Also, I saw the variable $quanity as opposed to quantity. I just wanted to make sure that was a typo. I didn't want to change that to "quantity" and not be able to figure out what the error was.

Link to comment
Share on other sites

I've got the script up and running, but it's echoing nothing out for me. Went into the script to put echoes into certain places to see if I'm getting that far and it's almost as if lines 17 to 34 aren't working. I switched around the query to echo it. I tried echoing the row data, and nothing printed out. I checked the first query, and did it in Mysql. It's pulling what it should:

 

SELECT * FROM `active_discounts` JOIN tbl_discount ON active_discounts.disc_id = tbl_discount.discount_id WHERE `code` = 'test' AND `class_id` = '215'

 

pulls one record with all the data on the discount, just as it should. It seems to be the workshop query that's lost somewhere.

 

<?php
include("dbconnection.php"); 
    $discount_code = "test"; //The discount code, if entered.
    $selected_classes = array(217 => 1, 215 => 2); //How many of each class was selected. class_id => quantity
    
    // We'll build an array with information about each class, and what discount it can get.
    $classes = array();
    foreach ($selected_classes as $class => $quantity)
    { $testquery = "SELECT * FROM `active_discounts` JOIN tbl_discount ON active_discounts.disc_id = tbl_discount.discount_id WHERE `code` = '{$discount_code}' AND `class_id` = '{$class}'";
    echo $testquery;
        $result = mysql_query($testquery);
        if (!$result)
        {
    die('Invalid query: ' . mysql_error());
        if (mysql_num_rows($result) > 0)
            {
            
            $discount_row = mysql_fetch_assoc($result);
            $discount_type = $discount_row['discount_type'];
            $discount_value = $discount_row['discount_amount'];
            $discount_name = $discount_row['discount_name'];

            $result = mysql_query("SELECT * FROM `tbl_workshops` WHERE `workshop_id` = '{$class}'");
// I switched the above query around to echo it before running the query. nothing printed. - it's changed back now
            $class_row = mysql_fetch_assoc($result);
            $class_name = $class_row['workshop_title'];
            $class_cost = $class_row['workshop_price'];
// I also tried echoing class_cost right here, nothing printed. not even plain text 
            $classes[$class]['workshop_title'] = $class_name;
            $classes[$class]['workshop_price'] = $class_cost;
            $classes[$class]['discount_name'] = $discount_name;
            $classes[$class]['discount_type'] = $discount_type;
            $classes[$class]['discount_value'] = $discount_value;
            $classes[$class]['quantity'] = $quanity;
            }
        else
            break;
        }
// I tried echoing the above data here as well, and still got nothing???
    // We'll set some constants, to make the code more readible.
    define("OFF_TOTAL", 1);
    define("OFF_INDIVIDUAL", 2);
    define("PERC_TOTAL", 3);
    define("PERC_INDIVIDUAL", 4);
    // Now we loop through each class and take off any valid discounts
    $grand_total = 0;
    foreach ($classes as &$class)
        {
        if ($class['discount_type'] == OFF_INDIVIDUAL)
            {
            $total = $class['cost'] * $class['quantity'];
            $discount = $class['quanity'] * $class['discount_value'];
            $total = $total - $discount;
            $gand_total += $total;
            }
        if ($class['discount_type'] == PERC_INDIVIDUAL)
            {
            $total = $class['cost'] * $class['quantity'];
            $discount = ($class['value'] / 100) * $class['cost'];
            $total = $total - $discount;
            $gand_total += $total;
            }
        if ($class['discount_type'] == OFF_TOTAL)
            {
            $gand_total += $class['cost'] * $class['quantity'];
            $discount_type = OFF_TOTAL;
            $discount_value = $class['discount_value'];
            }
        if ($class['discount_type'] == PERC_TOTAL)
            {
            $gand_total += $class['cost'] * $class['quantity'];
            $discount_type = PERC_TOTAL;
            $discount = ($class['value'] / 100) * $class['cost'];
            }
        }

    if($discount_type == PERC_TOTAL)
        {
        $discount = ($discount_value / 100) * $grand_total;
        $grand_total = $grand_total - $discount;
        
        }
    if($discount_type == OFF_TOTAL)
        {
        $grand_total = $grand_total - $discount_value;
        
        }
    
    }

echo "it worked? ".$grand_total;
// this printed 'it worked? 0' when it should've read 791


?>

 

 

Link to comment
Share on other sites

ok. scratch the previous post. I've figured a few things out on it, but I've run into one last roadblock. In my test, class 217 is $10 and has a discount of $9. Class 215 is $300 and has no discount. So in theory, my grand total should be grand_total = (300 x 2) plus (10-9)

 

But when I thought I was being slick and joining the workshop table so I could get it's price, I excluded the class with no discount. How should I rewrite this query to include that class?

 

 

Link to comment
Share on other sites

I don't know anything about linking tables.

But in my original code, just edit the foreach loop where it breaks on not finding any rows. These are the classes that have no discount, so just add the un discounted prices to the total there.

// NOTE We have to define grand_total here because we're using it earlier. So remove  the  old $grand_total = 0.
$grand_total = 0
foreach ($selected_classes as $class => $quantity)
    {
        $result = mysql_query("SELECT * FROM `active_discounts` WHERE `code` = '{$discount_code} AND `class_id` = '{$class}'");
        if (mysql_num_rows($result) > 0)
        {
            $discount_row = mysql_fetch_assoc($result);
            $discount_type = $discount_row['type'];
            $discount_value = $discount_row['value'];
            $discount_name = $discount_row['name'];

            $result = mysql_query("SELECT * FROM `classes` WHERE `id` = '{$class}'");
            $class_row = mysql_fetch_assoc($result);
            $class_name = $class_row['name'];
            $class_cost = $class_row['cost'];

            $classes[$class]['name'] = $class_name;
            $classes[$class]['cost'] = $class_cost;
            $classes[$class]['discount_name'] = $discount_name;
            $classes[$class]['discount_type'] = $discount_type;
            $classes[$class]['discount_value'] = $discount_value;
            $classes[$class]['quantity'] = $quanity;
        }
        else{
            $result = mysql_query('SELECT * FROM `classes` WHERE `id` = '$class');
            if (mysql_num_rows($result) > 0){
                $row = mysql_fetch_assoc($result);
                $grand_total += $row['cost'] * $quantity;
            }
            else {
                // The class doesn't exist
            }
        }
    }

 

Or something like that..

Link to comment
Share on other sites

Ah! ok.. I'd started working in that direction, but was doing more than I needed. That problem is fixed.

 

A follow-up question. My clients are driving me nuts. Now this is done, and they request ANOTHER discount scenario.

 

A "bring-a-friend" discount. They register  for class 123, signing up 2 people. The discount is to be applied to only one of those people.

 

Something like this?

 


if ($class['discount_type'] == BRING_A_FRIEND)
        {  if ($class['quantity'] == 2) {
                    $total = $class['cost'] + ($class['cost'] - $discount_amount)
                     $gand_total += $total;
                    }
        }

 

But what if they register more than 2 people??? gah!!

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.