public function getProductSkus()
 {
     static $data = null;
     if ($data === null) {
         $product_skus_model = new shopProductSkusModel();
         $data = $product_skus_model->getByField('product_id', $this->product_id, 'id');
     }
     return $data;
 }
 public function execute()
 {
     $sku_id = $this->get('id', true);
     $skus_model = new shopProductSkusModel();
     $sku = $skus_model->getSku($sku_id);
     if ($sku) {
         $this->response = $sku;
     } else {
         throw new waAPIException('invalid_param', 'SKU not found', 404);
     }
 }
Example #3
0
 /**
  * @param array $product_ids
  * @return array
  */
 public function skus($product_ids)
 {
     if (!$product_ids) {
         return array();
     }
     $skus_model = new shopProductSkusModel();
     $rows = $skus_model->select('*')->where('product_id IN (i:ids)', array('ids' => $product_ids))->order('sort')->fetchAll();
     $skus = array();
     foreach ($rows as $row) {
         $skus[$row['product_id']][] = $row;
     }
     return $skus;
 }
 public function execute()
 {
     $sku_id = waRequest::post('sku_id', 0, waRequest::TYPE_INT);
     $src_stock = waRequest::post('src_stock', 0, waRequest::TYPE_INT);
     $dst_stock = waRequest::post('dst_stock', 0, waRequest::TYPE_INT);
     $count = waRequest::post('count', 0, waRequest::TYPE_INT);
     if ($src_stock == $dst_stock || !$src_stock || !$dst_stock || !$count) {
         $this->errors[] = _w("Error when transfer");
         return;
     }
     $product_skus_model = new shopProductSkusModel();
     shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_STOCK);
     if (!$product_skus_model->transfer($sku_id, $count, $src_stock, $dst_stock)) {
         $this->errors[] = _w("Error when transfer");
         return;
     }
     shopProductStocksLogModel::clearContext();
     $sku = $product_skus_model->getById($sku_id);
     /*
     $product_stocks_model = new shopProductStocksModel();
     $data = $product_stocks_model->getStocksOfProduct($sku['product_id'], array($src_stock, $dst_stock), 'sku.count DESC');
     
     foreach ($data as &$stock) {
         foreach ($stock as &$stock_sku) {
             $stock_sku['icon'] = shopHelper::getStockCountIcon($stock_sku['count']);
         }
     }
     unset($stock, $stock_sku);
     */
     $stock_skus = array();
     $product_model = new shopProductModel();
     $data = $product_model->getProductStocksByProductId($sku['product_id']);
     if (isset($data[$sku['product_id']])) {
         $data = $data[$sku['product_id']];
         if (isset($data['stocks'][$src_stock])) {
             $stock_skus[$src_stock] = array();
             foreach ($data['stocks'][$src_stock] as $stock_sku) {
                 $stock_sku['icon'] = shopHelper::getStockCountIcon($stock_sku['count'], $src_stock);
                 $stock_skus[$src_stock][] = $stock_sku;
             }
         }
         if (isset($data['stocks'][$dst_stock])) {
             $stock_skus[$dst_stock] = array();
             foreach ($data['stocks'][$dst_stock] as $stock_sku) {
                 $stock_sku['icon'] = shopHelper::getStockCountIcon($stock_sku['count'], $dst_stock);
                 $stock_skus[$dst_stock][] = $stock_sku;
             }
         }
     }
     $this->response = array('stocks' => $stock_skus ? $stock_skus : new stdClass(), 'product_id' => $sku['product_id']);
 }
 public function execute()
 {
     $product_id = $this->get('product_id', true);
     $this->checkProductRights($product_id);
     $data = waRequest::post();
     $skus_model = new shopProductSkusModel();
     if ($sku_id = $skus_model->add($data)) {
         $_GET['id'] = $sku_id;
         $method = new shopProductSkusGetInfoMethod();
         $this->response = $method->getResponse(true);
     } else {
         throw new waAPIException('server_error', 500);
     }
 }
 protected function save(waRequestFile $file)
 {
     if (!$this->model) {
         $this->model = new shopProductSkusModel();
     }
     $field = array('id' => waRequest::post('sku_id', null, waRequest::TYPE_INT), 'product_id' => waRequest::post('product_id', null, waRequest::TYPE_INT));
     $data = array('file_size' => $file->size, 'file_name' => $file->name);
     $this->model->updateByField($field, $data);
     $file_path = shopProduct::getPath($field['product_id'], "sku_file/{$field['id']}." . pathinfo($file->name, PATHINFO_EXTENSION));
     if (file_exists($file_path) && !is_writable($file_path) || !file_exists($file_path) && !waFiles::create($file_path)) {
         $data = array('file_size' => 0, 'file_name' => '');
         $this->model->updateByField($field, $data);
         throw new waException(sprintf("The insufficient file write permissions for the %s folder.", substr($file_path, strlen($this->getConfig()->getRootPath()))));
     }
     $file->moveTo($file_path);
     return array('name' => $file->name, 'size' => waFiles::formatSize($file->size));
 }
 public function execute()
 {
     $sku_id = $this->get('id', true);
     $skus_model = new shopProductSkusModel();
     $sku = $skus_model->getById($sku_id);
     if (!$sku) {
         throw new waAPIException('invalid_param', 'SKU not found', 404);
     }
     $this->checkProductRights($sku['product_id']);
     $data = waRequest::post();
     if ($skus_model->update($sku_id, $data)) {
         $method = new shopProductSkusGetInfoMethod();
         $this->response = $method->getResponse(true);
     } else {
         throw new waAPIException('server_error', 500);
     }
 }
 public function execute()
 {
     $product_id = $this->get('product_id');
     $product_model = new shopProductModel();
     $product = $product_model->getById($product_id);
     if (!$product) {
         throw new waAPIException('invalid_param', 'Product not found', 404);
     }
     $skus_model = new shopProductSkusModel();
     $skus = $skus_model->getData(new shopProduct($product));
     foreach ($skus as &$sku) {
         $sku['currency'] = $product['currency'];
         $sku['primary_price'] = (double) $sku['primary_price'];
     }
     unset($sku);
     $this->response = array_values($skus);
     $this->response['_element'] = 'sku';
 }
 public function execute()
 {
     $sku_id = $this->post('id', true);
     $skus_model = new shopProductSkusModel();
     // check if sku exists
     $sku = $skus_model->getById($sku_id);
     if (!$sku) {
         throw new waAPIException('invalid_param', 'SKU not found', 404);
     }
     // check access rights
     $this->checkProductRights($sku['product_id']);
     // delete sku
     if ($skus_model->delete($sku_id)) {
         $this->response = true;
     } else {
         throw new waAPIException('server_error', 500);
     }
 }
 public function execute()
 {
     $sku_id = waRequest::post('sku_id', 0, waRequest::TYPE_INT);
     $product_id = waRequest::post('product_id', 0, waRequest::TYPE_INT);
     $after_id = waRequest::post('after_id', 0, waRequest::TYPE_INT);
     if (!$sku_id) {
         $this->setError(_w("Error when delete: unknown sku"));
     } elseif (!$product_id) {
         $this->setError(_w("Error when delete: unknown product"));
     } else {
         try {
             $product_skus_model = new shopProductSkusModel();
             $product_skus_model->move($sku_id, $after_id, $product_id);
         } catch (waException $e) {
             $this->setError($e->getMessage());
         }
     }
 }
 public static function getMapFields($flat = false, $extra_fields = false)
 {
     $fields = array('product' => array('name' => _w('Product name'), 'currency' => _w('Currency'), 'summary' => _w('Summary'), 'description' => _w('Description'), 'badge' => _w('Badge'), 'status' => _w('Status'), 'type_name' => _w('Product type'), 'tags' => _w('Tags'), 'tax_name' => _w('Taxable'), 'meta_title' => _w('Title'), 'meta_keywords' => _w('META Keyword'), 'meta_description' => _w('META Description'), 'url' => _w('Storefront link'), 'images' => _w('Product images')), 'sku' => array('skus:-1:name' => _w('SKU name'), 'skus:-1:sku' => _w('SKU code'), 'skus:-1:price' => _w('Price'), 'skus:-1:available' => _w('Available for purchase'), 'skus:-1:compare_price' => _w('Compare at price'), 'skus:-1:purchase_price' => _w('Purchase price'), 'skus:-1:stock:0' => _w('In stock')));
     if ($extra_fields) {
         $product_model = new shopProductModel();
         $sku_model = new shopProductSkusModel();
         $meta_fields = array('product' => $product_model->getMetadata(), 'sku' => $sku_model->getMetadata());
         $black_list = array('id', "contact_id", "create_datetime", "edit_datetime", "type_id", "image_id", "tax_id", "cross_selling", "upselling", "total_sales", "sku_type", "sku_count", 'sku_id', 'ext', 'price', 'compare_price', 'min_price', 'max_price', 'count', 'rating_count', 'category_id', 'base_price_selectable', 'rating');
         $white_list = array('id_1c' => '1C');
         foreach ($meta_fields['product'] as $field => $info) {
             if (!in_array($field, $black_list)) {
                 $name = ifset($white_list[$field], $field);
                 if (!empty($meta_fields['sku'][$field])) {
                     if (!isset($fields['sku']['skus:-1:' . $field])) {
                         $fields['sku']['skus:-1:' . $field] = $name;
                     }
                 } else {
                     if (!isset($fields['product'][$field])) {
                         $fields['product'][$field] = $name;
                     }
                 }
             }
         }
     }
     $stock_model = new shopStockModel();
     if ($stocks = $stock_model->getAll('id')) {
         foreach ($stocks as $stock_id => $stock) {
             $fields['sku']['skus:-1:stock:' . $stock_id] = _w('In stock') . ' @' . $stock['name'];
         }
     }
     if ($flat) {
         $fields_ = $fields;
         $fields = array();
         $flat_order = array('product:name', 'sku:skus:-1:name', 'sku:skus:-1:sku', 'product:currency');
         foreach ($flat_order as $field) {
             list($type, $field) = explode(':', $field, 2);
             $fields[$field] = $fields_[$type][$field];
             unset($fields_[$type][$field]);
         }
         $fields += $fields_['sku'];
         $fields += $fields_['product'];
     }
     return $fields;
 }
 public function orderCalculateDiscount($params)
 {
     if ($this->getSettings('status')) {
         if ($discountcard_number = wa()->getStorage()->get('shop/discountcard')) {
             $model = new shopDiscountcardsPluginModel();
             if ($this->getSettings('binding_customer')) {
                 if (wa()->getStorage()->get('shop/discountcard/customer_id')) {
                     $contact_id = wa()->getStorage()->get('shop/discountcard/customer_id');
                 } else {
                     $contact_id = wa()->getUser()->getId();
                 }
                 if ($contact_id) {
                     $discountcard = $model->getByField(array('contact_id' => $contact_id, 'discountcard' => $discountcard_number));
                     if (empty($discountcard)) {
                         $discountcard = $model->getByField(array('contact_id' => 0, 'discountcard' => $discountcard_number));
                     }
                 } else {
                     $discountcard = $model->getByField(array('contact_id' => 0, 'discountcard' => $discountcard_number));
                 }
             } else {
                 $discountcard = $model->getByField('discountcard', $discountcard_number);
             }
             if ($discountcard) {
                 if ($discountcard['discount']) {
                     $discount = array();
                     $def_currency = wa('shop')->getConfig()->getCurrency(true);
                     foreach ($params['order']['items'] as $item_id => $item) {
                         if ($item['type'] == 'product') {
                             $skus_model = new shopProductSkusModel();
                             $sku = $skus_model->getSku($item['sku_id']);
                             if (!($this->getSettings('ignore_compare_price') && $sku['compare_price'] > 0)) {
                                 $discount['items'][$item_id] = array('discount' => shop_currency($item['price'] * $discountcard['discount'] / 100.0, $item['currency'], $params['order']['currency'], false) * $item['quantity'], 'description' => "Скидка по дисконтной карте {$discountcard['discount']}%");
                             }
                         }
                     }
                     return $discount;
                 }
             } else {
                 wa()->getStorage()->set('shop/discountcard', '');
                 wa()->getStorage()->set('shop/discountcard/customer_id', '');
             }
         }
     }
 }
 public function execute()
 {
     $sku_id = waRequest::post('sku_id', 0, waRequest::TYPE_INT);
     if (!$sku_id) {
         $this->setError(_w("Error when delete: unknown sku"));
     }
     $product_id = waRequest::post('product_id', 0, waRequest::TYPE_INT);
     if (!$product_id) {
         $this->setError(_w("Error when delete: unknown product"));
     }
     $product_skus_model = new shopProductSkusModel();
     if (!$product_skus_model->delete($sku_id)) {
         $this->setError(_w("Error when delete"));
     }
     $product_model = new shopProductModel();
     $product = $product_model->getById($product_id);
     if (!$product) {
         $this->setError(_w("Error when delete"));
     }
     $this->response = $product;
 }
 public function execute()
 {
     $cart = new shopCart();
     $item_id = waRequest::post('id');
     $cart_items_model = new shopCartItemsModel();
     $item = $cart_items_model->getById($item_id);
     $is_html = waRequest::request('html');
     if ($q = waRequest::post('quantity', 0, 'int')) {
         if (!wa()->getSetting('ignore_stock_count')) {
             if ($item['type'] == 'product') {
                 $product_model = new shopProductModel();
                 $p = $product_model->getById($item['product_id']);
                 $sku_model = new shopProductSkusModel();
                 $sku = $sku_model->getById($item['sku_id']);
                 // check quantity
                 if ($sku['count'] !== null && $q > $sku['count']) {
                     $q = $sku['count'];
                     $name = $p['name'] . ($sku['name'] ? ' (' . $sku['name'] . ')' : '');
                     $this->response['error'] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $q, $name);
                     $this->response['q'] = $q;
                 }
             }
         }
         $cart->setQuantity($item_id, $q);
         $this->response['item_total'] = $is_html ? shop_currency_html($cart->getItemTotal($item_id), true) : shop_currency($cart->getItemTotal($item_id), true);
     } elseif ($v = waRequest::post('service_variant_id')) {
         $cart->setServiceVariantId($item_id, $v);
         $this->response['item_total'] = $is_html ? shop_currency_html($cart->getItemTotal($item['parent_id']), true) : shop_currency($cart->getItemTotal($item['parent_id']), true);
     }
     $total = $cart->total();
     $discount = $cart->discount();
     $this->response['total'] = $is_html ? shop_currency_html($total, true) : shop_currency($total, true);
     $this->response['discount'] = $is_html ? shop_currency_html($discount, true) : shop_currency($discount, true);
     $this->response['discount_numeric'] = $discount;
     $this->response['count'] = $cart->count();
     if (shopAffiliate::isEnabled()) {
         $add_affiliate_bonus = shopAffiliate::calculateBonus(array('total' => $total, 'discount' => $discount, 'items' => $cart->items(false)));
         $this->response['add_affiliate_bonus'] = sprintf(_w("This order will add +%s points to your affiliate bonus."), round($add_affiliate_bonus, 2));
     }
 }
 public function execute()
 {
     $encoded_order_id = waRequest::param('id');
     $order_id = shopHelper::decodeOrderId($encoded_order_id);
     if (!$order_id) {
         // fall back to non-encoded id
         $order_id = $encoded_order_id;
         $encoded_order_id = shopHelper::encodeOrderId($order_id);
     }
     $om = new shopOrderModel();
     $order = $om->getOrder($order_id);
     if (!$order) {
         throw new waException(_w('Order not found'), 404);
     }
     if (!$this->isAuth($order)) {
         throw new waException(_w('The file will be available for download after the order is paid and processed.'), 404);
     }
     // Check auth code
     $opm = new shopOrderParamsModel();
     $params = $opm->get($order_id);
     $code = waRequest::param('code');
     if (ifset($params['auth_code']) !== $code) {
         throw new waException(_w('Order not found'), 404);
     }
     if ($item = ifempty($order['items'][waRequest::param('item')])) {
         $skus_model = new shopProductSkusModel();
         $sku = $skus_model->getById(ifempty($item['sku_id']));
         if ($sku['file_name'] && $sku['file_size']) {
             $file_path = shopProductSkusModel::getPath($sku);
             waFiles::readFile($file_path, $sku['file_name']);
         } else {
             throw new waException(_w('File not found'), 404);
         }
     } else {
         throw new waException(_w('Order item not found'), 404);
     }
 }
 public function productsAutocomplete($q, $limit = null)
 {
     $limit = $limit !== null ? $limit : $this->limit;
     $product_model = new shopProductModel();
     $q = $product_model->escape($q, 'like');
     $fields = 'id, name AS value, price, count, sku_id';
     $products = $product_model->select($fields)->where("name LIKE '{$q}%'")->limit($limit)->fetchAll('id');
     $count = count($products);
     if ($count < $limit) {
         $product_skus_model = new shopProductSkusModel();
         $product_ids = array_keys($product_skus_model->select('id, product_id')->where("sku LIKE '{$q}%'")->limit($limit)->fetchAll('product_id'));
         if ($product_ids) {
             $data = $product_model->select($fields)->where('id IN (' . implode(',', $product_ids) . ')')->limit($limit - $count)->fetchAll('id');
             // not array_merge, because it makes first reset numeric keys and then make merge
             $products = $products + $data;
         }
     }
     // try find with LIKE %query%
     if (!$products) {
         $products = $product_model->select($fields)->where("name LIKE '%{$q}%'")->limit($limit)->fetchAll();
     }
     $currency = wa()->getConfig()->getCurrency();
     foreach ($products as &$p) {
         $p['price_str'] = wa_currency($p['price'], $currency);
     }
     unset($p);
     if (waRequest::get('with_sku_name')) {
         $sku_ids = array();
         foreach ($products as $p) {
             $sku_ids[] = $p['sku_id'];
         }
         $product_skus_model = new shopProductSkusModel();
         $skus = $product_skus_model->getByField('id', $sku_ids, 'id');
         $sku_names = array();
         foreach ($skus as $sku_id => $sku) {
             $name = '';
             if ($sku['name']) {
                 $name = $sku['name'];
                 if ($sku['sku']) {
                     $name .= ' (' . $sku['sku'] . ')';
                 }
             } else {
                 $name = $sku['sku'];
             }
             $sku_names[$sku_id] = $name;
         }
         foreach ($products as &$p) {
             $p['sku_name'] = $sku_names[$p['sku_id']];
         }
         unset($p);
     }
     return array_values($products);
 }
