
diff --git a/common/components/artboxtree/ArtboxTreeQueryTrait.php b/common/components/artboxtree/ArtboxTreeQueryTrait.php index 635812b..b3b46d4 100755 --- a/common/components/artboxtree/ArtboxTreeQueryTrait.php +++ b/common/components/artboxtree/ArtboxTreeQueryTrait.php @@ -31,7 +31,11 @@ trait ArtboxTreeQueryTrait { if ($with) { $this->with($with); } - $data = $this->all(); + $this->orderBy([$model->keyNameDepth => SORT_ASC]); + $data = []; + foreach($this->all() as $item) { + $data[$item->{$model->keyNameId}] = $item; + } if (empty($data)) return []; @@ -61,7 +65,7 @@ trait ArtboxTreeQueryTrait { $this->_recursiveRebuild($tree); } - protected function buildTree(array $data, $parentId = 0) { + /*protected function buildTree(array $data, $parentId = 0) { $model = $this->getModel(); $result = []; @@ -75,6 +79,28 @@ trait ArtboxTreeQueryTrait { } } return $result; + }*/ + + protected function buildTree(array $data, $parentId = 0) { + $model = $this->getModel(); + + $result = []; + foreach ($data as $element) { + + if ($element->{$model->keyNameDepth} == 0) { + $result[$element->{$model->keyNameId}]['item'] = $element; + $result[$element->{$model->keyNameId}]['children'] = []; + continue; + } + $parents = explode(",", trim($element->{$model->keyNamePath}, '{}')); + $node = &$result[$parents[0]]; + for($i=1;$i<$element->{$model->keyNameDepth};$i++) { + $node = &$node['children'][$parents[$i]]; + } + + $node['children'][$element->{$model->keyNameId}]['item'] = $element; + } + return $result; } public function normalizeTreeData(array $data, $parentId = null) diff --git a/common/config/bootstrap.php b/common/config/bootstrap.php index d195e08..34689a9 100755 --- a/common/config/bootstrap.php +++ b/common/config/bootstrap.php @@ -5,3 +5,6 @@ Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend'); Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console'); Yii::setAlias('@storage', dirname(dirname(__DIR__)) . '/storage'); Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage'); +Yii::setAlias('@imagesDir', dirname(dirname(__DIR__)) . '/frontend/web/images'); +Yii::setAlias('@imagesUrl', '/images'); + diff --git a/common/modules/product/controllers/ManageController.php b/common/modules/product/controllers/ManageController.php index f7bdddb..aab14f3 100755 --- a/common/modules/product/controllers/ManageController.php +++ b/common/modules/product/controllers/ManageController.php @@ -164,9 +164,9 @@ class ManageController extends Controller $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); if ($model->save()) { - foreach ($model->images as $image) { - $image->delete(); - } +// foreach ($model->images as $image) { +// $image->delete(); +// } if ( ($images = $model->imagesUpload()) !== FALSE) { foreach ($images as $image) { @@ -214,6 +214,26 @@ class ManageController extends Controller exit; } + public function actionIs_top($id) { + $model = $this->findModel($id); + + $model->is_top = intval(empty($model->is_top)); + + $model->save(false, ['is_top']); + + return $this->redirect(['index']); + } + + public function actionIs_new($id) { + $model = $this->findModel($id); + + $model->is_new = intval(empty($model->is_new)); + + $model->save(false, ['is_new']); + + return $this->redirect(['index']); + } + public function actionImport() { $searchModel = new RemoteProductsSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); diff --git a/common/modules/product/helpers/ProductHelper.php b/common/modules/product/helpers/ProductHelper.php index c16c184..8c019a3 100755 --- a/common/modules/product/helpers/ProductHelper.php +++ b/common/modules/product/helpers/ProductHelper.php @@ -5,6 +5,7 @@ namespace common\modules\product\helpers; use common\modules\product\models\Brand; use common\modules\product\models\Category; use common\modules\product\models\Product; +use common\modules\product\models\ProductVariant; use yii\base\Object; use Yii; @@ -73,4 +74,15 @@ class ProductHelper extends Object { } return $last_products; } + + public static function getSpecialProducts($type, $count, $sort = null) { + $data = [$type => true]; + return Product::find() +// ->joinWith('variants') + ->where($data) +// ->andWhere(['!=', ProductVariant::tableName() .'.stock', 0]) + ->limit($count) + /*->orderBy($sort)*/ + ->all(); + } } \ No newline at end of file diff --git a/common/modules/product/models/Product.php b/common/modules/product/models/Product.php index f9641df..56c1019 100755 --- a/common/modules/product/models/Product.php +++ b/common/modules/product/models/Product.php @@ -203,26 +203,28 @@ class Product extends \yii\db\ActiveRecord // // } - $todel = []; - foreach ($this->variants ? : [] as $_variant) { - $todel[$_variant->product_variant_id] = $_variant->product_variant_id; - } - foreach ($this->_variants as $_variant) { - if (!is_array($_variant)) { - return; + if (!empty($this->_variants)) { + $todel = []; + foreach ($this->variants ?: [] as $_variant) { + $todel[$_variant->product_variant_id] = $_variant->product_variant_id; } - if (!empty($_variant['product_variant_id'])) { - unset($todel[$_variant['product_variant_id']]); - $model = ProductVariant::findOne($_variant['product_variant_id']); - } else { - $model = new ProductVariant(); + foreach ($this->_variants as $_variant) { + if (!is_array($_variant)) { + return; + } + if (!empty($_variant['product_variant_id'])) { + unset($todel[$_variant['product_variant_id']]); + $model = ProductVariant::findOne($_variant['product_variant_id']); + } else { + $model = new ProductVariant(); + } + $_variant['product_id'] = $this->product_id; + $model->load(['ProductVariant' => $_variant]); + $model->save(); + } + if (!empty($todel)) { + ProductVariant::deleteAll(['product_variant_id' => $todel]); } - $_variant['product_id'] = $this->product_id; - $model->load(['ProductVariant' => $_variant]); - $model->save(); - } - if (!empty($todel)) { - ProductVariant::deleteAll(['product_variant_id' => $todel]); } } @@ -254,6 +256,12 @@ class Product extends \yii\db\ActiveRecord } } + public function getImageUrl() + { + $image = empty($this->variant) ? null : $this->variant->image; + return !empty($image) ? $image->imageUrl : '/images/no_photo.png'; + } + public function getImagesHTML() { $op = []; if ($this->images) { diff --git a/common/modules/product/models/ProductImage.php b/common/modules/product/models/ProductImage.php index daa3447..52d8fdd 100755 --- a/common/modules/product/models/ProductImage.php +++ b/common/modules/product/models/ProductImage.php @@ -110,7 +110,6 @@ class ProductImage extends \yii\db\ActiveRecord return isset($this->image) ? '/images/products/'. $this->image : '/images/no_photo.png'; } - /** * Process upload of image * diff --git a/common/modules/product/models/ProductSearch.php b/common/modules/product/models/ProductSearch.php index b74d03a..ab35423 100755 --- a/common/modules/product/models/ProductSearch.php +++ b/common/modules/product/models/ProductSearch.php @@ -48,41 +48,54 @@ class ProductSearch extends Product { $query = Product::find(); - // add conditions that should always apply here + $query->joinWith(['brand', 'brand.brandNames', 'categories', 'categories.categoryNames', 'variant']); + + $query->groupBy(['product.product_id']); + $query->orderBy('product.product_id', 'DESC'); $dataProvider = new ActiveDataProvider([ 'query' => $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'); + if ( !($this->load($params) && $this->validate()) ) { return $dataProvider; } $dataProvider->setSort([ 'attributes' => [ 'name', - 'brand_name', - 'category_name' + 'brand_name' => [ + 'asc' => ['brand_name.value' => SORT_ASC], + 'desc' => ['brand_name.value' => SORT_DESC], + 'default' => SORT_DESC, + 'label' => 'Brand name', + ], + 'category_name', + 'variant_sku', ] ]); - $query->joinWith(['brand', 'brand.brandNames', 'categories', 'categories.categoryNames']); + if (isset($this->is_top)) { + $query->andFilterWhere([ + 'is_top' => (bool)$this->is_top, + ]); + } + if (isset($this->is_new)) { + $query->andFilterWhere([ + 'is_new' => (bool)$this->is_new, + ]); + } - // grid filtering conditions $query->andFilterWhere([ - 'tax_brand_id' => $this->tax_brand_id, - 'product_id' => $this->product_id, - 'is_top' => (bool)$this->is_top, - 'is_new' => (bool)$this->is_new, + 'product.brand_id' => $this->brand_id, + 'product.product_id' => $this->product_id, + 'product_category.category_id' => $this->category_id ]); - $query->andFilterWhere(['ilike', 'name', $this->name]); + $query->andFilterWhere(['ilike', 'product.name', $this->name]); $query->andFilterWhere(['ilike', 'brand_name.value', $this->brand_name]); $query->andFilterWhere(['ilike', 'category_name.value', $this->category_name]); + $query->andFilterWhere(['ilike', 'product_variant.sku', $this->variant_sku]); return $dataProvider; } diff --git a/common/modules/product/models/ProductVariant.php b/common/modules/product/models/ProductVariant.php index 57f67e7..7a49e4c 100755 --- a/common/modules/product/models/ProductVariant.php +++ b/common/modules/product/models/ProductVariant.php @@ -87,6 +87,20 @@ class ProductVariant extends \yii\db\ActiveRecord } /** + * @return \yii\db\ActiveQuery + */ + public function getImage() + { + return $this->hasOne(ProductImage::className(), ['product_variant_id' => 'product_variant_id']); + } + + public function getImageUrl() + { + // return a default image placeholder if your source image is not found + return !empty($this->image) ? $this->image->imageUrl : '/images/no_photo.png'; + } + + /** * @inheritdoc * @return ProductVariantQuery the active query used by this AR class. */ diff --git a/common/modules/product/views/manage/index.php b/common/modules/product/views/manage/index.php index 41eb978..531f7ea 100755 --- a/common/modules/product/views/manage/index.php +++ b/common/modules/product/views/manage/index.php @@ -2,6 +2,11 @@ use yii\helpers\Html; use yii\grid\GridView; +use kartik\select2\Select2; +use yii\helpers\ArrayHelper; +use common\modules\product\helpers\ProductHelper; +use common\components\artboxtree\ArtboxTreeHelper; + /* @var $this yii\web\View */ /* @var $searchModel common\modules\product\models\ProductSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ @@ -22,25 +27,66 @@ $this->params['breadcrumbs'][] = $this->title; 'filterModel' => $searchModel, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], -// 'product_id', 'name', [ 'label' => Yii::t('product', 'Brand'), 'attribute' => 'brand_name', 'value' => 'brand.name', + 'format' => 'raw', + 'filter' => Select2::widget([ + 'model' => $searchModel, + 'attribute' => 'brand_id', + 'data' => ArrayHelper::map(ProductHelper::getBrands()->all(), 'brand_id', 'name'), + 'language' => 'ru', + 'options' => [ + 'placeholder' => Yii::t('product', 'Select brand'), + 'multiple' => false, + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ]) ], [ 'label' => Yii::t('product', 'Category'), 'attribute' => 'category_name', - 'value' => 'category.name', + 'value' => function($model) { + $categories = []; + foreach ($model->categories as $category) { + $categories[] = $category->name; + } + return implode(", ", $categories); + }, + 'format' => 'raw', + 'filter' => Select2::widget([ + 'model' => $searchModel, + 'attribute' => 'category_id', + 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), + 'language' => 'ru', + 'options' => [ + 'placeholder' => Yii::t('product', 'Select category'), + 'multiple' => false, + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ]) + ], + [ + 'label' => Yii::t('product', 'SKU'), + 'attribute' => 'variant_sku', + 'value' => 'variant.sku', ], 'variant.price', - 'variant.stock_caption', - - + 'variant.price_old', + [ + 'label' => Yii::t('product', 'Stock'), + 'attribute' => 'variant_stock', + 'value' => 'variant.stock_caption', + ], [ 'class' => 'yii\grid\ActionColumn', - 'template' => '{view} {is_top} {is_new} {update} {delete}', + 'template' => '{items} {view} |{is_top} {is_new} {akciya} | {update} {delete}', 'buttons' => [ 'is_top' => function ($url, $model) { return Html::a('', $url, [ @@ -52,15 +98,32 @@ $this->params['breadcrumbs'][] = $this->title; 'title' => Yii::t('product', ($model->is_new ? 'Set not is new' : 'Set is new')), ]); }, + 'akciya' => function ($url, $model) { + return Html::a('', $url, [ + 'title' => Yii::t('product', ($model->akciya ? 'Set not is promotion' : 'Set is promotion')), + ]); + }, + 'items' => function ($url, $model) { + return Html::a('', $url, [ + 'title' => Yii::t('product', 'Variants'), + ]); + }, + ], 'urlCreator' => function ($action, $model, $key, $index) { switch ($action) { + case 'items': + return \yii\helpers\Url::to(['/product/variant', 'product_id' => $model->product_id]); + break; case 'is_top': return \yii\helpers\Url::to(['manage/is_top', 'id' => $model->product_id]); break; case 'is_new': return \yii\helpers\Url::to(['manage/is_new', 'id' => $model->product_id]); break; + case 'akciya': + return \yii\helpers\Url::to(['manage/akciya', 'id' => $model->product_id]); + break; case 'view': return \yii\helpers\Url::to(['/catalog/product', 'id' => $model->product_id, ['target' => '_blank']]); break; diff --git a/common/modules/product/widgets/specialProducts.php b/common/modules/product/widgets/specialProducts.php new file mode 100644 index 0000000..68d8815 --- /dev/null +++ b/common/modules/product/widgets/specialProducts.php @@ -0,0 +1,48 @@ +type, $this->count, $this->sort); + + if (!$this->title) { + switch($this->type) { + case 'is_top': + $this->title = Yii::t('product', 'Top products'); + break; + case 'is_new': + $this->title = Yii::t('product', 'New products'); + break; + } + } + + return $this->render('products_block', [ + 'title' => $this->title, + 'class' => $this->classs ? $this->classs : $this->type, + 'products' => $products, + ]); + } +} \ No newline at end of file diff --git a/common/modules/product/widgets/views/product_smart.php b/common/modules/product/widgets/views/product_smart.php new file mode 100644 index 0000000..b47be81 --- /dev/null +++ b/common/modules/product/widgets/views/product_smart.php @@ -0,0 +1,64 @@ + +
+ enabledVariants[0]->price_old != 0 && $product->enabledVariants[0]->price_old != $product->enabledVariants[0]->price) :?>
+ = $product->enabledVariants[0]->price_old ?> грн.
+
+ = $product->enabledVariants[0]->price?> грн.