function fn_ult_get_product_data_post(&$product_data, &$auth)
{
    $product_id = $product_data['product_id'];
    $product_data['shared_product'] = fn_ult_is_shared_product($product_id);
    if ($product_data['shared_product'] == 'Y' && Registry::get('runtime.company_id')) {
        $company_product_data = db_get_row("SELECT * FROM ?:ult_product_descriptions WHERE product_id = ?i AND company_id = ?i AND lang_code = ?s", $product_id, Registry::get('runtime.company_id'), DESCR_SL);
        if (!empty($company_product_data)) {
            unset($company_product_data['company_id']);
            $product_data = array_merge($product_data, $company_product_data);
        }
        unset($product_data['prices']);
        fn_get_product_prices($product_id, $product_data, $auth, Registry::get('runtime.company_id'));
        if (empty($product_data['main_category'])) {
            $product_categories = array_keys($product_data['category_ids']);
            $product_data['main_category'] = $product_categories[0];
        }
    }
}
/**
 * Gets full product data by its id
 *
 * @param int $product_id Product ID
 * @param mixed $auth Array with authorization data
 * @param string $lang_code 2 letters language code
 * @param string $field_list List of fields for retrieving
 * @param boolean $get_add_pairs Get additional images
 * @param boolean $get_main_pair Get main images
 * @param boolean $get_taxes Get taxes
 * @param boolean $get_qty_discounts Get quantity discounts
 * @param boolean $preview Is product previewed by admin
 * @param boolean $features Get product features
 * @param boolean $skip_company_condition Skip company condition and retrieve product data for displayin on other store page. (Works only in ULT)
 * @return mixed Array with product data
 */
