News:

Support the VirtueMart project and become a member

Main Menu

Recent posts

#1
I have problem:

The quantity, name, SKU of products (item) not show on orderdone, order infomation page (front end) Both on orders page  (backend)

Payment method: standad
Shipment by weight, zip
Testing on Xampp
 
-PHP-Version 8.2.12
-Joomla 5.1.0
- Virtuemart 4.2.12.11012

debug
Backend

1 vmdebug Show All Errors, PHP-Version 8.2.12
2 vmdebug 1 Language, default shoplanguage (VmConfig::$jDefLang): vi_vn vi-VN
3 vmdebug vmTime: time to load config param $lang=1 and iniLang=0 $exeTrig = 0 now = 1: 0.0204181671142578
4 vmdebug Set router vars Input Get, Post Var0:
5 vmdebug Set router vars self::$get, Post, self::$request Var0:

6 vmdebug Start used Ram 32M
7 vmdebug BE main controller with controller orders and task orders
8 vmdebug exeSortSearchListQuery my $limitStart 0 $limit 0 q Var0:
9 vmdebug exeSortSearchListQuery result Var0:
10 vmdebug Defining custom function convertfromcurrency
11 vmdebug Defining custom function converttocurrency
12 vmdebug exeSortSearchListQuery my $limitStart 0 $limit 30 q Var0:
13 vmdebug exeSortSearchListQuery result Var0:

14 vmdebug exeSortSearchListQuery my $limitStart 0 $limit 0 q Var0:

15 vmdebug exeSortSearchListQuery result Var0:

16 vmdebug Get user, using given id 292
17 vmdebug Get user id 292
18 vmdebug VmViewAdmin addTemplatePath vmadmin
19 vmdebug checkSafePathBase return cached C:\xampp\htdocs\matkinh\administrator\components\com_virtuemart\su4ULI2CtosK19K0cMemt\
20 vmdebug getPagesLinks Var0:
C:\xampp\htdocs\matkinh/administrator/templates/atum/html/pagination.php
21 vmdebug vmTime: "VirtueMartControllerOrders" Finished task orders: 0.609486103057861
22 vmdebug End used Ram 36M
23 vmdebug Peak memory peak 36M
 
Fronted
271 vmdebug Building segments from initial query: Var0:
Array
(
    [option] => com_virtuemart
    [view] => productdetails
    [manage] => 1
    [managing] => 0
    [Itemid] => 605
    [limitstart] => 0
    [virtuemart_product_id] => 1808
    [virtuemart_category_id] =>
    [lang] => vi-VN
)
272 vmdebug vmRouter case 'productdetails' Itemid
273 vmdebug Building segments from query, left: Var0:
Array
(
    [non_segmented_query] => Array
        (
            [option] => com_virtuemart
            [manage] => 1
            [Itemid] => 605
            [lang] => vi-VN
        )

    [segments] => Array
        (
           
  • => kinh-mat-rayban-rb3447-9001a5-53-detail
        )

)

ADDTOCART click
My Memory Limit in MB 507Get user, using given id 0Get user id 0VmView loaded with overridesetCartIntoSession restart sessionsetActiveMenu Var0:

