+ + description)) :?> +
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')) ?> + */?> + + = $form->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 + ], + ] + ) ?> = ImageUploader::widget([ 'model'=> $model, @@ -52,6 +68,19 @@ use common\modules\file\widgets\ImageUploader; = $form->field($model, 'seo_text')->textarea(['rows' => 6]) ?> + = $form->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) :?> = $form->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; ] ) ?> - = $form->field($model, 'categories')->widget(\kartik\select2\Select2::className(), [ + = $form->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; +?> +
+ = Html::a(Yii::t('product', 'Import selected'), ['import'], ['class' => 'btn btn-success']) ?> +
+ = GridView::widget([ + 'dataProvider' => $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'], + ], + ]); ?> +Показать все товары из категории "= $category->categoryName->value?>"
+ + + +Показать все товары из категории "= $category->name?>"
+ + + + + +