From ad9b9ca961d8f2c8c8ffa587867c194b9f1b6b71 Mon Sep 17 00:00:00 2001 From: Karnovsky A Date: Fri, 29 Apr 2016 10:22:10 +0300 Subject: [PATCH] Karnovsky-29042016-1020 --- backend/config/main.php | 3 +++ backend/views/category/_form.php | 29 +++++++++++++++++++++++++++++ backend/views/category/index.php | 15 ++++++++++----- backend/views/layouts/main-sidebar.php | 1 + common/components/artboxtree/ArtboxTreeHelper.php | 17 +++++++++++++++++ common/modules/product/CatalogUrlManager.php | 16 ++++++++++++++-- common/modules/product/controllers/ManageController.php | 11 +++++++++++ common/modules/product/helpers/ProductHelper.php | 18 ++++++++++++++++++ common/modules/product/models/BrandSearch.php | 12 +++++++----- common/modules/product/models/Category.php | 30 ++++++++++++++++++++++-------- common/modules/product/models/CategorySearch.php | 16 ++++++++++++++++ common/modules/product/models/ProductSearch.php | 9 +++++++++ common/modules/product/models/ProductVariant.php | 4 +++- common/modules/product/models/ProductVariantSearch.php | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/modules/product/models/RemoteCategories.php | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/modules/product/models/RemoteCategoriesSearch.php | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/modules/product/models/RemoteProducts.php | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/modules/product/models/RemoteProductsSearch.php | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/modules/product/views/manage/_form.php | 5 +++-- common/modules/product/views/manage/remote-products.php | 42 ++++++++++++++++++++++++++++++++++++++++++ common/translation/ru/product.php | 3 +++ console/controllers/ImportController.php | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/controllers/CatalogController.php | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- frontend/models/ProductFrontendSearch.php | 44 ++++++++++++++++++++++++++++++-------------- frontend/views/catalog/product.php | 93 +++++++++++++-------------------------------------------------------------------------------- frontend/views/catalog/product_smart.php | 20 ++++++++++++++++++++ frontend/views/catalog/products.php | 19 ++++++++++++++++--- frontend/views/catalog/search.php | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/layouts/main.php | 2 +- 29 files changed, 998 insertions(+), 124 deletions(-) create mode 100644 common/modules/product/models/ProductVariantSearch.php create mode 100644 common/modules/product/models/RemoteCategories.php create mode 100644 common/modules/product/models/RemoteCategoriesSearch.php create mode 100644 common/modules/product/models/RemoteProducts.php create mode 100644 common/modules/product/models/RemoteProductsSearch.php create mode 100644 common/modules/product/views/manage/remote-products.php create mode 100644 console/controllers/ImportController.php create mode 100644 frontend/views/catalog/product_smart.php create mode 100644 frontend/views/catalog/search.php diff --git a/backend/config/main.php b/backend/config/main.php index 03589cf..a4de962 100755 --- a/backend/config/main.php +++ b/backend/config/main.php @@ -25,6 +25,9 @@ return [ 'product' => [ 'class' => 'common\modules\product\Module' ], + 'gridview' => [ + 'class' => '\kartik\grid\Module' + ] ], 'components' => [ 'user' => [ diff --git a/backend/views/category/_form.php b/backend/views/category/_form.php index 62de6b8..23a0154 100755 --- a/backend/views/category/_form.php +++ b/backend/views/category/_form.php @@ -3,6 +3,7 @@ use yii\helpers\Html; use yii\widgets\ActiveForm; use common\modules\file\widgets\ImageUploader; +use kartik\select2\Select2; /* @var $this yii\web\View */ /* @var $model common\modules\product\models\Category */ @@ -24,10 +25,25 @@ use common\modules\file\widgets\ImageUploader; ] ])->label(Yii::t('product', 'Parent category')) ?> + field($model, 'group_to_category')->dropDownList( \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), [ 'multiple' => true ])->label(Yii::t('product', 'Linked options')) ?> + */?> + + field($model, 'group_to_category')->widget(Select2::className(), [ + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), + 'language' => 'ru', + 'options' => [ + 'placeholder' => 'Linked options', + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ] + ) ?> $model, @@ -52,6 +68,19 @@ use common\modules\file\widgets\ImageUploader; field($model, 'seo_text')->textarea(['rows' => 6]) ?> + field($model, 'remote_category')->widget(Select2::className(), [ + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\product\models\RemoteCategories::find()->all(), 'ID', 'Name'), + 'language' => 'ru', + 'options' => [ + 'placeholder' => 'Select a remote category', + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ] + ) ?> + depth == 2) :?> field($model, 'populary')->checkbox() ?> diff --git a/backend/views/category/index.php b/backend/views/category/index.php index 7fef1f6..f1cb227 100755 --- a/backend/views/category/index.php +++ b/backend/views/category/index.php @@ -1,7 +1,7 @@ params['breadcrumbs'][] = $this->title; ], [ 'class' => 'yii\grid\ActionColumn', - 'template' => '{populary} {view} {update} {delete}', + 'template' => '{view} {update} {delete} {populary}', 'buttons' => [ 'populary' => function ($url, $model) { - return Html::a('', $url, [ - 'title' => Yii::t('product', ($model->populary ? 'Set not populary' : 'Set populary')), - ]); + if ($model->depth == 2) { + return Html::a('', $url, [ + 'title' => Yii::t('product', ($model->populary ? 'Set not populary' : 'Set populary')), + ]); + } }, ], 'urlCreator' => function ($action, $model, $key, $index) { @@ -63,5 +65,8 @@ $this->params['breadcrumbs'][] = $this->title; } ], ], + 'panel' => [ + 'type'=>'success', + ], ]); ?> diff --git a/backend/views/layouts/main-sidebar.php b/backend/views/layouts/main-sidebar.php index 4534331..a743b36 100755 --- a/backend/views/layouts/main-sidebar.php +++ b/backend/views/layouts/main-sidebar.php @@ -30,6 +30,7 @@ use yii\widgets\Menu; 'url' => ['/product/manage'], 'items' => [ ['label' => 'Товары', 'url' => ['/product/manage']], + ['label' => 'Импорт товаров', 'url' => ['/product/manage/import']], ['label' => 'Категории', 'url' => ['/category']], ['label' => 'Бренды', 'url' => ['/brand']], ] diff --git a/common/components/artboxtree/ArtboxTreeHelper.php b/common/components/artboxtree/ArtboxTreeHelper.php index d5da465..4926c32 100755 --- a/common/components/artboxtree/ArtboxTreeHelper.php +++ b/common/components/artboxtree/ArtboxTreeHelper.php @@ -15,6 +15,23 @@ class ArtboxTreeHelper extends Object { return $result; } + public static function setArrayField($path, $as_string = false) { + if (is_array($path)) { + if ($as_string) { + foreach ($path as &$item) { + $item = "'$item'"; + } + } + $path = implode(',', $path); + } + return '{'. $path .'}'; + } + + public static function getArrayField($path) { + $path = trim($path, '{}'); + return empty($path) ? [] : explode(',', $path); + } + protected static function _recursiveTreeMap(&$result, $tree, $from, $to, $symbol = '–') { foreach ($tree as $item) { $element = $item['item']; diff --git a/common/modules/product/CatalogUrlManager.php b/common/modules/product/CatalogUrlManager.php index b051554..4b8a3e0 100644 --- a/common/modules/product/CatalogUrlManager.php +++ b/common/modules/product/CatalogUrlManager.php @@ -41,8 +41,8 @@ class CatalogUrlManager implements UrlRuleInterface { } $params['category'] = $category; } - // Filter if (!empty($paths[2])) { + // Filter if (strpos($paths[2], 'filter:') === 0) { $params['filter'] = []; $filter_str = substr($paths[2], 7); @@ -65,6 +65,8 @@ class CatalogUrlManager implements UrlRuleInterface { } } + } elseif (strpos($paths[2], 'word:') === 0) { + $params['word'] = substr($paths[2], 5); } } } elseif ($paths[0] == 'product') { @@ -99,8 +101,17 @@ class CatalogUrlManager implements UrlRuleInterface { case 'catalog/category': if (!empty($params['category'])) { $category_alias = is_object($params['category']) ? $params['category']->alias : strtolower($params['category']); + $url = 'catalog/'. $category_alias .'/'; + } else { + $url = 'catalog/'; + } + + if (!empty($params['word'])) { + if (!is_array($params['word'])) { + $params['word'] = [$params['word']]; + } + $url .= 'word:'. implode(';', $params['word']); } - $url = 'catalog/'. $category_alias .'/'; $filter = []; if (!empty($params['filter'])) { @@ -135,6 +146,7 @@ class CatalogUrlManager implements UrlRuleInterface { } $url .= 'filter:'. implode(';', $filter); } + return $url; break; diff --git a/common/modules/product/controllers/ManageController.php b/common/modules/product/controllers/ManageController.php index f7bb879..940921a 100755 --- a/common/modules/product/controllers/ManageController.php +++ b/common/modules/product/controllers/ManageController.php @@ -5,6 +5,7 @@ namespace common\modules\product\controllers; use common\modules\product\helpers\ProductHelper; use common\modules\product\models\Category; use common\modules\product\models\ProductVariant; +use common\modules\product\models\RemoteProductsSearch; use Yii; use common\modules\product\models\Product; use common\modules\product\models\ProductSearch; @@ -162,6 +163,16 @@ class ManageController extends Controller return $this->redirect(['index']); } + public function actionImport() { + $searchModel = new RemoteProductsSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('remote-products', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + /** * Finds the Product model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. diff --git a/common/modules/product/helpers/ProductHelper.php b/common/modules/product/helpers/ProductHelper.php index 6662870..c16c184 100755 --- a/common/modules/product/helpers/ProductHelper.php +++ b/common/modules/product/helpers/ProductHelper.php @@ -4,7 +4,9 @@ namespace common\modules\product\helpers; use common\modules\product\models\Brand; use common\modules\product\models\Category; +use common\modules\product\models\Product; use yii\base\Object; +use Yii; class ProductHelper extends Object { public static function getCategories() { @@ -55,4 +57,20 @@ class ProductHelper extends Object { } return $result; } + + public static function addLastProsucts($product_id) { + $last_products = self::getLastProducts(); + if (!in_array($product_id, $last_products)) { + $last_products[] = $product_id; + Yii::$app->session->set('last_products', $last_products); + } + } + + public static function getLastProducts($as_object = false) { + $last_products = Yii::$app->session->get('last_products', []); + if ($as_object) { + $last_products = Product::find()->where(['product_id' => $last_products])->all(); + } + return $last_products; + } } \ No newline at end of file diff --git a/common/modules/product/models/BrandSearch.php b/common/modules/product/models/BrandSearch.php index 711aabf..eac3036 100755 --- a/common/modules/product/models/BrandSearch.php +++ b/common/modules/product/models/BrandSearch.php @@ -73,7 +73,7 @@ class BrandSearch extends Brand return $dataProvider; } - public function getBrands($category, $params) { + public function getBrands($category = null, $params = []) { $query = Brand::find() ->select([ Brand::tableName() .'.*', @@ -82,11 +82,13 @@ class BrandSearch extends Brand ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') - ->with('brandName') - ->where([ + ->with('brandName'); + if (!empty($category)) { + $query->where([ ProductCategory::tableName() .'.category_id' => $category->category_id - ]) - ->groupBy(Brand::tableName() .'.brand_id'); + ]); + } + $query->groupBy(Brand::tableName() .'.brand_id'); if (isset($params['options'])) { unset($params['options']); } diff --git a/common/modules/product/models/Category.php b/common/modules/product/models/Category.php index fac5f3b..f474cee 100755 --- a/common/modules/product/models/Category.php +++ b/common/modules/product/models/Category.php @@ -4,6 +4,7 @@ namespace common\modules\product\models; use common\behaviors\RuSlug; use common\components\artboxtree\ArtboxTreeBehavior; +use common\components\artboxtree\ArtboxTreeHelper; use common\modules\relation\relationBehavior; use common\modules\rubrication\behaviors\ArtboxSynonymBehavior; use Yii; @@ -12,6 +13,7 @@ use Yii; * This is the model class for table "category". * * @property integer $category_id + * @property string $remote_id * @property integer $parent_id * @property string $path * @property integer $depth @@ -86,7 +88,7 @@ class Category extends \yii\db\ActiveRecord [['meta_robots'], 'string', 'max' => 50], [['alias', 'name'], 'string', 'max' => 250], [['populary'], 'boolean'], - [['group_to_category'], 'safe'], + [['group_to_category', 'remote_category'], 'safe'], [['category_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => CategoryName::className(), 'targetAttribute' => ['category_name_id' => 'category_name_id']], // [['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'], // [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], @@ -112,6 +114,7 @@ class Category extends \yii\db\ActiveRecord 'alias' => Yii::t('product', 'Alias'), 'populary' => Yii::t('product', 'Populary'), 'name' => Yii::t('product', 'Name'), + 'remote_id' => Yii::t('product', 'Remote ID'), ]; } @@ -147,15 +150,14 @@ class Category extends \yii\db\ActiveRecord return $this->getRelations('tax_group_to_category'); } - public function beforeSave($insert) - { - if (parent::beforeSave($insert)) { + public function getRemote_category() { + return ArtboxTreeHelper::getArrayField($this->remote_id); + } - if (empty($this->parent_id)) - $this->parent_id = 0; - return true; + public function setRemote_category($value) { + if (!empty($value) && is_array($value)) { + $this->remote_id = ArtboxTreeHelper::setArrayField($value, false); } - return false; } public function getCategoryName() { @@ -165,4 +167,16 @@ class Category extends \yii\db\ActiveRecord public function getName() { return empty($this->categoryName) ? null : $this->categoryName->value; } + + public function beforeSave($insert) + { + if (parent::beforeSave($insert)) { + + if (empty($this->parent_id)) + $this->parent_id = 0; + + return true; + } + return false; + } } diff --git a/common/modules/product/models/CategorySearch.php b/common/modules/product/models/CategorySearch.php index 1155ea2..d3146aa 100755 --- a/common/modules/product/models/CategorySearch.php +++ b/common/modules/product/models/CategorySearch.php @@ -2,6 +2,7 @@ namespace common\modules\product\models; +use common\components\artboxtree\ArtboxTreeHelper; use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; @@ -97,4 +98,19 @@ class CategorySearch extends Category throw new NotFoundHttpException('The requested page does not exist.'); } } + + public static function findByRemoteID($id) { + /** @var CategoryQuery $query */ + $query = Category::find() + ->with('categoryName') + ->andFilterWhere(['@>', 'remote_id', ArtboxTreeHelper::setArrayField($id)]); + if (($model = $query->one()) !== null) { + return $model; + } + return null; + } + +// public static function findByProductsKeywords($keywords = [], $category = null) { +// +// } } diff --git a/common/modules/product/models/ProductSearch.php b/common/modules/product/models/ProductSearch.php index f59ea6a..4e96614 100755 --- a/common/modules/product/models/ProductSearch.php +++ b/common/modules/product/models/ProductSearch.php @@ -80,4 +80,13 @@ class ProductSearch extends Product } } + public static function findByRemoteID($id) { + /** @var CategoryQuery $query */ + $query = Product::find() + ->andFilterWhere(['remote_id' => $id]); + if (($model = $query->one()) !== null) { + return $model; + } + return null; + } } diff --git a/common/modules/product/models/ProductVariant.php b/common/modules/product/models/ProductVariant.php index e63190a..5172ffa 100755 --- a/common/modules/product/models/ProductVariant.php +++ b/common/modules/product/models/ProductVariant.php @@ -10,6 +10,7 @@ use Yii; * @property integer $product_variant_id * @property integer $product_id * @property string $name + * @property string $remote_id * @property string $sku * @property double $price * @property double $price_old @@ -34,10 +35,11 @@ class ProductVariant extends \yii\db\ActiveRecord public function rules() { return [ - [['product_id', 'name', 'sku', 'product_unit_id'], 'required'], + [['product_id', 'sku', 'product_unit_id'], 'required'], [['product_id', 'product_unit_id'], 'integer'], [['price', 'price_old', 'stock'], 'number'], [['name', 'sku'], 'string', 'max' => 255], + [['remote_id'], 'string', 'max' => 20], [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], ]; } diff --git a/common/modules/product/models/ProductVariantSearch.php b/common/modules/product/models/ProductVariantSearch.php new file mode 100644 index 0000000..17631fe --- /dev/null +++ b/common/modules/product/models/ProductVariantSearch.php @@ -0,0 +1,91 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'product_variant_id' => $this->product_variant_id, + 'product_id' => $this->product_id, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]) + ->andFilterWhere(['like', 'sku', $this->sku]); + + return $dataProvider; + } + + public static function findBySku($sku) { + /** @var ProductQuery $query */ + $query = ProductVariant::find() + ->andFilterWhere(['sku' => $sku]); + if (($model = $query->one()) !== null) { + return $model; + } + return; + } + + public static function findByRemoteID($id) { + /** @var CategoryQuery $query */ + $query = ProductVariant::find() + ->andFilterWhere(['remote_id' => $id]); + if (($model = $query->one()) !== null) { + return $model; + } + return; + } +} diff --git a/common/modules/product/models/RemoteCategories.php b/common/modules/product/models/RemoteCategories.php new file mode 100644 index 0000000..b9b6ae2 --- /dev/null +++ b/common/modules/product/models/RemoteCategories.php @@ -0,0 +1,63 @@ + 100], + [['ID_chief', 'ID'], 'string', 'max' => 20], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'Name' => Yii::t('product', 'Name'), + 'ID_chief' => Yii::t('product', 'Id Chief'), + 'ID' => Yii::t('product', 'ID'), + ]; + } + + public function getCategory() { + if (empty($this->ID)) { + return null; + } + return CategorySearch::findByRemoteID($this->ID); + } + + public static function findByID($id) { + /** @var CategoryQuery $query */ + $query = RemoteCategories::find() + ->andFilterWhere(['ID' => $id]); + if (($model = $query->one()) !== null) { + return $model; + } + return null; + } +} diff --git a/common/modules/product/models/RemoteCategoriesSearch.php b/common/modules/product/models/RemoteCategoriesSearch.php new file mode 100644 index 0000000..6cdc2b3 --- /dev/null +++ b/common/modules/product/models/RemoteCategoriesSearch.php @@ -0,0 +1,71 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'local_id' => $this->local_id, + ]); + + $query->andFilterWhere(['like', 'Name', $this->Name]) + ->andFilterWhere(['like', 'ID_chief', $this->ID_chief]) + ->andFilterWhere(['like', 'ID', $this->ID]); + + return $dataProvider; + } +} diff --git a/common/modules/product/models/RemoteProducts.php b/common/modules/product/models/RemoteProducts.php new file mode 100644 index 0000000..981f933 --- /dev/null +++ b/common/modules/product/models/RemoteProducts.php @@ -0,0 +1,77 @@ + 100], + [['ID_chief', 'Article', 'ID'], 'string', 'max' => 20], + [['Brand'], 'string', 'max' => 25], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'Name' => Yii::t('product', 'Name'), + 'Price' => Yii::t('product', 'Price'), + 'Price_old' => Yii::t('product', 'Price Old'), + 'ID_chief' => Yii::t('product', 'Id Chief'), + 'Article' => Yii::t('product', 'Article'), + 'Brand' => Yii::t('product', 'Brand'), + 'ID' => Yii::t('product', 'ID'), + 'Date_create' => Yii::t('product', 'Date Create'), + 'local_id' => Yii::t('product', 'Local ID'), + ]; + } + + public function getRemoteCategory() { + if (empty($this->ID_chief)) { + return null; + } + return RemoteCategories::findByID($this->ID_chief); + } + + public function getProduct() { + if (empty($this->ID)) { + return null; + } + return ProductVariantSearch::findByRemoteID($this->ID); + } +} diff --git a/common/modules/product/models/RemoteProductsSearch.php b/common/modules/product/models/RemoteProductsSearch.php new file mode 100644 index 0000000..7766eab --- /dev/null +++ b/common/modules/product/models/RemoteProductsSearch.php @@ -0,0 +1,77 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'Price' => $this->Price, + 'Price_old' => $this->Price_old, + 'Date_create' => $this->Date_create, + 'local_id' => $this->local_id, + ]); + + $query->andFilterWhere(['like', 'Name', $this->Name]) + ->andFilterWhere(['like', 'ID_chief', $this->ID_chief]) + ->andFilterWhere(['like', 'Article', $this->Article]) + ->andFilterWhere(['like', 'Brand', $this->Brand]) + ->andFilterWhere(['like', 'ID', $this->ID]); + + return $dataProvider; + } +} diff --git a/common/modules/product/views/manage/_form.php b/common/modules/product/views/manage/_form.php index 19520f9..c22a817 100755 --- a/common/modules/product/views/manage/_form.php +++ b/common/modules/product/views/manage/_form.php @@ -8,6 +8,7 @@ use common\modules\product\helpers\ProductHelper; use kartik\file\FileInput; use unclead\widgets\MultipleInput; use unclead\widgets\MultipleInputColumn; +use kartik\select2\Select2; /* @var $this yii\web\View */ /* @var $model common\modules\product\models\Product */ @@ -30,9 +31,9 @@ use unclead\widgets\MultipleInputColumn; ] ) ?> - field($model, 'categories')->widget(\kartik\select2\Select2::className(), [ + field($model, 'categories')->widget(Select2::className(), [ 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), - 'language' => 'de', + 'language' => 'ru', 'options' => [ 'placeholder' => 'Select a state ...', 'multiple' => true, diff --git a/common/modules/product/views/manage/remote-products.php b/common/modules/product/views/manage/remote-products.php new file mode 100644 index 0000000..0d94965 --- /dev/null +++ b/common/modules/product/views/manage/remote-products.php @@ -0,0 +1,42 @@ +title = Yii::t('product', 'Remote Products'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success']) ?> +

+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'Name', + 'ID_chief', + 'Article', + 'Price', + 'Price_old', + 'Brand', + 'ID', + 'Date_create', + 'remoteCategory.category.name', + 'remoteCategory.Name', + // 'local_id', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/common/translation/ru/product.php b/common/translation/ru/product.php index cdd0686..ca98483 100644 --- a/common/translation/ru/product.php +++ b/common/translation/ru/product.php @@ -5,4 +5,7 @@ return [ 'Name' => 'Наименование', 'Set populary' => 'Сделать популярной', 'Set not populary' => 'Сделать не популярной', + 'Remote ID' => 'ID в 1С', + 'Search for "{keywords}"' => 'Поиск по "{keywords}"', + 'Search for "{keywords}" in category "{category}"' => 'Поиск по "{keywords}" в категории "{category}"', ]; \ No newline at end of file diff --git a/console/controllers/ImportController.php b/console/controllers/ImportController.php new file mode 100644 index 0000000..63a28a1 --- /dev/null +++ b/console/controllers/ImportController.php @@ -0,0 +1,147 @@ +stdout("What is $section?\n"); + return Controller::EXIT_CODE_ERROR; + } + + $this->$method(); + + return Controller::EXIT_CODE_NORMAL; + } + + public function goGo() { + $new_products = $linked_products = 0; + foreach(RemoteProducts::find()->all() as $product) { + if (!empty($product->product->product_id)) { + $linked_products++; + + $_productVariant = ProductVariant::findOne($product->product->product_id); + $_product = Product::findOne($_productVariant->product_id); + + if ( + $_product->name != $product->Name || + $_product->categories != [$product->remoteCategory->category->category_id] || + ($product->Brand && ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null && $_product->brand_id != $brand->brand_id) + ) { + $_product->name = $product->Name; + $_product->categories = [$product->remoteCategory->category->category_id]; + if ( $product->Brand ) { + if ( ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null ) { + $_product->brand_id = $brand->brand_id; + } else { + // Create brand + $brand = new Brand(); + $brand->name = trim($product->Brand); + $brand->save(); + $_product->brand_id = $brand->brand_id; + } + } + $_product->save(); + } + + if ( + $_productVariant->price != floatval($product->Price) || + $_productVariant->price_old != floatval($product->Price_old) || + (!empty($product->Article) && $_productVariant->sku != $product->Article) + ) { + $_productVariant->price = floatval($product->Price); + $_productVariant->price_old = floatval($product->Price_old); + $_productVariant->sku = empty($product->Article) ? uniqid('gds_') : $product->Article; + if (!$_productVariant->price) { + $_productVariant->stock = 0; + } + $_productVariant->save(); + } + } elseif (!empty($product->remoteCategory) && !empty($product->remoteCategory->category) && !empty($product->remoteCategory->category->category_id)) { + $new_products++; + + $_product = new Product(); + $_productVariant = new ProductVariant(); + $_product->name = $product->Name; + $_product->categories = [$product->remoteCategory->category->category_id]; + + if ( $product->Brand ) { + if ( ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null ) { + $_product->brand_id = $brand->brand_id; + } else { + // Create brand + $brand = new Brand(); + $brand->name = trim($product->Brand); + $brand->save(); + $_product->brand_id = $brand->brand_id; + } + } + + $_productVariant->price = floatval($product->Price); + $_productVariant->price_old = floatval($product->Price_old); + $_productVariant->sku = empty($product->Article) ? uniqid('gds_') : $product->Article; + $_productVariant->product_unit_id = 1; + $_productVariant->remote_id = $product->ID; + $_productVariant->stock = $_productVariant->price > 0 ? null : 0; + + if (!$_product->save()) { + print $this->stdout("Saved error for the {$_product->name} {$_product->product_id}?\n"); + return Controller::EXIT_CODE_ERROR; + } + + $_productVariant->product_id = $_product->product_id; + if (!$_productVariant->save()) { + print $this->stdout("Saved error for variant of the {$_product->name} {$_product->product_id}?\n"); + return Controller::EXIT_CODE_ERROR; + } + } + } + + $this->goStat(); + } + + public function goStat() { + $all_products = $new_products = $linked_products = $orpahed_products = 0; + $remoteProducts = RemoteProducts::find()->all(); + + $not_linked_cats = []; + + foreach($remoteProducts as $product) { + if (!empty($product->product->product_id)) { + $linked_products++; + } elseif (!empty($product->remoteCategory) && !empty($product->remoteCategory->category) && !empty($product->remoteCategory->category->category_id)) { + $new_products++; + } else { + if (!empty($product->remoteCategory)) { + if (empty($not_linked_cats[$product->remoteCategory->ID])) { + $not_linked_cats[$product->remoteCategory->ID] = $product->remoteCategory->Name ." (". $product->remoteCategory->ID .")\n"; + } + } + $orpahed_products++; + } + $all_products++; + } + + $this->stdout("Всего $all_products товаров, $new_products новых и $linked_products уже связанных.\n"); + if (!empty($not_linked_cats)) { + $this->stdout("$orpahed_products товаров не привязаны к категориям:\n"); + foreach ($not_linked_cats as $not_linked_cat) { + $this->stdout("$not_linked_cat"); + } + } + } + + public function goProducts() { + + } +} \ No newline at end of file diff --git a/frontend/controllers/CatalogController.php b/frontend/controllers/CatalogController.php index 496a8cd..944e682 100755 --- a/frontend/controllers/CatalogController.php +++ b/frontend/controllers/CatalogController.php @@ -3,6 +3,7 @@ namespace frontend\controllers; use common\modules\product\Filter; +use common\modules\product\helpers\ProductHelper; use common\modules\rubrication\models\TaxOptionSearch; use frontend\models\ProductFrontendSearch; use Yii; @@ -35,15 +36,54 @@ class CatalogController extends \yii\web\Controller /** @var Category $category */ $category = Yii::$app->request->get('category'); $filter = Yii::$app->request->get('filter', []); + $word = trim(Yii::$app->request->get('word', '')); - if (empty($category->category_id)) { + if (empty($category->category_id) && empty($word)) { throw new HttpException(404 ,'Page not found'); } - if ($category->depth < 2) { + + $last_products = ProductHelper::getLastProducts(true); + + if (!empty($word)) { + $params = []; + + $params['keywords'] = explode(' ', preg_replace("|[\s,.!:&?~();-]|i", " ", $word)); + foreach($params['keywords'] as $i => &$keyword) { + $keyword = trim($keyword); + if (empty($keyword)) { + unset($params['keywords'][$i]); + } + } + + $productModel = new ProductFrontendSearch(); + $productProvider = $productModel->search($category, $params); + + $categoriesQuery = Category::find() + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.category_id = '. Category::tableName() .'.category_id') + ->innerJoin(Product::tableName(), Product::tableName() .'.product_id = '. ProductCategory::tableName() .'.product_id'); + foreach ($params['keywords'] as $keyword) { + $categoriesQuery->andWhere(['ilike', 'product.name', $keyword]); + } + $categories = $categoriesQuery->all(); + + return $this->render( + 'search', + [ + 'keywords' => $params['keywords'], + 'category' => $category, + 'productModel' => $productModel, + 'productProvider' => $productProvider, + 'last_products' => $last_products, + 'categories' => $categories, + ] + ); + + } elseif ($category->depth < 2) { return $this->render( 'categories', [ - 'category' => $category + 'category' => $category, + 'last_products' => $last_products, ] ); } else { @@ -113,6 +153,7 @@ class CatalogController extends \yii\web\Controller 'optionsProvider' => $optionsProvider, 'groups' => $groups, 'priceLimits' => $priceLimits, + 'last_products' => $last_products, ] ); } @@ -134,9 +175,13 @@ class CatalogController extends \yii\web\Controller unset($groups[$i]); } + $last_products = ProductHelper::getLastProducts(true); + ProductHelper::addLastProsucts($product->product_id); + return $this->render('product', [ 'product' => $product, 'properties' => $groups, + 'last_products' => $last_products ]); } diff --git a/frontend/models/ProductFrontendSearch.php b/frontend/models/ProductFrontendSearch.php index 0bf7fd3..7a6c156 100644 --- a/frontend/models/ProductFrontendSearch.php +++ b/frontend/models/ProductFrontendSearch.php @@ -5,6 +5,7 @@ namespace frontend\models; use common\modules\product\models\Brand; use common\modules\product\models\ProductCategory; use common\modules\product\models\ProductOption; +use common\modules\product\models\ProductSearch; use common\modules\rubrication\models\TaxGroup; use common\modules\rubrication\models\TaxOption; use Yii; @@ -43,14 +44,17 @@ class ProductFrontendSearch extends Product { * * @return ActiveDataProvider */ - public function search($category, $params) { - /** @var ActiveQuery $query */ - $query = $category->getRelations('product_categories'); - + public function search($category = null, $params = []) { + if (!empty($category)) { + /** @var ActiveQuery $query */ + $query = $category->getRelations('product_categories'); + } else { + $query = Product::find(); + } $query->joinWith('variant'); $query->joinWith('brand'); - $query->joinWith('categories'); $query->joinWith('image'); + $query->joinWith('categories'); $dataProvider = new ActiveDataProvider([ 'query' => $query, @@ -84,7 +88,7 @@ class ProductFrontendSearch extends Product { return $dataProvider; } - public function optionsForCategory($category, $params) { + public function optionsForCategory($category = null, $params = []) { $query = TaxOption::find() ->select([ TaxOption::tableName() .'.*', @@ -93,11 +97,11 @@ class ProductFrontendSearch extends Product { ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') ->innerJoin(TaxGroup::tableName(), TaxGroup::tableName() .'.tax_group_id='. TaxOption::tableName() .'.tax_group_id') - ->where([ - TaxGroup::tableName() .'.is_filter' => true, - ProductCategory::tableName() .'.category_id' => $category->category_id - ]) - ->groupBy(TaxOption::tableName() .'.tax_option_id'); + ->andWhere([TaxGroup::tableName() .'.is_filter' => true]); + if (!empty($category)) { + $query->andWhere([ProductCategory::tableName() .'.category_id' => $category->category_id]); + } + $query->groupBy(TaxOption::tableName() .'.tax_option_id'); if (!empty($params['prices'])) { if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { @@ -122,9 +126,13 @@ class ProductFrontendSearch extends Product { return $dataProvider; } - public function priceLimits($category, $params) { - /** @var ActiveQuery $query */ - $query = $category->getRelations('product_categories'); + public function priceLimits($category = null, $params = []) { + if (!empty($category)) { + /** @var ActiveQuery $query */ + $query = $category->getRelations('product_categories'); + } else { + $query = Product::find(); + } $query->joinWith('variant'); $this->_setParams($query, $params, false); @@ -141,6 +149,14 @@ class ProductFrontendSearch extends Product { } protected function _setParams(&$query, $params, $setPriceLimits = true) { + if (!empty($params['keywords'])) { + if (!is_array($params['keywords'])) { + $params['keywords'] = [$params['keywords']]; + } + foreach ($params['keywords'] as $keyword) { + $query->andFilterWhere(['ilike', Product::tableName() .'.name', $keyword]); + } + } if (!empty($params['brands'])) { $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); } diff --git a/frontend/views/catalog/product.php b/frontend/views/catalog/product.php index d0029d6..4bb4db7 100755 --- a/frontend/views/catalog/product.php +++ b/frontend/views/catalog/product.php @@ -1,7 +1,6 @@ title = $product->name; foreach($product->category->getParents()->all() as $parent) { $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; @@ -50,13 +49,19 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku;
Код: variant->sku?> - stock !== 0 ? ' есть в наличии' : ' нет в наличии'?> + stock !== 0 && $product->variant->price > 0 ? ' есть в наличии' : ' нет в наличии'?>
-
variant->price?>
+ variant->price > 0) :?> +
+ variant->price?> +
грн.
+ +
+
@@ -214,23 +219,12 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku;
description?>
- -
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. -
video)) :?>
video?>
- -
-
-
-
@@ -239,77 +233,16 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku;
- +
-