Example #17
0
 /**
  * @param array $options
  * @return shopProduct
  * @throws waException
  */
 public function duplicate($options = array())
 {
     if (!$this->checkRights()) {
         throw new waRightsException('Access denied');
     }
     $data = $this->data;
     $skip = array('id', 'create_datetime', 'id_1c', 'rating', 'rating_count', 'total_sales', 'image_id', 'contact_id', 'ext', 'count', 'sku_count');
     foreach ($skip as $field) {
         if (isset($data[$field])) {
             unset($data[$field]);
         }
     }
     $duplicate = new shopProduct();
     $this->getStorage(null);
     $sku_files = array();
     $sku_images = array();
     $ignore_select = true;
     foreach (self::$data_storages as $key => $i) {
         $raw = $this->getStorage($key)->getData($this);
         switch ($key) {
             case 'features_selectable':
                 $storage_data = array();
                 if (!$ignore_select) {
                     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
                         if (!is_array($raw)) {
                             $raw = array();
                         }
                         foreach ($raw as $id => $f) {
                             if (!empty($f['selected'])) {
                                 foreach ($f['values'] as $value_id => &$value) {
                                     if (!empty($value['selected'])) {
                                         $value = array('id' => $value_id);
                                     } else {
                                         unset($f['values'][$value_id]);
                                     }
                                 }
                                 $storage_data[$id] = $f;
                             }
                         }
                     }
                 }
                 break;
             case 'skus':
                 $storage_data = array();
                 $i = 0;
                 foreach ($raw as $sku_id => $sku) {
                     if (!empty($sku['virtual']) || $ignore_select) {
                         if ($file_path = shopProductSkusModel::getPath($sku)) {
                             $sku_files[$sku['id']] = array('file_name' => $sku['file_name'], 'file_description' => $sku['file_description'], 'file_size' => $sku['file_size'], 'file_path' => $file_path);
                         }
                         if (!empty($sku['image_id'])) {
                             $sku_images[$sku['id']] = $sku['image_id'];
                         }
                         foreach (array('id', 'id_1c', 'product_id', 'image_id', 'file_name', 'file_size', 'file_description') as $field) {
                             if (isset($sku[$field])) {
                                 unset($sku[$field]);
                             }
                         }
                         $storage_data[--$i] = $sku;
                     }
                 }
                 break;
             case 'tags':
                 $storage_data = array_values($raw);
                 break;
             case 'categories':
                 $storage_data = array_keys($raw);
                 break;
             default:
                 $storage_data = $raw;
                 break;
         }
         $duplicate->{$key} = $storage_data;
     }
     $counter = 0;
     $data['url'] = shopHelper::genUniqueUrl($this->url, $this->model, $counter);
     $data['name'] = $this->name . sprintf('(%d)', $counter ? $counter : 1);
     $duplicate->save($data);
     $product_id = $duplicate->getId();
     $sku_map = array_combine(array_keys($this->skus), array_keys($duplicate->skus));
     $config = wa('shop')->getConfig();
     $image_thumbs_on_demand = $config->getOption('image_thumbs_on_demand');
     /**
      * @var shopConfig $config
      */
     if ($this->pages) {
         $product_pages_model = new shopProductPagesModel();
         foreach ($this->pages as $page) {
             unset($page['id']);
             unset($page['create_time']);
             unset($page['update_datetime']);
             unset($page['create_contact_id']);
             $page['product_id'] = $duplicate->getId();
             $product_pages_model->add($page);
         }
     }
     #duplicate images
     $product_skus_model = new shopProductSkusModel();
     $images_model = new shopProductImagesModel();
     $images = $images_model->getByField('product_id', $this->getId(), $images_model->getTableId());
     $callback = create_function('$a, $b', 'return (max(-1, min(1, $a["sort"] - $b["sort"])));');
     usort($images, $callback);
     foreach ($images as $id => $image) {
         $source_path = shopImage::getPath($image);
         $original_file = shopImage::getOriginalPath($image);
         $image['product_id'] = $duplicate->getId();
         if ($sku_id = array_search($image['id'], $sku_images)) {
             $sku_id = $sku_map[$sku_id];
         }
         unset($image['id']);
         try {
             if ($image['id'] = $images_model->add($image, $id == $this->image_id)) {
                 waFiles::copy($source_path, shopImage::getPath($image));
                 if (file_exists($original_file)) {
                     waFiles::copy($original_file, shopImage::getOriginalPath($image));
                 }
                 if ($sku_id) {
                     $product_skus_model->updateById($sku_id, array('image_id' => $image['id']));
                 }
                 if (!$image_thumbs_on_demand) {
                     shopImage::generateThumbs($image, $config->getImageSizes());
                     //TODO use dummy copy  with rename files
                 }
             }
         } catch (waDbException $ex) {
             //just ignore it
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         } catch (waException $ex) {
             if (!empty($image['id'])) {
                 $images_model->deleteById($image['id']);
             }
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         }
     }
     foreach ($sku_files as $sku_id => $data) {
         $source_path = $data['file_path'];
         unset($data['file_path']);
         $sku_id = $sku_map[$sku_id];
         $sku = array_merge($duplicate->skus[$sku_id], $data);
         $product_skus_model->updateById($sku_id, $data);
         $target_path = shopProductSkusModel::getPath($sku);
         try {
             waFiles::copy($source_path, $target_path);
         } catch (waException $ex) {
             $data = array('file_name' => '', 'file_description' => '', 'file_size' => 0);
             $product_skus_model->updateById($sku_id, $data);
             print $ex->getMessage();
         }
     }
     $product_features_model = new shopProductFeaturesModel();
     $skus_features = $product_features_model->getSkuFeatures($this->id);
     $skus_features_data = array();
     foreach ($skus_features as $sku_id => $features) {
         $sku_id = $sku_map[$sku_id];
         foreach ($features as $feature_id => $feature_value_id) {
             $skus_features_data[] = compact('product_id', 'sku_id', 'feature_id', 'feature_value_id');
         }
     }
     if ($skus_features_data) {
         $product_features_model->multipleInsert($skus_features_data);
     }
     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
         $product_features_selectable_model = new shopProductFeaturesSelectableModel();
         if ($features_selectable = $product_features_selectable_model->getByField('product_id', $this->id, true)) {
             foreach ($features_selectable as &$feature_selectable) {
                 $feature_selectable['product_id'] = $product_id;
             }
             unset($feature_selectable);
             $product_features_selectable_model->multipleInsert($features_selectable);
         }
     }
     $product_services_model = new shopProductServicesModel();
     if ($services = $product_services_model->getByField('product_id', $this->id, true)) {
         foreach ($services as &$service) {
             unset($service['id']);
             $service['product_id'] = $product_id;
             $service['sku_id'] = ifset($sku_map[$service['sku_id']]);
             unset($service);
         }
         $product_services_model->multipleInsert($services);
     }
     $product_related_model = new shopProductRelatedModel();
     if ($related = $product_related_model->getByField('product_id', $this->id, true)) {
         foreach ($related as &$row) {
             $row['product_id'] = $product_id;
         }
         unset($row);
         $product_related_model->multipleInsert($related);
     }
     $params = array('product' => &$this, 'duplicate' => &$duplicate);
     /**
      * @wa-event product_duplicate
      */
     wa()->event('product_duplicate', $params);
     return $duplicate;
 }
 /**
  *
  * @param array $data
  * @return shopProduct
  */
 private function findProduct(&$data)
 {
     static $currencies;
     static $model;
     static $sku_model;
     /**
      * @var shopTypeFeaturesModel $type_features_model
      */
     static $type_features_model;
     if (empty($model)) {
         $model = new shopProductModel();
     }
     if (empty($currencies)) {
         $currencies = array();
         $config = wa()->getConfig();
         /**
          * @var shopConfig $config
          */
         $c = $config->getCurrency();
         $currencies[$c] = $c;
         foreach ($config->getCurrencies() as $row) {
             $currencies[$row['code']] = $row['code'];
         }
     }
     if (!empty($data['skus'][-1]['stock'])) {
         $per_stock = false;
         $stock =& $data['skus'][-1]['stock'];
         foreach ($stock as $id => &$count) {
             if ($count === '') {
                 $count = null;
             } else {
                 $count = intval($count);
                 if ($id) {
                     $per_stock = true;
                 }
             }
         }
         unset($count);
         if ($per_stock) {
             if (isset($stock[0])) {
                 unset($stock[0]);
             }
         } else {
             $count = ifset($stock[0]);
             $stock = array(0 => $count);
         }
         unset($stock);
     }
     $stack = ifset($this->data['map'][self::STAGE_CATEGORY], array());
     $category_id = end($stack);
     if (!$category_id) {
         $category_id = null;
     }
     $primary = $this->data['primary'];
     $fields = false;
     if (empty($primary)) {
         $keys = explode(':', $this->data['secondary']);
         if (empty($sku_model)) {
             $sku_model = new shopProductSkusModel();
         }
         $sku_fields = array(end($keys) => self::getData($data, $keys));
         //hack for empty SKU code ???
         if (false && reset($sku_fields) === '' && $this->data['extra_secondary']) {
             $extra_keys = explode(':', $this->data['extra_secondary']);
             $sku_fields[end($extra_keys)] = self::getData($data, $this->data['extra_secondary']);
         }
         if ($sku = $sku_model->getByField($sku_fields)) {
             $fields = array('category_id' => $category_id, 'id' => $sku['product_id']);
         }
     } elseif (!empty($primary)) {
         $fields = array('category_id' => $category_id, $primary => ifset($data[$primary], ''));
     }
     if ($fields && $this->data['ignore_category']) {
         unset($fields['category_id']);
     }
     $key = 'p';
     if ($fields && ($current_data = $model->getByField($fields))) {
         $product = new shopProduct($current_data['id']);
         $data['type_id'] = ifempty($current_data['type_id'], $this->data['type_id']);
         if (!empty($current_data['tax_id'])) {
             $data['tax_id'] = $current_data['tax_id'];
         }
         if (isset($data['currency']) && !isset($currencies[$data['currency']])) {
             $this->data['processed_count'][self::STAGE_PRODUCT]['currency']++;
             $data['currency'] = reset($currencies);
         }
         if (!empty($data['skus'])) {
             $data['sku_id'] = ifempty($current_data['sku_id'], -1);
         }
         foreach ($product->skus as $sku_id => $current_sku) {
             if (empty($data['skus'][$sku_id])) {
                 if (!count($current_sku['stock']) && $current_sku['count'] !== null) {
                     $current_sku['stock'][0] = $current_sku['count'];
                 }
                 $data['skus'][$sku_id] = $current_sku;
             }
         }
         $key .= ':u:' . $product->getId();
     } else {
         $product = new shopProduct();
         if ($category_id) {
             $data['categories'] = array($category_id);
         }
         $data['currency'] = ifempty($data['currency'], reset($currencies));
         if (!isset($currencies[$data['currency']])) {
             $this->data['processed_count'][self::STAGE_PRODUCT]['currency']++;
             $data['currency'] = reset($currencies);
         }
         if (!empty($data['skus'])) {
             $sku = reset($data['skus']);
             $data['sku_id'] = key($data['skus']);
             if (!isset($sku['available'])) {
                 $sku['available'] = true;
                 $data['skus'][$data['sku_id']] = $sku;
             }
         }
         $key .= ':i:' . $this->getKey($fields);
     }
     if (!empty($data['features'])) {
         foreach ($data['features'] as $feature => &$values) {
             if (is_array($values)) {
             } elseif (preg_match('/^<\\{(.*)\\}>$/', $values, $matches)) {
                 if (!isset($data['features_selectable'])) {
                     $data['features_selectable'] = array();
                 }
                 if ($values = explode(',', $matches[1])) {
                     foreach ($values as &$value) {
                         if (preg_match('@^(.+)=([\\+\\-]?(\\d+|\\.\\d+|\\d\\.\\d))$@', $value, $matches)) {
                             $value = array('value' => trim($matches[1]), 'price' => $matches[2]);
                         } else {
                             $value = array('value' => trim($value));
                         }
                         unset($value);
                     }
                     $data['features_selectable'][$feature] = array('values' => $values);
                     if (!empty($this->data['virtual_sku_stock']) && isset($data['skus'][-1]['stock'])) {
                         $stock = $data['skus'][-1]['stock'];
                         switch ($this->data['virtual_sku_stock']) {
                             case 'distribute':
                                 if (is_array($stock)) {
                                     foreach ($stock as &$stock_item) {
                                         $stock_item = $stock_item / count($values);
                                         unset($stock_item);
                                     }
                                 } else {
                                     $stock = $stock / count($values);
                                 }
                                 $data['features_selectable'][$feature]['stock'] = $stock;
                                 break;
                             case 'set':
                                 $data['features_selectable'][$feature]['stock'] = $stock;
                                 break;
                         }
                     }
                     $product->sku_type = shopProductModel::SKU_TYPE_SELECTABLE;
                     if (isset($data['skus'][-1])) {
                         if (!isset($data['base_price_selectable'])) {
                             $data['base_price_selectable'] = ifset($data['skus'][-1]['price']);
                         }
                         if (!isset($data['purchase_price_selectable'])) {
                             $data['purchase_price_selectable'] = ifset($data['skus'][-1]['purchase_price']);
                         }
                         if (!isset($data['compare_price_selectable'])) {
                             $data['compare_price_selectable'] = ifset($data['skus'][-1]['compare_price']);
                         }
                     }
                     unset($data['skus']);
                 }
                 unset($data['features'][$feature]);
             } elseif (preg_match('/^\\{(.*)\\}$/', $values, $matches)) {
                 $values = explode(',', $matches[1]);
             }
         }
         unset($values);
     }
     $this->findTax($data);
     $access = $this->findType($data);
     if ($access) {
         $access = !$product->type_id || in_array($product->type_id, $this->data['types']);
     }
     if ($access) {
         $product->__hash = $key;
         foreach ($this->data['new_features'] as $code => &$feature) {
             if (isset($data['features'][$code]) || isset($data['features_selectable'][$code])) {
                 if ($data['type_id'] && !in_array($data['type_id'], $feature['types'])) {
                     if (empty($type_features_model)) {
                         $type_features_model = new shopTypeFeaturesModel();
                     }
                     $type_features_model->updateByFeature($feature['id'], array($data['type_id']), false);
                     $feature['types'][] = $data['type_id'];
                 }
             }
             unset($feature);
         }
     }
     return $access ? $product : null;
 }
