Compare View
Commits (2)
Showing
20 changed files
Show diff stats
backend/views/layouts/main-sidebar.php
| @@ -34,6 +34,11 @@ use yii\widgets\Menu; | @@ -34,6 +34,11 @@ use yii\widgets\Menu; | ||
| 34 | 'options' => ['class'=>\Yii::$app->user->can('product') ? '' :'hide'] | 34 | 'options' => ['class'=>\Yii::$app->user->can('product') ? '' :'hide'] |
| 35 | ], | 35 | ], |
| 36 | [ | 36 | [ |
| 37 | + 'label' => 'Модификации', | ||
| 38 | + 'url' => ['/product/variant'], | ||
| 39 | + 'options' => ['class'=>\Yii::$app->user->can('product') ? '' :'hide'] | ||
| 40 | + ], | ||
| 41 | + [ | ||
| 37 | 'label' => 'Категории', | 42 | 'label' => 'Категории', |
| 38 | 'url' => ['/category'], | 43 | 'url' => ['/category'], |
| 39 | 'options' => ['class'=>\Yii::$app->user->can('category') ? '' :'hide'], | 44 | 'options' => ['class'=>\Yii::$app->user->can('category') ? '' :'hide'], |
common/config/main.php
| @@ -207,6 +207,27 @@ return [ | @@ -207,6 +207,27 @@ return [ | ||
| 207 | 'model' => 'common\modules\product\models\ProductOption', | 207 | 'model' => 'common\modules\product\models\ProductOption', |
| 208 | ] | 208 | ] |
| 209 | ], | 209 | ], |
| 210 | + 'product_variant_option' => [ | ||
| 211 | + 'name' => Yii::t('product', 'Properties'), | ||
| 212 | + 'field' => 'options', | ||
| 213 | + 'entity1' => [ | ||
| 214 | + 'model' => '\common\modules\product\models\ProductVariant', | ||
| 215 | + 'label' => 'Variant', | ||
| 216 | + 'listField' => 'fullname', | ||
| 217 | + 'key' => 'product_variant_id', | ||
| 218 | + 'linked_key' => 'product_variant_id', | ||
| 219 | + ], | ||
| 220 | + 'entity2' => [ | ||
| 221 | + 'model' => '\common\modules\rubrication\models\TaxOption', | ||
| 222 | + 'label' => 'Option', | ||
| 223 | + 'listField' => 'ValueRenderFlash', | ||
| 224 | + 'key' => 'tax_option_id', | ||
| 225 | + 'linked_key' => 'option_id', | ||
| 226 | + ], | ||
| 227 | + 'via' => [ | ||
| 228 | + 'model' => 'common\modules\product\models\ProductVariantOption', | ||
| 229 | + ] | ||
| 230 | + ], | ||
| 210 | 'tax_group_to_category' => [ | 231 | 'tax_group_to_category' => [ |
| 211 | 'name' => Yii::t('product', 'Характеристики по категориям'), | 232 | 'name' => Yii::t('product', 'Характеристики по категориям'), |
| 212 | 'field' => 'group_to_category', | 233 | 'field' => 'group_to_category', |
common/modules/product/controllers/ManageController.php
| @@ -117,16 +117,6 @@ class ManageController extends Controller | @@ -117,16 +117,6 @@ class ManageController extends Controller | ||
| 117 | $model = $this->findModel($id); | 117 | $model = $this->findModel($id); |
| 118 | if ($model->load(Yii::$app->request->post())) { | 118 | if ($model->load(Yii::$app->request->post())) { |
| 119 | $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | 119 | $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); |
| 120 | - $model->variantImagesUpload = UploadedFile::getInstances($model, 'variants'); | ||
| 121 | - /*if (!empty($variantImagesUpload)) { | ||
| 122 | - var_dump($variantImagesUpload);exit; | ||
| 123 | - }*/ | ||
| 124 | - /*$model->variantImagesUpload = []; | ||
| 125 | - foreach ($_POST['Product']['variants'] as $i => $variant) { | ||
| 126 | - if (!empty($variant['product_variant_id'])) { | ||
| 127 | - $model->variantImagesUpload[$variant['product_variant_id']] = $variantImagesUpload[$i]; | ||
| 128 | - } | ||
| 129 | - }*/ | ||
| 130 | if ($model->save()) { | 120 | if ($model->save()) { |
| 131 | // foreach ($model->images as $image) { | 121 | // foreach ($model->images as $image) { |
| 132 | // $image->delete(); | 122 | // $image->delete(); |
| @@ -140,19 +130,6 @@ class ManageController extends Controller | @@ -140,19 +130,6 @@ class ManageController extends Controller | ||
| 140 | } | 130 | } |
| 141 | } | 131 | } |
| 142 | 132 | ||
| 143 | - if ( ($images = $model->variantImagesUpload()) !== FALSE) { | ||
| 144 | - foreach ($images as $i => $image) { | ||
| 145 | - if (empty($model->_variants[$i])) { | ||
| 146 | - continue; | ||
| 147 | - } | ||
| 148 | - $imageModel = new ProductImage(); | ||
| 149 | - $imageModel->product_id = $model->product_id; | ||
| 150 | - $imageModel->product_variant_id = intval($model->_variants[$i]['product_variant_id']); | ||
| 151 | - $imageModel->image = $image; | ||
| 152 | - $imageModel->save(); | ||
| 153 | - } | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | return $this->redirect(['view', 'id' => $model->product_id]); | 133 | return $this->redirect(['view', 'id' => $model->product_id]); |
| 157 | } | 134 | } |
| 158 | } else { | 135 | } else { |
common/modules/product/controllers/VariantController.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace common\modules\product\controllers; | ||
| 4 | + | ||
| 5 | +use common\modules\product\models\Product; | ||
| 6 | +use common\modules\product\models\ProductVariant; | ||
| 7 | +use common\modules\product\models\ProductVariantSearch; | ||
| 8 | +use Yii; | ||
| 9 | +use yii\web\Controller; | ||
| 10 | +use yii\web\NotFoundHttpException; | ||
| 11 | +use yii\filters\VerbFilter; | ||
| 12 | +use yii\web\UploadedFile; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * ManageController implements the CRUD actions for ProductVariant model. | ||
| 16 | + */ | ||
| 17 | +class VariantController extends Controller | ||
| 18 | +{ | ||
| 19 | + /** | ||
| 20 | + * @inheritdoc | ||
| 21 | + */ | ||
| 22 | + public function behaviors() | ||
| 23 | + { | ||
| 24 | + return [ | ||
| 25 | + 'verbs' => [ | ||
| 26 | + 'class' => VerbFilter::className(), | ||
| 27 | + 'actions' => [ | ||
| 28 | + 'delete' => ['POST'], | ||
| 29 | + ], | ||
| 30 | + ], | ||
| 31 | + ]; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * Lists all ProductVariant models. | ||
| 36 | + * @return mixed | ||
| 37 | + */ | ||
| 38 | + public function actionIndex() | ||
| 39 | + { | ||
| 40 | + $searchModel = new ProductVariantSearch(); | ||
| 41 | + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | ||
| 42 | + | ||
| 43 | + if ( ($product = Yii::$app->request->get('product_id')) !== null) { | ||
| 44 | + $product = Product::findOne($product); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + return $this->render('index', [ | ||
| 48 | + 'searchModel' => $searchModel, | ||
| 49 | + 'dataProvider' => $dataProvider, | ||
| 50 | + 'product' => $product, | ||
| 51 | + ]); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * Displays a single ProductVariant model. | ||
| 56 | + * @param integer $id | ||
| 57 | + * @return mixed | ||
| 58 | + */ | ||
| 59 | + public function actionView($id) | ||
| 60 | + { | ||
| 61 | + return $this->render('view', [ | ||
| 62 | + 'model' => $this->findModel($id), | ||
| 63 | + ]); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * Creates a new ProductVariant model. | ||
| 68 | + * If creation is successful, the browser will be redirected to the 'view' page. | ||
| 69 | + * @return mixed | ||
| 70 | + */ | ||
| 71 | + public function actionCreate() | ||
| 72 | + { | ||
| 73 | + $model = new ProductVariant(); | ||
| 74 | + | ||
| 75 | + if ($model->load(Yii::$app->request->post())) { | ||
| 76 | + $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
| 77 | + | ||
| 78 | + if ($model->save() && $model->imagesUpload) { | ||
| 79 | + if ( ($images = $model->imagesUpload()) !== FALSE) { | ||
| 80 | + foreach ($images as $image) { | ||
| 81 | + $imageModel = new ProductImage(); | ||
| 82 | + $imageModel->product_id = $model->product_id; | ||
| 83 | + $imageModel->product_variant_id = $model->product_variant_id; | ||
| 84 | + $imageModel->image = $image; | ||
| 85 | + $imageModel->save(); | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + return $this->redirect(['view', 'id' => $model->product_variant_id]); | ||
| 90 | + } | ||
| 91 | + } else { | ||
| 92 | + return $this->render('create', [ | ||
| 93 | + 'model' => $model, | ||
| 94 | + ]); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + /** | ||
| 99 | + * Updates an existing ProductVariant model. | ||
| 100 | + * If update is successful, the browser will be redirected to the 'view' page. | ||
| 101 | + * @param integer $id | ||
| 102 | + * @return mixed | ||
| 103 | + */ | ||
| 104 | + public function actionUpdate($id) | ||
| 105 | + { | ||
| 106 | + $model = $this->findModel($id); | ||
| 107 | + if ($model->load(Yii::$app->request->post())) { | ||
| 108 | + $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
| 109 | + if ($model->save()) { | ||
| 110 | + if ( ($images = $model->imagesUpload()) !== FALSE) { | ||
| 111 | + foreach ($images as $image) { | ||
| 112 | + $imageModel = new ProductImage(); | ||
| 113 | + $imageModel->product_id = $model->product_id; | ||
| 114 | + $imageModel->product_variant_id = $model->product_variant_id; | ||
| 115 | + $imageModel->image = $image; | ||
| 116 | + $imageModel->save(); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + return $this->redirect(['view', 'id' => $model->product_variant_id]); | ||
| 121 | + } | ||
| 122 | + } else { | ||
| 123 | + $groups = $model->category->getTaxGroups(); | ||
| 124 | + | ||
| 125 | + return $this->render('update', [ | ||
| 126 | + 'model' => $model, | ||
| 127 | + 'groups' => $groups, | ||
| 128 | + ]); | ||
| 129 | + } | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * Deletes an existing ProductVariant model. | ||
| 134 | + * If deletion is successful, the browser will be redirected to the 'index' page. | ||
| 135 | + * @param integer $id | ||
| 136 | + * @return mixed | ||
| 137 | + */ | ||
| 138 | + public function actionDelete($id) | ||
| 139 | + { | ||
| 140 | + $this->findModel($id)->delete(); | ||
| 141 | + | ||
| 142 | + return $this->redirect(['index']); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + public function actionDelimg($id) | ||
| 146 | + { | ||
| 147 | + $image = ProductImage::findOne($id); | ||
| 148 | + | ||
| 149 | + if ($image) { | ||
| 150 | + $image->delete(); | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + print '1'; | ||
| 154 | + exit; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + /** | ||
| 158 | + * Finds the ProductVariant model based on its primary key value. | ||
| 159 | + * If the model is not found, a 404 HTTP exception will be thrown. | ||
| 160 | + * @param integer $id | ||
| 161 | + * @return ProductVariant the loaded model | ||
| 162 | + * @throws NotFoundHttpException if the model cannot be found | ||
| 163 | + */ | ||
| 164 | + protected function findModel($id) | ||
| 165 | + { | ||
| 166 | + if (($model = ProductVariant::findOne($id)) !== null) { | ||
| 167 | + return $model; | ||
| 168 | + } else { | ||
| 169 | + throw new NotFoundHttpException('The requested page does not exist.'); | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | +} |
common/modules/product/helpers/ProductHelper.php
| @@ -140,4 +140,63 @@ class ProductHelper extends Object { | @@ -140,4 +140,63 @@ class ProductHelper extends Object { | ||
| 140 | } | 140 | } |
| 141 | return $products; | 141 | return $products; |
| 142 | } | 142 | } |
| 143 | + | ||
| 144 | + public static function _setQueryParams(&$query, $params, $setPriceLimits = true) { | ||
| 145 | + if (!empty($params['keywords'])) { | ||
| 146 | + if (!is_array($params['keywords'])) { | ||
| 147 | + $params['keywords'] = [$params['keywords']]; | ||
| 148 | + } | ||
| 149 | + foreach ($params['keywords'] as $keyword) { | ||
| 150 | + $query->orFilterWhere(['ilike', Product::tableName() .'.name', $keyword]); | ||
| 151 | + $query->orFilterWhere(['ilike', BrandName::tableName() .'.value', $keyword]); | ||
| 152 | + $query->orFilterWhere(['ilike', CategoryName::tableName() .'.value', $keyword]); | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + if (!empty($params['special'])) { | ||
| 156 | + foreach($params['special'] as $key => $value) { | ||
| 157 | + $query->orFilterWhere([Product::tableName() .'.'. $key => $value]); | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | + if (!empty($params['brands'])) { | ||
| 161 | + $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); | ||
| 162 | + } | ||
| 163 | + if (!empty($params['options'])) { | ||
| 164 | + foreach ($params['options'] as $group => $options) { | ||
| 165 | + foreach ($options as &$option) { | ||
| 166 | + $option = "'$option'"; | ||
| 167 | + } | ||
| 168 | + $query->andWhere( | ||
| 169 | + Product::tableName() . '.product_id IN (SELECT product_id AS products FROM product_option INNER JOIN tax_option ON tax_option.tax_option_id = product_option.option_id INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id WHERE tax_group.alias LIKE \''. $group .'\' AND tax_option.alias IN (' . implode(',', $options) . '))' | ||
| 170 | + ); | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + if ($setPriceLimits && !empty($params['prices'])) { | ||
| 175 | + if ($params['prices']['min'] > 0) { | ||
| 176 | + $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | ||
| 177 | + } | ||
| 178 | + if ($params['prices']['max'] > 0) { | ||
| 179 | + $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + public static function productCountQuery($category = null, $params, $excludeKeys = []) { | ||
| 185 | + $p = []; | ||
| 186 | + foreach ($params as $key => $param) { | ||
| 187 | + if (in_array($key, $excludeKeys)) { | ||
| 188 | + $p[$key] = $param; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + /** @var ActiveQuery $query */ | ||
| 192 | + if (!empty($category)) { | ||
| 193 | + $query = $category->getProducts(); | ||
| 194 | + } else { | ||
| 195 | + $query = Product::find(); | ||
| 196 | + } | ||
| 197 | + ProductHelper::_setQueryParams($query, $params); | ||
| 198 | + $query->select(['COUNT(product.product_id)']); | ||
| 199 | + | ||
| 200 | + return $query; | ||
| 201 | + } | ||
| 143 | } | 202 | } |
| 144 | \ No newline at end of file | 203 | \ No newline at end of file |
common/modules/product/models/BrandSearch.php
| @@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
| 2 | 2 | ||
| 3 | namespace common\modules\product\models; | 3 | namespace common\modules\product\models; |
| 4 | 4 | ||
| 5 | +use common\modules\product\helpers\ProductHelper; | ||
| 6 | +use common\modules\rubrication\models\TaxOption; | ||
| 5 | use Yii; | 7 | use Yii; |
| 6 | use yii\base\Model; | 8 | use yii\base\Model; |
| 7 | use yii\data\ActiveDataProvider; | 9 | use yii\data\ActiveDataProvider; |
| @@ -89,14 +91,47 @@ class BrandSearch extends Brand | @@ -89,14 +91,47 @@ class BrandSearch extends Brand | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | public function getBrands($category = null, $params = []) { | 93 | public function getBrands($category = null, $params = []) { |
| 94 | +// $queryCount = ProductHelper::productCountQuery($category, $params, ['brands']); | ||
| 95 | + | ||
| 96 | + /*if (!empty($params['prices'])) { | ||
| 97 | + if ($params['prices']['min'] > 0) { | ||
| 98 | + $queryCount->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | ||
| 99 | + } | ||
| 100 | + if ($params['prices']['max'] > 0) { | ||
| 101 | + $queryCount->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | ||
| 102 | + } | ||
| 103 | + }*/ | ||
| 104 | +// if (!empty($params['options'])) { | ||
| 105 | +// $queryCount->innerJoin(TaxOption::tableName(), TaxOption::tableName()) | ||
| 106 | +// } | ||
| 107 | + | ||
| 92 | $query = Brand::find() | 108 | $query = Brand::find() |
| 93 | ->select([ | 109 | ->select([ |
| 94 | - Brand::tableName() .'.*', | ||
| 95 | - 'COUNT('. ProductCategory::tableName() .'.product_id) AS _items_count' | 110 | + Brand::tableName() .'.*' |
| 96 | ]) | 111 | ]) |
| 97 | ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') | 112 | ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') |
| 98 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') | 113 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') |
| 99 | ->with(['brandName']); | 114 | ->with(['brandName']); |
| 115 | + | ||
| 116 | + if (!empty($params['options'])) { | ||
| 117 | + $queryCount = ProductOption::find() | ||
| 118 | + ->select(['COUNT(pr.product_id)']) | ||
| 119 | + ->innerJoin('tax_option', 'tax_option.tax_option_id = product_option.option_id') | ||
| 120 | + ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id') | ||
| 121 | + ->innerJoin('product AS pr', 'pr.product_id = product_option.product_id') | ||
| 122 | + ->where('pr.brand_id = brand.brand_id'); | ||
| 123 | +// ->groupBy(['product.product_id']); | ||
| 124 | + foreach ($params['options'] as $group => $options) { | ||
| 125 | + $queryCount->andWhere([ | ||
| 126 | + 'tax_group.alias' => $group, | ||
| 127 | + 'tax_option.alias' => $options | ||
| 128 | + ]); | ||
| 129 | + } | ||
| 130 | + $query->addSelect(['_items_count' => $queryCount]); | ||
| 131 | +// $query->addSelect("(SELECT COUNT(product_option.product_id) AS products FROM product_option INNER JOIN tax_option ON tax_option.tax_option_id = product_option.option_id INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id WHERE tax_group.alias LIKE '$group' AND tax_option.alias IN (" . implode(',', $options) . ")) AS _items_count"); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + | ||
| 100 | $query->innerJoin('product_variant', 'product_variant.product_id = '. Product::tableName() .'.product_id'); | 135 | $query->innerJoin('product_variant', 'product_variant.product_id = '. Product::tableName() .'.product_id'); |
| 101 | $query->where(['!=', 'product_variant.stock', 0]); | 136 | $query->where(['!=', 'product_variant.stock', 0]); |
| 102 | $query->groupBy(Product::tableName() .'.product_id'); | 137 | $query->groupBy(Product::tableName() .'.product_id'); |
| @@ -106,20 +141,6 @@ class BrandSearch extends Brand | @@ -106,20 +141,6 @@ class BrandSearch extends Brand | ||
| 106 | ]); | 141 | ]); |
| 107 | } | 142 | } |
| 108 | $query->groupBy(Brand::tableName() .'.brand_id'); | 143 | $query->groupBy(Brand::tableName() .'.brand_id'); |
| 109 | - if (isset($params['options'])) { | ||
| 110 | - unset($params['options']); | ||
| 111 | - } | ||
| 112 | - if (!empty($params['prices'])) { | ||
| 113 | - if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { | ||
| 114 | - $query->innerJoin(ProductVariant::tableName(), ProductVariant::tableName() .'.product_id='. Product::tableName() .'.product_id'); | ||
| 115 | - } | ||
| 116 | - if ($params['prices']['min'] > 0) { | ||
| 117 | - $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | ||
| 118 | - } | ||
| 119 | - if ($params['prices']['max'] > 0) { | ||
| 120 | - $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | ||
| 121 | - } | ||
| 122 | - } | ||
| 123 | 144 | ||
| 124 | return $query; | 145 | return $query; |
| 125 | } | 146 | } |
common/modules/product/models/Product.php
| @@ -38,7 +38,7 @@ class Product extends \yii\db\ActiveRecord | @@ -38,7 +38,7 @@ class Product extends \yii\db\ActiveRecord | ||
| 38 | 38 | ||
| 39 | /** @var array $_images */ | 39 | /** @var array $_images */ |
| 40 | public $imagesUpload = []; | 40 | public $imagesUpload = []; |
| 41 | - public $variantImagesUpload = []; | 41 | + |
| 42 | /** | 42 | /** |
| 43 | * @inheritdoc | 43 | * @inheritdoc |
| 44 | */ | 44 | */ |
| @@ -318,27 +318,6 @@ class Product extends \yii\db\ActiveRecord | @@ -318,27 +318,6 @@ class Product extends \yii\db\ActiveRecord | ||
| 318 | ProductVariant::deleteAll(['product_id' => $this->product_id]); | 318 | ProductVariant::deleteAll(['product_id' => $this->product_id]); |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | - public function variantImagesUpload() | ||
| 322 | - { | ||
| 323 | - if ($this->validate()) { | ||
| 324 | - $images = []; | ||
| 325 | - foreach ($this->variantImagesUpload as $product_variant_id => $image) { | ||
| 326 | - $imageName = $image->baseName .'.'. $image->extension; | ||
| 327 | - $i = 0; | ||
| 328 | - while(file_exists(Yii::getAlias('@imagesDir/products/' . $imageName))) { | ||
| 329 | - $i++; | ||
| 330 | - $imageName = $image->baseName .'_'. $i .'.'. $image->extension; | ||
| 331 | - } | ||
| 332 | - | ||
| 333 | - $image->saveAs(Yii::getAlias('@imagesDir/products/' .$imageName)); | ||
| 334 | - $images[$product_variant_id] = $imageName; | ||
| 335 | - } | ||
| 336 | - return $images; | ||
| 337 | - } else { | ||
| 338 | - return false; | ||
| 339 | - } | ||
| 340 | - } | ||
| 341 | - | ||
| 342 | public function imagesUpload() | 321 | public function imagesUpload() |
| 343 | { | 322 | { |
| 344 | if ($this->validate()) { | 323 | if ($this->validate()) { |
common/modules/product/models/ProductVariant.php
| @@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
| 2 | 2 | ||
| 3 | namespace common\modules\product\models; | 3 | namespace common\modules\product\models; |
| 4 | 4 | ||
| 5 | +use common\modules\relation\relationBehavior; | ||
| 6 | +use common\modules\rubrication\models\TaxOption; | ||
| 5 | use Yii; | 7 | use Yii; |
| 6 | use yii\helpers\ArrayHelper; | 8 | use yii\helpers\ArrayHelper; |
| 7 | 9 | ||
| @@ -37,7 +39,23 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -37,7 +39,23 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 37 | public $stocks; | 39 | public $stocks; |
| 38 | 40 | ||
| 39 | /** @var array $_images */ | 41 | /** @var array $_images */ |
| 40 | -// public $imagesUpload = []; | 42 | + public $imagesUpload = []; |
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * @inheritdoc | ||
| 46 | + */ | ||
| 47 | + public function behaviors() | ||
| 48 | + { | ||
| 49 | + return [ | ||
| 50 | + [ | ||
| 51 | + 'class' => relationBehavior::className(), | ||
| 52 | + 'relations' => [ | ||
| 53 | + 'product_variant_option' => 'entity1' // Product variant options | ||
| 54 | + ] | ||
| 55 | + ] | ||
| 56 | + ]; | ||
| 57 | + } | ||
| 58 | + | ||
| 41 | /** | 59 | /** |
| 42 | * @inheritdoc | 60 | * @inheritdoc |
| 43 | */ | 61 | */ |
| @@ -57,6 +75,7 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -57,6 +75,7 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 57 | [['price', 'price_old', 'stock'], 'number'], | 75 | [['price', 'price_old', 'stock'], 'number'], |
| 58 | [['name', 'sku'], 'string', 'max' => 255], | 76 | [['name', 'sku'], 'string', 'max' => 255], |
| 59 | [['remote_id'], 'string', 'max' => 20], | 77 | [['remote_id'], 'string', 'max' => 20], |
| 78 | + [['options', 'imagesUpload'], 'safe'], | ||
| 60 | // [['imagesUpload'], 'safe'], | 79 | // [['imagesUpload'], 'safe'], |
| 61 | // [['imagesUpload'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif', 'maxFiles' => 50], | 80 | // [['imagesUpload'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif', 'maxFiles' => 50], |
| 62 | [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], | 81 | [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], |
| @@ -144,6 +163,34 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -144,6 +163,34 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 144 | return empty($this->product) ? null : ($this->product->name . (empty($this->name) ? '' : ' '. $this->name)); | 163 | return empty($this->product) ? null : ($this->product->name . (empty($this->name) ? '' : ' '. $this->name)); |
| 145 | } | 164 | } |
| 146 | 165 | ||
| 166 | + public function getImagesHTML() { | ||
| 167 | + $op = []; | ||
| 168 | + if ($this->images) { | ||
| 169 | + foreach ($this->images as $image) { | ||
| 170 | + $op[] = \common\components\artboximage\ArtboxImageHelper::getImage($image->imageUrl, 'admin_thumb'); | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + return $op; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + public function getImagesConfig() { | ||
| 177 | + $op = []; | ||
| 178 | + if ($this->images) { | ||
| 179 | + foreach ($this->images as $image) { | ||
| 180 | + $op[] = [ | ||
| 181 | + 'caption' => $image->image, | ||
| 182 | + 'width' => '120px', | ||
| 183 | + 'url' => \yii\helpers\Url::to(['/product/manage/delimg', 'id' => $image->product_image_id]), | ||
| 184 | + 'key' => $image->product_image_id, | ||
| 185 | + 'extra' => [ | ||
| 186 | + 'id' => $image->product_image_id, | ||
| 187 | + ], | ||
| 188 | + ]; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + return $op; | ||
| 192 | + } | ||
| 193 | + | ||
| 147 | /** | 194 | /** |
| 148 | * @return \yii\db\ActiveQuery | 195 | * @return \yii\db\ActiveQuery |
| 149 | */ | 196 | */ |
| @@ -152,6 +199,24 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -152,6 +199,24 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 152 | return $this->hasMany(ProductImage::className(), ['product_variant_id' => 'product_variant_id']); | 199 | return $this->hasMany(ProductImage::className(), ['product_variant_id' => 'product_variant_id']); |
| 153 | } | 200 | } |
| 154 | 201 | ||
| 202 | + public function getOptions() { | ||
| 203 | + return $this->hasMany(TaxOption::className(), ['tax_option_id' => 'option_id'])->viaTable('product_variant_option', ['product_variant_id' => 'product_variant_id']); | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + public function getProperties() { | ||
| 207 | + $groups = $options = []; | ||
| 208 | + foreach ($this->options as $option) { | ||
| 209 | + $options[$option->tax_group_id][] = $option; | ||
| 210 | + } | ||
| 211 | + foreach (TaxGroup::find()->where(['tax_group_id' => array_keys($options)])->all() as $group) { | ||
| 212 | + if (!empty($options[$group->tax_group_id])) { | ||
| 213 | + $group->_options = $options[$group->tax_group_id]; | ||
| 214 | + $groups[] = $group; | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + return $groups; | ||
| 218 | + } | ||
| 219 | + | ||
| 155 | /** | 220 | /** |
| 156 | * @inheritdoc | 221 | * @inheritdoc |
| 157 | * @return ProductVariantQuery the active query used by this AR class. | 222 | * @return ProductVariantQuery the active query used by this AR class. |
| @@ -169,6 +234,10 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -169,6 +234,10 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 169 | $this->stocks = (array) $stocks; | 234 | $this->stocks = (array) $stocks; |
| 170 | } | 235 | } |
| 171 | 236 | ||
| 237 | + public function getCategory() { | ||
| 238 | + return $this->hasOne(Category::className(), ['category_id' => 'category_id'])->viaTable('product_category', ['product_id' => 'product_id']); | ||
| 239 | + } | ||
| 240 | + | ||
| 172 | public function afterSave($insert, $changedAttributes) | 241 | public function afterSave($insert, $changedAttributes) |
| 173 | { | 242 | { |
| 174 | if (!is_null($this->stocks)) { | 243 | if (!is_null($this->stocks)) { |
| @@ -187,4 +256,25 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -187,4 +256,25 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
| 187 | ProductImage::deleteAll(['product_variant_id' => $this->product_variant_id]); | 256 | ProductImage::deleteAll(['product_variant_id' => $this->product_variant_id]); |
| 188 | ProductStock::deleteAll(['product_variant_id' => $this->product_variant_id]); | 257 | ProductStock::deleteAll(['product_variant_id' => $this->product_variant_id]); |
| 189 | } | 258 | } |
| 259 | + | ||
| 260 | + public function imagesUpload() | ||
| 261 | + { | ||
| 262 | + if ($this->validate()) { | ||
| 263 | + $images = []; | ||
| 264 | + foreach ($this->imagesUpload as $image) { | ||
| 265 | + $imageName = $image->baseName .'.'. $image->extension; | ||
| 266 | + $i = 0; | ||
| 267 | + while(file_exists(Yii::getAlias('@imagesDir/products/' . $imageName))) { | ||
| 268 | + $i++; | ||
| 269 | + $imageName = $image->baseName .'_'. $i .'.'. $image->extension; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + $image->saveAs(Yii::getAlias('@imagesDir/products/' .$imageName)); | ||
| 273 | + $images[] = $imageName; | ||
| 274 | + } | ||
| 275 | + return $images; | ||
| 276 | + } else { | ||
| 277 | + return false; | ||
| 278 | + } | ||
| 279 | + } | ||
| 190 | } | 280 | } |
common/modules/product/models/ProductVariantOption.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace common\modules\product\models; | ||
| 4 | + | ||
| 5 | +use Yii; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * This is the model class for table "product_variant_option". | ||
| 9 | + * | ||
| 10 | + * @property integer $product_variant_id | ||
| 11 | + * @property integer $option_id | ||
| 12 | + * | ||
| 13 | + * @property ProductVariant $productVariant | ||
| 14 | + * @property TaxOption $option | ||
| 15 | + */ | ||
| 16 | +class ProductVariantOption extends \yii\db\ActiveRecord | ||
| 17 | +{ | ||
| 18 | + /** | ||
| 19 | + * @inheritdoc | ||
| 20 | + */ | ||
| 21 | + public static function tableName() | ||
| 22 | + { | ||
| 23 | + return 'product_variant_option'; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * @inheritdoc | ||
| 28 | + */ | ||
| 29 | + public function rules() | ||
| 30 | + { | ||
| 31 | + return [ | ||
| 32 | + [['product_variant_id', 'option_id'], 'required'], | ||
| 33 | + [['product_variant_id', 'option_id'], 'integer'], | ||
| 34 | + [['product_variant_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductVariant::className(), 'targetAttribute' => ['product_variant_id' => 'product_variant_id']], | ||
| 35 | + [['option_id'], 'exist', 'skipOnError' => true, 'targetClass' => TaxOption::className(), 'targetAttribute' => ['option_id' => 'tax_option_id']], | ||
| 36 | + ]; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * @inheritdoc | ||
| 41 | + */ | ||
| 42 | + public function attributeLabels() | ||
| 43 | + { | ||
| 44 | + return [ | ||
| 45 | + 'product_variant_id' => 'Product Variant ID', | ||
| 46 | + 'option_id' => 'Option ID', | ||
| 47 | + ]; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * @return \yii\db\ActiveQuery | ||
| 52 | + */ | ||
| 53 | + public function getProductVariant() | ||
| 54 | + { | ||
| 55 | + return $this->hasOne(ProductVariant::className(), ['product_variant_id' => 'product_variant_id']); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * @return \yii\db\ActiveQuery | ||
| 60 | + */ | ||
| 61 | + public function getOption() | ||
| 62 | + { | ||
| 63 | + return $this->hasOne(TaxOption::className(), ['tax_option_id' => 'option_id']); | ||
| 64 | + } | ||
| 65 | +} |
common/modules/product/models/ProductVariantSearch.php
| @@ -24,7 +24,7 @@ class ProductVariantSearch extends ProductVariant | @@ -24,7 +24,7 @@ class ProductVariantSearch extends ProductVariant | ||
| 24 | public function rules() | 24 | public function rules() |
| 25 | { | 25 | { |
| 26 | return [ | 26 | return [ |
| 27 | - [['name', 'fullname', 'sku', 'price', 'price_old', 'stock', 'fullname', 'brand_name', 'category_name'], 'safe'], | 27 | + [['name', 'fullname', 'sku', 'price', 'price_old', 'stock', 'brand_name', 'category_name'], 'safe'], |
| 28 | [['product_variant_id', 'product_id'], 'integer'], | 28 | [['product_variant_id', 'product_id'], 'integer'], |
| 29 | [['is_top', 'is_new', 'akciya'], 'boolean'], | 29 | [['is_top', 'is_new', 'akciya'], 'boolean'], |
| 30 | ]; | 30 | ]; |
| @@ -48,7 +48,7 @@ class ProductVariantSearch extends ProductVariant | @@ -48,7 +48,7 @@ class ProductVariantSearch extends ProductVariant | ||
| 48 | */ | 48 | */ |
| 49 | public function search($params) | 49 | public function search($params) |
| 50 | { | 50 | { |
| 51 | - $query = Product::find(); | 51 | + $query = ProductVariant::find(); |
| 52 | 52 | ||
| 53 | // add conditions that should always apply here | 53 | // add conditions that should always apply here |
| 54 | 54 | ||
| @@ -58,6 +58,10 @@ class ProductVariantSearch extends ProductVariant | @@ -58,6 +58,10 @@ class ProductVariantSearch extends ProductVariant | ||
| 58 | 58 | ||
| 59 | $this->load($params); | 59 | $this->load($params); |
| 60 | 60 | ||
| 61 | + if (!empty($params['product_id'])) { | ||
| 62 | + $this->product_id = $params['product_id']; | ||
| 63 | + } | ||
| 64 | + | ||
| 61 | if (!$this->validate()) { | 65 | if (!$this->validate()) { |
| 62 | // uncomment the following line if you do not want to return any records when validation fails | 66 | // uncomment the following line if you do not want to return any records when validation fails |
| 63 | // $query->where('0=1'); | 67 | // $query->where('0=1'); |
| @@ -66,7 +70,12 @@ class ProductVariantSearch extends ProductVariant | @@ -66,7 +70,12 @@ class ProductVariantSearch extends ProductVariant | ||
| 66 | 70 | ||
| 67 | $dataProvider->setSort([ | 71 | $dataProvider->setSort([ |
| 68 | 'attributes' => [ | 72 | 'attributes' => [ |
| 69 | - 'name', | 73 | + 'name' => [ |
| 74 | + 'asc' => ['product_variant.name' => SORT_ASC], | ||
| 75 | + 'desc' => ['product_variant.value' => SORT_DESC], | ||
| 76 | + 'default' => SORT_DESC, | ||
| 77 | + 'label' => 'Variant name', | ||
| 78 | + ], | ||
| 70 | 'brand_name' => [ | 79 | 'brand_name' => [ |
| 71 | 'asc' => ['brand_name.value' => SORT_ASC], | 80 | 'asc' => ['brand_name.value' => SORT_ASC], |
| 72 | 'desc' => ['brand_name.value' => SORT_DESC], | 81 | 'desc' => ['brand_name.value' => SORT_DESC], |
| @@ -98,12 +107,12 @@ class ProductVariantSearch extends ProductVariant | @@ -98,12 +107,12 @@ class ProductVariantSearch extends ProductVariant | ||
| 98 | 107 | ||
| 99 | // grid filtering conditions | 108 | // grid filtering conditions |
| 100 | $query->andFilterWhere([ | 109 | $query->andFilterWhere([ |
| 101 | - 'product.product_id' => $this->product_id, | 110 | + 'product_variant.product_id' => $this->product_id, |
| 102 | 'product_variant_id' => $this->product_variant_id, | 111 | 'product_variant_id' => $this->product_variant_id, |
| 103 | ]); | 112 | ]); |
| 104 | 113 | ||
| 105 | if (!empty($this->fullname)) { | 114 | if (!empty($this->fullname)) { |
| 106 | - $query->orFilterWhere(['like', 'name', $this->fullname]); | 115 | + $query->orFilterWhere(['like', 'product_variant.name', $this->fullname]); |
| 107 | $query->orFilterWhere(['ilike', 'product.name', $this->fullname]); | 116 | $query->orFilterWhere(['ilike', 'product.name', $this->fullname]); |
| 108 | } | 117 | } |
| 109 | $query->andFilterWhere(['ilike', 'product.brand_name.value', $this->brand_name]); | 118 | $query->andFilterWhere(['ilike', 'product.brand_name.value', $this->brand_name]); |
| @@ -111,7 +120,7 @@ class ProductVariantSearch extends ProductVariant | @@ -111,7 +120,7 @@ class ProductVariantSearch extends ProductVariant | ||
| 111 | $query->andFilterWhere(['ilike', 'sku', $this->sku]); | 120 | $query->andFilterWhere(['ilike', 'sku', $this->sku]); |
| 112 | 121 | ||
| 113 | $query->groupBy(['product_variant_id']); | 122 | $query->groupBy(['product_variant_id']); |
| 114 | - $query->orderBy('product.product_id', 'DESC'); | 123 | + $query->orderBy('product_variant.product_id', 'ASC'); |
| 115 | 124 | ||
| 116 | return $dataProvider; | 125 | return $dataProvider; |
| 117 | } | 126 | } |
common/modules/product/views/manage/_form.php
| @@ -69,7 +69,7 @@ use kartik\select2\Select2; | @@ -69,7 +69,7 @@ use kartik\select2\Select2; | ||
| 69 | ], | 69 | ], |
| 70 | ]); ?> | 70 | ]); ?> |
| 71 | 71 | ||
| 72 | - <?= $form->field($model, 'variants')->widget(MultipleInput::className(), [ | 72 | + <?php /*= $form->field($model, 'variants')->widget(MultipleInput::className(), [ |
| 73 | 'columns' => [ | 73 | 'columns' => [ |
| 74 | [ | 74 | [ |
| 75 | 'name' => 'product_variant_id', | 75 | 'name' => 'product_variant_id', |
| @@ -119,7 +119,7 @@ use kartik\select2\Select2; | @@ -119,7 +119,7 @@ use kartik\select2\Select2; | ||
| 119 | ], | 119 | ], |
| 120 | ], | 120 | ], |
| 121 | ]); | 121 | ]); |
| 122 | - ?> | 122 | + */ ?> |
| 123 | 123 | ||
| 124 | <?php if(isset($groups)) :?> | 124 | <?php if(isset($groups)) :?> |
| 125 | <?php foreach($groups->all() as $group) :?> | 125 | <?php foreach($groups->all() as $group) :?> |
common/modules/product/views/manage/index.php
| @@ -27,7 +27,6 @@ $this->params['breadcrumbs'][] = $this->title; | @@ -27,7 +27,6 @@ $this->params['breadcrumbs'][] = $this->title; | ||
| 27 | 'filterModel' => $searchModel, | 27 | 'filterModel' => $searchModel, |
| 28 | 'columns' => [ | 28 | 'columns' => [ |
| 29 | ['class' => 'yii\grid\SerialColumn'], | 29 | ['class' => 'yii\grid\SerialColumn'], |
| 30 | -// 'product_id', | ||
| 31 | 'name', | 30 | 'name', |
| 32 | [ | 31 | [ |
| 33 | 'label' => Yii::t('product', 'Brand'), | 32 | 'label' => Yii::t('product', 'Brand'), |
| @@ -87,7 +86,7 @@ $this->params['breadcrumbs'][] = $this->title; | @@ -87,7 +86,7 @@ $this->params['breadcrumbs'][] = $this->title; | ||
| 87 | ], | 86 | ], |
| 88 | [ | 87 | [ |
| 89 | 'class' => 'yii\grid\ActionColumn', | 88 | 'class' => 'yii\grid\ActionColumn', |
| 90 | - 'template' => '{view} |{is_top} {is_new} {akciya} | {update} {delete}', | 89 | + 'template' => '{items} {view} |{is_top} {is_new} {akciya} | {update} {delete}', |
| 91 | 'buttons' => [ | 90 | 'buttons' => [ |
| 92 | 'is_top' => function ($url, $model) { | 91 | 'is_top' => function ($url, $model) { |
| 93 | return Html::a('<span class="glyphicon glyphicon-star' . ($model->is_top ? '' : '-empty') . '"></span>', $url, [ | 92 | return Html::a('<span class="glyphicon glyphicon-star' . ($model->is_top ? '' : '-empty') . '"></span>', $url, [ |
| @@ -104,9 +103,18 @@ $this->params['breadcrumbs'][] = $this->title; | @@ -104,9 +103,18 @@ $this->params['breadcrumbs'][] = $this->title; | ||
| 104 | 'title' => Yii::t('product', ($model->akciya ? 'Set not is promotion' : 'Set is promotion')), | 103 | 'title' => Yii::t('product', ($model->akciya ? 'Set not is promotion' : 'Set is promotion')), |
| 105 | ]); | 104 | ]); |
| 106 | }, | 105 | }, |
| 106 | + 'items' => function ($url, $model) { | ||
| 107 | + return Html::a('<span class="glyphicon glyphicon-th-list"></span>', $url, [ | ||
| 108 | + 'title' => Yii::t('product', 'Variants'), | ||
| 109 | + ]); | ||
| 110 | + }, | ||
| 111 | + | ||
| 107 | ], | 112 | ], |
| 108 | 'urlCreator' => function ($action, $model, $key, $index) { | 113 | 'urlCreator' => function ($action, $model, $key, $index) { |
| 109 | switch ($action) { | 114 | switch ($action) { |
| 115 | + case 'items': | ||
| 116 | + return \yii\helpers\Url::to(['/product/variant', 'product_id' => $model->product_id]); | ||
| 117 | + break; | ||
| 110 | case 'is_top': | 118 | case 'is_top': |
| 111 | return \yii\helpers\Url::to(['manage/is_top', 'id' => $model->product_id]); | 119 | return \yii\helpers\Url::to(['manage/is_top', 'id' => $model->product_id]); |
| 112 | break; | 120 | break; |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | +use yii\widgets\ActiveForm; | ||
| 5 | +use yii\helpers\ArrayHelper; | ||
| 6 | +use common\components\artboxtree\ArtboxTreeHelper; | ||
| 7 | +use common\modules\product\helpers\ProductHelper; | ||
| 8 | +use kartik\file\FileInput; | ||
| 9 | +use unclead\widgets\MultipleInput; | ||
| 10 | +use unclead\widgets\MultipleInputColumn; | ||
| 11 | +use kartik\select2\Select2; | ||
| 12 | + | ||
| 13 | +/* @var $this yii\web\View */ | ||
| 14 | +/* @var $model common\modules\product\models\Product */ | ||
| 15 | +/* @var $form yii\widgets\ActiveForm */ | ||
| 16 | +?> | ||
| 17 | + | ||
| 18 | +<div class="product-form"> | ||
| 19 | + | ||
| 20 | + <?php $form = ActiveForm::begin([ | ||
| 21 | + 'options' => ['enctype' => 'multipart/form-data'] | ||
| 22 | + ]); ?> | ||
| 23 | + | ||
| 24 | + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?> | ||
| 25 | + | ||
| 26 | + <?= $form->field($model, 'product_id')->hiddenInput()->label(''); ?> | ||
| 27 | + | ||
| 28 | + <?= $form->field($model, 'sku')->textarea(); ?> | ||
| 29 | + <?= $form->field($model, 'price')->textarea(); ?> | ||
| 30 | + <?= $form->field($model, 'price_old')->textarea(); ?> | ||
| 31 | + | ||
| 32 | + <?= $form->field($model, 'imagesUpload[]')->widget(\kartik\file\FileInput::classname(), [ | ||
| 33 | + 'language' => 'ru', | ||
| 34 | + 'options' => [ | ||
| 35 | + 'accept' => 'image/*', | ||
| 36 | + 'multiple' => true, | ||
| 37 | + ], | ||
| 38 | + 'pluginOptions' => [ | ||
| 39 | + 'allowedFileExtensions' => ['jpg', 'gif', 'png'], | ||
| 40 | + 'initialPreview' => !empty($model->imagesHTML) ? $model->imagesHTML : [], | ||
| 41 | + 'initialPreviewConfig' => $model->imagesConfig, | ||
| 42 | + 'overwriteInitial' => false, | ||
| 43 | + 'showRemove' => false, | ||
| 44 | + 'showUpload' => false, | ||
| 45 | +// 'uploadUrl' => empty($model->product_id) ? null : \yii\helpers\Url::to(['/product/manage/uploadImage']), | ||
| 46 | + 'uploadAsync' => !empty($model->product_id), | ||
| 47 | + 'previewFileType' => 'image', | ||
| 48 | + ], | ||
| 49 | + ]); ?> | ||
| 50 | + | ||
| 51 | + <?php /*= $form->field($model, 'variants')->widget(MultipleInput::className(), [ | ||
| 52 | + 'columns' => [ | ||
| 53 | + [ | ||
| 54 | + 'name' => 'product_variant_id', | ||
| 55 | + 'type' => MultipleInputColumn::TYPE_HIDDEN_INPUT, | ||
| 56 | + ], | ||
| 57 | + [ | ||
| 58 | + 'name' => 'name', | ||
| 59 | + 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, | ||
| 60 | + 'title' => Yii::t('product', 'Name'), | ||
| 61 | + ], | ||
| 62 | + [ | ||
| 63 | + 'name' => 'sku', | ||
| 64 | + 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, | ||
| 65 | + 'title' => Yii::t('product', 'SKU'), | ||
| 66 | + ], | ||
| 67 | + [ | ||
| 68 | + 'name' => 'price', | ||
| 69 | + 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, | ||
| 70 | + 'title' => Yii::t('product', 'Price'), | ||
| 71 | + ], | ||
| 72 | + [ | ||
| 73 | + 'name' => 'price_old', | ||
| 74 | + 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, | ||
| 75 | + 'title' => Yii::t('product', 'Old Price'), | ||
| 76 | + ], | ||
| 77 | + [ | ||
| 78 | + 'name' => 'product_unit_id', | ||
| 79 | + 'type' => MultipleInputColumn::TYPE_DROPDOWN, | ||
| 80 | + 'title' => Yii::t('product', 'Unit'), | ||
| 81 | + 'items' => ArrayHelper::map(\common\modules\product\models\ProductUnit::find()->all(), 'product_unit_id', 'name'), | ||
| 82 | + ], | ||
| 83 | + [ | ||
| 84 | + 'name' => 'stock', | ||
| 85 | + 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, | ||
| 86 | + 'title' => Yii::t('product', 'Stock'), | ||
| 87 | + 'options' => [ | ||
| 88 | + 'placeholder' => '∞' | ||
| 89 | + ], | ||
| 90 | + ], | ||
| 91 | + [ | ||
| 92 | + 'name' => 'image', | ||
| 93 | + 'type' => 'fileInput', | ||
| 94 | + 'title' => Yii::t('product', 'Image'), | ||
| 95 | + 'options' => [ | ||
| 96 | + 'multiple' => false | ||
| 97 | + ], | ||
| 98 | + ], | ||
| 99 | + ], | ||
| 100 | + ]); | ||
| 101 | + */ ?> | ||
| 102 | + | ||
| 103 | + <?php if(isset($groups)) :?> | ||
| 104 | + <?php foreach($groups->all() as $group) :?> | ||
| 105 | + <?= $form->field($model, 'options')->checkboxList( | ||
| 106 | + ArrayHelper::map($group->options, 'tax_option_id', 'ValueRenderFlash'), | ||
| 107 | + [ | ||
| 108 | + 'multiple' => true, | ||
| 109 | + 'unselect' => null, | ||
| 110 | + ] | ||
| 111 | + )->label($group->name);?> | ||
| 112 | + <?php endforeach?> | ||
| 113 | + <?php endif?> | ||
| 114 | + | ||
| 115 | + <div class="form-group"> | ||
| 116 | + <?= Html::submitButton($model->isNewRecord ? Yii::t('product', 'Create') : Yii::t('product', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> | ||
| 117 | + </div> | ||
| 118 | + | ||
| 119 | + <?php ActiveForm::end(); ?> | ||
| 120 | + | ||
| 121 | +</div> |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | +use yii\widgets\ActiveForm; | ||
| 5 | + | ||
| 6 | +/* @var $this yii\web\View */ | ||
| 7 | +/* @var $model common\modules\product\models\ProductSearch */ | ||
| 8 | +/* @var $form yii\widgets\ActiveForm */ | ||
| 9 | +?> | ||
| 10 | + | ||
| 11 | +<div class="product-search"> | ||
| 12 | + | ||
| 13 | + <?php $form = ActiveForm::begin([ | ||
| 14 | + 'action' => ['index'], | ||
| 15 | + 'method' => 'get', | ||
| 16 | + ]); ?> | ||
| 17 | + | ||
| 18 | + <?= $form->field($model, 'name') ?> | ||
| 19 | + | ||
| 20 | + <?= $form->field($model, 'brand_id') ?> | ||
| 21 | + | ||
| 22 | + <?= $form->field($model, 'product_id') ?> | ||
| 23 | + | ||
| 24 | + <div class="form-group"> | ||
| 25 | + <?= Html::submitButton(Yii::t('product', 'Search'), ['class' => 'btn btn-primary']) ?> | ||
| 26 | + <?= Html::resetButton(Yii::t('product', 'Reset'), ['class' => 'btn btn-default']) ?> | ||
| 27 | + </div> | ||
| 28 | + | ||
| 29 | + <?php ActiveForm::end(); ?> | ||
| 30 | + | ||
| 31 | +</div> |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +/* @var $this yii\web\View */ | ||
| 7 | +/* @var $model common\modules\product\models\Product */ | ||
| 8 | + | ||
| 9 | +$this->title = Yii::t('product', 'Create Product'); | ||
| 10 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['index']]; | ||
| 11 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 12 | +?> | ||
| 13 | +<div class="product-create"> | ||
| 14 | + | ||
| 15 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 16 | + | ||
| 17 | + <?= $this->render('_form', [ | ||
| 18 | + 'model' => $model, | ||
| 19 | + ]) ?> | ||
| 20 | + | ||
| 21 | +</div> |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | +use yii\grid\GridView; | ||
| 5 | + | ||
| 6 | +/* @var $this yii\web\View */ | ||
| 7 | +/* @var $searchModel common\modules\product\models\ProductVariantSearch */ | ||
| 8 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 9 | + | ||
| 10 | +$this->title = Yii::t('product', 'Variants'); | ||
| 11 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['/product/manage']]; | ||
| 12 | +if (!empty($product)) { | ||
| 13 | + $this->params['breadcrumbs'] = [ | ||
| 14 | + ['label' => Yii::t('product', 'Variants'), 'url' => ['/product/variant']], | ||
| 15 | + $product->fullname | ||
| 16 | + ]; | ||
| 17 | +} else { | ||
| 18 | + $this->params['breadcrumbs'][] = $this->title; | ||
| 19 | +} | ||
| 20 | +?> | ||
| 21 | +<div class="product-index"> | ||
| 22 | + | ||
| 23 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 24 | + <?php // echo $this->render('_search', ['model' => $searchModel]); ?> | ||
| 25 | + | ||
| 26 | + <p> | ||
| 27 | + <?= Html::a(Yii::t('product', 'Create Variant'), ['create'], ['class' => 'btn btn-success']) ?> | ||
| 28 | + </p> | ||
| 29 | + <?= GridView::widget([ | ||
| 30 | + 'dataProvider' => $dataProvider, | ||
| 31 | + 'filterModel' => $searchModel, | ||
| 32 | + 'columns' => [ | ||
| 33 | + ['class' => 'yii\grid\SerialColumn'], | ||
| 34 | + | ||
| 35 | + [ | ||
| 36 | + 'attribute' => 'product_id', | ||
| 37 | + 'value' => 'fullname', | ||
| 38 | + 'label' => Yii::t('product', 'Name'), | ||
| 39 | + 'filter' => \kartik\select2\Select2::widget([ | ||
| 40 | + 'model' => $searchModel, | ||
| 41 | + 'attribute' => 'product_id', | ||
| 42 | + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\product\models\Product::find()->orderBy(['name' => 'ASC'])->all(), 'product_id', 'name'), | ||
| 43 | + 'language' => 'ru', | ||
| 44 | + 'options' => [ | ||
| 45 | + 'placeholder' => Yii::t('product', 'Select product'), | ||
| 46 | + 'multiple' => false, | ||
| 47 | + ], | ||
| 48 | + 'pluginOptions' => [ | ||
| 49 | + 'allowClear' => true | ||
| 50 | + ], | ||
| 51 | + ]), | ||
| 52 | + ], | ||
| 53 | + 'sku', | ||
| 54 | + 'price', | ||
| 55 | + 'price_old', | ||
| 56 | + 'stock', | ||
| 57 | + | ||
| 58 | + ['class' => 'yii\grid\ActionColumn'], | ||
| 59 | + ], | ||
| 60 | + ]); ?> | ||
| 61 | +</div> |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | + | ||
| 5 | +/* @var $this yii\web\View */ | ||
| 6 | +/* @var $model common\modules\product\models\Product */ | ||
| 7 | + | ||
| 8 | +$this->title = Yii::t('product', 'Update {modelClass}: ', [ | ||
| 9 | + 'modelClass' => 'Product', | ||
| 10 | +]) . ' ' . $model->name; | ||
| 11 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['index']]; | ||
| 12 | +$this->params['breadcrumbs'][] = ['label' => $model->product->name, 'url' => ['view', 'id' => $model->product->product_id]]; | ||
| 13 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Variants'), 'url' => ['/product/variant?product_id='. $model->product->product_id]]; | ||
| 14 | +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->product_variant_id]]; | ||
| 15 | +$this->params['breadcrumbs'][] = Yii::t('product', 'Update'); | ||
| 16 | +?> | ||
| 17 | +<div class="product-update"> | ||
| 18 | + | ||
| 19 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 20 | + | ||
| 21 | + <?= $this->render('_form', [ | ||
| 22 | + 'model' => $model, | ||
| 23 | + 'groups' => $groups, | ||
| 24 | + ]) ?> | ||
| 25 | + | ||
| 26 | +</div> |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | +use yii\widgets\DetailView; | ||
| 5 | + | ||
| 6 | +/* @var $this yii\web\View */ | ||
| 7 | +/* @var $model common\modules\product\models\Product */ | ||
| 8 | + | ||
| 9 | +$this->title = $model->name; | ||
| 10 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['index']]; | ||
| 11 | +$this->params['breadcrumbs'][] = ['label' => $model->product->name, 'url' => ['view', 'id' => $model->product->product_id]]; | ||
| 12 | +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Variants'), 'url' => ['/product/variant?product_id='. $model->product->product_id]]; | ||
| 13 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 14 | +?> | ||
| 15 | +<div class="product-view"> | ||
| 16 | + | ||
| 17 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 18 | + | ||
| 19 | + <p> | ||
| 20 | + <?= Html::a(Yii::t('product', 'Update'), ['update', 'id' => $model->product_variant_id], ['class' => 'btn btn-primary']) ?> | ||
| 21 | + <?= Html::a(Yii::t('product', 'Delete'), ['delete', 'id' => $model->product_variant_id], [ | ||
| 22 | + 'class' => 'btn btn-danger', | ||
| 23 | + 'data' => [ | ||
| 24 | + 'confirm' => Yii::t('product', 'Are you sure you want to delete this item?'), | ||
| 25 | + 'method' => 'post', | ||
| 26 | + ], | ||
| 27 | + ]) ?> | ||
| 28 | + </p> | ||
| 29 | + | ||
| 30 | + <?= DetailView::widget([ | ||
| 31 | + 'model' => $model, | ||
| 32 | + 'attributes' => [ | ||
| 33 | + 'product_id', | ||
| 34 | + 'name', | ||
| 35 | + 'fullname', | ||
| 36 | + 'brand.name', | ||
| 37 | + 'category.name', | ||
| 38 | + 'image.imageUrl:image' | ||
| 39 | + ], | ||
| 40 | + ]) ?> | ||
| 41 | + | ||
| 42 | +</div> |
common/translation/ru/product.php
| @@ -24,6 +24,8 @@ return [ | @@ -24,6 +24,8 @@ return [ | ||
| 24 | 'Price Old' => 'Старая Цена', | 24 | 'Price Old' => 'Старая Цена', |
| 25 | 'Products' => 'Товары', | 25 | 'Products' => 'Товары', |
| 26 | 'Product' => 'Товар', | 26 | 'Product' => 'Товар', |
| 27 | + 'Variants' => 'Модифицкации', | ||
| 28 | + 'Variant' => 'Модифицкация', | ||
| 27 | 'Create Product' => 'Создать Товар', | 29 | 'Create Product' => 'Создать Товар', |
| 28 | 'Enable' => 'Доступно', | 30 | 'Enable' => 'Доступно', |
| 29 | 'Disable' => 'Отсутсвует', | 31 | 'Disable' => 'Отсутсвует', |
frontend/models/ProductFrontendSearch.php
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | namespace frontend\models; | 3 | namespace frontend\models; |
| 4 | 4 | ||
| 5 | +use common\modules\product\helpers\ProductHelper; | ||
| 5 | use common\modules\product\models\Brand; | 6 | use common\modules\product\models\Brand; |
| 6 | use common\modules\product\models\BrandName; | 7 | use common\modules\product\models\BrandName; |
| 7 | use common\modules\product\models\CategoryName; | 8 | use common\modules\product\models\CategoryName; |
| @@ -86,7 +87,7 @@ class ProductFrontendSearch extends Product { | @@ -86,7 +87,7 @@ class ProductFrontendSearch extends Product { | ||
| 86 | return $dataProvider; | 87 | return $dataProvider; |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | - $this->_setParams($query, $params); | 90 | + ProductHelper::_setQueryParams($query, $params); |
| 90 | 91 | ||
| 91 | $query->andWhere(['!=', ProductVariant::tableName() .'.stock', 0]); | 92 | $query->andWhere(['!=', ProductVariant::tableName() .'.stock', 0]); |
| 92 | 93 | ||
| @@ -144,7 +145,7 @@ class ProductFrontendSearch extends Product { | @@ -144,7 +145,7 @@ class ProductFrontendSearch extends Product { | ||
| 144 | } | 145 | } |
| 145 | $query->joinWith('variant'); | 146 | $query->joinWith('variant'); |
| 146 | 147 | ||
| 147 | - $this->_setParams($query, $params, false); | 148 | + ProductHelper::_setQueryParams($query, $params, false); |
| 148 | 149 | ||
| 149 | // $query->select([ | 150 | // $query->select([ |
| 150 | // 'MIN('. ProductVariant::tableName() .'.price) AS priceMIN', | 151 | // 'MIN('. ProductVariant::tableName() .'.price) AS priceMIN', |
| @@ -156,46 +157,4 @@ class ProductFrontendSearch extends Product { | @@ -156,46 +157,4 @@ class ProductFrontendSearch extends Product { | ||
| 156 | 'max' => $query->max(ProductVariant::tableName() .'.price'), | 157 | 'max' => $query->max(ProductVariant::tableName() .'.price'), |
| 157 | ]; | 158 | ]; |
| 158 | } | 159 | } |
| 159 | - | ||
| 160 | - protected function _setParams(&$query, $params, $setPriceLimits = true) { | ||
| 161 | - if (!empty($params['keywords'])) { | ||
| 162 | - if (!is_array($params['keywords'])) { | ||
| 163 | - $params['keywords'] = [$params['keywords']]; | ||
| 164 | - } | ||
| 165 | - foreach ($params['keywords'] as $keyword) { | ||
| 166 | - $query->orFilterWhere(['ilike', Product::tableName() .'.name', $keyword]); | ||
| 167 | - $query->orFilterWhere(['ilike', BrandName::tableName() .'.value', $keyword]); | ||
| 168 | - $query->orFilterWhere(['ilike', CategoryName::tableName() .'.value', $keyword]); | ||
| 169 | - } | ||
| 170 | - } | ||
| 171 | - if (!empty($params['special'])) { | ||
| 172 | - foreach($params['special'] as $key => $value) { | ||
| 173 | - $query->orFilterWhere([Product::tableName() .'.'. $key => $value]); | ||
| 174 | - } | ||
| 175 | - } | ||
| 176 | - if (!empty($params['brands'])) { | ||
| 177 | - $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); | ||
| 178 | - } | ||
| 179 | - if (!empty($params['options'])) { | ||
| 180 | - foreach ($params['options'] as $group => $options) { | ||
| 181 | - foreach ($options as &$option) { | ||
| 182 | - $option = "'$option'"; | ||
| 183 | - } | ||
| 184 | - $query->andWhere( | ||
| 185 | - Product::tableName() . '.product_id IN (SELECT product_id AS products FROM product_option INNER JOIN tax_option ON tax_option.tax_option_id = product_option.option_id INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id WHERE tax_group.alias LIKE \''. $group .'\' AND tax_option.alias IN (' . implode(',', $options) . '))' | ||
| 186 | - ); | ||
| 187 | - } | ||
| 188 | - } | ||
| 189 | - | ||
| 190 | - | ||
| 191 | - | ||
| 192 | - if ($setPriceLimits && !empty($params['prices'])) { | ||
| 193 | - if ($params['prices']['min'] > 0) { | ||
| 194 | - $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | ||
| 195 | - } | ||
| 196 | - if ($params['prices']['max'] > 0) { | ||
| 197 | - $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | ||
| 198 | - } | ||
| 199 | - } | ||
| 200 | - } | ||
| 201 | } | 160 | } |
| 202 | \ No newline at end of file | 161 | \ No newline at end of file |