Reputation: 1776
I am developing a little website and I have 20 product selling.
Each week I want to calculate new prices for every product taking into account the number of sells done of each product but following two rules:
1 - The sum of the 20 products' prices must always be 100€
2 - I want every product to be integer (no decimal) or to be .5, I mean, one product's price can be 7 or 8 or 9 or 7.5 or 8.5 but not 8.3 or 7.1.
3- Minimun price for a product is 1.5.
Lets' make an example but simplifying with 4 products:
Sells this week:
product_id sells
---------- ------
1 45
2 31
3 12
4 62
ok, total sells then are 150.
If i divide those 100€ by 150 sells I get 0.667€/sell. So If I multiply every product by this value I am getting:
product_id sells raw_price_next_week
---------- ------ -------------------
1 45 30.015
2 31 20.677
3 12 8.004
4 62 41.354
Then I need to normalize those raw_prices taking into account the second rule I mentioned before, getting the closest 0.5 multiple of each raw_value...
product_id sells raw_price_next_week final_price
---------- ------ ------------------- ------------
1 45 30.015 30
2 31 20.677 20.5
3 12 8.004 8
4 62 41.354 41.5
Ok I've got a code that does everything ok except the third point, the one that places a minimum price of 1.5. So, for example, if the raw price for a product is 0.5, the price should be 1.5, as it is the minimum price.
I guess then than first thing to do should be calculate how many € are spent in products that are adjusted to the minimum 1.5€ when their raw prices are less than 1.5, and store that sum of adjusted prices to 1.5 in a var (imagine 6€). After that make the 100€ - 6€ = 94€. With that amount run the rest of the algo...
This is the code so far:
// Start with the raw product data (array of object - from database likely)
var
products = [
{
product_id: 1,
sells: 45
},
{
product_id: 2,
sells: 31
},
{
product_id: 3,
sells: 12
},
{
product_id: 4,
sells: 62
},
{
product_id: 5,
sells: 1
},
{
product_id: 6,
sells: 2
}
]
;
// ###############################################################
window.Pricing = {
total_sum: 100, // This represents the 100€
sales : 0,
min_price : 1.5
init: function( products ) {
return this.calculate_final_price( products );
},
get_price_per_sale: function( products ) {
for( x in products ) {
this.sales += products[x].sells;
}
return this.total_sum / this.sales;
},
calculate_final_price: function( products ) {
var price_per_sale = this.get_price_per_sale( products );
for( x in products ) {
products[x].raw_price_next_week = +( products[x].sells * price_per_sale );
products[x].final_price = +( Math.round( products[x].raw_price_next_week * 2 ) / 2 ).toFixed(1);
}
return products;
}
};
// ###############################################################
// Init the pricing calculations and get the final objects with updated pricing.
Pricing.init( products );
Upvotes: 0
Views: 234
Reputation: 189
I added a few variables for validation, then had the function recall it self until it came to a valid solution.
// Start with the raw product data (array of object - from database
var products = [ { product_id: 1, sells: 45 }, { product_id: 2, sells: 31 }, { product_id: 3, sells: 12 }, { product_id: 4, sells: 62 }, { product_id: 5, sells: 1 }, { product_id: 6, sells: 2 } ] ;
var Pricing = {
necessary_sum: 100,
dummy_sum: 100, // This represents the 100€
sales : 0,
min_price : 1.5,
real_sum : 0,
init: function( products ) {
return this.calculate_final_price( products );
},
get_price_per_sale: function( products ) {
this.sales = 0;
for( x in products ) {
this.sales += products[x].sells;
}
return this.dummy_sum / this.sales;
},
calculate_final_price: function( products ) {
var price_per_sale = this.get_price_per_sale( products );
for( x in products ) {
products[x].raw_price_next_week = products[x].sells * price_per_sale;
products[x].final_price = (Math.round( products[x].raw_price_next_week * 2 ) / 2 ).toFixed(1);
if(products[x].final_price < this.min_price){
products[x].final_price = this.min_price;
}
this.real_sum += ~~products[x].final_price;
}
if(this.real_sum != this.necessary_sum){
this.dummy_sum -= this.real_sum - this.necessary_sum;
this.real_sum = 0;
price_per_sale = this.get_price_per_sale( products );
this.calculate_final_price(products);
}
return products;
}
};
// Init the pricing calculations and get the final objects with updated pricing.
console.log(Pricing.init( products ));
console.log('should be: ' + Pricing.necessary_sum);
console.log('really: ' + Pricing.real_sum);
Upvotes: 1