PDA

View Full Version : Calculate volume discount

stormshoppers
07-27-2010, 02:49 PM
I have been working on modifying a code to suit my needs, but am having no luck, maybe you guys could help me with this, I need this code to do % calculations for multiple products, otherwise I need to post like 100 of this code in one page:

function processOrder()
{
var quantity = parseInt(document.frmOrder.txtQuantity.value);
var unitPrice, totalPrice;

// The unit price depends on the quantity order
// The higher the quantity, the lower the unit price
if( quantity < 5 )
unitPrice = 22.80;
else if( quantity < 10 )
unitPrice = 20.80;
else if( quantity < 15 )
unitPrice = 18.80;
else if( quantity < 20 )
unitPrice = 16.80;
else if( quantity < 25 )
unitPrice = 14.80;
else if( quantity < 30 )
unitPrice = 12.80;
else if( quantity < 35 )
unitPrice = 10.80;
else if( quantity < 40 )
unitPrice = 8.80;
else
unitPrice = 6.80;

totalPrice = quantity * unitPrice;

document.frmOrder.txtUnitPrice.value = unitPrice.toFixed(2);
document.frmOrder.txtTotalOrder.value = totalPrice.toFixed(2);
// Create Advanced Product string for InternetSecure Processor
document.frmOrder.Products.value = “”+ unitPrice +”::”+ quantity +”::VERSION 2010::Discounted lisenses::”;
}

I want it to work in % intervals for bulk orders, for instance 1-4 no discount, 5-9 10%, 10-19 15%, 20-39 20%, 40+ 25%

is there any way you could help me out?

disastro
07-27-2010, 03:24 PM
function calcPrice(quantity,price) {
var totalPrice = 0.00;
var discount = 1.00;
if(quantity>4&&quantity<=9) discount = 0.90;
if(quantity>9&&quantity<=19) discount = 0.85;
if(quantity>19&&quantity<=39) discount = 0.80;
if(quantity>39) discount = 0.75;

totalPrice = price*quantity*discount;
return Math.round(totalPrice*100)/100;
}

Given the quantity and price, this will return the total price of the order rounded to the nearest cent. You should be able to incorporate this into your system.

It's fairly basic stuff. If you want to learn a little more javascript, there are plenty of resources listed in a sticky thread at the top of this forum.

stormshoppers
07-27-2010, 09:22 PM
thats looks awesome like it would work for just a simple calculation, how do I apply it to 86 products at the same time that maintains the product number like in the script I posted has

var quantity = parseInt(document.frmOrder.txtQuantity.value);

the txtquantity is the product number, I need it to maintain that for the merchant link of my merchant account.

I do not understand how to implement it into the form I have, I do not see how it refers to each individual product or it's initial price, what I am looking for is a code that will calculate the discount within the form but maintains each individual product name/number but calculates the discount for bulk orders and can be submitted to my merchant within the form.

for instance:

if product A cost 399.00 each and a customer buys 10 of them then the cost is 15% off

if product B cost 199.00 each and a customer buys 5 of them then the cost is 10% off

if product C cost 249.99 each and a customer buys 20 of them then the cost is 20% off

and so on for like 100's of products within one form.

in that code you posted, how do I differentiate between the different products and their prices?

disastro
07-27-2010, 09:44 PM
Firstly, you should not be sending this data straight to a merchant without checking it. The actual order processing and validation should happen on a machine which you control (your server) rather than the user's machine.

Imagine a user wanted a bigger discount. He could alter the discount values in your javascript to give himself a 99% discount. In my example script above, he could change 0.90 to 0.01 and if you don't double check the values, the user gets his 99% discount.

All these calculations should be happening server side where the user has no influence. If you wanted to simply display discount prices to the user, then you can use javascript. Trusting your clients 100% when it comes to money is a fast way to go broke.

Secondly, you generally won't find people here who will build your business for you. You will get pointers on how to solve problems yourself. You can try the projects forum (or a freelance site) to hire someone to work for you.

Old Pedant
07-27-2010, 09:47 PM
You would call disatro's function once for each product.

You don't show what your <form> looks like, so we can't really say much more than that.

I, personally, would rewrite his function a little to make it easier to read and relate to your stated discounts:

function calcPrice(quantity,price) {
var discount;
if ( quantity < 5 ) discount = 0;
else if ( quantity < 10 ) discount = 10;
else if ( quantity < 20 ) discount = 15;
else if ( quantity < 40 ) discount = 20;
else discount = 25;

totalPrice = price * quantity * ( 1 - discount/100 );
return Math.round(totalPrice*100)/100;
}

