# CartThrob automatic price calculated by VOLUME (or WEIGHT) and modifiers value

Here is what i'm gonna do with CartTrhob.

I want to sell a product that can be sold in different material. Every product has it's own volume in cm3, and every material has a Price per cm3.

So for example:

PRODUCT_A has a VOLUME of 10 cm3

In a channel called "MATERIAL" i have saved all the available material that can be applied to every PRODUCT. Every material has this fixed values:

MATERIAL_A - PRICE/CM3=2 - PRODUCTION_FEE=3; MATERIAL_B - PRICE/CM3=8 - PRODUCTION_FEE=2; MATERIAL_C - PRICE/CM3=6 - PRODUCTION_FEE=5;

The price is made by this formula:

MATERIAL_PRICE = (PRODUCT_VOLUME * MATERIAL_PRICE/CM3) + MATERIAL_PRODUCTION_FEE

So in this case i'll have:

PRODUCT_A:

• MATERIA_A_PRICE = (10 * 2) + 3 = 23\$
• MATERIA_B_PRICE = (10 * 8) + 2 = 82\$
• MATERIA_C_PRICE = (10 * 6) + 5 = 65\$

I would that every single material price for every single product is automatically calculated by the above formula. So every time i'll add new product i have to add only the VOLUME variable and EE does the rest.

At the end, after all material prices are calculated, i would that MATERIAL_A_PRICE is shown by default, as it is the default PRODUCT PRICE.

I think that the matrix price modifiers is the solution but i can't find the solution to make this MAGIC and store all that value in entries.

Some brave man can help me?

--- ADDED LATER ---

I found that question here:

Pre-fill matrix field when creating new entry?

and the script to add in the instruction is this:

``````<script>
\$(function() {

// Make sure that this is the publish form
if (!EE.publish)
return;

// Only proceed when creating a new entry
var entryId = \$('#publishForm').find('input[name="entry_id"]').val();
if (entryId != 0)
return;

function initLabels(id, labels) {
var addEntryButton = \$('#sub_hold_field_' + id + ' .matrix-btn.matrix-add');
return;

// Need to wait after `document.ready` has finished executing!
setTimeout(function() {
var field = \$('#sub_hold_field_' + id);

// Only proceed if matrix is empty
// Note: This is not the case if a validation error occurs!
if (!field.find('.matrix-norows').is(':visible'))
return;

// Create one row for each label
for (var i = 0; i < labels.length; ++i)

// Skip the placeholder row for "No rows have been added yet..."
field.find('tbody tr:not(.matrix-norows)').each(function(i) {
\$(this).find('.matrix-firstcell textarea').val(labels[i]);
});
}, 0);
}

// Check that this is an entry of the expected channel field group
if (EE.publish.field_group == 2) {
// "Custom Parameters"
initLabels('23', [
'Lens Type',
'Focal Length',
'Manufacturer',
'Model',
'Serial Number'
]);

// "Track Information"
initLabels('17', [
'Artist',
'Title',
'Label',
'Artwork'
]);
}

})
</script>
``````

But i have no idea on how to customize for me. How i can auto-fill with material name, price/cm3 and commission_fee hidden value in script to make the operations?

Your best bet here is to leave the actual price calculation out of the entry itself, and instead do it in the template using the Volume data you pull from the product entry and your available Material entries.

I'd write a custom plugin (start with pkg.io) that accepted the product's volume as a parameter, then grabbed a list of the materials and did the math in PHP, returning your list of prices for outputting in a dropdown or radio group with the `name` of `price`. (Make sure your CartThrob form has `allow_user_price="yes"` as a parameter.)

Some quick, untested code (will need to be modified for your particular setup obviously):

``````function get_prices()
{
\$vars = array();
\$volume = \$this->EE->TMPL->fetch_param('volume');
\$materials = \$this->EE->db->query("
SELECT t.title as material_name, d.field_id_XX as material_price, d.field_id_XX as material_production_fee
FROM exp_channel_titles t
LEFT JOIN exp_channel_data d
ON d.entry_id = t.entry_id
WHERE t.channel_id = XX
");
foreach(\$materials->result_array() as \$material)
{
extract(\$material);
\$price = (\$volume * \$material_price) + \$material_production_fee;
\$vars[] = array(
'material' => \$material_name,
'price' => \$price
);
}
return \$this->EE->TMPL->parse_variables(\$this->EE->TMPL->tagdata, \$vars);
}
``````

Then in your template:

``````<select name="price">
{exp:my_plugin:get_prices volume="{product_volume}"}
<option value="{price}">{material} ({price})</option>
{/exp:my_plugin:get_prices}
</select>
``````
• You are a god! But consider i'm a Dummy. So can you explain me how i've to start from, what i've to do exactly, and what i've to do with pkg.io? Mar 27, 2013 at 19:13

finally it seems i found the right way.

This is what i've done.

1. I create a Channel Material - Product. In that i put all the material i need, with this field:

• Title (name of material);
• Material price (price-per-volume);
• Material handling fee (fixed-fee-per-material);
2. Then i create a field in the product channel field

• I choose Playa as fieldtype, with multiselection for the material - product channel

In the view-product template i put this code:

``````{exp:cartthrob:add_to_cart_form
entry_id="{entry_id}"
allow_user_price="yes"
no_tax="{no_tax}"
no_shipping = "{no_shipping}"
return="store/carrello"}

<select name="price">
{exp:playa:children field="selezione_materiale"}
<option value="{exp:cartthrob:arithmetic prefix="" dec_point="." decimals="2" expression="{embed:volume} * {material_price} + {production_fee}"}">{title} - {exp:cartthrob:arithmetic prefix="€ " decimals="2" expression="{embed:volume} * {material_price} + {production_fee}"}</option>
{/exp:playa:children}
</select>

<button type="submit" class="btn btn-primary btn-block">Acquista</button>