/** * @param int $id * @param array $data * @param bool $correct * @param shopProduct $product * @return array */ protected function updateSku($id = 0, $data, $correct = true, shopProduct $product = null) { /** * @var shopProductStocksModel $stocks_model */ static $stocks_model; /** * @var bool $multi_stock */ static $multi_stock = null; /** * @var shopFeatureModel $feature_model */ static $feature_model; /** * @var shopProductFeaturesModel $product_features_model */ static $product_features_model; if (isset($data['price'])) { $data['price'] = $this->castValue('double', $data['price']); } if (isset($data['purchase_price'])) { $data['purchase_price'] = $this->castValue('double', $data['purchase_price']); } if (isset($data['compare_price'])) { $data['compare_price'] = $this->castValue('double', $data['compare_price']); } if ($id > 0) { if ($product && (!isset($data['virtual']) || !empty($data['virtual']))) { #check changes for virtual SKU $virtual_sku_defaults = array('price' => $product->base_price_selectable, 'purchase_price' => $product->purchase_price_selectable, 'compare_price' => $product->compare_price_selectable, 'count' => 0); $virtual = null; foreach ($virtual_sku_defaults as $field => $default) { if (isset($data[$field])) { $value = $data[$field]; if (is_array($value)) { $value = max($value); } if ($value != $default) { if ($virtual === null) { $virtual = isset($product->skus[$id]) && !empty($product->skus[$id]['virtual']); } if ($virtual) { $data['virtual'] = 0; $virtual = false; } if (!$virtual) { break; } } } } } if (empty($data['eproduct']) && !empty($data['file_name'])) { $file_path = shopProduct::getPath($data['product_id'], "sku_file/{$id}." . pathinfo($data['file_name'], PATHINFO_EXTENSION)); waFiles::delete($file_path); $data['file_name'] = ''; $data['file_description'] = ''; } elseif (isset($data['file_name'])) { unset($data['file_name']); } $this->updateById($id, $data); } else { if (!isset($data['sku'])) { $data['sku'] = ''; } $id = $this->insert($data); } $data['id'] = $id; $sku_count = false; // if stocking for this sku if (isset($data['stock']) && count($data['stock'])) { if ($multi_stock === null) { $stock_model = new shopStockModel(); $stocks = $stock_model->getAll($stock_model->getTableId()); $multi_stock = $stocks ? array_keys($stocks) : false; } // not multistocking if (!$multi_stock || isset($data['stock'][0])) { $sku_count = self::castStock($data['stock'][0]); unset($data['stock']); $this->logCount($data['product_id'], $id, $sku_count); // multistocking } else { $sku_count = 0; $missed = array_combine($multi_stock, $multi_stock); if (!$stocks_model) { $stocks_model = new shopProductStocksModel(); } // need for track transition from aggregating mode to multistocking mode $has_any_stocks = $stocks_model->hasAnyStocks($id); if (!$has_any_stocks) { $this->writeOffCount($data['product_id'], $id); } foreach ($data['stock'] as $stock_id => $count) { if ($stock_id > 0 && isset($missed[$stock_id])) { unset($missed[$stock_id]); $field = array('sku_id' => $id, 'stock_id' => $stock_id, 'product_id' => $data['product_id']); $count = self::castStock($count); $stock = array('count' => $count); if ($count === null) { $sku_count = null; } else { // Once turned into NULL value is not changed if ($sku_count !== null) { $sku_count += $count; } } // there is taking into account stocks log inside this method $stocks_model->set(array_merge($field, $stock)); $data['stock'][$stock_id] = $count; } } //get stock_count for missed stocks if ($sku_count !== null && !empty($missed)) { $search = array('stock_id' => $missed, 'sku_id' => $id, 'product_id' => $data['product_id']); foreach ($stocks_model->getByField($search, 'stock_id') as $stock_id => $row) { $count = $row['count']; $data['stock'][$stock_id] = $count; if ($count === null) { $sku_count = null; } else { // Once turned into NULL value is not changed if ($sku_count !== null) { $sku_count += $count; } } } } } } if ($sku_count !== false) { $data['count'] = $sku_count; $this->updateById($id, array('count' => $sku_count)); } if (isset($data['features'])) { if (!$feature_model) { $feature_model = new shopFeatureModel(); } if (!$product_features_model) { $product_features_model = new shopProductFeaturesModel(); } $features = $data['features']; $data['features'] = array(); $skip_values = array('', false, null); foreach ($features as $code => $value) { if ($feature = $feature_model->getByField('code', $code)) { $model = shopFeatureModel::getValuesModel($feature['type']); $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $feature['id']); $product_features_model->deleteByField($field); if (is_array($value)) { if (!empty($value['id'])) { $field['feature_value_id'] = $value['id']; } elseif (isset($value['value']) && !in_array($value['value'], $skip_values, true)) { $field['feature_value_id'] = $model->getId($feature['id'], $code == 'weight' ? $value : $value['value'], $feature['type']); } } elseif (!in_array($value, $skip_values, true)) { $field['feature_value_id'] = $model->getId($feature['id'], $value, $feature['type']); $value = array('value' => $value, 'id' => $field['feature_value_id']); } if (!empty($field['feature_value_id'])) { $product_features_model->insert($field); $data['features'][$code] = $value; } } elseif (is_numeric($code) && is_numeric($value)) { if ($feature = $feature_model->getById($code)) { $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $code); $product_features_model->deleteByField($field); if (empty($value)) { continue; } $field['feature_value_id'] = $value; $product_features_model->insert($field); $data['features'][$feature['code']] = $feature_model->getValuesModel($feature['type'])->getFeatureValue($value); } } } } if ($correct) { $product_model = new shopProductModel(); $product_model->correct($data['product_id']); } return $data; }
public function updateStockCount($data) { if (!$data) { return; } $product_skus_model = new shopProductSkusModel(); $product_stocks_model = new shopProductStocksModel(); $stocks_log_model = new shopProductStocksLogModel(); $sku_ids = array_map('intval', array_keys($data)); if (!$sku_ids) { return; } $skus = $product_skus_model->select('id,product_id')->where("id IN(" . implode(',', $sku_ids) . ")")->fetchAll('id'); $sku_ids = array_keys($skus); if (!$sku_ids) { return; } $product_ids = array(); foreach ($data as $sku_id => $sku_stock) { $sku_id = (int) $sku_id; if (!isset($skus[$sku_id]['product_id'])) { continue; } $product_id = $skus[$sku_id]['product_id']; foreach ($sku_stock as $stock_id => $count) { $stock_id = (int) $stock_id; if ($stock_id) { $item = $product_stocks_model->getByField(array('sku_id' => $sku_id, 'stock_id' => $stock_id)); if (!$item) { continue; } $product_stocks_model->set(array('sku_id' => $sku_id, 'product_id' => $product_id, 'stock_id' => $stock_id, 'count' => $item['count'] + $count)); } else { $old_count = $product_skus_model->select('count')->where('id=i:sku_id', array('sku_id' => $sku_id))->fetchField(); if ($old_count !== null) { $log_data = array('product_id' => $product_id, 'sku_id' => $sku_id, 'before_count' => $old_count, 'after_count' => $old_count + $count, 'diff_count' => $count); $stocks_log_model->insert($log_data); } $this->exec("UPDATE `shop_product_skus` SET count = count + ({$count})\n WHERE id = {$sku_id}"); } if (isset($skus[$sku_id]['product_id'])) { $product_ids[] = $product_id; } } } if (!$product_ids) { return; } // correct sku counters $sql = "\n UPDATE `shop_product_skus` sk JOIN (\n SELECT sk.id, SUM(st.count) AS count FROM `shop_product_skus` sk\n JOIN `shop_product_stocks` st ON sk.id = st.sku_id\n WHERE sk.id IN(" . implode(',', $sku_ids) . ")\n GROUP BY sk.id\n ORDER BY sk.id\n ) r ON sk.id = r.id\n SET sk.count = r.count\n WHERE sk.count IS NOT NULL"; $this->exec($sql); // correct product counters $sql = "\n UPDATE `shop_product` p JOIN (\n SELECT p.id, SUM(sk.count) AS count FROM `shop_product` p\n JOIN `shop_product_skus` sk ON p.id = sk.product_id\n WHERE p.id IN(" . implode(',', array_unique($product_ids)) . ") AND sk.available = 1\n GROUP BY p.id\n ORDER BY p.id\n ) r ON p.id = r.id\n SET p.count = r.count\n WHERE p.count IS NOT NULL"; $this->exec($sql); }