VirtueMart Forum

VirtueMart 2 + 3 + 4 => Product creation => Topic started by: Duvy on January 14, 2013, 06:18:24 AM

Title: Multiple Custom Fields
Post by: Duvy on January 14, 2013, 06:18:24 AM
Update:
Reading this is for developers, by adding the code, you can Multiply, or give % off from the price of a product, like this:
(http://img41.imageshack.us/img41/2509/calculatecustom.jpg)


First question:
I'd like to make a game hosting webpage, an i'm lost in virtuemart:

For a server the customer can order + slots over the base price, eg:
$5 base price
10 slots  ->  included
20 slots -> +$1

That's the easy part, the tricky part, that i cannot manage, is the subscription:
1 month full price of the previous selected ( $5 + slot's custom field)
3 month  ->  2.5 * ( $5 + slot's custom field )

How can i manage two custom field with a bit more complicated price calculation?

UDPATE 14.01.2013
Well, i was searching the problem, the sql field is numeric, and only support positive, or negative numbers, and also found in the administrator/components/com_virtuemart/helpers/calculationh.php
//TODO adding % and more We should use here $this->interpreteMathOp for calculating the price.
It's going to be a while to make it work.
Any have some experience doing it?
I'm digging myself in it, tomorrow, until i would need some help, or suggestions, or if theres any documention.
Title: Re: Multiple Custom Fields
Post by: Duvy on January 15, 2013, 05:06:40 AM
Getting Closer!

Looks like, base functions working, don't use for functioning shop:
We are still in the administrator/components/com_virtuemart/helpers/calculationh.php

1. Some modification inside the "calculateModificators" function,
2. Add a new function
3. Add 1 column to database

1.: Modified function:
public function calculateModificators(&$product, $variants) {

                $modificatorSum = 0.0;
                //MarkerVarMods
                $i = 0;
                foreach ($variants as $selected => $variant) {
                $i++;
                        if (!empty($selected)) {

                                $query = 'SELECT  C.* , field.*
                                                FROM `#__virtuemart_customs` AS C
LEFT JOIN `#__virtuemart_product_customfields` AS field ON C.`virtuemart_custom_id` = field.`virtuemart_custom_id`
                                                WHERE field.`virtuemart_customfield_id`=' .(int)$selected;
                                $this->_db->setQuery($query);
                                $productCustomsPrice = $this->_db->loadObject();
                                if (!empty($productCustomsPrice) and $productCustomsPrice->field_type =='E') {
                                        if(!class_exists('vmCustomPlugin')) require(JPATH_VM_PLUGINS.DS.'vmcustomplugin.php');
                                        JPluginHelper::importPlugin('vmcustom');
                                        $dispatcher = JDispatcher::getInstance();
                                        $dispatcher->trigger('plgVmCalculateCustomVariant',array(&$product, &$productCustomsPrice,$selected,$modificatorSum));

                                }
                                //$app = JFactory::getApplication();
                                if (!empty($productCustomsPrice->custom_price)) {
                                        //TODO adding % and more We should use here $this->interpreteMathOp
                                                $rule[$i]['calc_value_mathop'] = $productCustomsPrice->custom_op;
                                                $rule[$i]['calc_value'] = $productCustomsPrice->custom_price;
                                                $rule[$i]['calc_currency'] = '64';
}
                        }
                }
                $modificatorSum = $this->calculateModificatorhelper($rule,$product->product_price);
                return $modificatorSum;
        }



2. :Add the following function below:
public function calculateModificatorhelper($rules,$price){
                $temp = 0.0;
                foreach ($rules as $i){
                        if($i['calc_value_mathop'] == '+'){
                                $temp += $this->interpreteMathOp($i,$temp,"true");
                        }
                        else if($i['calc_value_mathop'] == '-'){
                                $temp -= $this->interpreteMathOp($i,$temp,"true");
                        }
                }
                foreach ($rules as $i){
                        if($i['calc_value_mathop'] == '+%'){
                                        $temp += $this->interpreteMathOp($i,$temp+$price,"true");

                        }
                        else if($i['calc_value_mathop'] == '-%'){
                                        $temp -= $this->interpreteMathOp($i,$temp+$price,"true");
                }
        return $temp;
        }


3.: Add a column to virtuemart_product_customfields as "custom_op"

(http://img51.imageshack.us/img51/4974/customop.jpg)

STILL TO DO:
1.: From admin side, to handle the new column!
2.: On frontend product printig the value is always +, make the new column there to be printed.

3.: It's easy to make the code only multiply the calculated price except the base price.
Eg.: base price = $100;
custom field 1 = $20
custom field 2 = $30
custom field 3 = 200%
final price = $100 + 2* ($30+$20) => $200
Now it works as I wanted to :
2* ($100 + $20 + $30) => $300

UPDATE:
Multiple multiplication +%, or -% might not be working as expected.

UPDATE 2:
Some code correction
It seems, that there are a lot of way, how more +% and -% can work, and most of them make sense on a product, i suggest to use only one multiplication custom fields per product.
More fields works like:
Product price: $100
1. field :   -20%
2. field :   -10%
first field selected, price goes to $80
and when field 2 selected, it goes to $72
Since we are talking about percents, the order is not necessary.
Title: Re: Multiple Custom Fields
Post by: Duvy on January 16, 2013, 03:14:34 AM
Next step, is to make the values printed properly, in the frontend, like this:
(http://img41.imageshack.us/img41/2509/calculatecustom.jpg)

You need some modification in the:
administrator/components/com_virtuemart/models/customfields.php

In the  public function getProductCustomsFieldCart ($product)

Find the line:
foreach ($groups as $group) {


And in the query below, add the highlighted column:

$query = 'SELECT field.`virtuemart_product_id`, `custom_params`,`custom_element`, field.`virtuemart_custom_id`,
                                                        field.`virtuemart_customfield_id`,field.`custom_value`, field.`custom_price`,field.`custom_op`, field.`custom_param`
                                        FROM `#__virtuemart_customs` AS C
                                        LEFT JOIN `#__virtuemart_product_customfields` AS field ON C.`virtuemart_custom_id` = field.`virtuemart_custom_id`
                                        Where `virtuemart_product_id` =' . (int)$product->virtuemart_product_id;
                        $query .= ' and is_cart_attribute = 1 and C.`virtuemart_custom_id`=' . (int)$group->virtuemart_custom_id


Around 15 lines down, again add the highlighted parameter:
if ($group->field_type == 'V') {
                                $default = current ($group->options);
                                foreach ($group->options as $productCustom) {
                                   $price = self::_getCustomPrice($productCustom->custom_price, $currency, $calculator, $productCustom->custom_op);
                                        $productCustom->text = $productCustom->custom_value . ' ' . $price;



find the static function _getCustomPrice downer, i replaced it like this:

static function _getCustomPrice($customPrice, $currency, $calculator, $custom_op ="") {
                if ((float)$customPrice) {
                        if($custom_op == '+%' || $custom_op == '-%')
                                $price = $customPrice;
                        else
                        $price = strip_tags ($currency->priceDisplay ($calculator->calculateCustomPriceWithTax ($customPrice)));

                        if ($customPrice >0) {
                                switch ($custom_op){
                                        case "-":
                                                $price ="   - ".$price;
                                                break;
                                        case "+%":
                                                $price ="   + ". (int)$price . "%";
                                                break;
                                        case "-%":
                                                $price = "   " . (int)$price . "% Off";
                                                break;
                                        default:
                                        $price ="   + ".$price;
                                }
                        }
                }
                else {
                        $price = ($customPrice === '') ? '' : "  " . JText::_ ('COM_VIRTUEMART_CART_PRICE_FREE');
                }
                return $price;
}


I made some modification, on the original printing, adding 2-3 spaces between the price, and the description.
A string using the JText, could be better printing the % Off.

After debuging it, it seems like working :)
The only thing left, is the admin side customization.
Or maybe an additional feature would be needed, only to multiply the original price, without the modifiers.
Title: Re: Multiple Custom Fields
Post by: Duvy on January 17, 2013, 06:01:51 AM
Well, I'm almost ready with the last part, just need some time for making it better:
(http://img405.imageshack.us/img405/3903/percent.jpg)