Example #19
0
 public function getByCode($code, $full_info = false, $hierarchy = true)
 {
     if (!$code) {
         return array();
     }
     $sql = "SELECT * FROM " . $this->table . " WHERE code = s:0 ORDER BY parent_id";
     $items = $this->query($sql, $code)->fetchAll('id');
     if ($full_info) {
         $product_ids = $sku_ids = $service_ids = $variant_ids = array();
         foreach ($items as $item) {
             $product_ids[] = $item['product_id'];
             $sku_ids[] = $item['sku_id'];
             if ($item['type'] == 'service') {
                 $service_ids[] = $item['service_id'];
                 if ($item['service_variant_id']) {
                     $variant_ids[] = $item['service_variant_id'];
                 }
             }
         }
         $product_model = new shopProductModel();
         $products = $product_model->getByField('id', $product_ids, 'id');
         $sku_model = new shopProductSkusModel();
         $skus = $sku_model->getByField('id', $sku_ids, 'id');
         $service_model = new shopServiceModel();
         $services = $service_model->getByField('id', $service_ids, 'id');
         $service_variants_model = new shopServiceVariantsModel();
         $variants = $service_variants_model->getByField('id', $variant_ids, 'id');
         $product_services_model = new shopProductServicesModel();
         $rows = $product_services_model->getByProducts($product_ids);
         $product_services = $sku_services = array();
         foreach ($rows as $row) {
             if ($row['sku_id'] && !in_array($row['sku_id'], $sku_ids)) {
                 continue;
             }
             $service_ids[] = $row['service_id'];
             if (!$row['sku_id']) {
                 $product_services[$row['product_id']][$row['service_variant_id']] = $row;
             }
             if ($row['sku_id']) {
                 $sku_services[$row['sku_id']][$row['service_variant_id']] = $row;
             }
         }
         foreach ($items as $item_key => &$item) {
             if ($item['type'] == 'product' && isset($products[$item['product_id']])) {
                 $item['product'] = $products[$item['product_id']];
                 if (!isset($skus[$item['sku_id']])) {
                     unset($items[$item_key]);
                     continue;
                 }
                 $sku = $skus[$item['sku_id']];
                 $item['sku_code'] = $sku['sku'];
                 $item['purchase_price'] = $sku['purchase_price'];
                 $item['sku_name'] = $sku['name'];
                 $item['currency'] = $item['product']['currency'];
                 $item['price'] = $sku['price'];
                 $item['name'] = $item['product']['name'];
                 if ($item['sku_name']) {
                     $item['name'] .= ' (' . $item['sku_name'] . ')';
                 }
             } elseif ($item['type'] == 'service' && isset($services[$item['service_id']])) {
                 $item['name'] = $item['service_name'] = $services[$item['service_id']]['name'];
                 $item['currency'] = $services[$item['service_id']]['currency'];
                 $item['service'] = $services[$item['service_id']];
                 $item['variant_name'] = $variants[$item['service_variant_id']]['name'];
                 if ($item['variant_name']) {
                     $item['name'] .= ' (' . $item['variant_name'] . ')';
                 }
                 $item['price'] = $variants[$item['service_variant_id']]['price'];
                 if (isset($product_services[$item['product_id']][$item['service_variant_id']])) {
                     if ($product_services[$item['product_id']][$item['service_variant_id']]['price'] !== null) {
                         $item['price'] = $product_services[$item['product_id']][$item['service_variant_id']]['price'];
                     }
                 }
                 if (isset($sku_services[$item['sku_id']][$item['service_variant_id']])) {
                     if ($sku_services[$item['sku_id']][$item['service_variant_id']]['price'] !== null) {
                         $item['price'] = $sku_services[$item['sku_id']][$item['service_variant_id']]['price'];
                     }
                 }
                 if ($item['currency'] == '%') {
                     $p = $items[$item['parent_id']];
                     $item['price'] = $item['price'] * $p['price'] / 100;
                     $item['currency'] = $p['currency'];
                 }
             }
         }
         unset($item);
     }
     // sort
     foreach ($items as $item_id => $item) {
         if ($item['parent_id']) {
             $items[$item['parent_id']]['services'][] = $item;
             unset($items[$item_id]);
         }
     }
     if (!$hierarchy) {
         $result = array();
         foreach ($items as $item_id => $item) {
             if (isset($item['services'])) {
                 $i = $item;
                 unset($i['services']);
                 $result[$item_id] = $i;
                 foreach ($item['services'] as $s) {
                     $result[$s['id']] = $s;
                 }
             } else {
                 $result[$item_id] = $item;
             }
         }
         $items = $result;
     }
     return $items;
 }
 /**
  * Set count for stock and sku. 
  * Make insert, update or delete depending on input parameters and current state (sku-stock record in table)
  * Take into account stocking log (@see shopProductStocksLog)
  * 
  * @param string[mixed] $data Specify sku ID, stock ID, count
  * @param int           $data['sku_id'] sku ID, obligatory
  * @param int           $data['product_id'] product ID, optional
  * @param int           $data['stock_id'] stock ID, obligatory
  * @param int|null      $data['count'] count, obligatory. 
  * 
  * <code>
  * array(
  *     'sku_id' => 123,      // sku ID, obligatory
  *     'product_id' => 111,  // product ID, optional
  *     'stock_id' => 23,     // stock ID, obligatory
  *     'count' => 12,        // Maybe null or integer greater or equals 0
  * )
  * </code>
  * 
  * @return boolean
  */
 public function set($data)
 {
     if (empty($data['sku_id']) || empty($data['stock_id'])) {
         return false;
     }
     // isset doesn't work correctly with null
     if (!array_key_exists('count', $data)) {
         return false;
     }
     $count = $data['count'];
     if (empty($data['product_id'])) {
         $product_skus_model = new shopProductSkusModel();
         $data['product_id'] = $product_skus_model->select('product_id')->where('sku_id = :sku_id', array('sku_id' => $data['sku_id']))->fetchField();
     }
     if (empty($data['product_id'])) {
         return false;
     }
     $key = array('sku_id' => $data['sku_id'], 'stock_id' => $data['stock_id']);
     $item = $this->getByField($key);
     if ($item && $count !== null && $count == $item['count'] || !$item && $count === null) {
         // nothing to update
         return true;
     }
     $log_data = array('product_id' => $data['product_id'], 'sku_id' => $data['sku_id'], 'stock_id' => $data['stock_id'], 'before_count' => null, 'after_count' => $count);
     if ($item) {
         $log_data['before_count'] = $item['count'];
     }
     if ($count === null) {
         $op = 'delete';
     } else {
         if ($item) {
             $op = 'update';
         } else {
             $op = 'insert';
         }
     }
     if ($op == 'delete') {
         $this->deleteByField($key);
     } else {
         if ($op == 'update') {
             $this->updateByField($key, $data);
         } else {
             $this->insert($data);
         }
     }
     $log_model = new shopProductStocksLogModel();
     $log_model->add($log_data);
     return true;
 }
 /**
  * @param $current_stage
  * @param $count
  * @param $processed
  *
  * @usedby shopYandexmarketPluginRunController::step()
  */
 private function stepProduct(&$current_stage, &$count, &$processed)
 {
     static $products;
     static $sku_model;
     static $categories;
     if (!$products) {
         $products = $this->getCollection()->getProducts($this->getProductFields(), $current_stage, self::PRODUCT_PER_REQUEST, false);
         if (!$products) {
             $current_stage = $count['product'];
         } elseif (!empty($this->data['export']['sku'])) {
             if (empty($sku_model)) {
                 $sku_model = new shopProductSkusModel();
             }
             $skus = $sku_model->getDataByProductId(array_keys($products));
             foreach ($skus as $sku_id => $sku) {
                 if (isset($products[$sku['product_id']])) {
                     if (!isset($products[$sku['product_id']]['skus'])) {
                         $products[$sku['product_id']]['skus'] = array();
                     }
                     $products[$sku['product_id']]['skus'][$sku_id] = $sku;
                     if (count($products[$sku['product_id']]['skus']) > 1) {
                         $group = false;
                         switch (ifset($this->data['export']['sku_group'])) {
                             case 'all':
                                 $group = $sku['product_id'];
                                 break;
                             case 'category':
                                 // user primary product's category property
                                 if (!is_array($categories)) {
                                     $category_params_model = new shopCategoryParamsModel();
                                     $categories = $category_params_model->getByField(array('name' => 'yandexmarket_group_skus', 'value' => 1), 'category_id');
                                     if ($categories) {
                                         $categories = array_fill_keys(array_keys($categories), true);
                                     }
                                 }
                                 if (isset($categories[$products[$sku['product_id']]['category_id']])) {
                                     $group = $sku['product_id'];
                                 }
                                 break;
                             case 'auto':
                                 $group = 'auto';
                                 //use product property yandex_category for it
                                 break;
                             default:
                                 break;
                         }
                         if ($group) {
                             $products[$sku['product_id']]['_group_id'] = $group;
                         }
                     }
                 }
             }
         }
         $params = array('products' => &$products, 'type' => 'YML');
         wa('shop')->event('products_export', $params);
     }
     $check_stock = !empty($this->data['export']['zero_stock']) || !empty($this->data['app_settings']['ignore_stock_count']);
     $chunk = 100;
     while (--$chunk >= 0 && ($product = reset($products))) {
         $check_type = empty($this->data['type_id']) || in_array($product['type_id'], $this->data['type_id']);
         $check_price = $product['price'] >= 0.5;
         $check_category = !empty($product['category_id']) && isset($this->data['categories'][$product['category_id']]);
         if ($check_category && $product['category_id'] != $this->data['categories'][$product['category_id']]) {
             // remap product category
             $product['category_id'] = $this->data['categories'][$product['category_id']];
         }
         if (false && $check_type && $check_price && !$check_category) {
             //debug option
             $this->error("Product #%d [%s] skipped because it's category %s is not available", $product['id'], $product['name'], var_export(ifset($product['category_id']), true));
         }
         if ($check_type && $check_price && $check_category) {
             $type = ifempty($this->data['types'][$product['type_id']], 'simple');
             if (!empty($this->data['export']['sku'])) {
                 $skus = $product['skus'];
                 unset($product['skus']);
                 foreach ($skus as $sku) {
                     $check_sku_price = $sku['price'] >= 0.5;
                     if ($check_sku_price && ($check_stock || $sku['count'] === null || $sku['count'] > 0)) {
                         if (count($skus) == 1) {
                             $product['price'] = $sku['price'];
                             $product['file_name'] = $sku['file_name'];
                             $product['sku'] = $sku['sku'];
                             $increment = false;
                         } else {
                             $increment = true;
                         }
                         $this->addOffer($product, $type, count($skus) > 1 ? $sku : null);
                         ++$processed;
                         if ($increment) {
                             ++$count['product'];
                         }
                     }
                 }
             } else {
                 if ($check_stock || $product['count'] === null || $product['count'] > 0) {
                     $this->addOffer($product, $type);
                     ++$processed;
                 }
             }
         }
         array_shift($products);
         ++$current_stage;
     }
 }
