How to create a quantity discount formula using Math JavaScript? - javascript

I am learning JavaScript for WordPress Websites, but I am only asked for the formula without including HTML or CSS fields, I just need the JS.
I need to create a formula to take a quantity [quantity] multiply it by the base price [base price] and then subtract the [discount] based on the following list they give me.
If you buy:
1 = 4
2 to 10 = 3.4
11 to 50 = 3.0
From 51 to 100 = 2.75
From 101 to 1000 = 2.50
This is the code I have been able to create but it only gives me the price until it reaches 10.
It is an exercise or an example, because I am learning how to create the code... the goal is to make the list above.
(function(){
if([field id="quantity"]<=10)
{
return 4;
}
else if(10>[field id="quantity"] && [field id="quantity"]<=20)
{
return 3.5;
}
else
{
return 0;
}
})() * [field id="quantity"]
Here is an example I made to give you an idea of the structure:
Loan Calculator Form | Monthly Payment:
[field id="amount"]*([field id="annual_interest"]/1200)/(1-(Math.pow(1/(1+([field id="annual_interest"]/1200)),([field id="repayment_period"]*12))))
List of available static mathematical methods I was given to use
Url of this list: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math?retiredLocale=vi#static_methods
I would like you to show me some examples of quantity discounts to learn how to handle the tools involved in performing this equation.

Related

Divide 100 in equal percentages in JavaScript

