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); } }
/** * @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); }
/** * @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; }
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; } }
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; }
/** * @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; }