Example #22
0
 public function getSkus($sku_ids)
 {
     if (!$sku_ids) {
         return array();
     }
     $model = new shopProductSkusModel();
     return $model->getByField('id', $sku_ids, 'id');
 }
 public static function checkCart(&$cart = null)
 {
     $error = false;
     $cart = new shopCart();
     $code = $cart->getCode();
     $view = wa()->getView();
     if (!wa()->getSetting('ignore_stock_count')) {
         $cart_model = new shopCartItemsModel();
         $sku_model = new shopProductSkusModel();
         $product_model = new shopProductModel();
         $items = $cart->items(false);
         foreach ($items as &$item) {
             if (!isset($item['product_id'])) {
                 $sku = $sku_model->getById($item['sku_id']);
                 $product = $product_model->getById($sku['product_id']);
             } else {
                 $product = $product_model->getById($item['product_id']);
                 if (isset($item['sku_id'])) {
                     $sku = $sku_model->getById($item['sku_id']);
                 } else {
                     if (isset($item['features'])) {
                         $product_features_model = new shopProductFeaturesModel();
                         $sku_id = $product_features_model->getSkuByFeatures($product['id'], $item['features']);
                         if ($sku_id) {
                             $sku = $sku_model->getById($sku_id);
                         } else {
                             $sku = null;
                         }
                     } else {
                         $sku = $sku_model->getById($product['sku_id']);
                         if (!$sku['available']) {
                             $sku = $sku_model->getByField(array('product_id' => $product['id'], 'available' => 1));
                         }
                         if (!$sku) {
                             $item['error'] = _w('This product is not available for purchase');
                             $error = true;
                         }
                     }
                 }
             }
             $quantity = $item['quantity'];
             $c = $cart_model->countSku($code, $sku['id']);
             if ($sku['count'] !== null && $c + $quantity > $sku['count']) {
                 $quantity = $sku['count'] - $c;
                 $name = $product['name'] . ($sku['name'] ? ' (' . $sku['name'] . ')' : '');
                 if ($quantity < 0) {
                     $item['error'] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                     $error = true;
                 }
             }
         }
         unset($item);
         foreach ($items as $item_id => $item) {
             $price = shop_currency($item['price'] * $item['quantity'], $item['currency'], null, false);
             if (isset($item['services'])) {
                 foreach ($item['services'] as $s) {
                     if (!empty($s['id'])) {
                         if (isset($s['variants'])) {
                             $price += shop_currency($s['variants'][$s['variant_id']]['price'] * $item['quantity'], $s['currency'], null, false);
                         } else {
                             $price += shop_currency($s['price'] * $item['quantity'], $s['currency'], null, false);
                         }
                     }
                 }
             }
             $items[$item_id]['full_price'] = $price;
         }
         $cart = array('items' => $items, 'total' => $cart->total(false), 'count' => $cart->count());
     }
     return $error;
 }
 public function getProductServiceFullInfo($product_id, $service_id = null)
 {
     $product = $this->getProduct($product_id);
     if (!$product) {
         return array();
     }
     $services = $this->getServices($product, $service_id);
     if (!$services) {
         return array();
     }
     if ($service_id) {
         $services = array($service_id => $services);
     }
     $service_ids = array_keys($services);
     $data = array();
     $product_skus_model = new shopProductSkusModel();
     $skus = $product_skus_model->getByField('product_id', $product_id, 'id');
     $variants = $this->getVariants($product_id, $service_ids);
     foreach ($variants as $s_id => $service) {
         foreach ($service['variants'] as &$variant) {
             if ($variant['status'] === null) {
                 $variant['status'] = $services[$s_id]['type_id'] ? self::STATUS_PERMITTED : self::STATUS_FORBIDDEN;
             }
             foreach ($skus as $sku_id => $sku) {
                 $sk_item =& $variant['skus'][$sku_id];
                 if (empty($sk_item)) {
                     $sk_item = array('id' => $variant['id'], 'sku_id' => $sku_id, 'price' => null, 'primary_price' => null, 'base_price' => $variant['base_price'], 'primary_base_price' => $variant['primary_base_price'], 'status' => self::STATUS_PERMITTED);
                 }
                 $sk_item['name'] = $sku['name'];
                 // base_price on sku level is price on product level
                 if ($variant['price'] !== null) {
                     $sk_item['base_price'] = $variant['price'];
                     $sk_item['primary_base_price'] = $variant['primary_base_price'];
                 }
                 if ($variant['status'] == self::STATUS_FORBIDDEN) {
                     $sk_item['status'] = self::STATUS_FORBIDDEN;
                 }
                 unset($sk_item);
             }
             unset($variant);
         }
         $this->setDefaultVariant($service['variants'], $services[$s_id]['variant_id']);
         $data[$s_id] = $services[$s_id];
         $data[$s_id]['variants'] = $service['variants'];
     }
     return $service_id ? $data[$service_id] : $data;
 }
 public function execute()
 {
     $category = $this->getCategory();
     $this->addCanonical();
     // breadcrumbs
     $root_category_id = $category['id'];
     if ($category['parent_id']) {
         $breadcrumbs = array();
         $path = array_reverse($this->getModel()->getPath($category['id']));
         $root_category = reset($path);
         $root_category_id = $root_category['id'];
         foreach ($path as $row) {
             $breadcrumbs[] = array('url' => wa()->getRouteUrl('/frontend/category', array('category_url' => waRequest::param('url_type') == 1 ? $row['url'] : $row['full_url'])), 'name' => $row['name']);
         }
         if ($breadcrumbs) {
             $this->view->assign('breadcrumbs', $breadcrumbs);
         }
     }
     $this->view->assign('root_category_id', $root_category_id);
     // sort
     if ($category['type'] == shopCategoryModel::TYPE_DYNAMIC && !$category['sort_products']) {
         $category['sort_products'] = 'create_datetime DESC';
     }
     if ($category['sort_products'] && !waRequest::get('sort')) {
         $sort = explode(' ', $category['sort_products']);
         $this->view->assign('active_sort', $sort[0] == 'count' ? 'stock' : $sort[0]);
     } elseif (!$category['sort_products'] && !waRequest::get('sort')) {
         $this->view->assign('active_sort', '');
     }
     $this->view->assign('category', $category);
     // products
     $collection = new shopProductsCollection('category/' . $category['id']);
     // filters
     if ($category['filter']) {
         $filter_ids = explode(',', $category['filter']);
         $feature_model = new shopFeatureModel();
         $features = $feature_model->getById(array_filter($filter_ids, 'is_numeric'));
         if ($features) {
             $features = $feature_model->getValues($features);
         }
         $category_value_ids = $collection->getFeatureValueIds();
         $filters = array();
         foreach ($filter_ids as $fid) {
             if ($fid == 'price') {
                 $range = $collection->getPriceRange();
                 if ($range['min'] != $range['max']) {
                     $filters['price'] = array('min' => shop_currency($range['min'], null, null, false), 'max' => shop_currency($range['max'], null, null, false));
                 }
             } elseif (isset($features[$fid]) && isset($category_value_ids[$fid])) {
                 $filters[$fid] = $features[$fid];
                 $min = $max = $unit = null;
                 foreach ($filters[$fid]['values'] as $v_id => $v) {
                     if (!in_array($v_id, $category_value_ids[$fid])) {
                         unset($filters[$fid]['values'][$v_id]);
                     } else {
                         if ($v instanceof shopRangeValue) {
                             $begin = $this->getFeatureValue($v->begin);
                             if ($min === null || $begin < $min) {
                                 $min = $begin;
                             }
                             $end = $this->getFeatureValue($v->end);
                             if ($max === null || $end > $max) {
                                 $max = $end;
                                 if ($v->end instanceof shopDimensionValue) {
                                     $unit = $v->end->unit;
                                 }
                             }
                         } else {
                             $tmp_v = $this->getFeatureValue($v);
                             if ($min === null || $tmp_v < $min) {
                                 $min = $tmp_v;
                             }
                             if ($max === null || $tmp_v > $max) {
                                 $max = $tmp_v;
                                 if ($v instanceof shopDimensionValue) {
                                     $unit = $v->unit;
                                 }
                             }
                         }
                     }
                 }
                 if (!$filters[$fid]['selectable'] && ($filters[$fid]['type'] == 'double' || substr($filters[$fid]['type'], 0, 6) == 'range.' || substr($filters[$fid]['type'], 0, 10) == 'dimension.')) {
                     if ($min == $max) {
                         unset($filters[$fid]);
                     } else {
                         $type = preg_replace('/^[^\\.]*\\./', '', $filters[$fid]['type']);
                         if ($type != 'double') {
                             $filters[$fid]['base_unit'] = shopDimension::getBaseUnit($type);
                             $filters[$fid]['unit'] = shopDimension::getUnit($type, $unit);
                             if ($filters[$fid]['base_unit']['value'] != $filters[$fid]['unit']['value']) {
                                 $dimension = shopDimension::getInstance();
                                 $min = $dimension->convert($min, $type, $filters[$fid]['unit']['value']);
                                 $max = $dimension->convert($max, $type, $filters[$fid]['unit']['value']);
                             }
                         }
                         $filters[$fid]['min'] = $min;
                         $filters[$fid]['max'] = $max;
                     }
                 }
             }
         }
         $this->view->assign('filters', $filters);
         $this->setCollection($collection);
         // fix prices
         $products = $this->view->getVars('products');
         $product_ids = array();
         foreach ($products as $p_id => $p) {
             if ($p['sku_count'] > 1) {
                 $product_ids[] = $p_id;
             }
         }
         if ($product_ids) {
             $min_price = $max_price = null;
             $tmp = array();
             foreach ($filters as $fid => $f) {
                 if ($fid == 'price') {
                     $min_price = waRequest::get('price_min');
                     if (!empty($min_price)) {
                         $min_price = (double) $min_price;
                     } else {
                         $min_price = null;
                     }
                     $max_price = waRequest::get('price_max');
                     if (!empty($max_price)) {
                         $max_price = (double) $max_price;
                     } else {
                         $max_price = null;
                     }
                 } else {
                     $fvalues = waRequest::get($f['code']);
                     if ($fvalues && !isset($fvalues['min']) && !isset($fvalues['max'])) {
                         $tmp[$fid] = $fvalues;
                     }
                 }
             }
             $product_skus = array();
             if ($tmp) {
                 $pf_model = new shopProductFeaturesModel();
                 $product_skus = $pf_model->getSkusByFeatures($product_ids, $tmp);
             } elseif ($min_price || $max_price) {
                 $ps_model = new shopProductSkusModel();
                 $rows = $ps_model->getByField('product_id', $product_ids, true);
                 foreach ($rows as $row) {
                     $product_skus[$row['product_id']][] = $row;
                 }
             }
             $default_currency = $this->getConfig()->getCurrency(true);
             if ($product_skus) {
                 foreach ($product_skus as $product_id => $skus) {
                     $currency = $products[$product_id]['currency'];
                     usort($skus, array($this, 'sortSkus'));
                     $k = 0;
                     if ($min_price || $max_price) {
                         foreach ($skus as $i => $sku) {
                             if ($min_price) {
                                 $tmp_price = shop_currency($min_price, true, $currency, false);
                                 if ($sku['price'] < $tmp_price) {
                                     continue;
                                 }
                             }
                             if ($max_price) {
                                 $tmp_price = shop_currency($max_price, true, $currency, false);
                                 if ($sku['price'] > $tmp_price) {
                                     continue;
                                 }
                             }
                             $k = $i;
                             break;
                         }
                     }
                     $sku = $skus[$k];
                     if ($products[$product_id]['sku_id'] != $sku['id']) {
                         $products[$product_id]['sku_id'] = $sku['id'];
                         $products[$product_id]['frontend_url'] .= '?sku=' . $sku['id'];
                         $products[$product_id]['price'] = shop_currency($sku['price'], $currency, $default_currency, false);
                         $products[$product_id]['compare_price'] = shop_currency($sku['compare_price'], $currency, $default_currency, false);
                     }
                 }
                 $this->view->assign('products', $products);
             }
         }
     } else {
         $this->setCollection($collection);
     }
     //отображение дополнительных размеров
     $products = $this->view->getVars('products');
     $product_features_model = new shopProductFeaturesSelectableModel();
     foreach ($products as &$p) {
         $sku_features = $product_features_model->getByProduct($p['id']);
         $sizes = $sku_features[3];
         if (!$sizes) {
             $p['sizes'] = array();
             continue;
         }
         $pf_names = $product_features_model->query("SELECT `id`, `value` FROM shop_feature_values_varchar where `id` IN (" . implode(',', $sizes) . ') ORDER BY `sort`;')->fetchAll();
         foreach ($pf_names as $key => $val) {
             $sizes[$val['id']] = $val['value'];
         }
         $p['sizes'] = $pf_names;
     }
     //отображение всех картинок
     foreach ($products as &$p) {
         $images_full = shopViewHelper::images($p['id']);
         if (isset($images_full[$p['id']])) {
             $p['image_ids'] = array_keys($images_full[$p['id']]);
         }
     }
     $this->view->assign('products', $products);
     // set meta
     $title = $category['meta_title'] ? $category['meta_title'] : $category['name'];
     wa()->getResponse()->setTitle($title);
     wa()->getResponse()->setMeta('keywords', $category['meta_keywords']);
     wa()->getResponse()->setMeta('description', $category['meta_description']);
     /**
      * @event frontend_category
      * @return array[string]string $return[%plugin_id%] html output for category
      */
     $this->view->assign('frontend_category', wa()->event('frontend_category', $category));
     $this->setThemeTemplate('category.html');
 }
 /**
  * @todo use delta/absolute price
  * @param shopProduct $product
  * @param array $selected
  * @param array $data
  * @return array
  */
 private function generateSku(shopProduct $product, $selected, &$data)
 {
     $skus = $product->skus;
     if (empty($skus)) {
         $skus = array();
     }
     #build features map for exists SKUs
     $sku_map = array();
     $product_features_model = new shopProductFeaturesModel();
     foreach ($z = $product_features_model->getSkuFeatures($product->id) as $sku_id => $f) {
         $key = "";
         foreach ($f as $feature_id => $value_id) {
             $key .= $feature_id . ":" . $value_id . ";";
         }
         $sku_map[$key] = $sku_id;
     }
     $map = array();
     foreach ($data as $code => $d) {
         $map[$d['feature_id']] = $code;
     }
     $default_sku = array('sku' => '', 'virtual' => 1, 'available' => 1, 'count' => null);
     $i = 0;
     foreach ($this->arrayCartesian($selected) as $features) {
         $sku = array('name' => array(), 'features' => array(), 'price' => $product->base_price_selectable, 'compare_price' => $product->compare_price_selectable, 'purchase_price' => $product->purchase_price_selectable);
         $sku_key = "";
         $last_value_id = end($features);
         foreach ($features as $feature_id => $value_id) {
             $code = $map[$feature_id];
             $value = $data[$code]['values'][$value_id];
             $sku['features'][$code] = $value;
             $sku['name'][] = ifset($value['value'], $value['id']);
             #correct price
             if (isset($data[$feature_id]['values'][$value_id]['price'])) {
                 self::parseSkuPrice($sku, $data[$feature_id]['values'][$value_id]['price']);
             }
             #set counts per stock
             if (isset($data[$feature_id]['stock'])) {
                 self::parseSkuStock($sku, $data[$feature_id]['stock'], $value_id == $last_value_id ? count($f) : null);
             }
             $sku_key .= $feature_id . ":" . $value_id . ";";
             $sku['key'] = $sku_key;
         }
         #concat name from feature values
         $sku['name'] = implode(', ', $sku['name']);
         if (isset($sku_map[$sku_key])) {
             // already exists
             $sku_id = $sku_map[$sku_key];
             if (!empty($skus[$sku_id]['virtual'])) {
                 //update SKU if still virtual
                 $skus[$sku_id] = array_merge($skus[$sku_id], $sku);
             }
             $sku_map[$sku_key] = false;
         } else {
             # get free sku_id
             do {
                 --$i;
             } while (isset($skus[$i]));
             $skus[$i] = array_merge($default_sku, $sku);
         }
     }
     if ($product->id) {
         // remove old virtual skus
         $sku_map = array_filter($sku_map);
         foreach ($sku_map as $key => $sku_id) {
             if (isset($skus[$sku_id])) {
                 if (empty($skus[$sku_id]['virtual'])) {
                     unset($sku_map[$key]);
                 } else {
                     unset($skus[$sku_id]);
                 }
             }
         }
         if ($sku_map && false) {
             $product_skus_model = new shopProductSkusModel();
             $product_skus_model->deleteJoin('shop_product_features', $product->id, array('virtual' => 1, 'id' => $sku_map));
             $product_skus_model->deleteByField(array('product_id' => $product->id, 'virtual' => 1, 'id' => $sku_map));
         }
     }
     $product->skus = $skus;
     return $sku_map;
 }
 public function execute()
 {
     $code = waRequest::cookie('shop_cart');
     if (!$code) {
         $code = md5(uniqid(time(), true));
         // header for IE
         wa()->getResponse()->addHeader('P3P', 'CP="NOI ADM DEV COM NAV OUR STP"');
         // set cart cookie
         wa()->getResponse()->setCookie('shop_cart', $code, time() + 30 * 86400, null, '', false, true);
     }
     $this->cart = new shopCart($code);
     $this->cart_model = new shopCartItemsModel();
     $data = waRequest::post();
     $this->is_html = waRequest::request('html');
     // add service
     if (isset($data['parent_id'])) {
         $this->addService($data);
         return;
     }
     // add sku
     $sku_model = new shopProductSkusModel();
     $product_model = new shopProductModel();
     if (!isset($data['product_id'])) {
         $sku = $sku_model->getById($data['sku_id']);
         $product = $product_model->getById($sku['product_id']);
     } else {
         $product = $product_model->getById($data['product_id']);
         if (isset($data['sku_id'])) {
             $sku = $sku_model->getById($data['sku_id']);
         } else {
             if (isset($data['features'])) {
                 $product_features_model = new shopProductFeaturesModel();
                 $sku_id = $product_features_model->getSkuByFeatures($product['id'], $data['features']);
                 if ($sku_id) {
                     $sku = $sku_model->getById($sku_id);
                 } else {
                     $sku = null;
                 }
             } else {
                 $sku = $sku_model->getById($product['sku_id']);
                 if (!$sku['available']) {
                     $sku = $sku_model->getByField(array('product_id' => $product['id'], 'available' => 1));
                 }
                 if (!$sku) {
                     $this->errors = _w('This product is not available for purchase');
                     return;
                 }
             }
         }
     }
     $quantity = waRequest::post('quantity', 1);
     if ($product && $sku) {
         // check quantity
         if (!wa()->getSetting('ignore_stock_count')) {
             $c = $this->cart_model->countSku($code, $sku['id']);
             if ($sku['count'] !== null && $c + $quantity > $sku['count']) {
                 $quantity = $sku['count'] - $c;
                 $name = $product['name'] . ($sku['name'] ? ' (' . $sku['name'] . ')' : '');
                 if (!$quantity) {
                     $this->errors = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                     return;
                 } else {
                     $this->response['error'] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                 }
             }
         }
         $services = waRequest::post('services', array());
         if ($services) {
             $variants = waRequest::post('service_variant');
             $temp = array();
             $service_ids = array();
             foreach ($services as $service_id) {
                 if (isset($variants[$service_id])) {
                     $temp[$service_id] = $variants[$service_id];
                 } else {
                     $service_ids[] = $service_id;
                 }
             }
             if ($service_ids) {
                 $service_model = new shopServiceModel();
                 $temp_services = $service_model->getById($service_ids);
                 foreach ($temp_services as $row) {
                     $temp[$row['id']] = $row['variant_id'];
                 }
             }
             $services = $temp;
         }
         $item_id = null;
         $item = $this->cart_model->getItemByProductAndServices($code, $product['id'], $sku['id'], $services);
         if ($item) {
             $item_id = $item['id'];
             $this->cart->setQuantity($item_id, $item['quantity'] + $quantity);
         }
         if (!$item_id) {
             $data = array('create_datetime' => date('Y-m-d H:i:s'), 'product_id' => $product['id'], 'sku_id' => $sku['id'], 'quantity' => $quantity, 'type' => 'product');
             if ($services) {
                 $data_services = array();
                 foreach ($services as $service_id => $variant_id) {
                     $data_services[] = array('service_id' => $service_id, 'service_variant_id' => $variant_id);
                 }
             } else {
                 $data_services = array();
             }
             $item_id = $this->cart->addItem($data, $data_services);
         }
         if (waRequest::isXMLHttpRequest()) {
             $this->response['item_id'] = $item_id;
             $this->response['total'] = $this->currencyFormat($this->cart->total());
             $this->response['discount'] = $this->currencyFormat($this->cart->discount());
             $this->response['count'] = $this->cart->count();
         } else {
             $this->redirect(waRequest::server('HTTP_REFERER'));
         }
     } else {
         throw new waException('product not found');
     }
 }
 private function workupList(&$list, $fields)
 {
     if (!$list) {
         return;
     }
     foreach ($list as &$v) {
         $v['icon'] = shopProductStocksLogModel::getIcon($v['type']);
         if (!$v['description']) {
             if ($v['after_count'] === null) {
                 $v['description'] = _w('In stock value updated to ∞');
             } else {
                 $v['description'] = sprintf(_w('In stock value updated to %d'), $v['after_count']);
             }
         } else {
             if ($v['type'] == self::TYPE_ORDER) {
                 $v['description'] = sprintf(_w($v['description']), '<a href="?action=orders#/order/' . $v['order_id'] . '/">' . shopHelper::encodeOrderId($v['order_id']) . '</a>');
             }
         }
     }
     unset($v);
     $stock_ids = array();
     foreach ($list as $v) {
         $stock_ids[] = $v['stock_id'];
     }
     $model = new shopStockModel();
     $stocks = $model->getByField('id', array_unique($stock_ids), 'id');
     foreach ($list as &$v) {
         if (isset($stocks[$v['stock_id']])) {
             $v['stock_name'] = $stocks[$v['stock_id']]['name'];
         }
     }
     unset($v);
     foreach ($fields as $f) {
         if ($f == 'sku_name') {
             $sku_ids = array();
             foreach ($list as $v) {
                 $sku_ids[] = $v['sku_id'];
             }
             $model = new shopProductSkusModel();
             $skus = $model->select('id,sku,name')->where("id IN(" . implode(',', array_unique($sku_ids)) . ")")->fetchAll('id');
             foreach ($list as &$v) {
                 if (isset($skus[$v['sku_id']])) {
                     $v['sku_name'] = $skus[$v['sku_id']]['name'];
                     if ($v['sku_name']) {
                         if ($skus[$v['sku_id']]['sku']) {
                             $v['sku_name'] .= ' (' . $skus[$v['sku_id']]['sku'] . ')';
                         }
                     } else {
                         if ($skus[$v['sku_id']]['sku']) {
                             $v['sku_name'] = $skus[$v['sku_id']]['sku'];
                         }
                     }
                 }
             }
             unset($v);
         }
         if ($f == 'product_name') {
             $product_ids = array();
             foreach ($list as $v) {
                 $product_ids[] = $v['product_id'];
             }
             $model = new shopProductModel();
             $products = $model->select('id,name')->where("id IN (" . implode(',', array_unique($product_ids)) . ")")->fetchAll('id');
             foreach ($list as &$v) {
                 if (isset($products[$v['product_id']])) {
                     $v['product_name'] = $products[$v['product_id']]['name'];
                 }
             }
             unset($v);
         }
     }
 }
 private function _getOrderData($order_id)
 {
     $order_model = new shopOrderModel();
     $order = $order_model->getById($order_id);
     if (!$order) {
         return false;
     }
     $order_items_model = new shopOrderItemsModel();
     $items_res = $order_items_model->getByField('order_id', $order_id, true);
     $items = array();
     $total_price = 0;
     $sku_model = new shopProductSkusModel();
     $ret = new stdClass();
     foreach ($items_res as $product) {
         $skus = $sku_model->getDataByProductId($product['product_id']);
         $product['product'] = reset($skus);
         $product_id = $product['product_id'];
         if ($product['sku_id'] != $product['product']['id']) {
             $product_id .= 's' . $product['sku_id'];
         }
         $items[] = array('product_id' => $product_id, 'qnt' => $product['quantity'], 'price' => $product['price'], 'product_name' => $product['name']);
         $total_price = $total_price + $product['price'] * $product['quantity'];
     }
     $ret->order_id = $order_id;
     $ret->items = $items;
     $ret->revenue = $total_price;
     $ret->state = $this->_switchState($order['state_id']);
     $ret->order = $order;
     return $ret;
 }