402
Var1:
402
setMenuItemId Var0:
Array
(
    [virtuemart_category_id] => Array
        (
            [44] => Array
                (
                   
  • => 257
                )

            [45] => Array
                (
                   
  • => 259
                )

            [52] => Array
                (
                   
  • => 260
                )

            [49] => Array
                (
                   
  • => 262
                )

            [43] => Array
                (
                   
  • => 266
                )

            [48] => Array
                (
                   
  • => 268
                )

            [46] => Array
                (
                   
  • => 270
                )

            [47] => Array
                (
                   
  • => 271
                )

            [23] => Array
                (
                   
  • => 528
                )

            [19] => Array
                (
                   
  • => 529
                )

            [34] => Array
                (
                   
  • => 533
                )

            [13] => Array
                (
                   
  • => 278
                )

            [32] => Array
                (
                   
  • => 534
                )

            [7] => Array
                (
                   
  • => 279
                )

            [30] => Array
                (
                   
  • => 535
                )

            [27] => Array
                (
                   
  • => 540
                )

            [26] => Array
                (
                   
  • => 487
                )

            [25] => Array
                (
                   
  • => 488
                )

            [11] => Array
                (
                   
  • => 495
                )

            [2] => Array
                (
                   
  • => 496
                )

            [12] => Array
                (
                   
  • => 497
                )

            [35] => Array
                (
                   
  • => 498
                )

            [36] => Array
                (
                   
  • => 500
                )

            [37] => Array
                (
                   
  • => 501
                )

            [3] => Array
                (
                   
  • => 503
                )

           
  • => Array
                (
                   
  • => 0
                )

        )

    [manufacturer] => 782
    [cart] => Array
        (
            [standard] => 530
        )

    [productdetails] => 275
    [virtuemart] => 605
    [virtuemart_manufacturer_id] => Array
        (
            [5] => 607
            [16] => 608
            [23] => 656
            [58] => 920
            [29] => 252
            [56] => 253
            [57] => 254
        )

)
Building segments from initial query: Var0:
Array
(
    [option] => com_virtuemart
    [view] => category
    [virtuemart_category_id] => 43
    [Itemid] => 402
    [lang] => vi-VN
)
my category build route Var0:
Array
(
    [option] => com_virtuemart
    [virtuemart_category_id] => 43
    [Itemid] => 402
    [lang] => vi-VN
)
category link segments Var0:
Array
(
    [option] => com_virtuemart
    [Itemid] => 266
    [lang] => vi-VN
)
Var1:
Array
(
)
Building segments from query, left: Var0:
Array
(
    [non_segmented_query] => Array
        (
            [option] => com_virtuemart
            [Itemid] => 266
            [lang] => vi-VN
        )

    [segments] => Array
        (
        )

)
My preprocess $Itemid Var0:
605
Building segments from initial query: Var0:
Array
(
    [option] => com_virtuemart
    [view] => cart
    [Itemid] => 605
    [lang] => vi-VN
)
Building segments from query, left: Var0:
Array
(
    [non_segmented_query] => Array
        (
            [option] => com_virtuemart
            [Itemid] => 605
            [lang] => vi-VN
        )

    [segments] => Array
        (
           
  • => cart
        )

)
EDITE Payment method page

Warning: openssl_decrypt(): IV passed is only 8 bytes long, cipher expects an IV of precisely 16 bytes, padding with \0 in C:\xampp\htdocs\matkinh\administrator\components\com_virtuemart\helpers\vmcrypt.php on line 87
#2
Thank you, Milbo. I did install the update last week and "that" part seems to be working fine. It's the error in the shopping cart (due to the type of captcha) that is a thorn in my side.
I decided I'd just put a message in the cart to log in before doing anything, or the user will get errors.
The problem with that is, no guest checkout.
#3
Because the prices are unnecessary complex, old vm1 stuff. Since vm2 it works a different way.

We have rules which works per categories, so using the "old parameters" just create more work than necessary.
#4
I think that is fixed with version 4.2.12
#5
hmmm, maybe too strong filter. What happens if you store a default without html? just something like "test", then we may get a grib of this problem.
#6
If you store a parent, which has the extra tab for children, than it takes this values for the children.

that works most time correctly, but if someone buys something meanwhile, it wont work 100%.

But that is a common problem for our stock feature.
#8
I have a very strange and weird bug. The stock gets automatically reverted back to it's old value. My client tells me it isn't that they do it by themselves, it gets done by the system. Any idea how this happens?

I checked all the plugins and components I have and none of them have anything to do with the stock. I'm very confused why this happens.

I think the best solution here is to add logging to the stock changes. I added in 2 places logging. Maybe a checkbox needs to be added so the logging only gets done when the user actually wants it, but for now I just hardcode it.

