function cw_rebuild_variants($product_id, $force_rebuild = false, $tick = 1) { global $tables; if (!$force_rebuild) { # Check variant's matrix $options_count = cw_query_first_cell("SELECT COUNT(*) FROM {$tables['product_options']}, {$tables['product_options_values']} WHERE {$tables['product_options']}.product_option_id = {$tables['product_options_values']}.product_option_id AND {$tables['product_options']}.product_id = '{$product_id}' AND {$tables['product_options']}.type = '' AND {$tables['product_options']}.avail = 1 AND {$tables['product_options_values']}.avail = 1"); $variants_count = count(cw_query_column("SELECT COUNT(*) FROM {$tables['product_variant_items']}, {$tables['product_variants']} WHERE {$tables['product_variants']}.product_id = '{$product_id}' AND {$tables['product_variants']}.variant_id = {$tables['product_variant_items']}.variant_id GROUP BY {$tables['product_variant_items']}.option_id")); if ($options_count == $variants_count && $options_count > 0) { return true; } } if ($tick > 0) { cw_display_service_header("lbl_rebuild_variants"); } $ids = cw_query_column("SELECT variant_id FROM {$tables['product_variants']} WHERE product_id = '{$product_id}'"); if (!empty($ids)) { # Save old data $vars = cw_query_hash("SELECT pv.*, pwa.avail FROM {$tables['product_variants']} as pv LEFT JOIN {$tables['products_warehouses_amount']} as pwa ON pv.variant_id = pwa.variant_id WHERE pv.product_id = '{$product_id}'", "variant_id", false); $prices = db_query("select pp.* from {$tables['products_prices']} as pp where pp.product_id = '{$product_id}' AND variant_id != 0"); if ($prices) { while ($v = db_fetch_array($prices)) { if (!isset($vars[$v['variant_id']])) { continue; } $key = $v['quantity'] . "|" . $v['membership_id']; if (!isset($vars[$v['variant_id']]['prices'])) { $vars[$v['variant_id']]['prices'] = array(); } if (!isset($vars[$v['variant_id']]['prices'][$key]) || $vars[$v['variant_id']]['prices'][$key]['price'] > $v['price']) { $vars[$v['variant_id']]['prices'][$key] = $v; } } db_free_result($prices); } unset($prices); $items = cw_query_hash("SELECT {$tables['product_variant_items']}.*, {$tables['product_options_values']}.product_option_id FROM {$tables['product_variant_items']}, {$tables['product_options_values']}, {$tables['product_variants']} WHERE {$tables['product_variant_items']}.option_id = {$tables['product_options_values']}.option_id AND {$tables['product_variant_items']}.variant_id = {$tables['product_variants']}.variant_id AND {$tables['product_variants']}.product_id = '{$product_id}'", array('product_option_id', "option_id"), true, true); # Delete old variants /* $tmp = cw_query_first("SELECT MIN(avail) as avail, MIN(weight) as weight FROM $tables[product_variants] WHERE product_id = '$product_id'"); db_query("UPDATE $tables[products] SET avail = '$tmp[avail]', weight = '$tmp[weight]' WHERE product_id = '$product_id'"); unset($tmp); */ db_query("DELETE FROM {$tables['products_prices']} WHERE product_id = '{$product_id}' AND variant_id != 0"); db_query("DELETE FROM {$tables['product_variant_items']} WHERE variant_id IN ('" . implode("','", $ids) . "')"); db_query("DELETE FROM {$tables['products_warehouses_amount']} WHERE product_id = '{$product_id}' AND variant_id != 0"); } unset($ids); db_query("DELETE FROM {$tables['product_variants']} WHERE product_id = '{$product_id}'"); # Get modifier-classes $classes = cw_query($sql = "SELECT product_option_id FROM {$tables['product_options']} WHERE product_id = '{$product_id}' AND type = '' AND avail = 1 ORDER BY orderby"); if (empty($classes)) { return false; } foreach ($classes as $k => $v) { $classes[$k]['cnt'] = 0; $classes[$k]['options'] = cw_query_column("SELECT option_id FROM {$tables['product_options_values']} WHERE product_option_id = '{$v['product_option_id']}' AND avail = 1 ORDER BY orderby, option_id ASC "); if (!@count($classes[$k]['options']) || !is_array($classes[$k]['options'])) { unset($classes[$k]); } } if (empty($classes)) { return false; } $classes = array_values($classes); $classes[0]['cnt'] = -1; # Build variant's matrix $variants = array(); # Write variants to DB $product = cw_query_first("SELECT {$tables['products']}.eancode, {$tables['products']}.productcode, {$tables['products']}.weight, {$tables['products']}.cost, {$tables['products_prices']}.price FROM {$tables['products']}, {$tables['products_prices']} WHERE {$tables['products_prices']}.variant_id = 0 AND {$tables['products_prices']}.quantity = '1' AND {$tables['products_prices']}.membership_id = 0 AND {$tables['products']}.product_id = '{$product_id}' GROUP BY {$tables['products']}.product_id"); $cnt_row = $cnt = $cnd_ean = 0; do { $is_end = false; $options = array(); $old_variants = array(); foreach ($classes as $k => $c) { $option_id = 0; if (!$is_end) { if ($c['cnt'] >= count($c['options']) - 1) { $c['cnt'] = 0; } else { $c['cnt']++; $is_end = true; } $classes[$k] = $c; } $option_id = $c['options'][$c['cnt']]; if (empty($option_id)) { continue; } $options[] = $option_id; if (isset($items[$c['product_option_id']][$option_id])) { if (empty($old_variants)) { $old_variants = $items[$c['product_option_id']][$option_id]; } else { $old_variants = array_intersect($old_variants, $items[$c['product_option_id']][$option_id]); } } } if (!$is_end || empty($options)) { break; } $_product = $product; # Restore old data $old_variant_id = false; if (is_array($old_variants) && !empty($old_variants)) { $old_variant_id = array_shift($old_variants); if (isset($vars[$old_variant_id])) { $_product = cw_array_merge($_product, $vars[$old_variant_id]); } } unset($old_variants); # Get unique SKU $sku = $_product['productcode']; while (cw_query_first_cell("SELECT COUNT(*) FROM {$tables['product_variants']} WHERE productcode = '{$sku}'") > 0) { $sku = $_product['productcode'] . ++$cnt; } $eancode = $_product['eancode']; while (cw_query_first_cell("SELECT COUNT(*) FROM {$tables['product_variants']} WHERE eancode = '{$eancode}'") > 0) { $eancode = $_product['eancode'] . ++$cnd_ean; } $data = array("product_id" => $product_id, "weight" => $_product['weight'], "cost" => $_product['cost'], "productcode" => $sku, 'eancode' => $eancode); # Check variant_id if (!empty($old_variant_id) && cw_query_first_cell("SELECT COUNT(*) FROM {$tables['product_variants']} WHERE variant_id = '{$old_variant_id}'") == 0) { $data['variant_id'] = $old_variant_id; } # Insert variant info $variant_id = cw_array2insert('product_variants', $data); if (empty($variant_id)) { continue; } if ($_product['avail'] == NULL) { $_product['avail'] = 0; } if (cw_query_first_cell("SELECT COUNT(*) FROM {$tables['products_warehouses_amount']} WHERE variant_id = '{$variant_id}'") == 0) { cw_array2insert('products_warehouses_amount', array('product_id' => $product_id, 'avail' => $_product['avail'], 'avail_ordered' => 0, 'avail_sold' => 0, 'avail_reserved' => '0', 'variant_id' => $variant_id, 'warehouse_customer_id' => '0'), false); } # Write products_prices if (empty($_product['prices'])) { cw_price_lists_replace_price($product_id, $_product['price'], $variant_id, true, true); } else { foreach ($_product['prices'] as $p) { cw_price_lists_replace_price($product_id, $p['price'], $variant_id, true, $p['is_manual']); } } # Restore image if (!empty($old_variant_id) && $variant_id != $old_variant_id) { cw_image_delete($variant_id, "W"); db_query("UPDATE {$tables['products_images_var']} SET id = '{$variant_id}' WHERE id = '{$old_variant_id}'"); } # Write matrix foreach ($options as $i) { db_query("INSERT INTO {$tables['product_variant_items']} (variant_id, option_id) VALUES ('{$variant_id}','{$i}')"); } if ($tick > 0 && $cnt_row++ % $tick == 0) { cw_flush(". "); } } while ($is_end); # Clean old variants images $images = cw_query_column("SELECT {$tables['products_images_var']}.id FROM {$tables['product_variants']} LEFT JOIN {$tables['products_images_var']} ON {$tables['product_variants']}.variant_id = {$tables['products_images_var']}.id WHERE {$tables['products_images_var']}.id IS NULL"); if (!empty($images)) { cw_image_delete($images, "W"); } return true; }
cw_array2update('product_variants', $query_data, "variant_id = '{$k}'"); cw_price_lists_replace_price($product_id, $v['price'], $k, false, $v['is_manual_price']); $v['variant_id'] = $k; $v['product_id'] = $product_id; $v['warehouse_customer_id'] = 0; cw_array2insert('products_warehouses_amount', $v, 1, array('product_id', 'avail', 'avail_ordered', 'avail_sold', 'avail_reserved', 'variant_id', 'warehouse_customer_id')); cw_call('cw_warehouse_recalculate', array($product_id)); if ($ge_id && !$fields['variants'][$k]) { cw_unset($query_data, 'productcode'); while ($pid = cw_group_edit_each($ge_id, 1, $product_id)) { $vid = cw_variants_get_same($k, $pid); if (empty($vid)) { continue; } cw_array2update('product_variants', $query_data, "variant_id = '{$vid}'"); cw_price_lists_replace_price($pid, $v['price'], $vid, false, $v['is_manual_price']); if ($def_variant == $k) { cw_array2update('product_variants', array('def' => ''), "product_id = '{$pid}'"); cw_array2update('product_variants', array('def' => 'Y'), "product_id = '{$pid}' and variant_id='{$vid}'"); } } } } } if (!empty($def_variant)) { cw_array2update('product_variants', array('def' => ''), "product_id = '{$product_id}'"); cw_array2update('product_variants', array("def" => 'Y'), "product_id = '{$product_id}' and variant_id='{$def_variant}'"); } if (is_array($vids) && cw_image_check_posted($file_upload_data['products_images_var'])) { $vids = array_keys($vids); $vid = array_shift($vids);
if ($is_new_product) { cw_add_top_message(cw_get_langvar_by_name('msg_adm_product_add')); } else { cw_add_top_message(cw_get_langvar_by_name("msg_adm_product_upd")); } if (!$is_variant) { //cw_price_lists_replace_price($product_id, $product_data['price'], 0, $is_new_product, $product_data['is_manual_price']); if (isset($product_data['price']) && isset($product_data['list_price'])) { cw_product_update_price($product_id, 0, 0, 0, 1, 1, $product_data['price'], $product_data['list_price']); } } if ($fields['price'] && !$is_variant) { if ($ge_id) { while ($pid = cw_group_edit_each($ge_id, 1, $product_id)) { if ($pid != $product_id) { cw_price_lists_replace_price($pid, $product_data['price'], 0); } } } } cw_func_call('cw_items_attribute_classes_save', array('item_id' => $product_id, 'attribute_class_ids' => $product_data['attribute_class_ids'], 'item_type' => 'P')); # kornev, it have to be product_data here - because we change the attributes in the error_check function cw_call('cw_attributes_save', array('item_id' => $product_id, 'item_type' => 'P', 'attributes' => $product_data['attributes'], 'language' => $edited_language, array('update_posted_only' => true, 'is_default' => false))); cw_attributes_group_update($ge_id, $product_id, 'P', $fields); cw_func_call('cw_product_build_flat', array('product_id' => $product_id)); cw_group_edit_end($product_id); cw_product_update_system_info($product_id, array('supplier_customer_id' => $product_data['supplier'])); cw_group_edit_copy_system_info($product_id, array('supplier_customer_id' => $product_data['supplier'])); cw_warehouse_recalculate($product_id); cw_product_filter_recalculate_price_ranges(); // tags