Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

Component prices in ACBC

I'm trying to find a way to explicitly itemize prices in ACBC.

Since an overall summed price attribute can be created from individual prices, it feels like there should be a way to show respondents how each individual component contributes to that price. It's more complicated than just typing the prices into the levels because the overall summed price varies, so it seems like we need a way to get the overall price and divide it out among the components.

For clarification, this is sort of what I think you'd see (e.g. attribute one's A level price could differ from concept to concept because it's being varied by up to 30% below/above the base price):

            Option 1  Option 2  Option 3
Att 1 | A - $100  |  A - $80   |  B - $20  |
Att 2 | A - $50    |  B - $36   |  A - $60   |
Att 3 | D - $20    |  D - $16   |  A - $30  |
Price|   $170      |    $132     |    $110    |

Is there a built-in way to do this? Any hints on how to script it if there's no built-in option?
asked Jul 6, 2016 by ldulude (205 points)
My first thought for handling the price varying would be to split up the final price following the ratio of prices in the levels.  For example, if level 1 is $100 and level 2 is $50, then a total price of $180 would be broken down into $120 and $60; you can see that the ratio of $120-to-$60 is the same as $100-to-$50.

This seems like the "fair" way to do it, but it may have some drawbacks.  For starters, you will likely end up with odd amounts, like the nice round $100 becoming the more clunky $98.62.  Additionally, this may result in the same level having two different costs in different concepts.

Are these drawbacks acceptable to you?  Am I going down the right path of how you imagine this working?
That was my thought, too, the ratio idea. It will certainly result in the same level having different prices on the same page, but I think we're all okay with that. I think the weird dollar amounts could probably be rectified by rounding to the nearest whole number. That would mean that a few times the overall price would be a dollar or two off based on the individual components, but that's not the worst thing.

1 Answer

+1 vote
 
Best answer
Alright, I think I've got it.

Start by putting the non-scaled component prices in the levels.  For example, here's how the list item should look like for a brand with a base price of $100:

<span data-price="100">Brand A</span>


For an ACBC Screening Task, put this code in the footer:

<script>
$(document).ready(function(){
    // Parameters
    var numberOfComponentAttributes = 3;
    var numberOfScreenerConcepts = 4;
    
    for (var concept = 1; concept <= numberOfScreenerConcepts; concept++) {
        // Read component prices
        var nonscaledPrices = [];
        var nonscaledTotal = 0;
        for (var attribute = 1; attribute <= numberOfComponentAttributes; attribute++) {
            var nonscaledPrice = $('.acbc_screener .question_body tbody > tr:nth-child(' + attribute + ') > td:nth-child(' + (concept + 1) + ') span').data('price');
            nonscaledPrices.push(nonscaledPrice);
            nonscaledTotal += nonscaledPrice;
        }
        
        // Read total price
        var scaledTotal = $('.acbc_screener .question_body tbody > tr:nth-child(' + (numberOfComponentAttributes + 1) + ') > td:nth-child(' + (concept + 1) + ') .level_text').text();
        scaledTotal = parseFloat(scaledTotal.replace('$', ''));
        
        // Calculate and write scaled prices
        for (var attribute = 1; attribute <= numberOfComponentAttributes; attribute++) {
            var scaledPrice = nonscaledPrices[attribute - 1] * scaledTotal / nonscaledTotal;
            scaledPrice = Math.round(scaledPrice);
            $('.acbc_screener .question_body tbody > tr:nth-child(' + attribute + ') > td:nth-child(' + (concept + 1) + ') span').append(' ($' + scaledPrice + ')');
        }
    }
})
</script>


For an ACBC Choice Task, put this code in the footer:

<script>
$(document).ready(function(){
    // Parameters
    var numberOfComponentAttributes = 3;
    var numberOfChoiceConcepts = 3;
    
    for (var concept = 1; concept <= numberOfChoiceConcepts; concept++) {
        // Read component prices
        var nonscaledPrices = [];
        var nonscaledTotal = 0;
        for (var attribute = 1; attribute <= numberOfComponentAttributes; attribute++) {
            var nonscaledPrice = $('.acbc_choicetask .question_body tbody > tr:nth-child(' + attribute + ') > td:nth-child(' + (concept + 1) + ') span').data('price');
            nonscaledPrices.push(nonscaledPrice);
            nonscaledTotal += nonscaledPrice;
        }
        
        // Read total price
        var scaledTotal = $('.acbc_choicetask .question_body tbody > tr:nth-child(' + (numberOfComponentAttributes + 1) + ') > td:nth-child(' + (concept + 1) + ') .level_text').text();
        scaledTotal = parseFloat(scaledTotal.replace('$', ''));
        
        // Calculate and write scaled prices
        for (var attribute = 1; attribute <= numberOfComponentAttributes; attribute++) {
            var scaledPrice = nonscaledPrices[attribute - 1] * scaledTotal / nonscaledTotal;
            scaledPrice = Math.round(scaledPrice);
            $('.acbc_choicetask .question_body tbody > tr:nth-child(' + attribute + ') > td:nth-child(' + (concept + 1) + ') span').append(' ($' + scaledPrice + ')');
        }
    }
})
</script>


For both codes, you should update the "Parameters" section.  Line 4 should be updated with the number of attributes (not counting the price attribute).  Line 5 should be updated with the number of concepts in the Screening / Choice Task.
answered Jul 6, 2016 by Zachary Platinum Sawtooth Software, Inc. (63,900 points)
selected Jul 26, 2016 by ldulude
Zachary, I just got around to trying this, and it works perfectly! Thank you!
...