Egidi
Egidi

Reputation: 1776

javascript building and algo for calculating product prices

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

Answers (1)

MarcJames
MarcJames

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

Related Questions