News:

Looking for documentation? Take a look on our wiki

Main Menu

Multiple Custom Fields

Started by Duvy, January 14, 2013, 06:18:24 AM

Previous topic - Next topic

Duvy

Update:
Reading this is for developers, by adding the code, you can Multiply, or give % off from the price of a product, like this:



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.
Everything is Possimpible

Duvy

#1
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"



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.
Everything is Possimpible

Duvy

#2
Next step, is to make the values printed properly, in the frontend, like this:


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.
Everything is Possimpible

Duvy

Well, I'm almost ready with the last part, just need some time for making it better:
Everything is Possimpible