Вы недавно просматривали

-
+
diff --git a/frontend/views/catalog/product_smart.php b/frontend/views/catalog/product_smart.php new file mode 100644 index 0000000..a0313e4 --- /dev/null +++ b/frontend/views/catalog/product_smart.php @@ -0,0 +1,20 @@ + +
+ +
+
name?>
+ brand) :?> +
Бренд: brand->name?>
+ +
categoriesNames)?>
+ variant) :?> +
variant->price?> грн.
+ + + добавить к сравнению + +
\ No newline at end of file diff --git a/frontend/views/catalog/products.php b/frontend/views/catalog/products.php index 347835c..5b5aa45 100755 --- a/frontend/views/catalog/products.php +++ b/frontend/views/catalog/products.php @@ -7,12 +7,12 @@ use yii\helpers\Url; use common\modules\product\helpers\ProductHelper; - -$this->title = $category->categoryName->value; +$this->title = $category->categoryName->value; foreach($category->getParents()->all() as $parent) { $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; } $this->params['breadcrumbs'][] = $category->categoryName->value; + $this->params['seo']['seo_text'] = 'TEST SEO TEXT'; $this->params['seo']['h1'] = 'TEST H1'; $this->params['seo']['description'] = 'TEST DESCRIPTION'; @@ -147,10 +147,11 @@ $filterWhitoutPrice['prices'] = [
categoryName->value?> (totalCount?>)
- count) :?>