Example #30
0
 /**
  * @param int $id
  * @return bool
  */
 public function correct($id)
 {
     if (!$id) {
         return false;
     }
     $id = (int) $id;
     $product = $this->getById($id);
     $product_skus_model = new shopProductSkusModel();
     $skus = $product_skus_model->getDataByProductId($id, true);
     $currency_model = new shopCurrencyModel();
     $currency = wa('shop')->getConfig()->getCurrency();
     $price = array();
     $update_product_data = array();
     // aggregate count by stocks for product
     // Invariant: if at least one sku.count IS NULL this aggregate count IS NULL
     $product_count = 0;
     $available_sku_count = 0;
     foreach ($skus as $sku) {
         if ($sku['available']) {
             $available_sku_count++;
         }
         $price[] = $this->castValue('double', $sku['price']);
         $sku_count = 0;
         $num_of_null = 0;
         foreach ($sku['stock'] as $count) {
             if ($count === null) {
                 // turn into NULL and is not longer changing
                 $sku_count = null;
                 $num_of_null++;
             } else {
                 // Once turned into NULL value is not changed
                 if ($sku_count !== null) {
                     $sku_count += $count;
                 }
             }
         }
         if ($num_of_null == count($sku['stock'])) {
             // all stock count is null means that not multistocking
             $sku_count = $sku['count'];
         }
         // maintain product_count invariant. See above
         if ($sku['available']) {
             if ($sku_count === null) {
                 $product_count = null;
             } elseif ($product_count !== null) {
                 $product_count += $sku_count;
             }
         }
     }
     if ($available_sku_count == 0) {
         $product_count = 0;
     }
     if (!$price) {
         $price[] = 0;
     }
     $update_product_data['sku_count'] = count($skus);
     $update_product_data['min_price'] = $currency_model->convert(min($price), $product['currency'], $currency);
     $update_product_data['max_price'] = $currency_model->convert(max($price), $product['currency'], $currency);
     $update_product_data['price'] = $currency_model->convert($skus[$product['sku_id']]['price'], $product['currency'], $currency);
     if (isset($skus[$product['sku_id']]['compare_price'])) {
         $update_product_data['compare_price'] = $currency_model->convert($skus[$product['sku_id']]['compare_price'], $product['currency'], $currency);
     }
     $update_product_data['count'] = $product_count;
     $this->updateById($product['id'], $update_product_data);
     return true;
 }