Ok. I will try to explain my case as good as I can.
Basically, I have this function here that will add an increment to my bootstrap progressbar:
function progress(increment) {
f = parseInt(document.getElementsByClassName('progress-bar')[0].style.width);
document.getElementsByClassName('progress-bar')[0].style.width = (f + increment) +'%';
}
Now for each step, for instance there are 6 steps, I must divide 100 into 6 steps incrementally.
For instance, if we are in step 1: 100 / 6 = 16.67 each so this must add 16.67 incrementally.
So it would be like this:
Step 1: Add 16.67
Step 2: Add 33.34
Step 3: Add 50.01
---- and the list go on
So on my program I have the ff variables:
let current_step = 0;
let stepCount = 6
So if I used the progress function, I tried dividing 100 to stepCount to the current_step:
progress(100 / (stepCount - current_step)
But this did not resolve the issue and I am getting only weird numbers.
Any idea what's the proper formula here to get the right numbers to add on the progressbar?
PS. Sorry, I hope its not that confusing. I tried to explain this at the best I can.
Your calculation isn't correct. This should give you the correct value.
progress((100 / stepCount) * current_step);
function progress(value) {
document.getElementsByClassName('progress-bar')[0].style.width = `${value}%`;
}
or you can do it like this
progress(100 / stepCount);
function progress(increment) {
let f = +document.querySelector('.progress-bar')[0].style.width.slice(0, -1);
// I'm slicing the width to remove the `%`
document.getElementsByClassName('progress-bar')[0].style.width = `${f + increment}%`;
}

Debugging a base conversion calculator up to base 809

So my calculator is built for absolutely huge numbers. I am having a bit of fun here and making a base system based on the pokedex. So for example, base 151 would include all the Pokemon from generation 1, and base 809 goes all the way to Melmetal from Pokemon Go. The number 0 is represented by an unhatched pokemon egg.
I am running into a problem that I cannot figure out how to determine what is wrong, some of these symptoms may be from the same problem but I am unsure.
Symptom 1:
Currently on my screen, I have it set to base pidgey (base 16) and I have input the base 10 number 80000006871717981.
My math gives me the following remainders, with the corresponding representative images
(1)(1)(12)(3)(7)(9)(5)(1)(7)(9)(14)(1)(8)(6)(0)
Bulbasaur Bulbasaur Butterfree Venusaur Squirtle Blastoise Charmeleon Bulbasaur Squirtle Blastoise Kakuna Bulbasaur Wartortle Charizard Egg
And the output from simply converting with toString(16) is 11c3795179e1860.
The output from the windows 10 calculator is ‭11C3795179E185D‬, implying that the e/Kakuna, 6/Charizard, and 0/Egg are wrong.
Symptom 2:
Large numbers will have the same outputs.
1000000000000000001 and 1000000000000000000 both output as
(3)(458)(599)(562)(324)(484)(498)
Venasaur Mantyke Klang Yamask Torkoal Palkia Tepig
I feel like this is relating to the size of the number, but don't know how I can prevent this.
For symptom 2, I have tried casting the value to a BigInt when I set the value for input, but that just gave me nothing, only the output3 got anything calculated
function calculate()
{
document.getElementById('output').innerHTML= '';
document.getElementById('output2').innerHTML= '';
var base = {{base}};//gets base from the python code
var input = document.getElementById('base10').value;
document.getElementById('output3').innerHTML= parseInt(input).toString(16);
var remainder = input % base;
while(input > 0)
{
//alert(input + " % " + base + " = " + remainder);
document.getElementById('output').innerHTML = '<img src="{{url_for('static', filename='images/')}}'+ remainder+'MS.png">' + document.getElementById('output').innerHTML;//adds the images of the pokemon
document.getElementById('output2').innerHTML = '('+remainder+')' + document.getElementById('output2').innerHTML;
input = parseInt(input / base);
remainder = input % base;
}
}
For my expected results, as I mentioned the built in js function shows the base 16 test is accurate, but the windows 10 calculator says otherwise. I don't know which one to go with.
And as far as the problems with large numbers go, I just need to make large base 10 numbers stay stable, not get scientific notation, and still be able to be processed.

Math: Pallet Packing (not quite the bin-packing situation)

I'm currently working on some private project on my spare time, and I've been stuck on a particular math problem.
I know that bin packing is a NP-HARD problem, but that's not exactly the problem I'm facing here.
What I must do is to calculate the number of pallets I would need to fit the given number of boxes, however the layout (of first/base level) is defined in advance. For me, the problem is that I have to take the box weight, pallet max weight, box height and pallet max height into consideration. In one moment it sounds like an elementary school math, but then I suddenly get lost with too many if and else statements.
The following is what I have:
Pallet (width, depth, max. height, max. weight)
Box ( total number of boxes, width, depth, height, weight)
Now, as I mentioned, the easy part is that I already know in advance how many boxes can I fit on a first layer. But then, I get lost because I'm trying to check too many things.
In example, the pallet can reach it's max weight before the max height is filled (and vice versa). Another (improbable but possible) scenario, the total number of boxes (if small enough) can be fitted on a single pallet without reaching the pallet's max height/weight.
In the end, I need to know the number of fully loaded pallets and if any boxes left for the last (partially filled) pallet.
I'm currently working in javascript. I'd be grateful if anyone can help me with with this, at least with some pseudo code that I can convert.
If you're willing to give it a shot, here are some numbers you can run your algorithm against:
Box Values:
+-----------+-----------+------------+------------+--------------------+-------------------+
| Width(cm) | Depth(cm) | Height(cm) | Weight(kg) | Fits(single layer) | Total (number of) |
+-----------+-----------+------------+------------+--------------------+-------------------+
| 32.5 | 24 | 22 | 14.7 | 9 | 111 |
+-----------+-----------+------------+------------+--------------------+-------------------+
Pallet Values:
+-----------+-----------+----------------+----------------+
| Width(cm) | Depth(cm) | Max.Height(cm) | Max.Weight(cm) |
+-----------+-----------+----------------+----------------+
| 120 | 80 | 145 | 725 |
+-----------+-----------+----------------+----------------+
EDIT:
I apologize for being unclear. I was lost in my own calculations. I updated the given values.
Also, I forgot to mention that the pallets are loaded to fill max in both weight and height. So, there can also be a partially filled layer on top (in case that max height isn't filled with previous layers and one more filled layer would go over allowed max weight).
OK, here is the code that I think embodies what meowgoesthedog meant:
function fillPallets(totalBoxNumber, boxHeight, boxWeight, boxesPerLayer, palletMaxHeight, palletMaxWeight) {
let maxBoxesByHeight = Math.floor(palletMaxHeight / boxHeight) * boxesPerLayer;
let maxBoxesByWeight = Math.floor(palletMaxWeight / boxWeight);
let maxBoxesPerPallet = Math.min(maxBoxesByHeight, maxBoxesByWeight);
let fullPalletsCount = Math.floor(totalBoxNumber / maxBoxesPerPallet);
let palletsCount = Math.ceil(totalBoxNumber / maxBoxesPerPallet);
let lastPalletBoxes = totalBoxNumber - fullPalletsCount * maxBoxesPerPallet;
let buildPallet = function (number) {
let palletLayers = [];
for (let rest = number; rest > 0; rest -= boxesPerLayer) {
palletLayers.push(Math.min(rest, boxesPerLayer))
}
return palletLayers;
}
let pallets = [];
let fullPallet = buildPallet(maxBoxesPerPallet);
for (let i = 0; i < fullPalletsCount; i++) {
pallets.push(fullPallet);
}
if (lastPalletBoxes > 0)
pallets.push(buildPallet(lastPalletBoxes));
return {
count: palletsCount,
palletsLayouts: pallets
}
}
Usage example
fillPallets(111,22,14.7,9,145,725)
produces following output
{
"count": 3,
"palletsLayouts": [[9, 9, 9, 9, 9, 4], [9, 9, 9, 9, 9, 4], [9, 4]]
}
The idea behind this code is that you want to calculate maxBoxesPerPallet and there are only two independent restrictions on that: either height or weight. So you calculate maxBoxesByHeight and maxBoxesByWeight first, then you get maxBoxesPerPallet, then you get the number of pallets (most of them will be "full" i.e. contain exactly maxBoxesPerPallet and there might be one last for the rest).

Using exponents in Gravity Forms calculations

Firstly, I am by no means versed in JavaScript or jQuery. That being said, I'm using Gravity Forms to create a savings calculator that contains exponents. I found THIS thread, but am confused as to how it actually works in calculating an exponential value.
Here's my setup:
I have 3 user-defined fields:
Principal amount
Interest rate
Number of monthly payments
The actual calculations are hidden from the user. There are two formulas calculating at once here. The first is the 'User calculations' working to find a 'Total Interest'. The second is a 'Fixed calculations' with a fixed interest rate of 1.95%, instead of the user-defined field, working towards the same goal. The fixed rate aside, both formulas are identical, and the results of which are incorporated into a final formula free of exponents. Thankfully. Here are the first three 'Number' fields (name & formula) after the user input:
'CALC'<br>
( {Interest rate::2} / 12 ) / 100
'MP exponent'
( 1 + {CALC:8} ) <---This is the formula that requires an exponent equal to the user-defined "Number of monthly payments" field.
'MP numerator'
{CALC:8} * {Principal amount::1} * {MP exponent:10}
The formula goes on and incorporates the MP exponent field multiple times. Given my case here, can I even use the aforementioned script (unedited from its source post):
<script>
gform.addFilter( 'gform_calculation_result', function(result, formulaField, formId, calcObj ){
if ( formulaField.field_id == "2" ) {
var field_five = jQuery('#input_2_5').val();
result = field_five * 12;
}
return result;
});
</script>
...for my calculation? I'm not at all sure how to specify something like this in 4 separate fields... I understand this may not be possible with Gravity Forms - or certainly not simple - so I greatly appreciate any help the community may offer me.
The javascript snippet you used above will change what the user sees, but it will not change the saved form data, per say. You instead need to add a PHP filter to the functions.php file of your theme.
add_filter( 'gform_calculation_result', function ( $result, $formula, $field, $form, $entry ) {
if ( $form['id'] == 1 && $field['id'] == 10 ) {
$base = 1 + (float) rgar( $entry, '8' ); // '8' should be field ID of Calc
$exponent = (float) rgar( $entry, '1' ); // '1' should be field ID of Number of monthly payments
$result = pow( $base, $exponent );
}
return $result;
}, 10, 5 );
One warning: this will not change anything that the user "sees" when filling out the form. It will only change the final calculation after the user hits the submit button.
It would also be cleaner to do all of your calculations in a filter like this rather than using hidden form data.

Car loan calculator in Javascript displays nothing

I hope someone can help with this:
I am currently working on a motor dealership website. On this website is a car loan calculator that calculates your monthly repayments. I have successfully created a basic calculator that calculates the correct amount.
The client isn't happy with that. They want a more advanced calculator that calculates the monthly repayments with balloon considerations and a deposit and initiation and admin fees.
I altered the code to reflect that, but now the thing won't work anymore. I can't find any error in my code.
Here's the Javascript that's supposed to do the calculation:
function calculate() {
// Get the user's input from the form. Assume it is all valid.
// Convert interest from a percentage to a decimal, and convert from
// an annual rate to a monthly rate. Convert payment period in years
// to the number of monthly payments.
var principal = document.loandata.principal.value;
var lessDeposit = document.loandata.deposit.value;
var adminFee = document.loandata.admin.value;
var initiationFee = document.loandata.initiation.value;
var interest = document.loandata.interest.value / 100 / 12;
var payments = document.loandata.years.value * 12;
var balloonPercent = document.loandata.balloon.value / 100;
// Now compute the monthly payment figure, using esoteric math.
var balloonFinal = (principal * balloonPercent);
var totalPrincipal = (principal + initiationFee + balloonfinal - lessDeposit);
var x = Math.pow(1 + interest, payments);
var monthly = (totalPrincipal*x*interest)/(x-1);
// Check that the result is a finite number. If so, display the results
if (!isNaN(monthly) &&
(monthly != Number.POSITIVE_INFINITY) &&
(monthly != Number.NEGATIVE_INFINITY)) {
document.loandata.payment.value = round(monthly + adminFee);
document.loandata.total.value = round(monthly * payments);
document.loandata.totalinterest.value =
round((monthly * payments) - principal);
}
// Otherwise, the user's input was probably invalid, so don't
// display anything.
else {
document.loandata.payment.value = "";
document.loandata.total.value = "";
document.loandata.totalinterest.value = "";
}
}
// This simple method rounds a number to two decimal places.
function round(x) {
return Math.round(x*100)/100;
}
Also, if possible, there needs to be some validation. Like purchase price, interest rate and payment period are required fields. But the rest are not. So if someone fills in the required fields but not the rest, the calculator still needs to work, but if someone does NOT complete one of the required fields, they need to be prompted to do so.
For those who don't know what a balloon payment is, here's an example;
Purchase Price is R117 000
You decide on a balloon payment of 30%. On the initial purchase price, the 30% amounts to R35 100. This amount is then subtracted from your initial purchase price so that means your purchase is now R81 900. After that comes the deposit, which is subtracted, and the extras and the admin and initiation fees. So the monthly repayments are calculated using this new purchase price of R81 900 + extras - deposit (if any). For interest sake, after your contract ends, you have to pay the balloon amount in full or re-finance the vehicle.
PS: I'm a complete newbie when it comes to JavaScript. So any help would be greatly appreciated.
If the result is nothing, one of these three conditions is likely triggering the else statement:
if (!isNaN(monthly) &&
(monthly != Number.POSITIVE_INFINITY) &&
(monthly != Number.NEGATIVE_INFINITY)) {
You have a typo in the JS, you need to change balloonfinal to be balloonFinal with a capital F in the var totalPrincipal = line of code.
The principal, lessDeposit, adminFee, initiationFee may also need to be typecast as an integer/float.

Categories

Resources