Doesn't change the results, just makes the quantity/percentages match what you stated.

Old Pedant
07-27-2010, 09:51 PM
Agree w/ disastro re using these calculations only for "feedback" to the user. Make sure you duplicate the calculations in your server-side code (PHP/ASP/JSP/whatever), ignoring the values the JS gets.

disastro
07-27-2010, 09:56 PM
I, personally, would rewrite his function a little to make it easier to read

Much easier to read. I just have an irrational dislike of if - else if statements. :D
No idea why. They just rub me up the wrong way.

Old Pedant
07-27-2010, 10:05 PM
Well, we could do this, to satisfy you dissatisfication:

function getDiscount( quantity ) {
if ( quantity < 5 ) return 0;
if ( quantity < 10 ) return 10;
if ( quantity < 20 ) return 15;
if ( quantity < 40 ) return 20;
return 25;
}
function calcPrice(quantity,price) {
totalPrice = price * quantity * ( 1 - getDiscount(quantity)/100 );
return Math.round(totalPrice*100)/100;
}

<grin/>

disastro
07-27-2010, 10:18 PM
Looks like old age and cunning do win out.
Well played, Old Pedant :D

Old Pedant
07-27-2010, 11:07 PM
FWIW, Visual Basic has (or used to have, not sure about VB.NET) an interesting and useful syntax for this kind of thing:

SELECT CASE quantity
CASE 0 TO 4: discount = 0
CASE 5 TO 9: discount = 10
CASE 10 TO 19: discount = 15
CASE 20 To 39: discount = 20
CASE ELSE: discount = 25
END SELECT

I wouldn't mind seeing a syntax similar to that incorporated into other languages, including JavaScript.

You *can* do it in JS, but the syntax is ugly:

switch ( quantity ) {
case 0: case 1: case 2: case 3: case 4:
discount = 0; break;
case 5: case 6: case 7: case 8: case 9:
discount = 10; break;
case 10: case 11: case 12: case 13: case 14:
case 15: case 16: case 17: case 18: case 19:
discount = 15; break;
case 20: case 21: case 22: case 23: case 24:
case 25: case 26: case 27: case 28: case 29:
case 30: case 31: case 32: case 33: case 34:
case 35: case 36: case 37: case 38: case 39:
discount = 20; break;
default:
discount = 25;
}

BLECH!

disastro
07-27-2010, 11:17 PM
I wouldn't mind seeing a syntax similar to that incorporated into other languages

I agree. Very few common languages implement ranges well. With the possible exception of perl:

foreach (1 .. 10) {
print "\$_ ";
}

Of course, there's nothing perl can't do :D
It's just a shame you need 5 pages of comments to explain a nifty one-liner.

Old Pedant
07-27-2010, 11:19 PM
Of course, there's nothing perl can't do :D
It's just a shame you need 5 pages of comments to explain a nifty one-liner.
LOL!

Oh, too too true!!

stormshoppers
07-28-2010, 12:53 AM
the thing is, nobody can alter the data in the code, everything references back to a database I can not access fully, I can set prices, I can make the product id, but I can not export the database to use.

the code I initially posted works as a basic for one item, problem is, if I went to use it, I would have to have a button and such on each item and put each item into it's own form, very sloppy and very ugly.

I was given another script which after testing works to an extent, but does not post when the order form goes to post to my merchant account, heres the code with a table which I easily modified in my site.

Now I need to figure out a way to connect this code to product names that match in the database so it recognizes the purchase.

I do not understand what you guys mean by clients changing code, if everything is done inside the script which I ftp to my site, how can they adjust it? I have the prices unadjustable and use the code for calculation but the display is unadjustable, they can view source code, but they can't change it there either, I am confused on what u mean.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<body>
<script type="text/javascript">

function recalc_total(field)
{
var inputs;
inputs = document.getElementsByName(field +"_price");
var price = inputs[0].value;
inputs = document.getElementsByName(field +"_qty");
var qty = inputs[0].value;

var disc_price;

if(qty<5)
{
disc_price = price * 1.00;
}
else if(qty>=5 && qty <10)
{
disc_price = price * 0.95;
}
else if(qty>=10 && qty <15)
{
disc_price = price * 0.9;
}
else if(qty>=15 && qty <20)
{
disc_price = price * 0.85;
}
else
{
disc_price = price * 0.8;
}
inputs = document.getElementsByName(field +"_discount");
inputs[0].value = disc_price.toFixed(2);

inputs = document.getElementsByName(field +"_total");
var total = disc_price * qty;
inputs[0].value = total.toFixed(2);

}

</script>