function fn_get_product_data($product_id, &$auth, $lang_code = CART_LANGUAGE, $field_list = '', $get_add_pairs = true, $get_main_pair = true, $get_taxes = true, $get_qty_discounts = false, $preview = false, $features = true, $skip_company_condition = false, $feature_variants_selected_only = false)
{
    $product_id = intval($product_id);
    /**
     * Change parameters for getting product data
     *
     * @param int     $product_id             Product ID
     * @param mixed   $auth                   Array with authorization data
     * @param string  $lang_code              2 letters language code
     * @param string  $field_list             List of fields for retrieving
     * @param boolean $get_add_pairs          Get additional images
     * @param boolean $get_main_pair          Get main images
     * @param boolean $get_taxes              Get taxes
     * @param boolean $get_qty_discounts      Get quantity discounts
     * @param boolean $preview                Is product previewed by admin
     * @param boolean $features               Get product features
     * @param boolean $skip_company_condition Skip company condition and retrieve product data for displaying on other store page. (Works only in ULT)
     */
    fn_set_hook('get_product_data_pre', $product_id, $auth, $lang_code, $field_list, $get_add_pairs, $get_main_pair, $get_taxes, $get_qty_discounts, $preview, $features, $skip_company_condition);
    if (!empty($product_id)) {
        if (empty($field_list)) {
            $descriptions_list = "?:product_descriptions.*";
            $field_list = "?:products.*, {$descriptions_list}";
        }
        $field_list .= ", MIN(IF(?:product_prices.percentage_discount = 0, ?:product_prices.price, ?:product_prices.price - (?:product_prices.price * ?:product_prices.percentage_discount)/100)) as price";
        $field_list .= ", GROUP_CONCAT(IF(?:products_categories.link_type = 'M', CONCAT(?:products_categories.category_id, 'M'), ?:products_categories.category_id)) as category_ids";
        $field_list .= ", popularity.total as popularity";
        $price_usergroup = db_quote(" AND ?:product_prices.usergroup_id IN (?n)", AREA == 'A' && !defined('ORDER_MANAGEMENT') ? USERGROUP_ALL : array_merge(array(USERGROUP_ALL), $auth['usergroup_ids']));
        $_p_statuses = array('A', 'H');
        $_c_statuses = array('A', 'H');
        $condition = $join = $avail_cond = '';
        if (!fn_allowed_for('ULTIMATE')) {
            $avail_cond .= fn_get_company_condition('?:products.company_id');
        } else {
            if (!$skip_company_condition && Registry::get('runtime.company_id')) {
                if (AREA == 'C') {
                    $avail_cond .= fn_get_company_condition('?:categories.company_id');
                } else {
                    $avail_cond .= ' AND (' . fn_get_company_condition('?:categories.company_id', false) . ' OR ' . fn_get_company_condition('?:products.company_id', false) . ')';
                }
            }
            if (Registry::get('runtime.company_id')) {
                $field_list .= ', IF(' . 'shared_prices.product_id IS NOT NULL,' . 'MIN(IF(shared_prices.percentage_discount = 0, shared_prices.price, shared_prices.price - (shared_prices.price * shared_prices.percentage_discount)/100)),' . 'MIN(IF(?:product_prices.percentage_discount = 0, ?:product_prices.price, ?:product_prices.price - (?:product_prices.price * ?:product_prices.percentage_discount)/100))' . ') as price';
                $shared_prices_usergroup = db_quote(" AND shared_prices.usergroup_id IN (?n)", AREA == 'A' && !defined('ORDER_MANAGEMENT') ? USERGROUP_ALL : array_merge(array(USERGROUP_ALL), $auth['usergroup_ids']));
                $join .= db_quote(' LEFT JOIN ?:ult_product_prices shared_prices ON shared_prices.product_id = ?:products.product_id AND shared_prices.company_id = ?i AND shared_prices.lower_limit = 1 ?p', Registry::get('runtime.company_id'), $shared_prices_usergroup);
            }
        }
        $avail_cond .= AREA == 'C' && empty($preview) ? ' AND (' . fn_find_array_in_set($auth['usergroup_ids'], "?:categories.usergroup_ids", true) . ')' : '';
        $avail_cond .= AREA == 'C' && empty($preview) ? ' AND (' . fn_find_array_in_set($auth['usergroup_ids'], "?:products.usergroup_ids", true) . ')' : '';
        $avail_cond .= AREA == 'C' && empty($preview) ? db_quote(' AND ?:categories.status IN (?a) AND ?:products.status IN (?a)', $_c_statuses, $_p_statuses) : '';
        $avail_cond .= fn_get_localizations_condition('?:products.localization');
        $avail_cond .= fn_get_localizations_condition('?:categories.localization');
        if (AREA == 'C' && !$preview) {
            $field_list .= ', companies.company as company_name';
            $condition .= " AND (companies.status = 'A' OR ?:products.company_id = 0) ";
            $join .= " LEFT JOIN ?:companies as companies ON companies.company_id = ?:products.company_id";
        }
        $join .= " INNER JOIN ?:products_categories ON ?:products_categories.product_id = ?:products.product_id INNER JOIN ?:categories ON ?:categories.category_id = ?:products_categories.category_id {$avail_cond}";
        $join .= " LEFT JOIN ?:product_popularity as popularity ON popularity.product_id = ?:products.product_id";
        /**
         * Change SQL parameters for product data select
         *
         * @param int $product_id Product ID
         * @param string $field_list List of fields for retrieving
         * @param string $join String with the complete JOIN information (JOIN type, tables and fields) for an SQL-query
         * @param mixed $auth Array with authorization data
         * @param string $lang_code Two-letter language code (e.g. 'en', 'ru', etc.)
         * @param string $condition Condition for selecting product data
         */
        fn_set_hook('get_product_data', $product_id, $field_list, $join, $auth, $lang_code, $condition);
        $product_data = db_get_row("SELECT {$field_list} FROM ?:products LEFT JOIN ?:product_prices ON ?:product_prices.product_id = ?:products.product_id AND ?:product_prices.lower_limit = 1 ?p LEFT JOIN ?:product_descriptions ON ?:product_descriptions.product_id = ?:products.product_id AND ?:product_descriptions.lang_code = ?s ?p WHERE ?:products.product_id = ?i ?p GROUP BY ?:products.product_id", $price_usergroup, $lang_code, $join, $product_id, $condition);
        if (empty($product_data)) {
            return false;
        }
        $product_data['base_price'] = $product_data['price'];
        // save base price (without discounts, etc...)
        list($product_data['category_ids'], $product_data['main_category']) = fn_convert_categories($product_data['category_ids']);
        // Generate meta description automatically
        if (!empty($product_data['full_description']) && empty($product_data['meta_description']) && defined('AUTO_META_DESCRIPTION') && AREA != 'A') {
            $product_data['meta_description'] = fn_generate_meta_description($product_data['full_description']);
        }
        // If tracking with options is enabled, check if at least one combination has positive amount
        if (!empty($product_data['tracking']) && $product_data['tracking'] == 'O') {
            $product_data['amount'] = db_get_field("SELECT MAX(amount) FROM ?:product_options_inventory WHERE product_id = ?i", $product_id);
        }
        //var_dump($product_data['amount']);
        $product_data['product_id'] = $product_id;
        // Get product shipping settings
        if (!empty($product_data['shipping_params'])) {
            $product_data = array_merge(unserialize($product_data['shipping_params']), $product_data);
        }
        // Get main image pair
        if ($get_main_pair == true) {
            $product_data['main_pair'] = fn_get_image_pairs($product_id, 'product', 'M', true, true, $lang_code);
        }
        // Get additional image pairs
        if ($get_add_pairs == true) {
            $product_data['image_pairs'] = fn_get_image_pairs($product_id, 'product', 'A', true, true, $lang_code);
        }
        // Get taxes
        $product_data['tax_ids'] = !empty($product_data['tax_ids']) ? explode(',', $product_data['tax_ids']) : array();
        // Get qty discounts
        if ($get_qty_discounts == true) {
            fn_get_product_prices($product_id, $product_data, $auth);
        }
        if ($features) {
            // Get product features
            $path = !empty($product_data['main_category']) ? explode('/', db_get_field("SELECT id_path FROM ?:categories WHERE category_id = ?i", $product_data['main_category'])) : '';
            if (fn_allowed_for('ULTIMATE')) {
                $product_data['shared_product'] = fn_ult_is_shared_product($product_id);
                if ($product_data['shared_product'] == 'Y') {
                    //we should get features for all categories, not only main
                    $path = !empty($product_data['category_ids']) ? explode('/', implode('/', db_get_fields("SELECT id_path FROM ?:categories WHERE category_id IN (?a)", $product_data['category_ids']))) : '';
                }
            }
            $_params = array('category_ids' => $path, 'product_id' => $product_id, 'product_company_id' => !empty($product_data['company_id']) ? $product_data['company_id'] : 0, 'statuses' => AREA == 'C' ? array('A') : array('A', 'H'), 'variants' => true, 'plain' => false, 'display_on' => AREA == 'A' ? '' : 'product', 'existent_only' => AREA != 'A', 'variants_selected_only' => $feature_variants_selected_only);
            list($product_data['product_features']) = fn_get_product_features($_params, 0, $lang_code);
            $product_data['header_features'] = fn_get_product_features_list($product_data, 'H');
        } else {
            $product_data['product_features'] = fn_get_product_features_list($product_data, 'A');
        }
    } else {
        return false;
    }
    $product_data['detailed_params']['info_type'] = 'D';
    /**
     * Particularize product data
     *
     * @param array   $product_data List with product fields
     * @param mixed   $auth         Array with authorization data
     * @param boolean $preview      Is product previewed by admin
     * @param string  $lang_code    2-letter language code (e.g. 'en', 'ru', etc.)
     */
    fn_set_hook('get_product_data_post', $product_data, $auth, $preview, $lang_code);
    return !empty($product_data) ? $product_data : false;
}