/**
  * @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;
 }
Example #2
0
 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);
 }