<table>
<tr>
</tr>

<tr>
<td>Product 1</td>
<td><input type="hidden" name="product1_price" value="100" />100</td>
<td><input type="text" name="product1_qty" onkeyup="recalc_total('product1');"/></td>
<td><input type="text" name="product1_discount" disabled /></td>
<td><input type="text" name="product1_total" disabled /></td>
</tr>
</table>

</body>
</html>

Old Pedant
07-28-2010, 01:19 AM
You've never heard of "spoofing"???? Hackers *will* hit your site using hacked versions of your <form>s and files and trying to "buy" stuff with fake information.

Your only safety net is server-side code. *NEVER* depend upon calculations or even safe input coming from the browser.

Oh, and the reason that "form" doesn't post to the server is simple: There's no <form> tag any place on the page. It's not a form.

Old Pedant
07-28-2010, 01:21 AM
By the way, the fact that those calculated fields are marked disabled goes a long way toward making me believe you can get this all to work.

Fields that are disabled never get submitted to the server, so you will *HAVE* to use server-side code to recalculate those values. Which is a *good* thing.

disastro
07-28-2010, 01:24 AM
Sorry.

As for:

I do not understand what you guys mean by clients changing code

I'll give you a painful example.
Many, many years ago, I was a broke student. My first attempt at programming for the web was creating a type of roulette game. The only place where it was legal to setup and had cheap servers was Panama.

I had it running perfectly, I could set my profit margin as a percentage of the total money being played. The perfect business.
I launched it around 8pm. Went to bed later that night making money.
I woke up the next morning broke.

As it turned out, I forgot to test which currency the players were paying in. I paid winnings in US dollars but some clever !#*# figured out that he could pay in japanese yen and get paid in US\$. He told his friends, they told their friends and my working capital was gone in a few hours.

Lesson learned. (I was eating nothing but noodles for months) :D

It's getting late here, so I won't try to write anything now (mistakes will be made). I will check back tomorrow and see if I can help.

disastro
07-28-2010, 01:28 AM
Oh, and the reason that "form" doesn't post to the server is simple: There's no <form> tag any place on the page. It's not a form.

Nicely spotted.

Damnit, I must be tired.
Time to call it a day methinks.

stormshoppers
07-28-2010, 02:12 AM
I know there is no form tag on what I posted, this script is within a very large form of like 90 products and adding more, I know that it needs to link to SSI, like the initial script I posted links to SSI, but it is limited to one product, I just need it to do all products and do it with %'s so it can work with all products.

I do not know how to explain everything, for instance, the site is not self running, I get the receipt of every purchase, if the code is modified using hacks, I will see that in the order before I ship, so, that's not really a worry, the shipping is not automatic and there is no download product, the products r physical and I send, if there r hacks to place orders then the numbers won't add up and I cancel the order and report the fraud and block the ip from trying again, also block the credit card number.

with this recent script I posted, there has to be a way for it to connect to the product via it's product name, here is an example of a product listing in the table:

<tr>
<td class="price"><input type="hidden" name="Quantity0082_price" value="399.99" />\$399.99</td>
<td class="product">iPhone 3gs 8gb</td>
<td class="productamount"><input name="Quantity0082_qty" type="text" size="6" maxlength="4" value="0" onkeyup="recalc_total('Quantity0082');"/></td>
<td class="productamount"><input name="Quantity0082_discount" type="text" disabled size="9" /></td>
<td class="productamount">
<input name="Quantity0082_total" type="text" disabled size="9" />
</td>
</tr>

stormshoppers
07-28-2010, 02:25 AM
I don't understand why my new post had to be reviewed by admin before posting, that really slows down the ability to respond and to get help

stormshoppers
07-28-2010, 02:31 AM
the script is within a form, the form is just way too long to post here, here is an example of one product within a table within the form that I am trying to use with the latest script I posted.

<table>
<tr>
<td class="price"><input type="hidden" name="Quantity0082_price" value="399.99" />\$399.99</td>
<td class="product">iPhone 3gs 8gb</td>
<td class="productamount"><input name="Quantity0082_qty" type="text" size="6" maxlength="4" value="0" onkeyup="recalc_total('Quantity0082');"/></td>
<td class="productamount"><input name="Quantity0082_discount" type="text" disabled size="9" /></td>
<td class="productamount">
<input name="Quantity0082_total" type="text" disabled size="9" />
</td>
</tr>
<tr>
</table>

but with the _total and the _table and the _price additions it makes the product number not match the number in the database, I am new to javascript but I have designed a few websites that were completely static, this is my first attempt at a semi dynamic site and once finished with this, then I will be working on building my own shopping cart and having the entire site fully dynamic, but I need this site to do this semi dynamic thing to bring in some revenue so I can afford to live while building my fully dynamic site.