По данному запросу товары не найдены.


+

Показать все товары из категории "categoryName->value?>"

+
@@ -235,4 +236,16 @@ $filterWhitoutPrice['prices'] = [
+ + +
+
+

Вы недавно просматривали

+
+ + + +
+
+
\ No newline at end of file diff --git a/frontend/views/catalog/search.php b/frontend/views/catalog/search.php new file mode 100644 index 0000000..db193fe --- /dev/null +++ b/frontend/views/catalog/search.php @@ -0,0 +1,136 @@ + implode(' ', $keywords), +]; + +if (!empty($category)) { + $page_data['category'] = $category->name; +} + +$this->title = Yii::t('product', "Search for \"{keywords}\"". (empty($category) ? '' : ' in category \"{category}\"'), $page_data); + +$this->params['seo']['seo_text'] = 'TEST SEO TEXT'; +$this->params['seo']['h1'] = 'TEST H1'; +$this->params['seo']['description'] = 'TEST DESCRIPTION'; +$this->params['seo']['fields']['name'] = 'TEST NAME FROM FIELD'; +$this->params['seo']['key']= 'product_list'; +?> +
+ + +
+
Категории
+
+ +
+
+ + + +
+
totalCount ? ' ('.$productProvider->totalCount .')' : ''?>
+ count) :?> +

