function cw_products_from_scratch($scratch_products, $user_info, $persistent_products, $leave_info = false)
{
    global $addons, $tables, $config, $app_main_dir;
    global $current_area, $current_language, $customer_id;
    cw_load('image');
    $products = array();
    if (empty($scratch_products)) {
        return $products;
    }
    $pids = array();
    foreach ($scratch_products as $product_data) {
        $pids[] = $product_data['product_id'];
    }
    $int_res = cw_query_hash("SELECT * FROM {$tables['products_lng']} WHERE code = '{$current_language}' AND product_id IN ('" . implode("','", $pids) . "')", "product_id", false);
    unset($pids);
    cw_event('on_before_products_from_scratch', array(&$scratch_products));
    $hash = array();
    cw_load('warehouse');
    foreach ($scratch_products as $product_data) {
        $product_id = $product_data['product_id'];
        $cartid = $product_data['cartid'];
        $amount = $product_data['amount'];
        $variant_id = $product_data['variant_id'];
        $warehouse = $product_data['warehouse_customer_id'];
        if (!cw_warehouse_is_customer($customer_id, $warehouse)) {
            continue;
        }
        if (!is_numeric($amount)) {
            $amount = 0;
        }
        $options = $product_data['options'];
        $product_options = false;
        $variant = array();
        # kornev, TOFIX
        if ($addons['product_options'] && !empty($options) && is_array($options)) {
            if (!cw_check_product_options($product_id, $options)) {
                continue;
            }
            list($variant, $product_options) = cw_get_product_options_data($product_id, $options, $membership_id);
            if (empty($variant_id) && isset($variant['variant_id'])) {
                $variant_id = $variant['variant_id'];
            }
        }
        $fields[] = "p.*";
        # kornev, supplier has got it's own prices
        if ($current_area != 'S') {
            $fields[] = "min(pq.price) as price";
        }
        $fields[] = 'avail';
        $status = cw_core_get_required_status($current_area);
        $products_array = cw_func_call('cw_product_get', array('id' => $product_id, 'variant_id' => $variant_id, 'amount' => $amount, 'user_account' => $user_info, 'info_type' => 8192));
        //cw_query_first($sql="select ".implode(', ', $fields)." from $tables[products] as p, $tables[products_prices] as pq, $tables[products_enabled] as pe left join $tables[products_warehouses_amount] as pwa on pwa.product_id=pe.product_id and pwa.variant_id='$variant_id' and pwa.warehouse_customer_id='$warehouse' WHERE p.product_id= pe.product_id and pe.product_id=pq.product_id AND pe.status in (".implode(", ", $status).") AND pe.product_id='$product_id' AND pq.quantity<='$amount' AND pq.membership_id IN(0, '$user_info[membership_id]') AND pq.variant_id = '$variant_id' ORDER BY pq.quantity DESC");
        $unlimited_products = true;
        if ($products_array['avail'] < $amount && in_array($current_area, array('G', 'C'))) {
            $unlimited_products = cw_query_first_cell("select backorder & " . ($current_area == 'G' ? 2 : 1) . " from {$tables['warehouse_divisions']} where division_id = '{$warehouse}'");
            if (!$unlimited_products) {
                $amount = $products_array['avail'];
            }
        }
        if ($products_array) {
            $products_array = cw_array_merge($product_data, $products_array);
            if ($leave_info) {
                $products_array['price'] = abs($product_data['price']);
            }
            $products_array['warehouse_customer_id'] = $warehouse;
            $hash_key = $product_id . "|" . $warehouse;
            cw_event('on_product_from_scratch', array(&$products_array));
            #
            # If priduct's price is 0 then use customer-defined price
            #
            $free_price = false;
            if ($products_array['price'] == 0) {
                $free_price = true;
                $products_array['taxed_price'] = $products_array['price'] = price_format($product_data['free_price'] ? $product_data['free_price'] : 0);
            }
            # kornev, TOFIX
            if ($addons['product_options'] && $options) {
                if (!empty($variant)) {
                    # kornev, it's not allow to set the variant price.
                    //					unset($variant['price']);
                    if (is_null($variant['pimage_path'])) {
                        cw_unset($variant, "pimage_path", "pimage_x", "pimage_y");
                    } else {
                        $variant['is_pimage'] = 'W';
                    }
                    $products_array = cw_array_merge($products_array, $variant);
                }
                $hash_key .= "|" . $products_array['variant_id'];
                if ($product_options === false) {
                    unset($product_options);
                } else {
                    $variant['price'] = $products_array['price'];
                    $variant['cost'] = $products_array['cost'];
                    $products_array['options_surcharge'] = 0;
                    $products_array['cost_surcharge'] = 0;
                    if ($product_options) {
                        foreach ($product_options as $o) {
                            $products_array['options_surcharge'] += $o['modifier_type'] ? $products_array['price'] * $o['price_modifier'] / 100 : $o['price_modifier'];
                            $products_array['cost_surcharge'] += $o['cost_modifier_type'] ? $products_array['cost'] * $o['cost_modifier'] / 100 : $o['cost_modifier'];
                        }
                    }
                }
            }
            if (!$unlimited_products && !$persistent_products && $products_array['avail'] - $hash[$hash_key] < $amount) {
                continue;
            }
            # Get thumbnail's URL (uses only if images stored in FS)
            $products_array['image_thumb'] = cw_image_get('products_images_thumb', $product_id);
            $products_array['price'] += $products_array['options_surcharge'];
            $products_array['cost'] += $products_array['cost_surcharge'];
            if ($products_array['price'] < 0) {
                $products_array['price'] = 0;
            }
            if ($products_array['cost'] < 0) {
                $products_array['cost'] = 0;
            }
            if (in_array($current_area, array('C', 'G'))) {
                $products_array['taxes'] = cw_get_products_taxes($products_array, $user_info, false, '', $current_area == 'G' && $customer_info['usertype'] != 'R');
                if ($config['Taxes']['display_taxed_order_totals'] == 'Y') {
                    $products_array['display_price'] = $products_array['taxed_price'];
                    $products_array['display_net_price'] = $products_array['taxed_net_price'];
                } else {
                    $products_array['display_price'] = $products_array['price'];
                    $products_array['display_net_price'] = $products_array['net_price'];
                }
            }
            $products_array['total'] = $amount * $products_array['price'];
            $products_array['product_options'] = $product_options;
            $products_array['options'] = $options;
            $products_array['amount'] = $amount;
            $products_array['cartid'] = $cartid;
            $products_array['product_orig'] = $products_array['product'];
            if (isset($int_res[$product_id])) {
                $products_array['product'] = stripslashes($int_res[$product_id]['product']);
                $products_array['descr'] = stripslashes($int_res[$product_id]['descr']);
                $products_array['fulldescr'] = stripslashes($int_res[$product_id]['fulldescr']);
                cw_unset($int_res, $product_id);
            }
            if ($products_array['descr'] == strip_tags($products_array['descr'])) {
                $products_array['descr'] = str_replace("\n", "<br />", $products_array['descr']);
            }
            if ($products_array['fulldescr'] == strip_tags($products_array['fulldescr'])) {
                $products_array['fulldescr'] = str_replace("\n", "<br />", $products_array['fulldescr']);
            }
            // Order hash defines how all products in cart will be split by orders
            // Listen for the event and return own part of hash
            $order_hash = cw_event('on_build_order_hash', array($products_array), array());
            $order_hash[] = 'W' . $products_array['warehouse_customer_id'];
            $products_array['order_hash'] = join('-', $order_hash);
            $products[] = $products_array;
            $hash[$hash_key] += $amount;
        }
    }
    //cw_var_dump($products);
    return $products;
}
} else {
    $options = $cart['products'][$cartindex]['options'];
}
if (!empty($options)) {
    foreach ($options as $k => $v) {
        $options[$k] = stripslashes($v);
    }
}
cw_load('product', 'warehouse', 'cart');
$product_info = cw_func_call('cw_product_get', array('id' => $product_id, 'user_account' => $user_account));
$smarty->assign('product', $product_info);
//include $app_main_dir.'/addons/product_options/customer/product.php';
cw_include('addons/product_options/customer/product.php');
if ($REQUEST_METHOD == "POST" && $action == "update") {
    $poptions = $_POST['product_options'];
    if (!cw_check_product_options($product_id, $poptions)) {
        cw_header_location("index.php?target=popup_poptions&target={$target}&id={$id}&err=exception");
    }
    if ($mode == 'wishlist') {
        db_query("UPDATE {$tables['wishlist']} SET options = '" . addslashes(serialize($poptions)) . "' WHERE wishlist_id = '{$id}' AND event_id = '{$eventid}'");
    } else {
        $variant_id = cw_get_variant_id($product_options, $product_id);
        $amount = cw_warehouse_get_warehouse_avail($cart['products'][$cartindex]['warehouse'], $product_id, null, $variant_id);
        //		$amount = cw_get_options_amount($poptions, $cart['products'][$cartindex]['product_id']);
        if ($amount >= $cart['products'][$cartindex]['amount']) {
            $cart['products'][$cartindex]['options'] = $poptions;
            cw_unset($cart['products'][$cartindex], 'variant_id');
        } else {
            cw_header_location("index.php?target=popup_poptions&target={$target}&id={$id}&err=avail");
        }
        # Recalculate cart totals after updating
function cw_gift_add2wishlist($product_id, $amount, $product_options = null)
{
    global $addons, $tables;
    global $user_account, $customer_id;
    if (is_array($amount)) {
        $amount = array_sum($amount);
    }
    $_options = array();
    if ($addons['product_options']) {
        if (is_array($product_options) && cw_check_product_options($product_id, $product_options)) {
            $product_options = cw_array_map('stripslashes', $product_options);
        } else {
            $product_options = cw_get_default_options($product_id, $amount, $user_account['membership_id']);
        }
        if (!is_array($product_options)) {
            unset($product_options);
        } else {
            $_options = addslashes(serialize($product_options));
        }
    }
    $added_product = cw_func_call('cw_product_get', array('id' => $product_id, 'user_account' => $user_account, 'info_type' => 3));
    $oamount = 0;
    $wlid = FALSE;
    $object = '';
    // Save to session for not loggin in customers
    if (empty($customer_id)) {
        $customer_wishlist =& cw_session_register('customer_wishlist');
        if ((empty($added_product['distribution']) || !$addons['egoods']) && !empty($customer_wishlist)) {
            $wlid = cw_gift_get_session_wishlist_id($product_id, $_options);
            if ($wlid !== FALSE) {
                $oamount = $customer_wishlist[$wlid]['amount'];
            }
        }
        if ($wlid !== FALSE) {
            $customer_wishlist[$wlid]['amount'] = $amount + $oamount;
        } else {
            $customer_wishlist[] = array('product_id' => $product_id, 'amount' => $amount, 'amount_purchased' => 0, 'options' => $_options, 'object' => $object, 'event_id' => 0);
            $index = count($customer_wishlist) - 1;
            $customer_wishlist[$index]['wishlist_id'] = $index;
        }
    } else {
        if (empty($added_product['distribution']) || !$addons['egoods']) {
            $oamount = cw_query_first_cell("SELECT amount FROM {$tables['wishlist']} WHERE customer_id='{$customer_id}' AND product_id='{$product_id}' AND options='{$_options}' AND event_id='0'");
        }
        $wlid = cw_query_first_cell("SELECT wishlist_id FROM {$tables['wishlist']} WHERE customer_id='{$customer_id}' AND product_id='{$product_id}' AND options='{$_options}' AND event_id='0'");
        if (!empty($wlid)) {
            cw_array2update('wishlist', array('amount' => $amount + $oamount), "wishlist_id='{$wlid}'");
        } else {
            cw_array2insert('wishlist', array('customer_id' => $customer_id, 'product_id' => $product_id, 'amount' => $amount, 'options' => $_options, 'object' => $object));
        }
    }
}
function cw_add_to_cart(&$cart, $product_data)
{
    global $user_account;
    global $addons, $config, $top_message, $app_main_dir, $HTTP_REFERER, $app_catalogs, $tables;
    global $from, $current_area;
    $return = array();
    # Extracts to: $product_id, $amount, $product_options, $price, $warehouse_customer_id
    extract($product_data);
    $warehouse = $product_data['warehouse_customer_id'];
    cw_load('warehouse');
    $added_product = cw_func_call('cw_product_get', array('id' => $product_id, 'user_account' => $user_account, 'info_type' => 3));
    if ($added_product['product_type'] == 10) {
        $warehouse = $added_product['warehouse_customer_id'];
    }
    if (!$warehouse) {
        $possible_warehouse = cw_warehouse_get_max_amount_warehouse($product_id);
    }
    if (!empty($addons['egoods']) && !empty($added_product['distribution'])) {
        $amount = 1;
    } else {
        $amount = abs(intval($amount));
    }
    if ($amount == 0) {
        $amount = 1;
    }
    # kornev, TOFIX
    if ($addons['product_options']) {
        #
        # Prepare the product options for added products
        #
        if (!empty($product_options)) {
            # Check the received options
            if (!cw_check_product_options($product_id, $product_options)) {
                $return['redirect_to'] = "product.php?product_id={$product_id}&err=options";
                return $return;
            }
        } else {
            # Get default options
            $product_options = cw_get_default_options($product_id, $amount, @$user_account['membership_id']);
            if ($product_options === false) {
                $return['redirect_to'] = 'index.php?target=error_message&error=access_denied&id=30';
                return $return;
            } elseif ($product_options === true) {
                $product_options = "";
                unset($product_options);
            }
        }
        # Get the variant_id of options
        $variant_id = cw_get_variant_id($product_options, $product_id);
        if (!empty($variant_id)) {
            $possible_warehouse = cw_warehouse_get_max_amount_warehouse($product_id, $variant_id);
            if (empty($warehouse)) {
                $warehouse = $possible_warehouse;
            }
            # Get the variant amount
            $added_product['avail'] = cw_warehouse_get_warehouse_avail($warehouse, $product_id, null, $variant_id);
            //cw_get_options_amount($product_options, $product_id);
            if (!empty($cart['products'])) {
                foreach ($cart['products'] as $k => $v) {
                    if ($v['product_id'] == $product_id && $variant_id == $v['variant_id']) {
                        $added_product['avail'] -= $v['amount'];
                    }
                }
            }
        } else {
            if (empty($warehouse)) {
                $warehouse = $possible_warehouse;
            }
            $added_product['avail'] = cw_warehouse_get_warehouse_avail($warehouse, $product_id);
        }
    }
    /*
    kornev, the amount is checked by another function - during the calculation
    	if ($config['General']['unlimited_products'] == "N" && $added_product['product_type'] != 10) {
    		#
    		# Add to cart amount of items that is not much than in stock
    		#
    		if ($amount > $added_product['avail'])
    			$amount = $added_product['avail'];
    	}
    */
    if ($from == 'salesman' && empty($amount)) {
        $return['redirect_to'] = $app_catalogs['customer'] . "/product.php?product_id=" . $product_id;
        return $return;
    }
    if ($product_id && $amount) {
        if ($amount < $added_product['min_amount']) {
            $return['redirect_to'] = "index.php?target=error_message&error=access_denied&id=31";
            return $return;
        }
        $found = false;
        $_product = cw_array_merge($product_data, $added_product, array('options' => $product_options, 'free_price' => $price));
        // Product hash defines how to differ/join products in cart
        // Listen for the event and return own part of hash. See also default handler.
        $product_hash = cw_event('on_build_cart_product_hash', array($_product), array());
        $product_data['product_hash'] = $_product['product_hash'] = join('-', $product_hash);
        if (!empty($cart) && @$cart['products']) {
            foreach ($cart['products'] as $k => $v) {
                $product_hash = join('-', cw_event('on_build_cart_product_hash', array($v), array()));
                if ($product_hash == $_product['product_hash']) {
                    if (doubleval($v['free_price']) != $price) {
                        continue;
                    }
                    $found = true;
                    if ($cart['products'][$k]['amount'] >= 1 && (!empty($added_product['distribution']) || !empty($subscribed_product))) {
                        $cart['products'][$k]['amount'] = 1;
                        $amount = 0;
                    }
                    $cart['products'][$k]['amount'] += $amount;
                    $return['added_amount'] += $amount;
                    $return['productindex'] = $k;
                    $return['cartid'] = $v['cartid'];
                    $return['merged'] = true;
                    break;
                }
            }
        }
        if (!$found) {
            #
            # Add product to the cart
            #
            if (!empty($price)) {
                # price value is defined by customer if admin set it to '0.00'
                $free_price = abs(doubleval($price));
            }
            $cartid = cw_generate_cartid($cart['products']);
            if (empty($cart['products'])) {
                $add_to_cart_time = time();
            }
            $_product = array("cartid" => $cartid, "product_id" => $product_id, "amount" => $amount, "options" => $product_options, "free_price" => @price_format(@$free_price), "salesman_doc_id" => $salesman_doc_id, "distribution" => $added_product['distribution'], "variant_id" => $variant_id, "warehouse_customer_id" => $warehouse);
            // Add all custom fields from added products
            foreach ($product_data as $k => $v) {
                if (!isset($_product[$k])) {
                    $_product[$k] = $v;
                }
            }
            $cart['products'][] = $_product;
            // count add to cart
            cw_call('cw_product_run_counter', array('product_id' => $product_id, 'count' => 1, 'type' => 3));
            $return['added_amount'] = $amount;
            $_ak = array_keys($cart['products']);
            $return['productindex'] = end($_ak);
            $return['cartid'] = $cartid;
            $return['merged'] = false;
        }
    }
    return $return;
}
 if ($is_old) {
     $count_product_in_stock += $v['amount'];
 }
 # kornev
 # pos orders && supplier orders are unlimited
 if ($v['amount'] > 0) {
     $aom_orders[$doc_id]['products'][$index]['amount'] = $config['unlimited_products'] ? $v['amount'] : min($v['amount'], $count_product_in_stock);
 }
 $v['price'] = cw_aom_validate_price($v['price']);
 if ($config['Taxes']['display_taxed_order_totals'] == 'Y') {
     $v['price'] = cw_taxes_price_without_tax($v['price'], $aom_orders[$doc_id]['products'][$index]['taxes']);
 }
 $product_options_result = array();
 # kornev, TOFIX
 if ($v['product_options'] && $addons['product_options']) {
     if (!cw_check_product_options($product_id, $v['product_options'])) {
         $v['product_options'] = cw_get_default_options($product_id, $v['amount'], $aom_orders[$doc_id]['userinfo']['membership_id']);
     }
     list($variant, $product_options_result) = cw_get_product_options_data($product_id, $v['product_options'], $aom_orders[$doc_id]['userinfo']['membership_id']);
     $aom_orders[$doc_id]['products'][$index]['options_surcharge'] = 0;
     if ($product_options_result) {
         foreach ($product_options_result as $key => $o) {
             $aom_orders[$doc_id]['products'][$index]['options_surcharge'] += $o['modifier_type'] == '%' ? $v['price'] * $o['price_modifier'] / 100 : $o['price_modifier'];
         }
     }
 }
 $is_copy_price = false;
 if (in_array($aom_orders[$doc_id]['type'], array('P', 'Q', 'R')) && !$aom_orders[$doc_id]['products'][$index]['is_net_price']) {
     $is_copy_price = true;
 }
 if ($current_area == 'G' && !$accl['100001']) {
function cw_get_default_variant_id($product_id)
{
    global $tables, $config;
    # Get classes (variant type)
    $classes = cw_query_hash("SELECT {$tables['product_options']}.product_option_id FROM {$tables['product_options']}, {$tables['product_options_values']}, {$tables['product_variant_items']} WHERE {$tables['product_options']}.product_option_id = {$tables['product_options_values']}.product_option_id AND {$tables['product_options_values']}.avail = 1 AND {$tables['product_options']}.avail = 1 AND {$tables['product_options']}.product_id = '{$product_id}' AND {$tables['product_options']}.type = '' AND {$tables['product_variant_items']}.option_id = {$tables['product_options_values']}.option_id GROUP BY {$tables['product_options']}.product_option_id", "product_option_id");
    if (empty($classes)) {
        return false;
    }
    $avail_where = "";
    if ($config['General']['disable_outofstock_products'] == 'Y') {
        $avail_where = "AND pa.avail > 0";
    }
    # Detect default variant
    $def_variant_id = cw_query_first_cell("SELECT pv.variant_id FROM {$tables['product_variants']} as pv, {$tables['products_warehouses_amount']} as pa WHERE pa.variant_id=pv.variant_id and pv.product_id = '{$product_id}' AND def = 'Y' " . $avail_where);
    if (!empty($def_variant_id)) {
        $_product_options = cw_query_hash("SELECT {$tables['product_options_values']}.product_option_id, {$tables['product_options_values']}.option_id FROM {$tables['product_options_values']}, {$tables['product_variant_items']} WHERE {$tables['product_variant_items']}.variant_id = '{$def_variant_id}' AND {$tables['product_variant_items']}.option_id = {$tables['product_options_values']}.option_id", "product_option_id", false, true);
        if (count($_product_options) != count($classes)) {
            return false;
        }
        # Check exceptions
        $exceptions = cw_query_hash("SELECT exception_id, COUNT(option_id) FROM {$tables['products_options_ex']} WHERE option_id IN ('" . implode("','", $_product_options) . "') GROUP BY exception_id", "exception_id", false, true);
        if (!empty($exceptions)) {
            # Get exceptions counters
            $exception_counters = cw_query_hash("SELECT exception_id, COUNT(option_id) FROM {$tables['products_options_ex']} WHERE exception_id IN ('" . implode("','", array_keys($exceptions)) . "') GROUP BY exception_id", "exception_id", false, true);
            foreach ($exceptions as $eid => $cnt) {
                if ($exception_counters[$eid] == $cnt) {
                    $_product_options = array();
                    break;
                }
            }
            if (!empty($_product_options)) {
                # When the set of exceptions defined for a product covers not only the
                # combination of options that make the product's default variant, but
                # also a whole group of non-variant options which can be used in
                # combination with them, this check-up ensures that a different
                # (non-exceptional) combination of variant options is selected as the
                # products's default one.
                $exceptions = cw_query_hash("SELECT {$tables['product_options_values']}.product_option_id, COUNT({$tables['products_options_ex']}.exception_id) FROM {$tables['products_options_ex']}, {$tables['product_options_values']} WHERE {$tables['products_options_ex']}.option_id = {$tables['product_options_values']}.option_id AND {$tables['products_options_ex']}.exception_id IN ('" . implode("','", array_keys($exceptions)) . "') AND {$tables['products_options_ex']}.option_id NOT IN ('" . implode("','", $_product_options) . "') GROUP BY {$tables['product_options_values']}.product_option_id", "product_option_id", false, true);
                if (!empty($exceptions)) {
                    $class_counters = cw_query_hash("SELECT {$tables['product_options_values']}.product_option_id, COUNT({$tables['product_options_values']}.option_id) FROM {$tables['product_options']}, {$tables['product_options_values']} WHERE {$tables['product_options_values']}.product_option_id IN ('" . implode("','", array_keys($exceptions)) . "') AND {$tables['product_options_values']}.avail = 1 AND {$tables['product_options']}.product_option_id = {$tables['product_options_values']}.product_option_id AND {$tables['product_options']}.avail = 1 GROUP BY {$tables['product_options_values']}.product_option_id", "product_option_id", false, true);
                    foreach ($exceptions as $cid => $cnt) {
                        if (isset($class_counters[$cid]) && $class_counters[$cid] == $cnt) {
                            $_product_options = array();
                            break;
                        }
                    }
                }
            }
            unset($exceptions, $exception_counters);
        }
        if (!empty($_product_options)) {
            return $def_variant_id;
        }
    }
    # Get class options
    $options = cw_query_hash("SELECT product_option_id, option_id FROM {$tables['product_options_values']} WHERE product_option_id IN ('" . implode("','", array_keys($classes)) . "') AND avail = 1 ORDER BY orderby", "product_option_id", true, true);
    $_flag = false;
    foreach ($classes as $k => $class) {
        $classes[$k]['cnt'] = $_flag ? 0 : -1;
        $_flag = true;
        if (isset($options[$k])) {
            $classes[$k]['options'] = array_values($options[$k]);
        } else {
            unset($classes[$k]);
        }
    }
    unset($options);
    if (empty($classes)) {
        return false;
    }
    # Scan & check classes options array
    $variant_id = false;
    $first_variant_id = false;
    do {
        $product_options = array();
        $is_add = true;
        # Build full 'product_option_id->option_id' hash
        foreach ($classes as $k => $class) {
            if ($is_add) {
                if (count($class['options']) - 1 <= $class['cnt']) {
                    $class['cnt'] = 0;
                } else {
                    $is_add = false;
                    $class['cnt']++;
                }
            }
            $product_options[$k] = $class['options'][$class['cnt']];
            $classes[$k]['cnt'] = $class['cnt'];
        }
        # Check current product options array
        if (cw_check_product_options($product_id, $product_options)) {
            $variant_id = cw_get_variant_id($product_options, $product_id);
            # Save first valid variant id
            if (!$first_variant_id) {
                $first_variant_id = $variant_id;
            }
            # Check variant quantity in stock
            if ($config['General']['disable_outofstock_products'] != 'Y' || cw_query_first_cell("SELECT avail FROM {$tables['products_warehouses_amount']} WHERE variant_id = '{$variant_id}'") > 0) {
                break;
            }
            $variant_id = false;
        }
    } while (!$is_add);
    # Get first valid variant if all valid variants is out-of-stock
    if ($variant_id === false && !empty($first_variant_id)) {
        $variant_id = $first_variant_id;
    }
    return $variant_id;
}
}
if (!empty($product_options) && !empty($products_options_ex)) {
    $options = array();
    foreach ($product_options as $c) {
        if ($c['avail'] != 'Y') {
            continue;
        }
        if ($c['type'] == 'T') {
            $options[$c['product_option_id']] = '';
        } elseif (!empty($c['options'])) {
            foreach ($c['options'] as $oid => $o) {
                if ($o['avail'] == 'Y') {
                    $options[$c['product_option_id']] = $oid;
                    break;
                }
            }
        }
    }
    if (!empty($options) && !cw_check_product_options($product_id, $options)) {
        $smarty->assign('def_options_failure', true);
    }
}
$smarty->assign('product_options', $product_options);
$smarty->assign('products_options_ex', $products_options_ex);
$smarty->assign('product_options_js', $product_options_js);
if ($product_option && empty($product_option['options'])) {
    cw_unset($product_option, 'options');
}
$smarty->assign('product_option', $product_option);
$smarty->assign('product_option_lng', $product_option_lng);
$smarty->assign('submode', $submode);