I am creating a simple form that calculates price based on quantity ordered and tax. I also want to apply a discount for the following quantities:
10-19: 10% discount
20-29: 20% discount
30-39: 30 % discount
40-99: 40 % discount
My issue is that the function still returns the total price without the discount for a certain quantity. When the quantity entered is in a certain range, I have set it up so that the discount updates to the appropriate percentage (var discountPrice). If a discount is applied, then the total should update to the discountedTotal, and calculate the tax and final total from there. However, there seems to be an issue with my syntax since none of this is being applied to the function when I run it.
Any insight as to why the if/else statement or the function as a whole is not running properly would be appreciated. If needed, here is the full HTML/JS: http://jsfiddle.net/pas0tmpL/
function priceCalculation() {
var nameFirst = document.getElementById("first_name").value;
var nameLast = document.getElementById("last_name").value;
var phoneNum = document.getElementById("phone_number").value;
var quantity = document.getElementById("quantity_order").value;
var price = document.getElementById("price_fixed").value;
var total = quantity * price;
var discountPrice = 0
var discountedTotal = total - (total * discountPrice);
const taxRate = 0.085;
var tax = total * taxRate;
var totalPlusTax = total + tax;
if (quantity > 9 || quantity < 20) {
discountPrice = .10;
total = discountedTotal;
}
else if (quantity > 19 || quantity < 30) {
discountPrice = .20;
total = discountedTotal;
}
else if (quantity > 29 || quantity < 40) {
discountPrice = .30;
total = discountedTotal;
}
else if (quantity > 39 || quantity < 100) {
discountPrice = .40;
total = discountedTotal;
}
document.getElementById("order_total").value = "$" + totalPlusTax.toFixed(2);
Like this:
function priceCalculation() {
var nameFirst = document.getElementById("first_name").value;
var nameLast = document.getElementById("last_name").value;
var phoneNum = document.getElementById("phone_number").value;
var quantity = document.getElementById("quantity_order").value;
var price = document.getElementById("price_fixed").value;
var total = quantity * price;
var discountPrice = 0 ;
var discountedTotal = 0;
const taxRate = 0.085;
var tax = total * taxRate;
var totalPlusTax = total + tax;
if (quantity > 9 || quantity < 20) {
discountPrice = .10;
total = total - (total * discountPrice);
}
else if (quantity > 19 || quantity < 30) {
discountPrice = .20;
total = total - (total * discountPrice);
}
else if (quantity > 29 || quantity < 40) {
discountPrice = .30;
total = total - (total * discountPrice);
}
else if (quantity > 39 || quantity < 100) {
discountPrice = .40;
total = total - (total * discountPrice);
}
document.getElementById("order_total").value = "$" + totalPlusTax.toFixed(2);
} // end function priceCalculation();
You have several problems that I can see. One is, you calculate the discountedTotal at the beginning using
var discountPrice = 0
var discountedTotal = total - (total * discountPrice);
total - (total * 0) will just give you total. You should probably only set discountedTotal after you know what your discountPrice is...
Your if statements have some problems also. As a hint, || means "or". Thus your first if is saying "if the quantity is more than 9 or less than 20"--and every integer in existence is either more than 9 or less than 20 (some are both!). So you'll only ever attempt to apply the first discount, and that to everything.
Good luck!
Related
I have an issue with the decimals in a result in my script, it gives unlimited decimals, I want to limit it to 2, I have tried using to.fixed(2) without luck, but the script broke.
This is my script:
$.each(rows, function () {
quantity = $(this).find('[data-quantity]').val();
if (quantity == '') {
quantity = 1;
$(this).find('[data-quantity]').val(1);
}
_amount = parseFloat($(this).find('td.rate input').val()) * quantity;
$(this).find('td.amount').html(_amount);
subtotal += _amount;
row = $(this);
item_taxes = $(this).find('select.tax').selectpicker('val');
if (item_taxes) {
$.each(item_taxes, function (i, taxname) {
taxrate = row.find('select.tax [value="' + taxname + '"]').data('taxrate');
calculated_tax = (_amount / 100 * taxrate);
if (!taxes.hasOwnProperty(taxname)) {
if (taxrate != 0) {
_tax_name = taxname.split('|');
tax_row = '<tr class="tax-area"><td>' + _tax_name[0] + '(' + taxrate + '%)</td><td id="tax_id_' + slugify(taxname) + '"></td></tr>';
$(discount_area).after(tax_row);
taxes[taxname] = calculated_tax;
}
} else {
// Increment total from this tax
taxes[taxname] = taxes[taxname] += calculated_tax;
}
});
}
});
The code line that does the operation is:
calculated_tax = (_amount / 100 * taxrate);
The correct is toFixed(), not to.fixed(), see the example:
let number = 12.128361;
let _amount = number.toFixed(2);
let calculated_tax = (_amount / 100 * 100);
console.log(calculated_tax);
Use this method to round to any amount of decimal places:
let v = 3.486894716724;
let rounded = Math.round(v * 100) / 100; // => 3.49
Multiply and divide by 10 to round to one DP, 100 for 2DP, 1000 for 3, etc...
Hi i have issue with the below JavaScript code not taking current GrossTotal() value until i rewrite Quantity or the UnitPrice values
$(document).ready(function () {
$("[id*=gridpur]input[type=text][id*=txtCalc]").on('keyup', (function (e) {
var unitprice = $(this).closest('tr').find("input[type=text][id*=txtCalcUnitprice]").val();
var quantity = $(e.target).closest('tr').find("input[type=text][id*=txtCalcQuantity]").val();
var total = unitprice * quantity;
var cost = (total / GrossTotal())*100;
$(e.target).closest('tr').find("[id*=lblTotal]").text(total);
$(e.target).closest('tr').find("[id*=lblcost]").text(cost);
}));
});
var gross;
function GrossTotal() {
gross = 0;
$("[id*=gridpur][id*=lblTotal]").each(function (index, item) {
gross = gross + parseInt($(item).text());
});
$("[id*=lblGrandTotal]").text(gross);
return gross;
}
for example if have entered the following values output i get which is not correct
ProductName UnitPrice Quantity Amount Cost %
product1 9 1 9 Infinity
product2 9 1 9 100
product3 9 1 9 50
I only get the correct values after rewriting Quantity or the UnitPrice which is
ProductName UnitPrice Quantity Amount Cost %
product1 9 1 9 33.3
product2 9 1 9 33.3
product3 9 1 9 33.3
Make sure, you default them to 0 when you read the value from the input. Also Check for 0 before dividing it
unitprice = !isNaN(unitprice) ? 0 : unitprice;
quantity = !isNaN(quantity) ? 0 : quantity;
var total = unitprice * quantity;
var grossTotal = GrossTotal(),
cost = 0;
if(grossTotal > 0) {
cost = (total / grossTotal) *100;
}
Also it is a better habit to use radix when using parseInt
parseInt($(item).text(), 10)
The problem is that GrossTotal() adds up the values in all the lblTotal fields, but you're not filling them in until after you call it. Change these lines:
var cost = (total / GrossTotal())*100;
$(e.target).closest('tr').find("[id*=lblTotal]").text(total);
$(e.target).closest('tr').find("[id*=lblcost]").text(cost);
to:
$(e.target).closest('tr').find("[id*=lblTotal]").text(total);
var cost = (total / GrossTotal())*100;
$(e.target).closest('tr').find("[id*=lblcost]").text(cost);
I am trying to do math with Javascript, it will run calculation from one input (monthly salary) to result (tax) as following:
Deduction from annual income (12000)
here comes the hard part, tax is calculated in different levels, so if annual is between 6500 and 25000, tax should be 10%. And if there is more left after 25000 and less than 40000, tax should be 15% added to the previous 10%, and so on.
EX. if annual is 60000, the math will be like this:
60000 - 12000 = 48000 // deduction
25000 X (10/100) = 2500 // 10% tax on 6500-25000 range
48000 - 25000 = 23000 // first cut 25000
23000 X (15/100) = 3450 // 15% tax on 25000-40000 range
total tax will be 2500 + 3450 = 5950
Code:
<input type=text id="salary">
<div id="total"></div>
<script>
function calc(){
var salary = document.getElementById('salary').value;
var annual = salary * 12;
var net = annual - 12000;
// Define Tax brackets
var bracket1 = (10 / 100);
var bracket2 = (15 / 100);
if (net >= 6500){
if ( net >= 6500 && net <= 25000 ) {
var tax1 = (net * bracket1);
}
else if ( net >= 30000 && net <= 40000 ) {
var tax2 = (net * bracket2);
}
var result = (tax1 + tax2) / 12; //monthly tax
document.getElementById('total').innerHTML = result ;
}
</script>
So output comes as NaN, I am not sure if what I have done so far is the right thing or variables inside statement is the problem here.
The algorithm itself seems to be... buggy (you might want to review
it), but, assuming some things myself, this works. Try running it and
see what you can improve.
<html>
<head>
<title>TAX</title>
</head>
<script type="text/javascript">
function calc(){
var result, tax1 = 0, tax2 = 0;
var salary = document.getElementById('salary').value;
var annual = salary * 12;
var net = annual - 12000;
// Define Tax brackets
var bracket1 = (10 / 100);
var bracket2 = (15 / 100);
if (net >= 6500) {
if (net >= 6500 && net <= 25000) {
tax1 = (net * bracket1);
}
else if (net >= 30000 && net <= 40000) {
tax2 = (net * bracket2);
}
result = (tax1 + tax2) / 12; // monthly tax
}
document.getElementById('total').innerHTML = result;
console.log(result);
}
</script>
<body>
<input type=text id="salary" onblur="calc();" value="0" />
<div id="total"></div>
</body>
</html>
There was a missing };
using var inside the if declarations is not a common practice, so I declared them in a bigger scope (calc() for this matter);
I assumed the line if (net = 30000 && net <= 40000) was about net >= 30000, but... your call;
The way it is now, either tax1 or tax2 will be setted. One of them will be zero. That's because of the if/else statements, they are confusing.
ps.: also, you might wanna use the parseFloat, as stated by some, considering the 'incoming' is not always an integer;
pps: I added a value="" in the input so it is - somewhat - defined at all times.
With the example given, this code might help you get started on the logic.
function calc(){
var salary = document.getElementById('salary').value;
var annual = salary * 12;
var net = annual - 12000;
console.log(salary, annual, net);
// Define Tax brackets
var bracket1 = (0.1);
var bracket2 = (0.15);
var tax1 = 0;
var tax2 = 0;
var runningNet = net;
if (net >= 6500){
if (net >= 25000) {
tax1 = 2500; // 2500 * 0.10, max tax on bracket 1
runningNet = runningNet - 25000;
tax2 = runningNet * bracket2; // whatever is left over * bracket2
}
else {
tax1 = runningNet * bracket1;
}
var result = (parseFloat(tax1) + parseFloat(tax2));
var monthly = result / 12; //monthly tax
document.getElementById('total').innerHTML = result ;
document.getElementById('monthly').innerHTML = monthly ;
}
}
<input type="text" id="salary" />
<button type="button" onclick="calc()">Calculate</button>
<br/>
Total: <div id="total"></div>
Monthly: <div id="monthly"></div>
I'm working on the classic "making change" problem, which is highly documented in plenty of other languages, but there's not much out there for it in Javascript. So far, I have this:
var total = $('#total').val();
var coins = [];
function makeChange(total, coins) {
var remainder = 0;
if (total % 0.25 < total) {
coins[3] = parseInt(total / 0.25);
remainder = total % 0.25;
total = remainder;
}
if (total % 0.10 < total) {
coins[2] = parseInt(total / 0.10);
remainder = total % 0.10;
total = remainder;
}
if (total % 0.05 < total) {
coins[1] = parseInt(total / 0.05);
remainder = total % 0.05;
total = remainder;
}
coins[0] = parseInt(total / 0.01);
}
function showChange(coins) {
if (coins[3] > 0) {
$('.quarter').html(coins[3] + " quarter(s).");
}
if (coins[2] > 0) {
$('.dime').html(coins[2] + " dime(s).");
}
if (coins[1] > 0) {
$('.nickel').html(coins[1] + " nickel(s).");
}
if (coins[0] > 0) {
$('.penny').html(coins[0] + " pennies.");
}
}
makeChange(total, coins);
showChange(coins);
However, this seems awfully repetitive and I'm finding that with certain values, it's a penny off. How can I make it more accurate and concise?
I'm finding that with certain values, it's a penny off.
Probably due to floating-point issues. And you shouldn't use parseInt to convert a number - it's meant for strings.
this seems awfully repetitive
A loop, with a data structure that represent the different coins will help. You already did something like that for your result: coins is an array, not 4 different variables.
function makeChange(total, values) {
var coins = [],
epsilon = 1e-5; // this is wrong in general!
// assume values are ascending, so we loop backwards
for (var i=values.length; i--; ) {
coins[i] = Math.floor(total / values[i].val + epsilon);
total %= values[i].val;
}
return coins;
}
function showChange(coins, values) {
for (var i=values.length; i--; ) {
var el = $(values[i].sel);
if (coins[i] > 0) {
el.html(coins[i] + " "+values[i].name+".");
} else {
el.empty();
}
}
}
var values = [
{val:0.01, sel:'.penny', name:"pennies"},
{val:0.05, sel:'.nickel', name:"nickel(s)"},
{val:0.10, sel:'.dime', name:"dime(s)"},
{val:0.25, sel:'.quarter', name:"quarter(s)"}
];
showChange(makeChange(parseFloat($('#total').val()), values), values);
Your best bet to avoid rounding problems is to just multiple your total by 100 to convert your dollar amount into all pennies, then do you conversion. For example:
function makeChange(total, coins) {
var remainder = 0;
total = Math.round(total * 100);
coins[3] = Math.floor(total / 25);
remainder = total - coins[3] * 25;
total = remainder;
coins[2] = Math.floor(total / 10);
remainder = total - coins[2] * 10;
total = remainder;
coins[1] = Math.floor(total / 5);
remainder = total - coins[1] * 5;
total = remainder;
coins[0] = total;
}
http://jsfiddle.net/t14cwdph/4/
For making your code easier to manage - see #Bergi's answer.
How do I get cart checkout price exact to the penny using Javascript?
Right now after taking out all of the trial .rounds etc I was trying.. I am coming up 1.5 cents too high using a high 15 products/prices to test.
for (var i = 0; i < Cookie.products.length; i++) {
boolActive = Cookie.products[i].og_active;
if (boolActive)
{
itemPrice = Cookie.products[i].price;
itemQty = Cookie.products[i].quantity;
itemDiscountPercent = Cookie.products[i].discount_percent;
subtotal = itemPrice * itemQty;
priceDiscount = (subtotal * itemDiscountPercent);
discountAmount += priceDiscount;
}
}
if (!isNaN(discountAmount))
{
var newCartTotal = (cartTotal - priceDiscount);
alert("New Cart Total: " + newCartTotal);
}
var newCartTotal = (cartTotal - pricediscount).toFixed(2)
that will give you the value, but it will be a string. If you need it to stay numeric, use:
var newCartTotal = ((cartTotal - pricediscount * 100) << 0) / 100;
You need to round the discount for each line item: priceDiscount = round_to_hundredth(subtotal * itemDiscountPercent)
Note that this result may not agree with the result you'd get if you add the unrounded results and then round the sum. However, this is the way invoices usually work when calculated by hand (especially since each item can have a different discount percent, so the discount is calculated for each line).
I think you left out a line saying discountAmount += priceDiscount.
modify your code to :
priceDiscount = parseFloat( (subtotal * itemDiscountPercent).toFixed(2) );
and:
newCartTotal = parseFloat( (cartTotal - priceDiscount).toFixed(2) );