По данному запросу товары не найдены.


+ +

Показать все товары из категории "name?>"

+ + + +
+ +
+ Сортировка: + $productProvider->sort, + 'attributes' => [ + 'name', + 'price', + ] + ]); + ?> +
+ +
+ +
+ + totalCount > $productProvider->pagination->pageSize) :?> +
+ Страница: + $productProvider->pagination, + 'options' => ['class' => 'pagination pull-right'], + ]); + ?> +
+ + +
+ +
+
+
+
+ models as $product) :?> + + +
+ + totalCount > $productProvider->pagination->pageSize) :?> + + + +
+ Страница: + $productProvider->pagination, + 'options' => ['class' => 'pagination pull-right'], + ]); + ?> +
+ +
+ + description)) :?> +
+ description?> + +
+
+ +
+
+
+ + +
+ + +
+
+

Вы недавно просматривали

+
+ + + +
+
+ +
\ No newline at end of file diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php index 619470d..2b4e79d 100755 --- a/frontend/views/layouts/main.php +++ b/frontend/views/layouts/main.php @@ -58,7 +58,7 @@ AppAsset::register($this); '0']), ['/'],['class'=>'head_up_cell bau_logo'])?>
-
+
Введите запрос Шифер Рубероид
-- libgit2 0.21.4