@Milbo

      public function updateStockInDB ($product, $amount, $signInStock, $signOrderedStock) {
           

        // Get the currently logged-in user
        $user = Factory::getUser();
        $userId = $user->id;
        $username = $user->username;
   
        // Log the start of the stock update process
        JLog::addLogger(
            array(
                'text_file' => 'com_virtuemart.log.php', // Name of the log file
                'text_entry_format' => '{DATETIME} {PRIORITY} {CATEGORY} {MESSAGE}' // Log entry format
            ),
            JLog::ALL, // Log all levels of messages
            array('com_virtuemart') // Categories to log
        );
   
        JLog::add(
            sprintf(
                'User %s (ID: %d) is attempting to update stock for product ID %d with amount %f, signInStock %s, signOrderedStock %s',
                $username, $userId, $product->virtuemart_product_id, $amount, $signInStock, $signOrderedStock
            ),
            Log::INFO,
            'com_virtuemart'
        );

        vmdebug('updateStockInDB start ', $signInStock, $signOrderedStock);
        $validFields = array('=', '+', '-');
        if (!in_array ($signInStock, $validFields)) {
            return FALSE;
        }
        if (!in_array ($signOrderedStock, $validFields)) {
            return FALSE;
        }

        $lproduct = $this->getProductSingle($product->virtuemart_product_id);
        if($lproduct->shared_stock){
            $productId = $lproduct->product_parent_id;
        } else {
            $productId = $product->virtuemart_product_id;
        }

        $amount = (float)$amount;
        $update = array();

        if ($signInStock != '=' or $signOrderedStock != '=') {

            if ($signInStock != '=') {
                $update[] = '`product_in_stock` = `product_in_stock` ' . $signInStock . $amount;

                if (strpos ($signInStock, '+') !== FALSE) {
                    $signInStock = '-';
                }
                else {
                    $signInStock = '+';
                }
                $update[] = '`product_sales` = `product_sales` ' . $signInStock . $amount;

            }
            if ($signOrderedStock != '=') {
                $update[] = '`product_ordered` = `product_ordered` ' . $signOrderedStock . $amount;
            }
            $q = 'UPDATE `#__virtuemart_products` SET ' . implode (", ", $update) . ' WHERE `virtuemart_product_id` = ' . (int)$productId;

            $db = JFactory::getDbo();
            $db->setQuery ($q);
            $db->execute ();
            //vmdebug('updateStockInDB executed query ', $q);
            //The low on stock notification comes now, when the people ordered.
            //You need to know that the stock is going low before you actually sent the wares, because then you ususally know it already yourself
            //note by Max Milbers
            if ($signInStock == '+' or $signOrderedStock == '+') {

                $q = 'SELECT (IFNULL(`product_in_stock`,"0")-IFNULL(`product_ordered`,"0")) < IFNULL(`low_stock_notification`,"0") '
                . 'FROM `#__virtuemart_products` '
                . 'WHERE `virtuemart_product_id` = ' . (int)$productId;
                $db->setQuery ( $q );
                //vmdebug('Check for low stock ',$q);
                if ($db->loadResult () == 1) {
                    vmdebug('Check for low stock said therre is a low stock ');
                    $this->lowStockWarningEmail( $productId) ;
                }
            }
        }

    }


And then I also added the logging to the store when a user changes the stock manually:

