Commit 4e55ce81faa87fb22605e278b6c921b061b4a401

Authored by Yarik
1 parent 00731fef

Another one admin fix

backend/views/category/index.php
@@ -21,49 +21,27 @@ @@ -21,49 +21,27 @@
21 </p> 21 </p>
22 <?= GridView::widget([ 22 <?= GridView::widget([
23 'dataProvider' => $dataProvider, 23 'dataProvider' => $dataProvider,
  24 + 'filterModel' => $searchModel,
24 'columns' => [ 25 'columns' => [
25 [ 'class' => 'yii\grid\SerialColumn' ], 26 [ 'class' => 'yii\grid\SerialColumn' ],
  27 + 'category_id',
26 [ 28 [
27 - 'label' => Yii::t('product', 'Name'), 29 + 'attribute' => 'category_name',
28 'content' => function($data) { 30 'content' => function($data) {
29 /** 31 /**
30 * @var Category $data 32 * @var Category $data
31 */ 33 */
32 $op = []; 34 $op = [];
33 - foreach($data->getParents() 35 + foreach($data->getParents()->with('lang')
34 ->all() as $parent) { 36 ->all() as $parent) {
35 - $op[] = $parent->category_id; 37 + $op[] = $parent->lang->name;
36 } 38 }
37 - $op[] = $data->category_id; 39 + $op[] = $data->lang->name;
38 return implode('&nbsp;&rarr;&nbsp;', $op); 40 return implode('&nbsp;&rarr;&nbsp;', $op);
39 }, 41 },
40 ], 42 ],
41 [ 43 [
42 'class' => 'yii\grid\ActionColumn', 44 'class' => 'yii\grid\ActionColumn',
43 - 'template' => '{view} {update} {delete}',  
44 - 'urlCreator' => function($action, $model, $key, $index) {  
45 - switch($action) {  
46 - case 'view':  
47 - return \yii\helpers\Url::to([  
48 - 'category/view',  
49 - 'id' => $model->category_id,  
50 - ]);  
51 - break;  
52 - case 'update':  
53 - return \yii\helpers\Url::to([  
54 - 'category/update',  
55 - 'id' => $model->category_id,  
56 - ]);  
57 - break;  
58 - case 'delete':  
59 - return \yii\helpers\Url::to([  
60 - 'category/delete',  
61 - 'id' => $model->category_id,  
62 - ]);  
63 - break;  
64 - }  
65 - return '';  
66 - },  
67 ], 45 ],
68 ], 46 ],
69 'panel' => [ 47 'panel' => [
common/modules/product/controllers/ManageController.php
@@ -68,10 +68,12 @@ @@ -68,10 +68,12 @@
68 $variants = $model->getVariants() 68 $variants = $model->getVariants()
69 ->with('lang') 69 ->with('lang')
70 ->all(); 70 ->all();
  71 + $properties = $model->getProperties();
71 return $this->render('view', [ 72 return $this->render('view', [
72 'model' => $this->findModel($id), 73 'model' => $this->findModel($id),
73 'categories' => $categories, 74 'categories' => $categories,
74 'variants' => $variants, 75 'variants' => $variants,
  76 + 'properties' => $properties,
75 ]); 77 ]);
76 } 78 }
77 79
common/modules/product/controllers/VariantController.php
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 use common\modules\product\models\ProductImage; 6 use common\modules\product\models\ProductImage;
7 use common\modules\product\models\ProductStock; 7 use common\modules\product\models\ProductStock;
8 use common\modules\product\models\ProductVariant; 8 use common\modules\product\models\ProductVariant;
9 - use common\modules\product\models\ProductVariantListSearch; 9 + use common\modules\product\models\ProductVariantSearch;
10 use common\modules\product\models\Stock; 10 use common\modules\product\models\Stock;
11 use Yii; 11 use Yii;
12 use yii\web\Controller; 12 use yii\web\Controller;
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 use yii\filters\VerbFilter; 14 use yii\filters\VerbFilter;
15 15
16 /** 16 /**
17 - * ManageController implements the CRUD actions for ProductVariant model. 17 + * VartiantController implements the CRUD actions for ProductVariant model.
18 */ 18 */
19 class VariantController extends Controller 19 class VariantController extends Controller
20 { 20 {
@@ -40,18 +40,16 @@ @@ -40,18 +40,16 @@
40 */ 40 */
41 public function actionIndex($product_id) 41 public function actionIndex($product_id)
42 { 42 {
43 - $searchModel = new ProductVariantListSearch();  
44 - $dataProvider = $searchModel->search(Yii::$app->request->queryParams, $product_id);  
45 -  
46 - if(( $product = Yii::$app->request->get('product_id') ) !== NULL) {  
47 - $product = Product::findOne($product);  
48 - } 43 + $product = $this->findProduct($product_id);
  44 + $searchModel = new ProductVariantSearch();
  45 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  46 + $dataProvider->query->andWhere([ 'product_id' => $product->product_id ])
  47 + ->with('image');
49 48
50 return $this->render('index', [ 49 return $this->render('index', [
51 'searchModel' => $searchModel, 50 'searchModel' => $searchModel,
52 'dataProvider' => $dataProvider, 51 'dataProvider' => $dataProvider,
53 'product' => $product, 52 'product' => $product,
54 - 'product_id' => $product_id,  
55 ]); 53 ]);
56 } 54 }
57 55
@@ -64,8 +62,11 @@ @@ -64,8 +62,11 @@
64 */ 62 */
65 public function actionView($id) 63 public function actionView($id)
66 { 64 {
  65 + $model = $this->findModel($id);
  66 + $properties = $model->getProperties();
67 return $this->render('view', [ 67 return $this->render('view', [
68 - 'model' => $this->findModel($id), 68 + 'model' => $model,
  69 + 'properties' => $properties,
69 ]); 70 ]);
70 } 71 }
71 72
@@ -76,8 +77,9 @@ @@ -76,8 +77,9 @@
76 */ 77 */
77 public function actionCreate($product_id) 78 public function actionCreate($product_id)
78 { 79 {
  80 + $product = $this->findProduct($product_id);
79 $model = new ProductVariant(); 81 $model = new ProductVariant();
80 - $model->product_id = $product_id; 82 + $model->product_id = $product->product_id;
81 $model->generateLangs(); 83 $model->generateLangs();
82 if($model->load(Yii::$app->request->post())) { 84 if($model->load(Yii::$app->request->post())) {
83 $model->loadLangs(\Yii::$app->request); 85 $model->loadLangs(\Yii::$app->request);
@@ -132,7 +134,7 @@ @@ -132,7 +134,7 @@
132 if($model->save() && $model->transactionStatus) { 134 if($model->save() && $model->transactionStatus) {
133 return $this->redirect([ 135 return $this->redirect([
134 'index', 136 'index',
135 - 'product_id' => $product_id, 137 + 'product_id' => $product->product_id,
136 ]); 138 ]);
137 } 139 }
138 } 140 }
@@ -143,6 +145,7 @@ @@ -143,6 +145,7 @@
143 'model_langs' => $model->model_langs, 145 'model_langs' => $model->model_langs,
144 'groups' => $groups, 146 'groups' => $groups,
145 'stocks' => [ new ProductStock() ], 147 'stocks' => [ new ProductStock() ],
  148 + 'product' => $product,
146 ]); 149 ]);
147 } 150 }
148 151
@@ -157,6 +160,7 @@ @@ -157,6 +160,7 @@
157 */ 160 */
158 public function actionUpdate($product_id, $id) 161 public function actionUpdate($product_id, $id)
159 { 162 {
  163 + $product = $this->findProduct($product_id);
160 $model = $this->findModel($id); 164 $model = $this->findModel($id);
161 $model->generateLangs(); 165 $model->generateLangs();
162 if($model->load(Yii::$app->request->post())) { 166 if($model->load(Yii::$app->request->post())) {
@@ -222,6 +226,7 @@ @@ -222,6 +226,7 @@
222 'model_langs' => $model->model_langs, 226 'model_langs' => $model->model_langs,
223 'groups' => $groups, 227 'groups' => $groups,
224 'stocks' => ( !empty( $model->variantStocks ) ) ? $model->variantStocks : [ new ProductStock ], 228 'stocks' => ( !empty( $model->variantStocks ) ) ? $model->variantStocks : [ new ProductStock ],
  229 + 'product' => $product,
225 ]); 230 ]);
226 } 231 }
227 232
@@ -269,7 +274,30 @@ @@ -269,7 +274,30 @@
269 */ 274 */
270 protected function findModel($id) 275 protected function findModel($id)
271 { 276 {
272 - if(( $model = ProductVariant::findOne($id) ) !== NULL) { 277 + if(( $model = ProductVariant::find()
  278 + ->where([ 'product_variant_id' => $id ])
  279 + ->with('lang')
  280 + ->one() ) !== NULL
  281 + ) {
  282 + return $model;
  283 + } else {
  284 + throw new NotFoundHttpException('The requested page does not exist.');
  285 + }
  286 + }
  287 +
  288 + /**
  289 + * @param int $product_id
  290 + *
  291 + * @return Product
  292 + * @throws NotFoundHttpException
  293 + */
  294 + protected function findProduct($product_id)
  295 + {
  296 + if(( $model = Product::find()
  297 + ->with('lang')
  298 + ->where([ 'product_id' => $product_id ])
  299 + ->one() ) !== NULL
  300 + ) {
273 return $model; 301 return $model;
274 } else { 302 } else {
275 throw new NotFoundHttpException('The requested page does not exist.'); 303 throw new NotFoundHttpException('The requested page does not exist.');
common/modules/product/models/CategorySearch.php
1 <?php 1 <?php
2 -  
3 -namespace common\modules\product\models;  
4 -  
5 -use common\components\artboxtree\ArtboxTreeHelper;  
6 -use yii\base\Model;  
7 -use yii\data\ActiveDataProvider;  
8 -  
9 -/**  
10 - * CategorySearch represents the model behind the search form about `common\modules\product\models\Category`.  
11 - */  
12 -class CategorySearch extends Category  
13 -{  
14 - public function behaviors()  
15 - {  
16 - return [];  
17 - }  
18 -  
19 - /**  
20 - * @inheritdoc  
21 - */  
22 - public function rules()  
23 - {  
24 - return [  
25 - [['category_id', 'parent_id', 'depth', 'product_unit_id'], 'integer'],  
26 - ];  
27 - }  
28 -  
29 - /**  
30 - * @inheritdoc  
31 - */  
32 - public function scenarios()  
33 - {  
34 - // bypass scenarios() implementation in the parent class  
35 - return Model::scenarios();  
36 - }  
37 - 2 +
  3 + namespace common\modules\product\models;
  4 +
  5 + use common\components\artboxtree\ArtboxTreeHelper;
  6 + use yii\base\Model;
  7 + use yii\data\ActiveDataProvider;
  8 +
38 /** 9 /**
39 - * Creates data provider instance with search query applied  
40 - *  
41 - * @param array $params  
42 - *  
43 - * @return ActiveDataProvider 10 + * CategorySearch represents the model behind the search form about
  11 + * `common\modules\product\models\Category`.
44 */ 12 */
45 - public function search($params) 13 + class CategorySearch extends Category
46 { 14 {
47 - $query = Category::find();  
48 -  
49 - // add conditions that should always apply here  
50 -  
51 - $dataProvider = new ActiveDataProvider([  
52 - 'query' => $query,  
53 - ]);  
54 -  
55 - $this->load($params);  
56 -  
57 - /*if (!$this->validate()) {  
58 - // uncomment the following line if you do not want to return any records when validation fails  
59 - // $query->where('0=1');  
60 - return $dataProvider;  
61 - }*/  
62 -  
63 - // grid filtering conditions  
64 - $query->andFilterWhere([  
65 - 'category.category_id' => $this->category_id,  
66 - 'category.parent_id' => $this->parent_id,  
67 - 'category.product_unit_id' => $this->product_unit_id,  
68 - ]);  
69 15
70 - $query->orderBy(['category.path' => SORT_ASC, 'category.depth' => SORT_ASC, 'category.category_id' => SORT_ASC]);  
71 -  
72 - return $dataProvider; 16 + public $category_name;
  17 +
  18 + public function behaviors()
  19 + {
  20 + return [];
  21 + }
  22 +
  23 + /**
  24 + * @inheritdoc
  25 + */
  26 + public function rules()
  27 + {
  28 + return [
  29 + [
  30 + [ 'category_name' ],
  31 + 'safe',
  32 + ],
  33 + [
  34 + [],
  35 + 'integer',
  36 + ],
  37 + ];
  38 + }
  39 +
  40 + /**
  41 + * @inheritdoc
  42 + */
  43 + public function scenarios()
  44 + {
  45 + // bypass scenarios() implementation in the parent class
  46 + return Model::scenarios();
  47 + }
  48 +
  49 + /**
  50 + * Creates data provider instance with search query applied
  51 + *
  52 + * @param array $params
  53 + *
  54 + * @return ActiveDataProvider
  55 + */
  56 + public function search($params)
  57 + {
  58 + $query = Category::find()
  59 + ->joinWith('lang');
  60 +
  61 + // add conditions that should always apply here
  62 +
  63 + $dataProvider = new ActiveDataProvider([
  64 + 'query' => $query,
  65 + 'sort' => false,
  66 + ]);
  67 +
  68 + $this->load($params);
  69 +
  70 + /*if (!$this->validate()) {
  71 + // uncomment the following line if you do not want to return any records when validation fails
  72 + // $query->where('0=1');
  73 + return $dataProvider;
  74 + }*/
  75 +
  76 + // grid filtering conditions
  77 + $query->andFilterWhere([
  78 + 'ilike',
  79 + 'category_lang.name',
  80 + $this->category_name,
  81 + ]);
  82 +
  83 + $query->orderBy([
  84 + 'category.path' => SORT_ASC,
  85 + 'category.depth' => SORT_ASC,
  86 + 'category.category_id' => SORT_ASC,
  87 + ]);
  88 +
  89 + return $dataProvider;
  90 + }
73 } 91 }
74 -}  
common/modules/product/models/Product.php
@@ -104,15 +104,15 @@ @@ -104,15 +104,15 @@
104 'model' => ProductCertificate::className(), 104 'model' => ProductCertificate::className(),
105 ], 105 ],
106 'multipleImage' => [ 106 'multipleImage' => [
107 - 'class' => MultipleImgBehavior::className(),  
108 - 'links' => [ 107 + 'class' => MultipleImgBehavior::className(),
  108 + 'links' => [
109 'product_id' => 'product_id', 109 'product_id' => 'product_id',
110 ], 110 ],
111 - 'model' => ProductImage::className(), 111 + 'model' => ProductImage::className(),
112 'config' => [ 112 'config' => [
113 - 'caption' => 'image', 113 + 'caption' => 'image',
114 'delete_action' => '/product/manage/delimg', 114 'delete_action' => '/product/manage/delimg',
115 - 'id' => 'product_image_id', 115 + 'id' => 'product_image_id',
116 ], 116 ],
117 ], 117 ],
118 [ 118 [
@@ -302,14 +302,20 @@ @@ -302,14 +302,20 @@
302 ->viaTable('product_option', [ 'product_id' => 'product_id' ]); 302 ->viaTable('product_option', [ 'product_id' => 'product_id' ]);
303 } 303 }
304 304
  305 + /**
  306 + * @return TaxGroup[]
  307 + */
305 public function getProperties() 308 public function getProperties()
306 { 309 {
307 $groups = $options = []; 310 $groups = $options = [];
308 - foreach($this->options as $option) { 311 + foreach($this->getOptions()
  312 + ->with('lang')
  313 + ->all() as $option) {
309 $options[ $option->tax_group_id ][] = $option; 314 $options[ $option->tax_group_id ][] = $option;
310 } 315 }
311 foreach(TaxGroup::find() 316 foreach(TaxGroup::find()
312 ->where([ 'tax_group_id' => array_keys($options) ]) 317 ->where([ 'tax_group_id' => array_keys($options) ])
  318 + ->with('lang')
313 ->all() as $group) { 319 ->all() as $group) {
314 if(!empty( $options[ $group->tax_group_id ] )) { 320 if(!empty( $options[ $group->tax_group_id ] )) {
315 $group->_options = $options[ $group->tax_group_id ]; 321 $group->_options = $options[ $group->tax_group_id ];
common/modules/product/models/ProductSearch.php
@@ -93,7 +93,6 @@ @@ -93,7 +93,6 @@
93 { 93 {
94 94
95 $query = Product::find(); 95 $query = Product::find();
96 -  
97 $query->select([ 96 $query->select([
98 'product.*', 97 'product.*',
99 'COUNT(product_variant.product_variant_id) as count', 98 'COUNT(product_variant.product_variant_id) as count',
@@ -123,10 +122,6 @@ @@ -123,10 +122,6 @@
123 'query' => $query, 122 'query' => $query,
124 ]); 123 ]);
125 124
126 - if(!( $this->load($params) && $this->validate() )) {  
127 - return $dataProvider;  
128 - }  
129 -  
130 $dataProvider->setSort([ 125 $dataProvider->setSort([
131 'attributes' => [ 126 'attributes' => [
132 'product_id', 127 'product_id',
@@ -147,17 +142,17 @@ @@ -147,17 +142,17 @@
147 ]); 142 ]);
148 143
149 if(isset( $this->is_top )) { 144 if(isset( $this->is_top )) {
150 - $query->andFilterWhere([ 145 + $query->andWhere([
151 'is_top' => (bool) $this->is_top, 146 'is_top' => (bool) $this->is_top,
152 ]); 147 ]);
153 } 148 }
154 if(isset( $this->is_new )) { 149 if(isset( $this->is_new )) {
155 - $query->andFilterWhere([ 150 + $query->andWhere([
156 'is_new' => (bool) $this->is_new, 151 'is_new' => (bool) $this->is_new,
157 ]); 152 ]);
158 } 153 }
159 if(isset( $this->akciya )) { 154 if(isset( $this->akciya )) {
160 - $query->andFilterWhere([ 155 + $query->andWhere([
161 'akciya' => (bool) $this->akciya, 156 'akciya' => (bool) $this->akciya,
162 ]); 157 ]);
163 } 158 }
common/modules/product/models/ProductVariantSearch.php
1 <?php 1 <?php
2 -  
3 -namespace common\modules\product\models;  
4 -  
5 -use yii\base\Model;  
6 -use yii\data\ActiveDataProvider;  
7 -use yii\db\ActiveQuery;  
8 -/**  
9 - * ProductVariantSearch represents the model behind the search form about `common\modules\product\models\ProductVariant`.  
10 - */  
11 -class ProductVariantSearch extends ProductVariant  
12 -{  
13 - public $brand_name;  
14 - public $category_name;  
15 - public $tax_group_id;  
16 - public $is_top;  
17 - public $is_new;  
18 - public $akciya;  
19 2
20 - public function behaviors()  
21 - {  
22 - return [];  
23 - } 3 + namespace common\modules\product\models;
  4 +
  5 + use yii\base\Model;
  6 + use yii\data\ActiveDataProvider;
24 7
25 /** 8 /**
26 - * @inheritdoc  
27 - */  
28 - public function rules()  
29 - {  
30 - return [  
31 - [['name', 'fullname', 'sku', 'price', 'price_old', 'stock', 'brand_name', 'category_name'], 'safe'],  
32 - [['product_variant_id', 'product_id'], 'integer'],  
33 - [['is_top', 'is_new', 'akciya'], 'boolean'],  
34 - ];  
35 - }  
36 -  
37 - /**  
38 - * @inheritdoc  
39 - */  
40 - public function scenarios()  
41 - {  
42 - // bypass scenarios() implementation in the parent class  
43 - return Model::scenarios();  
44 - }  
45 -  
46 - /**  
47 - * Creates data provider instance with search query applied  
48 - *  
49 - * @param array $params  
50 - *  
51 - * @return ActiveDataProvider 9 + * ProductVariantSearch represents the model behind the search form about
  10 + * `common\modules\product\models\ProductVariant`.
52 */ 11 */
53 - public function search($params) 12 + class ProductVariantSearch extends ProductVariant
54 { 13 {
55 - $query = ProductVariant::find();  
56 -  
57 - // add conditions that should always apply here  
58 -  
59 - $dataProvider = new ActiveDataProvider([  
60 - 'query' => $query,  
61 - ]);  
62 -  
63 - $this->load($params);  
64 -  
65 - if (!empty($params['product_id'])) {  
66 - $this->product_id = $params['product_id'];  
67 - }  
68 -  
69 - if (!$this->validate()) {  
70 - // uncomment the following line if you do not want to return any records when validation fails  
71 - // $query->where('0=1');  
72 - return $dataProvider; 14 +
  15 + public $variant_name;
  16 +
  17 + public function behaviors()
  18 + {
  19 + return [];
73 } 20 }
74 -  
75 - $dataProvider->setSort([  
76 - 'attributes' => [  
77 - 'name' => [  
78 - 'asc' => ['product_variant.name' => SORT_ASC],  
79 - 'desc' => ['product_variant.value' => SORT_DESC],  
80 - 'default' => SORT_DESC,  
81 - 'label' => 'Variant name', 21 +
  22 + /**
  23 + * @inheritdoc
  24 + */
  25 + public function rules()
  26 + {
  27 + return [
  28 + [
  29 + [
  30 + 'variant_name',
  31 + 'sku',
  32 + ],
  33 + 'safe',
82 ], 34 ],
83 - 'brand_name' => [  
84 - 'asc' => ['brand_name.value' => SORT_ASC],  
85 - 'desc' => ['brand_name.value' => SORT_DESC],  
86 - 'default' => SORT_DESC,  
87 - 'label' => 'Brand name', 35 + [
  36 + [
  37 + 'product_variant_id',
  38 + 'stock',
  39 + ],
  40 + 'integer',
88 ], 41 ],
89 - 'category_name',  
90 - 'sku',  
91 - ]  
92 - ]);  
93 -  
94 - $query->joinWith(['product', 'product.brand', 'product.categories']);  
95 -  
96 - if (isset($this->is_top)) {  
97 - $query->andFilterWhere([  
98 - 'product.is_top' => (bool)$this->is_top,  
99 - ]); 42 + [
  43 + [
  44 + 'price',
  45 + 'price_old',
  46 + ],
  47 + 'number',
  48 + ],
  49 + ];
  50 + }
  51 +
  52 + /**
  53 + * @inheritdoc
  54 + */
  55 + public function scenarios()
  56 + {
  57 + // bypass scenarios() implementation in the parent class
  58 + return Model::scenarios();
100 } 59 }
101 - if (isset($this->is_new)) { 60 +
  61 + /**
  62 + * Creates data provider instance with search query applied
  63 + *
  64 + * @param array $params
  65 + *
  66 + * @return ActiveDataProvider
  67 + */
  68 + public function search($params)
  69 + {
  70 + $query = ProductVariant::find()
  71 + ->joinWith('lang');
  72 +
  73 + // add conditions that should always apply here
  74 +
  75 + $dataProvider = new ActiveDataProvider([
  76 + 'query' => $query,
  77 + ]);
  78 +
  79 + $this->load($params);
  80 +
  81 + if(!$this->validate()) {
  82 + // uncomment the following line if you do not want to return any records when validation fails
  83 + // $query->where('0=1');
  84 + return $dataProvider;
  85 + }
  86 +
  87 + $dataProvider->setSort([
  88 + 'attributes' => [
  89 + 'product_variant_id',
  90 + 'sku',
  91 + 'variant_name' => [
  92 + 'asc' => [ 'product_variant_lang.name' => SORT_ASC ],
  93 + 'desc' => [ 'product_variant_lang.name' => SORT_DESC ],
  94 + ],
  95 + 'price',
  96 + 'price_old',
  97 + 'stock',
  98 + ],
  99 + ]);
  100 +
102 $query->andFilterWhere([ 101 $query->andFilterWhere([
103 - 'product.is_new' => (bool)$this->is_new, 102 + 'price' => $this->price,
  103 + 'price_old' => $this->price_old,
  104 + 'stock' => $this->stock,
104 ]); 105 ]);
105 - }  
106 - if (isset($this->akciya)) { 106 +
107 $query->andFilterWhere([ 107 $query->andFilterWhere([
108 - 'product.akciya' => (bool)$this->akciya, 108 + 'ilike',
  109 + 'product_variant_lang.name',
  110 + $this->variant_name,
  111 + ])
  112 + ->andFilterWhere([
  113 + 'ilike',
  114 + 'sku',
  115 + $this->sku,
  116 + ]);
  117 +
  118 + $query->groupBy([
  119 + 'product_variant.product_variant_id',
  120 + 'product_variant_lang.name',
109 ]); 121 ]);
  122 +
  123 + return $dataProvider;
110 } 124 }
111 -  
112 - // grid filtering conditions  
113 - $query->andFilterWhere([  
114 - 'product_variant.product_id' => $this->product_id,  
115 - 'product_variant_id' => $this->product_variant_id,  
116 - ]);  
117 -  
118 - if (!empty($this->fullname)) {  
119 - $query->orFilterWhere(['like', 'product_variant.name', $this->fullname]);  
120 - $query->orFilterWhere(['ilike', 'product.name', $this->fullname]);  
121 - }  
122 - $query->andFilterWhere(['ilike', 'product.brand_name.value', $this->brand_name]);  
123 - $query->andFilterWhere(['ilike', 'product.category_name.value', $this->category_name]);  
124 - $query->andFilterWhere(['ilike', 'sku', $this->sku]);  
125 -  
126 - $query->groupBy(['product_variant_id']);  
127 - $query->orderBy(['product_variant.product_id' => SORT_ASC]);  
128 -  
129 - return $dataProvider;  
130 - }  
131 -  
132 - public static function findBySku($sku) {  
133 - /** @var ActiveQuery $query */  
134 - $query = ProductVariant::find()  
135 - ->andFilterWhere(['sku' => $sku]);  
136 - if (($model = $query->one()) !== null) {  
137 - return $model; 125 +
  126 + /**
  127 + * @param string $sku
  128 + *
  129 + * @return ProductVariant|null
  130 + */
  131 + public static function findBySku($sku)
  132 + {
  133 + /**
  134 + * @var ProductVariant|null $result
  135 + */
  136 + $result = ProductVariant::find()
  137 + ->andWhere([ 'sku' => $sku ])
  138 + ->one();
  139 + return $result;
138 } 140 }
139 - return NULL;  
140 } 141 }
141 -}  
common/modules/product/views/manage/update.php
@@ -17,13 +17,13 @@ @@ -17,13 +17,13 @@
17 17
18 $this->title = Yii::t('product', 'Update {modelClass}: ', [ 18 $this->title = Yii::t('product', 'Update {modelClass}: ', [
19 'modelClass' => 'Product', 19 'modelClass' => 'Product',
20 - ]) . ' ' . $model->product_id; 20 + ]) . ' ' . $model->lang->name;
21 $this->params[ 'breadcrumbs' ][] = [ 21 $this->params[ 'breadcrumbs' ][] = [
22 'label' => Yii::t('product', 'Products'), 22 'label' => Yii::t('product', 'Products'),
23 'url' => [ 'index' ], 23 'url' => [ 'index' ],
24 ]; 24 ];
25 $this->params[ 'breadcrumbs' ][] = [ 25 $this->params[ 'breadcrumbs' ][] = [
26 - 'label' => $model->product_id, 26 + 'label' => $model->lang->name,
27 'url' => [ 27 'url' => [
28 'view', 28 'view',
29 'id' => $model->product_id, 29 'id' => $model->product_id,
common/modules/product/views/manage/view.php
@@ -2,15 +2,19 @@ @@ -2,15 +2,19 @@
2 2
3 use common\modules\product\models\Category; 3 use common\modules\product\models\Category;
4 use common\modules\product\models\Product; 4 use common\modules\product\models\Product;
  5 + use common\modules\product\models\ProductVariant;
  6 + use common\modules\rubrication\models\TaxGroup;
5 use yii\helpers\ArrayHelper; 7 use yii\helpers\ArrayHelper;
6 use yii\helpers\Html; 8 use yii\helpers\Html;
7 use yii\web\View; 9 use yii\web\View;
8 use yii\widgets\DetailView; 10 use yii\widgets\DetailView;
9 11
10 /** 12 /**
11 - * @var View $this  
12 - * @var Product $model  
13 - * @var Category[] $categories 13 + * @var View $this
  14 + * @var Product $model
  15 + * @var Category[] $categories
  16 + * @var TaxGroup[] $properties
  17 + * @var ProductVariant[] $variants
14 */ 18 */
15 19
16 $this->title = $model->lang->name; 20 $this->title = $model->lang->name;
@@ -19,6 +23,21 @@ @@ -19,6 +23,21 @@
19 'url' => [ 'index' ], 23 'url' => [ 'index' ],
20 ]; 24 ];
21 $this->params[ 'breadcrumbs' ][] = $this->title; 25 $this->params[ 'breadcrumbs' ][] = $this->title;
  26 + $properties_string = '';
  27 + foreach($properties as $property) {
  28 + $property_list = '';
  29 + foreach($property->options as $option) {
  30 + $property_list .= Html::tag('li', $option->lang->value);
  31 + }
  32 + $properties_string .= Html::tag('p', $property->lang->name) . Html::tag('ul', $property_list);
  33 + }
  34 + $variants_string = '';
  35 + foreach($variants as $variant) {
  36 + $variants_string .= Html::a($variant->lang->name, [
  37 + '/product/variant/view',
  38 + 'id' => $variant->product_variant_id,
  39 + ]) . '<br>';
  40 + }
22 ?> 41 ?>
23 <div class="product-view"> 42 <div class="product-view">
24 43
@@ -39,6 +58,10 @@ @@ -39,6 +58,10 @@
39 'method' => 'post', 58 'method' => 'post',
40 ], 59 ],
41 ]) ?> 60 ]) ?>
  61 + <?= Html::a(Yii::t('product', 'Variants'), [
  62 + '/product/variant/index',
  63 + 'product_id' => $model->product_id,
  64 + ], [ 'class' => 'btn btn-info' ]) ?>
42 </p> 65 </p>
43 66
44 <?= DetailView::widget([ 67 <?= DetailView::widget([
@@ -68,8 +91,19 @@ @@ -68,8 +91,19 @@
68 ], 91 ],
69 [ 92 [
70 'attribute' => 'video', 93 'attribute' => 'video',
  94 + 'format' => 'html',
  95 + ],
  96 + [
  97 + 'label' => \Yii::t('app', 'Properties'),
  98 + 'value' => $properties_string,
  99 + 'format' => 'html',
  100 + ],
  101 + [
  102 + 'label' => \Yii::t('app', 'Variants'),
  103 + 'value' => $variants_string,
71 'format' => 'html', 104 'format' => 'html',
72 ], 105 ],
  106 + 'lang.description:html',
73 'image.imageUrl:image', 107 'image.imageUrl:image',
74 ], 108 ],
75 ]) ?> 109 ]) ?>
common/modules/product/views/variant/_form.php
1 <?php 1 <?php
2 2
3 use common\modules\language\widgets\LanguageForm; 3 use common\modules\language\widgets\LanguageForm;
  4 + use common\modules\product\models\Product;
4 use common\modules\product\models\ProductStock; 5 use common\modules\product\models\ProductStock;
5 use common\modules\product\models\ProductUnit; 6 use common\modules\product\models\ProductUnit;
6 use common\modules\product\models\ProductVariant; 7 use common\modules\product\models\ProductVariant;
@@ -19,6 +20,7 @@ @@ -19,6 +20,7 @@
19 * @var ActiveQuery $groups 20 * @var ActiveQuery $groups
20 * @var ProductStock[] $stocks 21 * @var ProductStock[] $stocks
21 * @var ActiveForm $form 22 * @var ActiveForm $form
  23 + * @var Product $product
22 */ 24 */
23 25
24 $js = ' 26 $js = '
@@ -55,7 +57,7 @@ $(&quot;.dynamicform_wrapper&quot;).on(&quot;limitReached&quot;, function(e, item) { @@ -55,7 +57,7 @@ $(&quot;.dynamicform_wrapper&quot;).on(&quot;limitReached&quot;, function(e, item) {
55 ->textarea(); ?> 57 ->textarea(); ?>
56 <?= $form->field($model, 'imagesUpload[]') 58 <?= $form->field($model, 'imagesUpload[]')
57 ->widget(\kartik\file\FileInput::className(), [ 59 ->widget(\kartik\file\FileInput::className(), [
58 - 'language' => 'ru', 60 + 'language' => 'ru',
59 'options' => [ 61 'options' => [
60 'accept' => 'image/*', 62 'accept' => 'image/*',
61 'multiple' => true, 63 'multiple' => true,
common/modules/product/views/variant/create.php
1 <?php 1 <?php
2 2
  3 + use common\modules\product\models\Product;
3 use common\modules\product\models\ProductStock; 4 use common\modules\product\models\ProductStock;
4 use common\modules\product\models\ProductVariant; 5 use common\modules\product\models\ProductVariant;
5 use common\modules\product\models\ProductVariantLang; 6 use common\modules\product\models\ProductVariantLang;
@@ -13,11 +14,20 @@ @@ -13,11 +14,20 @@
13 * @var ProductVariantLang[] $model_langs 14 * @var ProductVariantLang[] $model_langs
14 * @var ActiveQuery $groups 15 * @var ActiveQuery $groups
15 * @var ProductStock[] $stocks 16 * @var ProductStock[] $stocks
  17 + * @var Product $product
16 */ 18 */
17 - $this->title = Yii::t('product', 'Create Product'); 19 + $this->title = Yii::t('product', 'Create Variant');
18 $this->params[ 'breadcrumbs' ][] = [ 20 $this->params[ 'breadcrumbs' ][] = [
19 'label' => Yii::t('product', 'Products'), 21 'label' => Yii::t('product', 'Products'),
20 - 'url' => [ 'index' ], 22 + 'url' => [ '/product/manage/index' ],
  23 + ];
  24 + $this->params[ 'breadcrumbs' ][] = [
  25 + 'label' => $product->lang->name,
  26 + 'url' => [ '/product/manage/view', 'id' => $product->product_id ],
  27 + ];
  28 + $this->params[ 'breadcrumbs' ][] = [
  29 + 'label' => Yii::t('product', 'Variants'),
  30 + 'url' => [ 'index', 'product_id' => $product->product_id ],
21 ]; 31 ];
22 $this->params[ 'breadcrumbs' ][] = $this->title; 32 $this->params[ 'breadcrumbs' ][] = $this->title;
23 ?> 33 ?>
@@ -30,6 +40,7 @@ @@ -30,6 +40,7 @@
30 'model_langs' => $model_langs, 40 'model_langs' => $model_langs,
31 'groups' => $groups, 41 'groups' => $groups,
32 'stocks' => $stocks, 42 'stocks' => $stocks,
  43 + 'product' => $product,
33 ]) ?> 44 ]) ?>
34 45
35 </div> 46 </div>
common/modules/product/views/variant/index.php
1 <?php 1 <?php
2 -  
3 -use yii\helpers\Html;  
4 -use yii\grid\GridView;  
5 -use yii\helpers\Url;  
6 -  
7 -/* @var $this yii\web\View */  
8 -/* @var $searchModel common\modules\product\models\ProductVariantSearch */  
9 -/* @var $dataProvider yii\data\ActiveDataProvider */  
10 -  
11 -$this->title = Yii::t('product', 'Variants');  
12 -$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['/product/manage']];  
13 -if (!empty($product)) {  
14 - $this->params['breadcrumbs'] = [  
15 - ['label' => Yii::t('product', 'Variants'), 'url' => ['/product/variant']],  
16 - $product->fullname 2 +
  3 + use common\modules\product\models\Product;
  4 + use common\modules\product\models\ProductVariantSearch;
  5 + use yii\data\ActiveDataProvider;
  6 + use yii\helpers\Html;
  7 + use yii\grid\GridView;
  8 + use yii\helpers\Url;
  9 + use yii\web\View;
  10 +
  11 + /**
  12 + * @var View $this
  13 + * @var ProductVariantSearch $searchModel
  14 + * @var ActiveDataProvider $dataProvider
  15 + * @var Product $product
  16 + */
  17 +
  18 + $this->title = Yii::t('product', 'Variants for ').$product->lang->name;
  19 + $this->params[ 'breadcrumbs' ][] = [
  20 + 'label' => Yii::t('product', 'Products'),
  21 + 'url' => [ '/product/manage/index' ],
17 ]; 22 ];
18 -} else {  
19 - $this->params['breadcrumbs'][] = $this->title;  
20 -} 23 + $this->params[ 'breadcrumbs' ][] = [
  24 + 'label' => $product->lang->name,
  25 + 'url' => [
  26 + '/product/manage/view',
  27 + 'id' => $product->product_id,
  28 + ],
  29 + ];
  30 + $this->params['breadcrumbs'][] = \Yii::t('product', 'Variants');
21 ?> 31 ?>
22 <div class="product-index"> 32 <div class="product-index">
23 - 33 +
24 <h1><?= Html::encode($this->title) ?></h1> 34 <h1><?= Html::encode($this->title) ?></h1>
25 - 35 +
26 <p> 36 <p>
27 - <?= Html::a(Yii::t('product', 'Create Variant'), Url::toRoute(['create','product_id'=> $product_id]), ['class' => 'btn btn-success']) ?> 37 + <?= Html::a(Yii::t('product', 'Create Variant'), Url::toRoute([
  38 + 'create',
  39 + 'product_id' => $product->product_id,
  40 + ]), [ 'class' => 'btn btn-success' ]) ?>
28 </p> 41 </p>
29 <?= GridView::widget([ 42 <?= GridView::widget([
30 'dataProvider' => $dataProvider, 43 'dataProvider' => $dataProvider,
31 - 'filterModel' => $searchModel,  
32 - 'columns' => [  
33 - ['class' => 'yii\grid\SerialColumn'], 44 + 'filterModel' => $searchModel,
  45 + 'columns' => [
  46 + 'product_variant_id',
34 [ 47 [
35 - 'attribute' => 'product_id',  
36 - 'value' => 'fullname',  
37 - 'label' => Yii::t('product', 'Name'),  
38 - 'filter' => \kartik\select2\Select2::widget([  
39 - 'model' => $searchModel,  
40 - 'attribute' => 'product_id',  
41 -// 'data' => \yii\helpers\ArrayHelper::map(\common\modules\product\models\Product::find()->orderBy(['name' => 'ASC'])->all(), 'product_id', 'name'),  
42 - 'language' => 'ru',  
43 - 'options' => [  
44 - 'placeholder' => Yii::t('product', 'Select product'),  
45 - 'multiple' => false,  
46 - ],  
47 - 'pluginOptions' => [  
48 - 'allowClear' => true  
49 - ],  
50 - ]), 48 + 'attribute' => 'variant_name',
  49 + 'value' => 'lang.name',
51 ], 50 ],
52 'sku', 51 'sku',
53 'price', 52 'price',
54 'price_old', 53 'price_old',
55 'stock', 54 'stock',
  55 + 'image.imageUrl:image',
56 [ 56 [
57 - 'class' => 'yii\grid\ActionColumn',  
58 - 'buttons' => [  
59 - 'view' => function ($url, $model)  
60 - {  
61 - return Html::a (  
62 - '<span class="glyphicon glyphicon-eye-open"></span>',  
63 - Url::to(['view','product_id'=> $model->product_id, 'id' => $model->product_variant_id]),  
64 - [  
65 - 'title' => "ะŸั€ะพัะผะพั‚ั€",  
66 - ]  
67 - ); 57 + 'class' => 'yii\grid\ActionColumn',
  58 + 'buttons' => [
  59 + 'view' => function($url, $model) {
  60 + return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', Url::to([
  61 + 'view',
  62 + 'product_id' => $model->product_id,
  63 + 'id' => $model->product_variant_id,
  64 + ]), [
  65 + 'title' => \Yii::t('app', "ะŸั€ะพัะผะพั‚ั€"),
  66 + ]);
68 }, 67 },
69 - 'update' => function ($url, $model)  
70 - {  
71 - return Html::a (  
72 - '<span class="glyphicon glyphicon-pencil"></span>',  
73 - Url::to(['update','product_id'=> $model->product_id, 'id' => $model->product_variant_id]),  
74 - [  
75 - 'title' => "ะ ะตะดะฐะบั‚ะธั€ะพะฒะฐั‚ัŒ",  
76 - ]  
77 - ); 68 + 'update' => function($url, $model) {
  69 + return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Url::to([
  70 + 'update',
  71 + 'product_id' => $model->product_id,
  72 + 'id' => $model->product_variant_id,
  73 + ]), [
  74 + 'title' => \Yii::t('app', "ะ ะตะดะฐะบั‚ะธั€ะพะฒะฐั‚ัŒ"),
  75 + ]);
78 }, 76 },
79 - 'delete' => function ($url, $model)  
80 - {  
81 -  
82 - return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::to(['delete','product_id'=> $model->product_id, 'id' => $model->product_variant_id]), [  
83 - 'title' => Yii::t('yii', 'Delete'), 77 + 'delete' => function($url, $model) {
  78 +
  79 + return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::to([
  80 + 'delete',
  81 + 'product_id' => $model->product_id,
  82 + 'id' => $model->product_variant_id,
  83 + ]), [
  84 + 'title' => Yii::t('yii', 'Delete'),
84 'data-confirm' => Yii::t('yii', 'Are you sure to delete this item?'), 85 'data-confirm' => Yii::t('yii', 'Are you sure to delete this item?'),
85 - 'data-method' => 'post', 86 + 'data-method' => 'post',
86 ]); 87 ]);
87 - 88 +
88 }, 89 },
89 ], 90 ],
90 ], 91 ],
common/modules/product/views/variant/update.php
1 <?php 1 <?php
2 2
  3 + use common\modules\product\models\Product;
3 use common\modules\product\models\ProductStock; 4 use common\modules\product\models\ProductStock;
4 use common\modules\product\models\ProductVariant; 5 use common\modules\product\models\ProductVariant;
5 use common\modules\product\models\ProductVariantLang; 6 use common\modules\product\models\ProductVariantLang;
@@ -14,28 +15,36 @@ @@ -14,28 +15,36 @@
14 * @var ProductVariantLang[] $model_langs 15 * @var ProductVariantLang[] $model_langs
15 * @var ActiveQuery $groups 16 * @var ActiveQuery $groups
16 * @var ProductStock[] $stocks 17 * @var ProductStock[] $stocks
  18 + * @var Product $product
17 */ 19 */
18 $this->title = Yii::t('product', 'Update {modelClass}: ', [ 20 $this->title = Yii::t('product', 'Update {modelClass}: ', [
19 'modelClass' => 'Product', 21 'modelClass' => 'Product',
20 - ]) . ' ' . $model->product_variant_id; 22 + ]) . ' ' . $model->lang->name;
21 $this->params[ 'breadcrumbs' ][] = [ 23 $this->params[ 'breadcrumbs' ][] = [
22 'label' => Yii::t('product', 'Products'), 24 'label' => Yii::t('product', 'Products'),
23 - 'url' => [ 'index' ], 25 + 'url' => [ '/product/manage/index' ],
24 ]; 26 ];
25 $this->params[ 'breadcrumbs' ][] = [ 27 $this->params[ 'breadcrumbs' ][] = [
26 - 'label' => $model->product->product_id, 28 + 'label' => $model->product->lang->name,
27 'url' => [ 29 'url' => [
28 - 'view', 30 + '/product/manage/view',
29 'id' => $model->product->product_id, 31 'id' => $model->product->product_id,
30 ], 32 ],
31 ]; 33 ];
32 $this->params[ 'breadcrumbs' ][] = [ 34 $this->params[ 'breadcrumbs' ][] = [
33 'label' => Yii::t('product', 'Variants'), 35 'label' => Yii::t('product', 'Variants'),
34 'url' => Url::to([ 36 'url' => Url::to([
35 - '/product/variant', 37 + 'index',
36 'product_id' => $model->product->product_id, 38 'product_id' => $model->product->product_id,
37 ]), 39 ]),
38 ]; 40 ];
  41 + $this->params[ 'breadcrumbs' ][] = [
  42 + 'label' => Yii::t('product', $model->lang->name),
  43 + 'url' => Url::to([
  44 + 'view',
  45 + 'id' => $model->product_variant_id,
  46 + ]),
  47 + ];
39 $this->params[ 'breadcrumbs' ][] = Yii::t('product', 'Update'); 48 $this->params[ 'breadcrumbs' ][] = Yii::t('product', 'Update');
40 ?> 49 ?>
41 <div class="product-update"> 50 <div class="product-update">
@@ -47,6 +56,7 @@ @@ -47,6 +56,7 @@
47 'model_langs' => $model_langs, 56 'model_langs' => $model_langs,
48 'groups' => $groups, 57 'groups' => $groups,
49 'stocks' => $stocks, 58 'stocks' => $stocks,
  59 + 'product' => $product,
50 ]) ?> 60 ]) ?>
51 61
52 </div> 62 </div>
common/modules/product/views/variant/view.php
1 <?php 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\ProductVariant */  
8 -  
9 -$this->title = $model->product_variant_id;  
10 -$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Products'), 'url' => ['index']];  
11 -$this->params['breadcrumbs'][] = ['label' => $model->product->lang->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; 2 +
  3 + use common\modules\product\models\ProductVariant;
  4 + use common\modules\rubrication\models\TaxGroup;
  5 + use yii\helpers\Html;
  6 + use yii\web\View;
  7 + use yii\widgets\DetailView;
  8 +
  9 + /**
  10 + * @var View $this
  11 + * @var ProductVariant $model
  12 + * @var TaxGroup[] $properties
  13 + */
  14 +
  15 + $this->title = $model->lang->name;
  16 + $this->params[ 'breadcrumbs' ][] = [
  17 + 'label' => Yii::t('product', 'Products'),
  18 + 'url' => [ 'index' ],
  19 + ];
  20 + $this->params[ 'breadcrumbs' ][] = [
  21 + 'label' => $model->product->lang->name,
  22 + 'url' => [
  23 + 'view',
  24 + 'id' => $model->product->product_id,
  25 + ],
  26 + ];
  27 + $this->params[ 'breadcrumbs' ][] = [
  28 + 'label' => Yii::t('product', 'Variants'),
  29 + 'url' => [ '/product/variant?product_id=' . $model->product->product_id ],
  30 + ];
  31 + $this->params[ 'breadcrumbs' ][] = $this->title;
  32 + $properties_string = '';
  33 + foreach($properties as $property) {
  34 + $options_string = '';
  35 + foreach($property->options as $option) {
  36 + $options_string .= Html::tag('li', $option->lang->value);
  37 + }
  38 + $properties_string .= Html::tag('p', $property->lang->name).Html::tag('ul', $options_string);
  39 + }
14 ?> 40 ?>
15 <div class="product-view"> 41 <div class="product-view">
16 - 42 +
17 <h1><?= Html::encode($this->title) ?></h1> 43 <h1><?= Html::encode($this->title) ?></h1>
18 - 44 +
19 <p> 45 <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], [ 46 + <?= Html::a(Yii::t('product', 'Update'), [
  47 + 'update',
  48 + 'id' => $model->product_variant_id,
  49 + ], [ 'class' => 'btn btn-primary' ]) ?>
  50 + <?= Html::a(Yii::t('product', 'Delete'), [
  51 + 'delete',
  52 + 'id' => $model->product_variant_id,
  53 + ], [
22 'class' => 'btn btn-danger', 54 'class' => 'btn btn-danger',
23 - 'data' => [ 55 + 'data' => [
24 'confirm' => Yii::t('product', 'Are you sure you want to delete this item?'), 56 'confirm' => Yii::t('product', 'Are you sure you want to delete this item?'),
25 - 'method' => 'post', 57 + 'method' => 'post',
26 ], 58 ],
27 ]) ?> 59 ]) ?>
28 </p> 60 </p>
29 - 61 +
30 <?= DetailView::widget([ 62 <?= DetailView::widget([
31 - 'model' => $model, 63 + 'model' => $model,
32 'attributes' => [ 64 'attributes' => [
33 - 'product_id',  
34 - 'fullname',  
35 - 'image.imageUrl:image' 65 + 'product_variant_id',
  66 + 'lang.name',
  67 + 'sku',
  68 + 'price',
  69 + 'price_old',
  70 + 'stock',
  71 + 'productUnit.lang.name',
  72 + [
  73 + 'attribute' => 'product_id',
  74 + 'value' => Html::a($model->product->fullName, [
  75 + '/product/manage/view',
  76 + 'id' => $model->product_id,
  77 + ]),
  78 + 'format' => 'html',
  79 + ],
  80 + 'image.imageUrl:image',
  81 + [
  82 + 'label' => \Yii::t('app', 'Properties'),
  83 + 'value' => $properties_string,
  84 + 'format' => 'html',
  85 + ]
36 ], 86 ],
37 ]) ?> 87 ]) ?>
38 88