stormshoppers
07-28-2010, 02:32 AM
ok, thats twice now I wrote a post for what I need and it went straight to moderator to review and hasnt posted, but these little posts post no problem, wtf?

Old Pedant
07-28-2010, 08:29 AM
Dunno. Something in your content must have triggered automatic moderation. As I recall, there's something in the guidelines of the forum that say posts are subject to moderation until you have 50 good posts to your credit or something like that. Not a moderator, so no idea for sure. Find one of the moderators and ask him??

Philip M
07-28-2010, 08:44 AM
Dunno. Something in your content must have triggered automatic moderation. As I recall, there's something in the guidelines of the forum that say posts are subject to moderation until you have 50 good posts to your credit or something like that. Not a moderator, so no idea for sure. Find one of the moderators and ask him??

Surely that cannot be right - almost every day spam of some kind is posted. :mad:

I think that the 50 posts relates to admission to the members' lounge.

stormshoppers
07-28-2010, 10:12 AM
there wasn't anything in it either message that could have "triggered" spam or nething, it makes no sense, and if everything I try to add to the issue for help gets moderated and not posted, then the forum is completely useless

stormshoppers
07-28-2010, 10:14 AM
it's not blocking these messages, just the ones I put code into to show what I have and need help on, this is complete crap

Philip M
07-28-2010, 10:21 AM
As far as I know posts in this forum are not moderated. You seem to be saying that some of your posts did not appear at all - not that they were delayed. If so, "The fault, dear Brutus, lies not in the stars....". In other words, did you press the Submit Reply button?

stormshoppers
07-28-2010, 10:41 AM
yes, of course I hit the submit reply button, I even got a response saying that my post is delayed while a moderator reviews my post, which was hours ago, yet there are other posts I post in the meantime that don't get moderated, just the ones in the last 5 messages that had code in them, which I did use the proper code methods of posting, before thats asked.

evo
07-28-2010, 11:28 AM
Certain topics / structures of posts are flagged automatically by vBulletin. I'm not sure why, but I don't think there's a way to stop it.

Kinda like webmail flagging legitimate stuff as spam. Unfortunately, vB seems to miss quite a lot of the real spam.

I've validated the posts for you now.

Old Pedant
07-28-2010, 09:37 PM
<input type="hidden" name="Quantity0082_price" value="399.99" />
<input name="Quantity0082_qty" type="text" size="6" maxlength="4" value="0" onkeyup="recalc_total('Quantity0082');"/>
etc.
...

but with the _total and the _table and the _price additions it makes the product number not match the number in the database.

GOT YOU! Makes TONS of sense now!

This is easy to fix.

Leave the *NAME* properties alone. Make them so they match what your database code needs.

Instead, *ADD* ID properties to the fields using the _price, _qty, etc., suffixes!

Example:

<input type="hidden" name="something" id="ID0082_price" value="399.99" />
<input name="whatever" id="ID0082_qty" ... onchange="recalc_total('ID0082');"/>
<input id="ID0082_discount" type="text" disabled size="9" />
<input id="ID0082_total" type="text" disabled size="9" />
...

Notice that the DISABLED fields don't even get names. Pointless, since they won't be sent to the next page, anyway.

And then the JS code is simple:

function recalc_total(id)
{
var qtyfld = document.getElementById(id + "_qty");
var quantity = parseInt( qtyfld.value );
if ( isNaN(quantity) )
{
alert("Quantity must be an integer...quantity 1 assumed!");
quantity = 1;
qtyfld.value = 1;
}
var price = parseFloat( document.getElementById(id + "_price").value );

var discount;
if ( quantity < 5 ) discount = 0;
else if ( quantity < 10 ) discount = 10;
else if ( quantity < 20 ) discount = 15;
else if ( quantity < 40 ) discount = 20;
else discount = 25;
var discountedPrice = price * ( 1 - discount/100 );
document.getElementById(id + "_discount").value = discountedPrice.toFixed(2);
document.getElementById(id + "_total").value = (quantity * discountedPrice).toFixed(2);
}

Does that work for you???

I changed your onkeyup to onchanged. You can change it back, but onchanged makes more sense. If the person were to type in (say) 25, he/she would see the discount and total change to reflect the quantity of just 2 and then see it change again after typing the 5. I think that's kind of ugly.

The point is, by the by, that ID's are never seen by the pages that a <form> submits to. Only the names are passed along. (And only fields that are not disabled, too.)