public function store (&$data) {

        vRequest::vmCheckToken();

        if(!vmAccess::manager('product.edit')){
            vmError('You are not a vendor or administrator, storing of product cancelled');
            return FALSE;
        }

        if ($data and is_object($data)) {
            $data = get_object_vars($data);
        }

        $isChild = FALSE;
        if(!empty($data['isChild'])) $isChild = $data['isChild'];

        if (isset($data['intnotes'])) {
            $data['intnotes'] = trim ($data['intnotes']);
        }

        // Setup some place holders
        $product_data = $this->getTable ('products');

        $data['new'] = '1';
        if(!empty($data['virtuemart_product_id'])){
            $product_data -> load($data['virtuemart_product_id']);
            $data['new'] = '0';
        }
        if( (empty($data['virtuemart_product_id']) or empty($product_data->virtuemart_product_id)) and !vmAccess::manager('product.create')){
            vmWarn('Insufficient permission to create product');
            return false;
        }

        $vendorId = vmAccess::isSuperVendor();
        $vM = VmModel::getModel('vendor');
        $ven = $vM->getVendor($vendorId);

        if(VmConfig::get('multix','none')!='none' and !vmAccess::manager('core')){

            if($ven->max_products!=-1){
                $this->setGetCount (true);
                //$this->setDebugSql(true);
                parent::exeSortSearchListQuery(2,'virtuemart_product_id',' FROM #__virtuemart_products',' WHERE ( `virtuemart_vendor_id` = "'.$vendorId.'" AND `published`="1") ');
                $this->setGetCount (false);
                if($ven->max_products<($this->_total+1)){
                    vmWarn('You are not allowed to create more than '.$ven->max_products.' products');
                    return false;
                }
            }
        }

        if(!vmAccess::manager('product.edit.state')){
            if( (empty($data['virtuemart_product_id']) or empty($product_data->virtuemart_product_id))){
                $data['published'] = 0;
            } else {
                $data['published'] = $product_data->published;
            }
        }

        //Set the decimals like product packaging
        foreach(self::$decimals as $decimal){
            if (array_key_exists ($decimal, $data)) {
                if(!empty($data[$decimal])){
                    $data[$decimal] = str_replace(',','.',$data[$decimal]);
                    //vmdebug('Store product '.$data['virtuemart_product_id'].', set $decimal '.$decimal.' = '.$data[$decimal]);
                } else {
                    $data[$decimal] = null;
                    $product_data->{$decimal} = null;
                    //vmdebug('Store product '.$data['virtuemart_product_id'].', set $decimal '.$decimal.' = null');
                }
            }
        }

        if($ven->force_product_pattern>0 and empty($data['product_parent_id']) and $ven->force_product_pattern!=$data['virtuemart_product_id']){
            $data['product_parent_id'] = $ven->force_product_pattern;
        }

        //We prevent with this line, that someone is storing a product as its own parent
        if(!empty($data['product_parent_id']) and !empty($data['virtuemart_product_id']) and $data['product_parent_id'] == $data['virtuemart_product_id']){
            $data['product_parent_id'] = 0;
        }

        $product_data->has_prices = (isset($data['mprices']['product_price']) and count($data['mprices']['product_price']) > 0)? 1:0;

        if (!$isChild) {
            $product_data->has_shoppergroups = empty($data['virtuemart_shoppergroup_id'])? 0:1;
            $product_data->has_manufacturers = empty($data['virtuemart_manufacturer_id'])? 0:1;
            //$product_data->has_medias = !empty($data['virtuemart_media_id']) or !empty($data['media']['virtuemart_media_id'])? 1:0;
            $product_data->has_categories = empty($data['categories'])? 0:1;
            if(!empty($data['virtuemart_media_id']) or !empty($data['media']['virtuemart_media_id']) or !empty($data['media']['media_action'])){
                $product_data->has_medias = 1;
            } else {
                $product_data->has_medias = 0;
            }
        }


        vDispatcher::importVMPlugins('vmcustom');
        vDispatcher::trigger('plgVmBeforeStoreProduct',array(&$data, &$product_data));

        $stored = $product_data->bindChecknStore($data, false);

       

        if(!$stored ){
            vmError('You are not an administrator or the correct vendor, storing of product cancelled');
            vmdebug('You are not an administrator or the correct vendor, storing of product cancelled', $data, $product_data->loadFieldValues());
            return FALSE;
        }

        $this->_id = $data['virtuemart_product_id'] = (int)$product_data->virtuemart_product_id;

        if (empty($this->_id)) {
            vmError('Product not stored, no id');
            return FALSE;
        }

        //We may need to change this, the reason it is not in the other list of commands for parents
        if (!$isChild) {
            $modelCustomfields = VmModel::getModel ('Customfields');
            $modelCustomfields->storeProductCustomfields ('product', $data, $product_data->virtuemart_product_id);
        }

        // Get old IDS
        $old_price_ids = $this->loadProductPrices($this->_id,array(0),false);

        if (isset($data['mprices']['product_price']) and count($data['mprices']['product_price']) > 0){

            foreach($data['mprices']['product_price'] as $k => $product_price){

                $pricesToStore = array();
                $pricesToStore['virtuemart_product_id'] = $this->_id;
                $pricesToStore['virtuemart_product_price_id'] = (int)$data['mprices']['virtuemart_product_price_id'][$k];

                if (!$isChild){
                    //$pricesToStore['basePrice'] = $data['mprices']['basePrice'][$k];
                    $pricesToStore['product_override_price'] = $data['mprices']['product_override_price'][$k];
                    $pricesToStore['override'] = isset($data['mprices']['override'][$k])?(int)$data['mprices']['override'][$k]:0;
                    $pricesToStore['virtuemart_shoppergroup_id'] = (int)$data['mprices']['virtuemart_shoppergroup_id'][$k];
                    $pricesToStore['product_tax_id'] = !empty($data['mprices']['product_tax_id'][$k])? (int)$data['mprices']['product_tax_id'][$k]:0;
                    $pricesToStore['product_discount_id'] = !empty($data['mprices']['product_discount_id'][$k])? (int)$data['mprices']['product_discount_id'][$k]:0;
                    $pricesToStore['product_currency'] = !empty($data['mprices']['product_currency'][$k])? (int)$data['mprices']['product_currency'][$k] : $ven->vendor_currency;
                    $pricesToStore['product_price_publish_up'] = !empty($data['mprices']['product_price_publish_up'][$k])? $data['mprices']['product_price_publish_up'][$k]:0;
                    $pricesToStore['product_price_publish_down'] = !empty($data['mprices']['product_price_publish_down'][$k])? $data['mprices']['product_price_publish_down'][$k]:0;
                    $pricesToStore['price_quantity_start'] = !empty($data['mprices']['price_quantity_start'][$k])? (int)$data['mprices']['price_quantity_start'][$k]:0;
                    $pricesToStore['price_quantity_end'] = !empty($data['mprices']['price_quantity_end'][$k])? (int)$data['mprices']['price_quantity_end'][$k]:0;
                }

                if (!$isChild and isset($data['mprices']['use_desired_price'][$k]) and $data['mprices']['use_desired_price'][$k] == "1") {

                    $calculator = calculationHelper::getInstance ();
                    if(isset($data['mprices']['salesPrice'][$k])){
                        $data['mprices']['salesPrice'][$k] = str_replace(array(',',' '),array('.',''),$data['mprices']['salesPrice'][$k]);
                    }
                    $pricesToStore['salesPrice'] = $data['mprices']['salesPrice'][$k];
                    $pricesToStore['product_price'] = $data['mprices']['product_price'][$k] = $calculator->calculateCostprice ($this->_id, $pricesToStore);
                    unset($data['mprices']['use_desired_price'][$k]);
                } else {
                    if(isset($data['mprices']['product_price'][$k]) ){
                        $pricesToStore['product_price'] = $data['mprices']['product_price'][$k];
                    }

                }

                if ($isChild) $childPrices = $this->loadProductPrices($this->_id,array(0),false);

                if ((isset($pricesToStore['product_price']) and $pricesToStore['product_price']!='' and $pricesToStore['product_price']!=='0') || (isset($childPrices) and is_array($childPrices) and count($childPrices)>1)) {

                    if ($isChild) {

                        if(is_array($old_price_ids) and count($old_price_ids)>1){

                            //We do not touch multiple child prices. Because in the parent list, we see no price, the gui is
                            //missing to reflect the information properly.
                            $pricesToStore = false;
                            $old_price_ids = array();
                        } else {
                            unset($data['mprices']['product_override_price'][$k]);
                            unset($pricesToStore['product_override_price']);
                            unset($data['mprices']['override'][$k]);
                            unset($pricesToStore['override']);
                        }

                    }

                    if($pricesToStore){
                        $toUnset = array();
                        if (!empty($old_price_ids) and count($old_price_ids) ) {
                            foreach($old_price_ids as $key => $oldprice){
                                if($pricesToStore['virtuemart_product_price_id'] == $oldprice['virtuemart_product_price_id'] ){
                                    $pricesToStore = array_merge($oldprice,$pricesToStore);
                                    $toUnset[] = $key;
                                }
                            }
                        }
                        $this->updateXrefAndChildTables ($pricesToStore, 'product_prices',$isChild);

                        foreach($toUnset as $key){
                            unset( $old_price_ids[ $key ] );
                        }
                    }
                }
            }
        }

        if (!empty($old_price_ids) and count($old_price_ids) ) {
            $oldPriceIdsSql = array();
            foreach($old_price_ids as $oldPride){
                $oldPriceIdsSql[] = $oldPride['virtuemart_product_price_id'];
            }
            $db = JFactory::getDbo();
            // delete old unused Prices
            $db->setQuery( 'DELETE FROM `#__virtuemart_product_prices` WHERE `virtuemart_product_price_id` in ("'.implode('","', $oldPriceIdsSql ).'") ');
            $err = '';
            try {
                $db->execute();
            } catch(Exception $e) {
                $err = $e->getMessage();
            }
           
            if(!empty($err)){
                vmWarn('In store prodcut, deleting old price error',$err);
            }
        }

        if (!empty($data['childs'])) {
            foreach ($data['childs'] as $productId => $child) {
                if(empty($productId)) continue;
                if($productId!=$data['virtuemart_product_id']){

                    if(empty($child['product_parent_id'])) $child['product_parent_id'] = $data['virtuemart_product_id'];
                    $child['virtuemart_product_id'] = $productId;

                    if(!empty($child['product_parent_id']) and $child['product_parent_id'] == $child['virtuemart_product_id']){
                        $child['product_parent_id'] = 0;
                    }

                    $child['isChild'] = $this->_id;
                    $this->store ($child);
                }
            }
        }

        if (!$isChild) {

            $data = $this->updateXrefAndChildTables ($data, 'product_shoppergroups');

            $data = $this->updateXrefAndChildTables ($data, 'product_manufacturers');

            $storeCats = false;
            if (empty($data['categories']) or (!empty($data['categories'][0]) and $data['categories'][0]!="-2")){
                $storeCats = true;
            }

            if($storeCats){
                if (!empty($data['categories']) && count ($data['categories']) > 0) {
                    if(VmConfig::get('multix','none')!='none' and !vmAccess::manager('managevendors')){

                        if($ven->max_cats_per_product>=0){
                            while($ven->max_cats_per_product<count($data['categories'])){
                                array_pop($data['categories']);
                            }
                        }

                    }
                    $data['virtuemart_category_id'] = $data['categories'];
                } else {
                    $data['virtuemart_category_id'] = array();
                }
                $data = $this->updateXrefAndChildTables ($data, 'product_categories');
            }

            // Update waiting list
            if (!empty($data['notify_users'])) {
                if ($data['product_in_stock'] > 0 && $data['notify_users'] == '1') {
                    $waitinglist = VmModel::getModel ('Waitinglist');
                    $waitinglist->notifyList ($data['virtuemart_product_id']);
                }
            }

            // Process the images
            $mediaModel = VmModel::getModel ('Media');
            $mediaModel->storeMedia ($data, 'product');

        }

        $oldStock = $product_data->product_in_stock;

        // Attempt to store product data
       

        // Get the currently logged-in user
        $user = Factory::getUser();
        $userId = $user->id;
        $username = $user->username;

        // Initialize the logger
        Log::addLogger(
            array(
                'text_file' => 'com_virtuemart.log.php', // Name of the log file
                'text_entry_format' => '{DATETIME} {PRIORITY} {CATEGORY} {MESSAGE}' // Log entry format
            ),
            Log::ALL, // Log all levels of messages
            array('com_virtuemart') // Categories to log
        );

        // Check if the stock has changed and log the changes
        if ($oldStock != $data['product_in_stock']) {
            Log::add(
                sprintf(
                    'User %s (ID: %d) changed stock for product ID %d from %d to %d',
                    $username, $userId, $product_data->virtuemart_product_id, $oldStock, $data['product_in_stock']
                ),
                Log::INFO,
                'com_virtuemart'
            );
        }

        $cache = VmConfig::getCache('com_virtuemart_orderby_manus','callback');
        $cache->clean();

        vDispatcher::trigger('plgVmAfterStoreProduct',array(&$data, &$product_data));

        return $product_data->virtuemart_product_id;
    }
#9
Product pricing / for those who wants to remove ...
Last post by rdcustom - Yesterday at 12:23:58 PM
did a trick today, I post here for future reference in case of updates:

currencydisplay.php

on line 301

add:

$res = preg_replace('/\,00/', '', $res);
$res = rtrim($res, ",");

this will show prices without useless ",00"

125,00 will result in "125"
#10
Product pricing / Re: If there's an override, cu...
Last post by rdcustom - Yesterday at 11:46:22 AM
I found myself the bug:

in calculationh.php - line 416

need to remove:

"if($variant){
            $this->productPrices['discountedPriceWithoutTax'] += $variant;
         }

"