Reputation: 524
My client needs a formula to work in a certain way.
Here's my code:
/* Daily rate */
var rate = 50;
/* If 18 days or less, discount is 20% */
if (this.value <= 18) {
var discount = 20;
}
/* Otherwise if more than 18 days */
else if (this.value > 18) {
var discount = 30;
}
/* Total - I realise this is wrong and needs to be changed */
total = rate / 100 * discount;
console.log(total);
Basically the way it needs to work is that if this.value
is more than 18 days, then the discount needs to only be 30% of every day past 18.
So for example, if this.value
is 22, then the 20% discount still applies for every day up to 18 days, but 30% discount also needs to apply for every day after 18 days, in this case, 4 days.
The expected result would be 860.
Because...
20% of 50 x 18 = 720
30% of 50 x 4 = 140
Total = 860
How can I modify my code to accommodate?
Upvotes: 0
Views: 72
Reputation: 29010
You can calculate the rate for each day in a for
loop and then total them. To do this, a little helper function discountForDay
can handle the variable discount rate for each day, this can make it easier to refactor later:
//fake the value by putting it in an object
var obj = {
value: 5,
discountForDay: function(day) {
if (day <= 18) {
return 0.20;
}
/* Otherwise if more than 18 days */
else if (day > 18) {
return 0.30;
}
},
calculate: function() {
/* Daily rate */
var rate = 50;
var total = 0;
for(var i = 0; i < this.value; i++) {
var discount = this.discountForDay(i + 1);
var rateForDay = rate - discount * rate;
total += rateForDay;
}
return total
}
}
console.log("total for 5 days:", obj.calculate());
obj.value = 18;
console.log("total for 18 days:", obj.calculate());
obj.value = 22;
console.log("total for 22 days:", obj.calculate());
So, this would work. If you wish to collapse it into a single mathematical formula, then you need:
Total = (rate * min(days, 18) - rate * min(days, 18) * 0.2) + (rate * max((days-18), 0) - rate * max((days-18), 0) * 0.3)
= rate * min(days, 18) * (1 - 0.2) + rate * max((days-18), 0) * (1 - 0.3)
= rate * (min(days, 18) * 0.8 + max((days-18), 0) * 0.7)
So, when encoded as a function this is:
function calculate(rate, days) {
return rate * (Math.min(days, 18) * 0.8 + Math.max((days-18), 0) * 0.7)
}
console.log("total for 5 days:", calculate(50, 5));
console.log("total for 18 days:", calculate(50, 18));
console.log("total for 22 days:", calculate(50, 22));
However, the mathematical formula will only work for this specific division of days and rates. It's not very maintainable if it changes and has to change often. It's not hard to derive new formulas, but it's probably not the best use of your time. You better embrace the iterative approach, as it's easier to extend in the future.
Upvotes: 2
Reputation: 396
This could be one solution:
var value = 22
var rate = 50
var total = 0
var baseDiscount = 20
var more18DaysDiscount = 30
if (this.value <= 18) {
total = value * rate * (100-baseDiscount)/100
} else {
var baseTotal = 18 * rate * (100-baseDiscount)/100
var more18DaysTotal = (value - 18) * rate * (100-more18DaysDiscount)/100
total = baseTotal + more18DaysTotal
}
console.log(total)
Upvotes: 1