Commit a0da38ca8f71a10592d7b4624367d8127d869369
Merge branch 'master' of gitlab.artweb.com.ua:yarik.nechyporuk/artbox-ecommerce
Showing
17 changed files
with
1757 additions
and
582 deletions
Show diff stats
controllers/OrderController.php
... | ... | @@ -3,19 +3,21 @@ |
3 | 3 | namespace artweb\artbox\ecommerce\controllers; |
4 | 4 | |
5 | 5 | use artweb\artbox\components\SmsSender; |
6 | + use artweb\artbox\ecommerce\models\OrderLabelHistory; | |
7 | + use artweb\artbox\ecommerce\models\OrderLog; | |
6 | 8 | use artweb\artbox\ecommerce\models\OrderSearch; |
9 | + use common\components\CreditHelper; | |
7 | 10 | use common\models\User; |
8 | - use phpDocumentor\Reflection\Types\Null_; | |
9 | 11 | use Yii; |
10 | 12 | use yii\data\ArrayDataProvider; |
11 | - use yii\helpers\ArrayHelper; | |
13 | + use yii\db\ActiveQuery; | |
12 | 14 | use yii\helpers\Json; |
13 | 15 | use yii\helpers\VarDumper; |
16 | + use yii\validators\NumberValidator; | |
14 | 17 | use yii\web\Controller; |
15 | 18 | use yii\filters\VerbFilter; |
16 | 19 | use yii\data\ActiveDataProvider; |
17 | 20 | use yii\web\ForbiddenHttpException; |
18 | - use yii\web\HttpException; | |
19 | 21 | use artweb\artbox\ecommerce\models\Order; |
20 | 22 | use artweb\artbox\ecommerce\models\OrderProduct; |
21 | 23 | use artweb\artbox\ecommerce\models\ProductVariant; |
... | ... | @@ -107,6 +109,14 @@ |
107 | 109 | public function actionView($id) |
108 | 110 | { |
109 | 111 | $model = $this->findModel($id); |
112 | + | |
113 | + $historyData = new ActiveDataProvider( | |
114 | + [ | |
115 | + 'query' => $model->getLabelsHistory() | |
116 | + ->with('order', 'label', 'user'), | |
117 | + ] | |
118 | + ); | |
119 | + | |
110 | 120 | $dataProvider = new ActiveDataProvider( |
111 | 121 | [ |
112 | 122 | 'query' => $model->getProducts(), |
... | ... | @@ -115,8 +125,9 @@ |
115 | 125 | return $this->render( |
116 | 126 | 'view', |
117 | 127 | [ |
118 | - 'model' => $model, | |
119 | - 'products' => $dataProvider, | |
128 | + 'model' => $model, | |
129 | + 'products' => $dataProvider, | |
130 | + 'historyData' => $historyData, | |
120 | 131 | ] |
121 | 132 | ); |
122 | 133 | } |
... | ... | @@ -128,6 +139,25 @@ |
128 | 139 | $model->save(); |
129 | 140 | } |
130 | 141 | |
142 | + public function actionLog($id) | |
143 | + { | |
144 | + $model = Order::findOne($id); | |
145 | + | |
146 | + $logData = new ActiveDataProvider( | |
147 | + [ | |
148 | + 'query' => $model->getLogs(), | |
149 | + ] | |
150 | + ); | |
151 | + | |
152 | + return $this->render( | |
153 | + 'log', | |
154 | + [ | |
155 | + 'model' => $model, | |
156 | + 'logData' => $logData, | |
157 | + ] | |
158 | + ); | |
159 | + } | |
160 | + | |
131 | 161 | public function actionDelete($id) |
132 | 162 | { |
133 | 163 | if (\Yii::$app->user->identity->isAdmin()) { |
... | ... | @@ -151,10 +181,10 @@ |
151 | 181 | |
152 | 182 | public function actionAdd() |
153 | 183 | { |
154 | - if (!empty( \Yii::$app->request->post() )) { | |
184 | + if (!empty(\Yii::$app->request->post())) { | |
155 | 185 | $id = \Yii::$app->request->post('OrderProduct')[ 'id' ]; |
156 | 186 | $order_id = \Yii::$app->request->post('OrderProduct')[ 'order_id' ]; |
157 | - if (!empty( \Yii::$app->request->post('OrderProduct')[ 'count' ] )) { | |
187 | + if (!empty(\Yii::$app->request->post('OrderProduct')[ 'count' ])) { | |
158 | 188 | $count = \Yii::$app->request->post('OrderProduct')[ 'count' ]; |
159 | 189 | } else { |
160 | 190 | $count = 1; |
... | ... | @@ -174,7 +204,7 @@ |
174 | 204 | ) |
175 | 205 | ->one(); |
176 | 206 | |
177 | - if (!empty( $model )) { | |
207 | + if (!empty($model)) { | |
178 | 208 | $model->count += $count; |
179 | 209 | $model->removed = false; |
180 | 210 | } else { |
... | ... | @@ -221,7 +251,7 @@ |
221 | 251 | if ($orderProduct->load($post)) { |
222 | 252 | $orderProduct->save(); |
223 | 253 | $output = ''; |
224 | - if (isset( $posted[ 'count' ] )) { | |
254 | + if (isset($posted[ 'count' ])) { | |
225 | 255 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); |
226 | 256 | } |
227 | 257 | $out = Json::encode( |
... | ... | @@ -283,7 +313,7 @@ |
283 | 313 | return $this->renderPartial( |
284 | 314 | 'print', |
285 | 315 | [ |
286 | - 'order' => $order, | |
316 | + 'order' => $order, | |
287 | 317 | 'dataProvider' => $dataProvider, |
288 | 318 | ] |
289 | 319 | ); |
... | ... | @@ -309,7 +339,7 @@ |
309 | 339 | $orderProduct->save(); |
310 | 340 | $orderProduct->order->totalRecount(); |
311 | 341 | $output = ''; |
312 | - if (isset( $posted[ 'count' ] )) { | |
342 | + if (isset($posted[ 'count' ])) { | |
313 | 343 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); |
314 | 344 | } |
315 | 345 | $out = Json::encode( |
... | ... | @@ -322,9 +352,21 @@ |
322 | 352 | |
323 | 353 | return $out; |
324 | 354 | } |
325 | - | |
355 | + | |
326 | 356 | $model = $this->findModel($id); |
327 | 357 | |
358 | + if ($model->payment == 10) { | |
359 | + $model->validators->append( | |
360 | + new NumberValidator( | |
361 | + [ | |
362 | + 'attributes' => 'credit_sum', | |
363 | + 'max' => $model->total - CreditHelper::MIN_CREDIT_SUM, | |
364 | + 'min' => $model->total - CreditHelper::MAX_CREDIT_SUM, | |
365 | + ] | |
366 | + ) | |
367 | + ); | |
368 | + } | |
369 | + | |
328 | 370 | /** |
329 | 371 | * @var User $user |
330 | 372 | */ |
... | ... | @@ -334,7 +376,7 @@ |
334 | 376 | throw new ForbiddenHttpException(); |
335 | 377 | } |
336 | 378 | } |
337 | - | |
379 | + | |
338 | 380 | $dataProvider = new ActiveDataProvider( |
339 | 381 | [ |
340 | 382 | 'query' => $model->getProducts() |
... | ... | @@ -344,10 +386,10 @@ |
344 | 386 | ] |
345 | 387 | ); |
346 | 388 | |
347 | - if (empty( $model->manager_id )) { | |
389 | + if (empty($model->manager_id)) { | |
348 | 390 | $model->manager_id = \Yii::$app->user->id; |
349 | 391 | } |
350 | - | |
392 | + | |
351 | 393 | $headers = \Yii::$app->response->headers; |
352 | 394 | $headers->set('Access-Control-Allow-Origin', '*'); |
353 | 395 | |
... | ... | @@ -392,7 +434,7 @@ |
392 | 434 | } |
393 | 435 | } |
394 | 436 | |
395 | - public function actionFindProduct($q = null, $id = null) | |
437 | + public function actionFindProduct($q = NULL, $id = NULL) | |
396 | 438 | { |
397 | 439 | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; |
398 | 440 | $out = [ |
... | ... | @@ -452,7 +494,7 @@ |
452 | 494 | |
453 | 495 | protected function findModel($id) |
454 | 496 | { |
455 | - if (( $model = Order::findOne($id) ) !== null) { | |
497 | + if (( $model = Order::findOne($id) ) !== NULL) { | |
456 | 498 | return $model; |
457 | 499 | } else { |
458 | 500 | throw new NotFoundHttpException('The requested page does not exist.'); |
... | ... | @@ -469,7 +511,7 @@ |
469 | 511 | if ($model->edit_id == \Yii::$app->user->id) { |
470 | 512 | $this->unblockOrder(\Yii::$app->request->post('id')); |
471 | 513 | } |
472 | - | |
514 | + | |
473 | 515 | if (!$model->published) { |
474 | 516 | $model->deleteUnpublished(); |
475 | 517 | } |
... | ... | @@ -495,7 +537,7 @@ |
495 | 537 | |
496 | 538 | public function actionBlockOrder() |
497 | 539 | { |
498 | - if (!empty( \Yii::$app->request->post() )) { | |
540 | + if (!empty(\Yii::$app->request->post())) { | |
499 | 541 | \Yii::$app->response->format = Response::FORMAT_JSON; |
500 | 542 | |
501 | 543 | $model = $this->findModel(\Yii::$app->request->post('id')); |
... | ... | @@ -512,7 +554,7 @@ |
512 | 554 | if ($model->save()) { |
513 | 555 | return [ |
514 | 556 | 'time' => $date, |
515 | - 'user' => !empty( $user ) ? $user->username : '', | |
557 | + 'user' => !empty($user) ? $user->username : '', | |
516 | 558 | ]; |
517 | 559 | } else { |
518 | 560 | return [ |
... | ... | @@ -540,6 +582,18 @@ |
540 | 582 | } |
541 | 583 | $model->published = true; |
542 | 584 | $model->save(); |
585 | + | |
586 | + /** | |
587 | + * Add order to history | |
588 | + */ | |
589 | + $history = new OrderLabelHistory(); | |
590 | + | |
591 | + $history->label_id = (integer) $model->label; | |
592 | + $history->order_id = (integer) $model->id; | |
593 | + $history->user_id = (integer) \Yii::$app->user->identity->id; | |
594 | + | |
595 | + $history->save(); | |
596 | + | |
543 | 597 | /** |
544 | 598 | * @var SmsSender $sender |
545 | 599 | */ | ... | ... |
controllers/StatisticsController.php
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | |
5 | 5 | use artweb\artbox\ecommerce\models\Label; |
6 | 6 | use artweb\artbox\ecommerce\models\Order; |
7 | + use common\models\User; | |
7 | 8 | use yii\data\ActiveDataProvider; |
8 | 9 | use yii\helpers\ArrayHelper; |
9 | 10 | use yii\helpers\VarDumper; |
... | ... | @@ -11,7 +12,7 @@ |
11 | 12 | |
12 | 13 | class StatisticsController extends Controller |
13 | 14 | { |
14 | - public function actionIndex($date_range = NULL, $label = NULL) | |
15 | + public function actionIndex($date_range = NULL, $label = NULL, $manager = NULL) | |
15 | 16 | { |
16 | 17 | /** |
17 | 18 | * Get a dates range |
... | ... | @@ -34,6 +35,12 @@ |
34 | 35 | } else { |
35 | 36 | $labelFilter = []; |
36 | 37 | } |
38 | + | |
39 | + if (!empty($manager)) { | |
40 | + $managerFilter = [ 'manager_id' => $manager ]; | |
41 | + } else { | |
42 | + $managerFilter = []; | |
43 | + } | |
37 | 44 | |
38 | 45 | /** |
39 | 46 | * Get labels |
... | ... | @@ -41,61 +48,137 @@ |
41 | 48 | $labels = Label::find() |
42 | 49 | ->with('lang') |
43 | 50 | ->all(); |
51 | + | |
52 | + /** | |
53 | + * Get user | |
54 | + */ | |
55 | + $managers = User::find() | |
56 | + ->all(); | |
44 | 57 | |
45 | 58 | /** |
46 | 59 | * Generate statistics |
47 | 60 | */ |
48 | 61 | $labelStatistics = ArrayHelper::map( |
49 | 62 | $labels, |
50 | - function($model) { | |
51 | - /** | |
52 | - * @var Label $model | |
53 | - */ | |
63 | + function(Label $model) { | |
54 | 64 | return $model->lang->title; |
55 | 65 | }, |
56 | - function($model) use ($dateFilter) { | |
57 | - /** | |
58 | - * @var Label $model | |
59 | - */ | |
60 | - return $model->getStatistics($dateFilter); | |
66 | + function(Label $model) use ($dateFilter, $managerFilter) { | |
67 | + return $model->getStatistics($dateFilter, $managerFilter); | |
61 | 68 | } |
62 | 69 | ); |
63 | - | |
70 | + | |
71 | + /** | |
72 | + * Data provider for table | |
73 | + */ | |
64 | 74 | $dataProvider = new ActiveDataProvider( |
65 | 75 | [ |
66 | 76 | 'query' => Order::find() |
67 | 77 | ->filterWhere($dateFilter) |
78 | + ->andFilterWhere($managerFilter) | |
68 | 79 | ->andFilterWhere($labelFilter), |
69 | 80 | ] |
70 | 81 | ); |
82 | + | |
83 | + /** | |
84 | + * Creating charts data | |
85 | + */ | |
86 | + $labelChartData1 = [ | |
87 | + 'labels' => array_keys($labelStatistics), | |
88 | + 'datasets' => [ | |
89 | + [ | |
90 | + 'label' => 'Заказов, шт.', | |
91 | + 'data' => ArrayHelper::getColumn($labelStatistics, 'count', false), | |
92 | + 'backgroundColor' => 'rgba(54, 162, 235, 0.2)', | |
93 | + 'borderColor' => 'rgba(54, 162, 235, 1)', | |
94 | + 'borderWidth' => 1, | |
95 | + ], | |
96 | + ], | |
97 | + ]; | |
71 | 98 | |
72 | - $chartData = []; | |
73 | - foreach ($labelStatistics as $statistic) { | |
74 | - $chartData[] = $statistic[ 'sum' ]; | |
75 | - } | |
76 | - $chartLabels = []; | |
77 | - foreach ($labelStatistics as $name => $statistic) { | |
78 | - $chartLabels[] = $name; | |
79 | - } | |
80 | - $labelChartData = [ | |
81 | - 'labels' => $chartLabels, | |
99 | + $labelChartData2 = [ | |
100 | + 'labels' => array_keys($labelStatistics), | |
101 | + 'datasets' => [ | |
102 | + [ | |
103 | + 'label' => 'На сумму, грн.', | |
104 | + 'data' => ArrayHelper::getColumn($labelStatistics, 'sum', false), | |
105 | + 'backgroundColor' => 'rgba(255, 99, 132, 0.2)', | |
106 | + 'borderColor' => 'rgba(255,99,132,1)', | |
107 | + 'borderWidth' => 1, | |
108 | + ], | |
109 | + ], | |
110 | + ]; | |
111 | + | |
112 | + $labelChartData3 = [ | |
113 | + 'labels' => array_keys($labelStatistics), | |
82 | 114 | 'datasets' => [ |
83 | 115 | [ |
84 | - 'label' => 'На сумму, грн.', | |
85 | - 'data' => $chartData, | |
116 | + 'label' => 'Заказано товаров, шт.', | |
117 | + 'data' => ArrayHelper::getColumn($labelStatistics, 'products', false), | |
118 | + 'backgroundColor' => 'rgba(255, 206, 86, 0.2)', | |
119 | + 'borderColor' => 'rgba(255, 206, 86, 1)', | |
120 | + 'borderWidth' => 1, | |
121 | + ], | |
122 | + [ | |
123 | + 'label' => 'Уникальных товаров, шт.', | |
124 | + 'data' => ArrayHelper::getColumn($labelStatistics, 'unique', false), | |
125 | + 'backgroundColor' => 'rgba(75, 192, 192, 0.2)', | |
126 | + 'borderColor' => 'rgba(75, 192, 192, 1)', | |
127 | + 'borderWidth' => 1, | |
86 | 128 | ], |
87 | 129 | ], |
88 | 130 | ]; |
131 | + | |
132 | + /** | |
133 | + * Getting rejection statistics | |
134 | + */ | |
135 | + $rejectStatistics = Order::getRejectionStatistics($dateFilter, $managerFilter); | |
136 | + | |
137 | + /** | |
138 | + * Charts data for rejects | |
139 | + */ | |
140 | + $rejectChartData1 = [ | |
141 | + 'labels' => array_keys($rejectStatistics), | |
142 | + 'datasets' => [ | |
143 | + [ | |
144 | + 'label' => 'Заказов, шт.', | |
145 | + 'data' => ArrayHelper::getColumn($rejectStatistics, 'count', false), | |
146 | + 'backgroundColor' => 'rgba(153, 102, 255, 0.2)', | |
147 | + 'borderColor' => 'rgba(153, 102, 255, 1)', | |
148 | + 'borderWidth' => 1, | |
149 | + ], | |
150 | + ], | |
151 | + ]; | |
152 | + | |
153 | + $rejectChartData2 = [ | |
154 | + 'labels' => array_keys($rejectStatistics), | |
155 | + 'datasets' => [ | |
156 | + [ | |
157 | + 'label' => 'На сумму, грн.', | |
158 | + 'data' => ArrayHelper::getColumn($rejectStatistics, 'sum', false), | |
159 | + 'backgroundColor' => 'rgba(255, 159, 64, 0.2)', | |
160 | + 'borderColor' => 'rgba(255, 159, 64, 1)', | |
161 | + 'borderWidth' => 1, | |
162 | + ], | |
163 | + ], | |
164 | + ]; | |
165 | + | |
89 | 166 | return $this->render( |
90 | 167 | 'index', |
91 | 168 | [ |
92 | 169 | 'labels' => $labels, |
170 | + 'managers' => $managers, | |
93 | 171 | 'labelStatistics' => $labelStatistics, |
94 | - 'rejectionStatistics' => Order::getRejectionStatistics($dateFilter), | |
172 | + 'rejectionStatistics' => $rejectStatistics, | |
95 | 173 | 'dataProvider' => $dataProvider, |
96 | - 'labelChartData' => $labelChartData, | |
174 | + 'labelChartData1' => $labelChartData1, | |
175 | + 'labelChartData2' => $labelChartData2, | |
176 | + 'labelChartData3' => $labelChartData3, | |
177 | + 'rejectChartData1' => $rejectChartData1, | |
178 | + 'rejectChartData2' => $rejectChartData2, | |
97 | 179 | 'dateValue' => empty($date_range) ? '' : $date_range, |
98 | 180 | 'dataLabel' => empty($label) ? false : $label, |
181 | + 'dataManager' => empty($manager) ? false : $manager, | |
99 | 182 | ] |
100 | 183 | ); |
101 | 184 | } | ... | ... |
models/Basket.php
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | /** |
11 | 11 | * Class Basket to work with basket |
12 | 12 | * |
13 | + * @property bool isCredit | |
13 | 14 | * @package artweb\artbox\ecommerce\models |
14 | 15 | */ |
15 | 16 | class Basket extends Component |
... | ... | @@ -32,7 +33,7 @@ |
32 | 33 | $this->session = \Yii::$app->session; |
33 | 34 | if (!$this->session->has('basket')) { |
34 | 35 | $this->session->set('basket', []); |
35 | - } elseif(!empty($this->session->get('basket'))) { | |
36 | + } elseif (!empty( $this->session->get('basket') )) { | |
36 | 37 | $cookies = \Yii::$app->response->cookies; |
37 | 38 | $cookies->add( |
38 | 39 | new Cookie( |
... | ... | @@ -144,8 +145,9 @@ |
144 | 145 | { |
145 | 146 | $this->session->set('basket', $data); |
146 | 147 | $cookies = \Yii::$app->response->cookies; |
147 | - if(empty($data)) { | |
148 | + if (empty( $data )) { | |
148 | 149 | $cookies->remove('basket'); |
150 | + $cookies->remove('isCredit'); | |
149 | 151 | } else { |
150 | 152 | $cookies->add( |
151 | 153 | new Cookie( |
... | ... | @@ -247,6 +249,23 @@ |
247 | 249 | public function clear() |
248 | 250 | { |
249 | 251 | $this->setData([]); |
252 | + \Yii::$app->response->cookies->remove('isCredit'); | |
253 | + } | |
254 | + | |
255 | + /** | |
256 | + * Check if is credit cookie flag set | |
257 | + * | |
258 | + * @return bool | |
259 | + */ | |
260 | + public static function getIsCredit(): bool | |
261 | + { | |
262 | + // Get cookies from global in order to skip yii2 cookie validation | |
263 | + $cookies = $_COOKIE; | |
264 | + if (isset( $cookies[ 'isCredit' ] )) { | |
265 | + return true; | |
266 | + } else { | |
267 | + return false; | |
268 | + } | |
250 | 269 | } |
251 | 270 | |
252 | 271 | } | ... | ... |
models/Label.php
... | ... | @@ -65,40 +65,43 @@ |
65 | 65 | ]; |
66 | 66 | } |
67 | 67 | |
68 | - public function getStatistics(array $where = []) | |
68 | + public function getStatistics(array $date = [], array $manager = []) | |
69 | 69 | { |
70 | - $query = ( new Query() )->select( | |
71 | - [ | |
72 | - 'sum' => 'SUM(total)', | |
73 | - 'count' => 'COUNT(*)', | |
74 | - 'unique' => ( new Query() )->select('COUNT(*)') | |
75 | - ->from('order') | |
76 | - ->leftJoin( | |
77 | - 'order_product', | |
78 | - '"order"."id"="order_product"."order_id"' | |
79 | - ) | |
80 | - ->where([ 'order.label' => $this->id ]) | |
81 | - ->andFilterWhere( | |
82 | - $where | |
83 | - ), | |
84 | - 'products' => ( new Query() )->select('SUM(count)') | |
85 | - ->from('order') | |
86 | - ->leftJoin( | |
87 | - 'order_product', | |
88 | - '"order"."id"="order_product"."order_id"' | |
89 | - ) | |
90 | - ->where([ 'order.label' => $this->id ]) | |
91 | - ->andFilterWhere( | |
92 | - $where | |
93 | - ), | |
94 | - ] | |
95 | - ) | |
96 | - ->from('order') | |
97 | - ->where([ 'label' => $this->id ]) | |
98 | - ->andFilterWhere( | |
99 | - $where | |
100 | - ); | |
101 | - | |
70 | + $query = ( new Query() )->select( | |
71 | + [ | |
72 | + 'sum' => 'SUM(total)', | |
73 | + 'count' => 'COUNT(*)', | |
74 | + 'unique' => ( new Query() )->select('COUNT(*)') | |
75 | + ->from('order') | |
76 | + ->leftJoin( | |
77 | + 'order_product', | |
78 | + '"order"."id"="order_product"."order_id"' | |
79 | + ) | |
80 | + ->where([ 'order.label' => $this->id ]) | |
81 | + ->andFilterWhere( | |
82 | + $date | |
83 | + ) | |
84 | + ->andFilterWhere($manager), | |
85 | + 'products' => ( new Query() )->select('SUM(count)') | |
86 | + ->from('order') | |
87 | + ->leftJoin( | |
88 | + 'order_product', | |
89 | + '"order"."id"="order_product"."order_id"' | |
90 | + ) | |
91 | + ->where([ 'order.label' => $this->id ]) | |
92 | + ->andFilterWhere( | |
93 | + $date | |
94 | + ) | |
95 | + ->andFilterWhere($manager), | |
96 | + ] | |
97 | + ) | |
98 | + ->from('order') | |
99 | + ->where([ 'label' => $this->id ]) | |
100 | + ->andFilterWhere( | |
101 | + $date | |
102 | + ) | |
103 | + ->andFilterWhere($manager); | |
104 | + | |
102 | 105 | return $query->one(); |
103 | 106 | } |
104 | 107 | } | ... | ... |
models/Order.php
... | ... | @@ -8,6 +8,8 @@ |
8 | 8 | use yii\behaviors\TimestampBehavior; |
9 | 9 | use yii\db\ActiveRecord; |
10 | 10 | use yii\db\Query; |
11 | + use yii\helpers\Json; | |
12 | + use yii\helpers\VarDumper; | |
11 | 13 | |
12 | 14 | /** |
13 | 15 | * Class Order |
... | ... | @@ -55,6 +57,12 @@ |
55 | 57 | * @property string $city |
56 | 58 | * @property string $deliveryString |
57 | 59 | * @property boolean $published |
60 | + * @property Label $orderLabel | |
61 | + * @property Delivery $orderDelivery | |
62 | + * @property OrderPayment $orderPayment | |
63 | + * @property OrderLog[] $logs | |
64 | + * @property float $credit_sum | |
65 | + * @property int $credit_month | |
58 | 66 | */ |
59 | 67 | class Order extends ActiveRecord |
60 | 68 | { |
... | ... | @@ -92,13 +100,14 @@ |
92 | 100 | { |
93 | 101 | return 'order'; |
94 | 102 | } |
95 | - | |
103 | + | |
96 | 104 | /** |
97 | - * @param array $where | |
105 | + * @param array $date | |
106 | + * @param array $manager | |
98 | 107 | * |
99 | 108 | * @return array |
100 | 109 | */ |
101 | - public static function getRejectionStatistics(array $where = []) | |
110 | + public static function getRejectionStatistics(array $date = [], array $manager = []) | |
102 | 111 | { |
103 | 112 | $result = []; |
104 | 113 | foreach (self::REASONS as $id => $reason) { |
... | ... | @@ -113,12 +122,87 @@ |
113 | 122 | [ |
114 | 123 | 'reason' => $id, |
115 | 124 | ] |
116 | - )->andFilterWhere($where)->one(); | |
125 | + ) | |
126 | + ->andFilterWhere($date) | |
127 | + ->andFilterWhere($manager) | |
128 | + ->one(); | |
117 | 129 | } |
118 | 130 | |
119 | 131 | return $result; |
120 | 132 | } |
121 | 133 | |
134 | + /** | |
135 | + * @param string $attr | |
136 | + * @param array $values | |
137 | + * | |
138 | + * @return array | |
139 | + * Return array in form ['old'=>'old value ...', 'new' => 'new value ...'] | |
140 | + */ | |
141 | + public function getLogAttributes(string $attr, array $values) | |
142 | + { | |
143 | + if ($attr == 'deadline') { | |
144 | + return [ | |
145 | + 'old' => empty($values[ 'old' ]) ? '' : date('d.m.Y', $values[ 'old' ]), | |
146 | + 'new' => empty($values[ 'new' ]) ? '' : date('d.m.Y', $values[ 'new' ]), | |
147 | + ]; | |
148 | + } elseif ($attr == 'reason') { | |
149 | + return [ | |
150 | + 'old' => empty($values[ 'old' ]) ? '' : self::REASONS[ $values[ 'old' ] ], | |
151 | + 'new' => empty($values[ 'new' ]) ? '' : self::REASONS[ $values[ 'new' ] ], | |
152 | + ]; | |
153 | + } elseif ($attr == 'label') { | |
154 | + $labels = Label::find() | |
155 | + ->with('lang') | |
156 | + ->indexBy('id') | |
157 | + ->all(); | |
158 | + return [ | |
159 | + 'old' => empty($values[ 'old' ]) ? '' : $labels[ $values[ 'old' ] ]->lang->title, | |
160 | + 'new' => empty($values[ 'new' ]) ? '' : $labels[ $values[ 'new' ] ]->lang->title, | |
161 | + ]; | |
162 | + } elseif ($attr == 'delivery') { | |
163 | + $deliveries = Delivery::find() | |
164 | + ->with('lang') | |
165 | + ->indexBy('id') | |
166 | + ->all(); | |
167 | + return [ | |
168 | + 'old' => empty($values[ 'old' ]) ? '' : $deliveries[ $values[ 'old' ] ]->lang->title, | |
169 | + 'new' => empty($values[ 'new' ]) ? '' : $deliveries[ $values[ 'new' ] ]->lang->title, | |
170 | + ]; | |
171 | + } elseif ($attr == 'manager_id') { | |
172 | + $users = User::find() | |
173 | + ->indexBy('id') | |
174 | + ->all(); | |
175 | + return [ | |
176 | + 'old' => empty($values[ 'old' ]) ? '' : $users[ $values[ 'old' ] ]->username, | |
177 | + 'new' => empty($values[ 'new' ]) ? '' : $users[ $values[ 'new' ] ]->username, | |
178 | + ]; | |
179 | + } elseif ($attr == 'payment') { | |
180 | + $payment = OrderPayment::find() | |
181 | + ->with('lang') | |
182 | + ->indexBy('id') | |
183 | + ->all(); | |
184 | + return [ | |
185 | + 'old' => empty($values[ 'old' ]) ? '' : $payment[ $values[ 'old' ] ]->lang->title, | |
186 | + 'new' => empty($values[ 'new' ]) ? '' : $payment[ $values[ 'new' ] ]->lang->title, | |
187 | + ]; | |
188 | + } elseif ($attr == 'shipping_by') { | |
189 | + return [ | |
190 | + 'old' => empty($values[ 'old' ]) ? '' : self::SHIPPING_BY[ $values[ 'old' ] ][ 'label' ], | |
191 | + 'new' => empty($values[ 'new' ]) ? '' : self::SHIPPING_BY[ $values[ 'new' ] ][ 'label' ], | |
192 | + ]; | |
193 | + } elseif ($attr == 'pay') { | |
194 | + return [ | |
195 | + 'old' => ( $values[ 'old' ] == true ) ? 'Оплачен' : 'Не оплачен', | |
196 | + 'new' => ( $values[ 'new' ] == true ) ? 'Оплачен' : 'Не оплачен', | |
197 | + ]; | |
198 | + } else { | |
199 | + return $values; | |
200 | + } | |
201 | + } | |
202 | + | |
203 | + /** | |
204 | + * @inheritdoc | |
205 | + */ | |
122 | 206 | public function behaviors() |
123 | 207 | { |
124 | 208 | return [ |
... | ... | @@ -131,6 +215,9 @@ |
131 | 215 | ]; |
132 | 216 | } |
133 | 217 | |
218 | + /** | |
219 | + * @inheritdoc | |
220 | + */ | |
134 | 221 | public function rules() |
135 | 222 | { |
136 | 223 | return [ |
... | ... | @@ -188,6 +275,21 @@ |
188 | 275 | ], |
189 | 276 | [ |
190 | 277 | [ |
278 | + 'credit_month', | |
279 | + ], | |
280 | + 'integer', | |
281 | + 'min' => 3, | |
282 | + 'max' => 36, | |
283 | + ], | |
284 | + [ | |
285 | + [ | |
286 | + 'credit_sum', | |
287 | + ], | |
288 | + 'number', | |
289 | + 'min' => 0, | |
290 | + ], | |
291 | + [ | |
292 | + [ | |
191 | 293 | 'deadline', |
192 | 294 | 'name', |
193 | 295 | 'numbercard', |
... | ... | @@ -209,6 +311,49 @@ |
209 | 311 | ]; |
210 | 312 | } |
211 | 313 | |
314 | + public function afterSave($insert, $changedAttributes) | |
315 | + { | |
316 | + $data = []; | |
317 | + foreach ($changedAttributes as $key => $attribute) { | |
318 | + if ($this->oldAttributes[ $key ] != $attribute && $key != 'updated_at') { | |
319 | + $data[ $key ] = $this->getLogAttributes( | |
320 | + $key, | |
321 | + [ | |
322 | + 'old' => $attribute, | |
323 | + 'new' => $this->oldAttributes[ $key ], | |
324 | + ] | |
325 | + ); | |
326 | + } | |
327 | + } | |
328 | + | |
329 | + if (!empty($data) && empty($data[ 'edit_time' ])) { | |
330 | + $log = new OrderLog(); | |
331 | + $log->order_id = (integer) $this->id; | |
332 | + $log->user_id = (integer) \Yii::$app->user->identity->id; | |
333 | + $log->data = Json::encode($data); | |
334 | + | |
335 | + $log->save(); | |
336 | + } | |
337 | + | |
338 | + if (!empty($changedAttributes[ 'label' ])) { | |
339 | + if ($this->label != (string) $changedAttributes[ 'label' ]) { | |
340 | + $history = new OrderLabelHistory(); | |
341 | + | |
342 | + $history->label_id = (integer) $this->label; | |
343 | + $history->order_id = (integer) $this->id; | |
344 | + $history->user_id = (integer) \Yii::$app->user->identity->id; | |
345 | + | |
346 | + if ($history->save()) { | |
347 | + \Yii::$app->session->setFlash('label_update', 'Статус заказа обновлен'); | |
348 | + } | |
349 | + } | |
350 | + } | |
351 | + parent::afterSave($insert, $changedAttributes); | |
352 | + } | |
353 | + | |
354 | + /** | |
355 | + * @inheritdoc | |
356 | + */ | |
212 | 357 | public function afterFind() |
213 | 358 | { |
214 | 359 | parent::afterFind(); |
... | ... | @@ -216,6 +361,9 @@ |
216 | 361 | |
217 | 362 | } |
218 | 363 | |
364 | + /** | |
365 | + * @inheritdoc | |
366 | + */ | |
219 | 367 | public function beforeSave($insert) |
220 | 368 | { |
221 | 369 | if (parent::beforeSave($insert)) { |
... | ... | @@ -227,6 +375,9 @@ |
227 | 375 | |
228 | 376 | } |
229 | 377 | |
378 | + /** | |
379 | + * Convert some date | |
380 | + */ | |
230 | 381 | protected function convertDate() |
231 | 382 | { |
232 | 383 | if (!empty($this->deadline)) { |
... | ... | @@ -239,6 +390,9 @@ |
239 | 390 | |
240 | 391 | } |
241 | 392 | |
393 | + /** | |
394 | + * @inheritdoc | |
395 | + */ | |
242 | 396 | public function attributeLabels() |
243 | 397 | { |
244 | 398 | return [ |
... | ... | @@ -273,9 +427,14 @@ |
273 | 427 | 'shipping_by' => Yii::t('app', 'Отправка за счет'), |
274 | 428 | 'city' => Yii::t('app', 'Город'), |
275 | 429 | 'numbercard' => Yii::t('app', '№ карточки'), |
430 | + 'credit_month' => Yii::t('app', 'Количество месяцев'), | |
431 | + 'credit_sum' => Yii::t('app', 'Первоначальный взнос'), | |
276 | 432 | ]; |
277 | 433 | } |
278 | 434 | |
435 | + /** | |
436 | + * @return \yii\db\ActiveQuery | |
437 | + */ | |
279 | 438 | public function getUser() |
280 | 439 | { |
281 | 440 | return $this->hasOne(Customer::className(), [ 'id' => 'user_id' ]); |
... | ... | @@ -314,6 +473,14 @@ |
314 | 473 | } |
315 | 474 | |
316 | 475 | /** |
476 | + * @return \yii\db\ActiveQuery | |
477 | + */ | |
478 | + public function getLabelsHistory() | |
479 | + { | |
480 | + return $this->hasMany(OrderLabelHistory::className(), [ 'order_id' => 'id' ]); | |
481 | + } | |
482 | + | |
483 | + /** | |
317 | 484 | * @return string |
318 | 485 | */ |
319 | 486 | public function getDeliveryString() |
... | ... | @@ -330,6 +497,14 @@ |
330 | 497 | } |
331 | 498 | |
332 | 499 | /** |
500 | + * @return \yii\db\ActiveQuery | |
501 | + */ | |
502 | + public function getLogs() | |
503 | + { | |
504 | + return $this->hasMany(OrderLog::className(), [ 'order_id' => 'id' ]); | |
505 | + } | |
506 | + | |
507 | + /** | |
333 | 508 | * If deadline is fucked up returns true, |
334 | 509 | * if deadline is not setted return false, like everything is ok |
335 | 510 | * |
... | ... | @@ -345,13 +520,18 @@ |
345 | 520 | } |
346 | 521 | |
347 | 522 | /** |
348 | - * | |
523 | + * @return \yii\db\ActiveQuery | |
349 | 524 | */ |
350 | 525 | public function getManager() |
351 | 526 | { |
352 | 527 | return $this->hasOne(User::className(), [ 'id' => 'manager_id' ]); |
353 | 528 | } |
354 | 529 | |
530 | + /** | |
531 | + * Check if order is blocked for updating | |
532 | + * | |
533 | + * @return bool | |
534 | + */ | |
355 | 535 | public function isBlocked() |
356 | 536 | { |
357 | 537 | if ($this->edit_id === 0) { |
... | ... | @@ -365,6 +545,9 @@ |
365 | 545 | } |
366 | 546 | } |
367 | 547 | |
548 | + /** | |
549 | + * If order products changed recount te total value | |
550 | + */ | |
368 | 551 | public function totalRecount() |
369 | 552 | { |
370 | 553 | $products = $this->products; |
... | ... | @@ -379,6 +562,9 @@ |
379 | 562 | $this->save(); |
380 | 563 | } |
381 | 564 | |
565 | + /** | |
566 | + * If exit unpublished order - delete it | |
567 | + */ | |
382 | 568 | public function deleteUnpublished() |
383 | 569 | { |
384 | 570 | /** | ... | ... |
1 | +<?php | |
2 | + | |
3 | + namespace artweb\artbox\ecommerce\models; | |
4 | + | |
5 | + use yii\behaviors\TimestampBehavior; | |
6 | + use yii\db\ActiveRecord; | |
7 | + use common\models\User; | |
8 | + use Yii; | |
9 | + | |
10 | + /** | |
11 | + * This is the model class for table "order_label_history". | |
12 | + * | |
13 | + * @property integer $id | |
14 | + * @property integer $label_id | |
15 | + * @property integer $order_id | |
16 | + * @property integer $user_id | |
17 | + * @property integer $created_at | |
18 | + * @property Order $order | |
19 | + * @property Label $label | |
20 | + * @property User $user | |
21 | + */ | |
22 | + class OrderLabelHistory extends ActiveRecord | |
23 | + { | |
24 | + /** | |
25 | + * @inheritdoc | |
26 | + */ | |
27 | + public static function tableName() | |
28 | + { | |
29 | + return 'order_label_history'; | |
30 | + } | |
31 | + | |
32 | + /** | |
33 | + * @inheritdoc | |
34 | + */ | |
35 | + public function behaviors() | |
36 | + { | |
37 | + return [ | |
38 | + [ | |
39 | + 'class' => TimestampBehavior::className(), | |
40 | + 'updatedAtAttribute' => false, | |
41 | + ], | |
42 | + ]; | |
43 | + } | |
44 | + | |
45 | + /** | |
46 | + * @inheritdoc | |
47 | + */ | |
48 | + public function rules() | |
49 | + { | |
50 | + return [ | |
51 | + [ | |
52 | + [ | |
53 | + 'label_id', | |
54 | + 'order_id', | |
55 | + 'user_id', | |
56 | + 'created_at', | |
57 | + ], | |
58 | + 'integer', | |
59 | + ], | |
60 | + [ | |
61 | + [ 'order_id' ], | |
62 | + 'exist', | |
63 | + 'skipOnError' => true, | |
64 | + 'targetClass' => Order::className(), | |
65 | + 'targetAttribute' => [ 'order_id' => 'id' ], | |
66 | + ], | |
67 | + [ | |
68 | + [ 'label_id' ], | |
69 | + 'exist', | |
70 | + 'skipOnError' => true, | |
71 | + 'targetClass' => Label::className(), | |
72 | + 'targetAttribute' => [ 'label_id' => 'id' ], | |
73 | + ], | |
74 | +// [ | |
75 | +// [ 'user_id' ], | |
76 | +// 'exist', | |
77 | +// 'skipOnError' => true, | |
78 | +// 'targetClass' => User::className(), | |
79 | +// 'targetAttribute' => [ 'user_id' => 'id' ], | |
80 | +// ], | |
81 | + ]; | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * @inheritdoc | |
86 | + */ | |
87 | + public function attributeLabels() | |
88 | + { | |
89 | + return [ | |
90 | + 'id' => Yii::t('app', 'ID'), | |
91 | + 'label_id' => Yii::t('app', 'Label ID'), | |
92 | + 'order_id' => Yii::t('app', 'Order ID'), | |
93 | + 'user_id' => Yii::t('app', 'User ID'), | |
94 | + 'created_at' => Yii::t('app', 'Created At'), | |
95 | + ]; | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * @return \yii\db\ActiveQuery | |
100 | + */ | |
101 | + public function getOrder() | |
102 | + { | |
103 | + return $this->hasOne(Order::className(), [ 'id' => 'order_id' ]); | |
104 | + } | |
105 | + | |
106 | + /** | |
107 | + * @return \yii\db\ActiveQuery | |
108 | + */ | |
109 | + public function getLabel() | |
110 | + { | |
111 | + return $this->hasOne(Label::className(), [ 'id' => 'label_id' ]); | |
112 | + } | |
113 | + | |
114 | + /** | |
115 | + * @return \yii\db\ActiveQuery | |
116 | + */ | |
117 | + public function getUser() | |
118 | + { | |
119 | + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); | |
120 | + } | |
121 | + } | ... | ... |
1 | +<?php | |
2 | + | |
3 | + namespace artweb\artbox\ecommerce\models; | |
4 | + | |
5 | + use common\models\User; | |
6 | + use Yii; | |
7 | + use yii\behaviors\TimestampBehavior; | |
8 | + use yii\db\ActiveRecord; | |
9 | + | |
10 | + /** | |
11 | + * This is the model class for table "order_log". | |
12 | + * | |
13 | + * @property integer $id | |
14 | + * @property integer $order_id | |
15 | + * @property integer $created_at | |
16 | + * @property integer $user_id | |
17 | + * @property string $data | |
18 | + * @property Order $order | |
19 | + * @property User $user | |
20 | + */ | |
21 | + class OrderLog extends ActiveRecord | |
22 | + { | |
23 | + /** | |
24 | + * @inheritdoc | |
25 | + */ | |
26 | + public static function tableName() | |
27 | + { | |
28 | + return 'order_log'; | |
29 | + } | |
30 | + | |
31 | + /** | |
32 | + * @inheritdoc | |
33 | + */ | |
34 | + public function behaviors() | |
35 | + { | |
36 | + return [ | |
37 | + [ | |
38 | + 'class' => TimestampBehavior::className(), | |
39 | + 'updatedAtAttribute' => false, | |
40 | + ], | |
41 | + ]; | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * @inheritdoc | |
46 | + */ | |
47 | + public function rules() | |
48 | + { | |
49 | + return [ | |
50 | + [ | |
51 | + [ | |
52 | + 'order_id', | |
53 | + 'created_at', | |
54 | + 'user_id', | |
55 | + ], | |
56 | + 'integer', | |
57 | + ], | |
58 | + [ | |
59 | + [ 'data' ], | |
60 | + 'string', | |
61 | + ], | |
62 | + [ | |
63 | + [ 'order_id' ], | |
64 | + 'exist', | |
65 | + 'skipOnError' => true, | |
66 | + 'targetClass' => Order::className(), | |
67 | + 'targetAttribute' => [ 'order_id' => 'id' ], | |
68 | + ], | |
69 | + // [ | |
70 | + // [ 'user_id' ], | |
71 | + // 'exist', | |
72 | + // 'skipOnError' => true, | |
73 | + // 'targetClass' => User::className(), | |
74 | + // 'targetAttribute' => [ 'user_id' => 'id' ], | |
75 | + // ], | |
76 | + ]; | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * @inheritdoc | |
81 | + */ | |
82 | + public function attributeLabels() | |
83 | + { | |
84 | + return [ | |
85 | + 'id' => Yii::t('app', 'ID'), | |
86 | + 'order_id' => Yii::t('app', 'Order ID'), | |
87 | + 'created_at' => Yii::t('app', 'Created At'), | |
88 | + 'user_id' => Yii::t('app', 'User ID'), | |
89 | + 'data' => Yii::t('app', 'Data'), | |
90 | + ]; | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * @return \yii\db\ActiveQuery | |
95 | + */ | |
96 | + public function getOrder() | |
97 | + { | |
98 | + return $this->hasOne(Order::className(), [ 'id' => 'order_id' ]); | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * @return \yii\db\ActiveQuery | |
103 | + */ | |
104 | + public function getUser() | |
105 | + { | |
106 | + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); | |
107 | + } | |
108 | + } | ... | ... |
models/Product.php
... | ... | @@ -571,7 +571,40 @@ |
571 | 571 | } |
572 | 572 | return $groups; |
573 | 573 | } |
574 | - | |
574 | + | |
575 | + | |
576 | + /** | |
577 | + * Get characteristic from TaxGroups for current Product filled with $customOptions that satisfy current Product | |
578 | + * | |
579 | + * @return TaxGroup[] | |
580 | + */ | |
581 | + public function getCharacteristic(): array | |
582 | + { | |
583 | + $groups = $options = []; | |
584 | + foreach ($this->getOptions() | |
585 | + ->with('lang') | |
586 | + ->all() as $option) { | |
587 | + /** | |
588 | + * @var TaxOption $option | |
589 | + */ | |
590 | + $options[ $option[ 'tax_group_id' ] ][] = $option; | |
591 | + } | |
592 | + foreach (TaxGroup::find() | |
593 | + ->where(['is_menu'=>true]) | |
594 | + ->andWhere([ 'id' => array_keys($options) ]) | |
595 | + ->with('lang') | |
596 | + ->all() as $group) { | |
597 | + /** | |
598 | + * @var TaxGroup $group | |
599 | + */ | |
600 | + if (!empty($options[ $group->id ])) { | |
601 | + $group->customOptions = $options[ $group->id ]; | |
602 | + $groups[] = $group; | |
603 | + } | |
604 | + } | |
605 | + return $groups; | |
606 | + } | |
607 | + | |
575 | 608 | public function getVideos() |
576 | 609 | { |
577 | 610 | return $this->hasMany(ProductVideo::className(), [ 'product_id' => 'id' ]); | ... | ... |
models/ProductVariant.php
... | ... | @@ -398,6 +398,38 @@ |
398 | 398 | } |
399 | 399 | return $groups; |
400 | 400 | } |
401 | + | |
402 | + /** | |
403 | + * Get characteristic from TaxGroups for current ProductVariant filled with $customOptions that satisfy current Product | |
404 | + * | |
405 | + * @return TaxGroup[] | |
406 | + */ | |
407 | + public function getCharacteristic(): array | |
408 | + { | |
409 | + $groups = $options = []; | |
410 | + foreach ($this->getOptions() | |
411 | + ->with('lang') | |
412 | + ->all() as $option) { | |
413 | + /** | |
414 | + * @var TaxOption $option | |
415 | + */ | |
416 | + $options[ $option[ 'tax_group_id' ] ][] = $option; | |
417 | + } | |
418 | + foreach (TaxGroup::find() | |
419 | + ->where(['is_menu'=>true]) | |
420 | + ->andWhere([ 'id' => array_keys($options) ]) | |
421 | + ->with('lang') | |
422 | + ->all() as $group) { | |
423 | + /** | |
424 | + * @var TaxGroup $group | |
425 | + */ | |
426 | + if (!empty($options[ $group->id ])) { | |
427 | + $group->customOptions = $options[ $group->id ]; | |
428 | + $groups[] = $group; | |
429 | + } | |
430 | + } | |
431 | + return $groups; | |
432 | + } | |
401 | 433 | |
402 | 434 | /** |
403 | 435 | * Set stocks to override existing in product_stock table | ... | ... |
views/order/_form.php
... | ... | @@ -146,8 +146,7 @@ JS; |
146 | 146 | |
147 | 147 | <?php $form = ActiveForm::begin( |
148 | 148 | [ |
149 | - 'id' => 'main-form', | |
150 | -// 'options' => [ 'class' => 'form-inline' ], | |
149 | + 'id' => 'main-form', | |
151 | 150 | ] |
152 | 151 | ); ?> |
153 | 152 | <div class="container"> |
... | ... | @@ -333,7 +332,10 @@ JS; |
333 | 332 | 'id', |
334 | 333 | 'short' |
335 | 334 | ), |
336 | - [ 'prompt' => 'Способ оплаты ...' ] | |
335 | + [ | |
336 | + 'prompt' => 'Способ оплаты ...', | |
337 | + 'disabled' => $model->payment == 10 ? 'disabled' : false, | |
338 | + ] | |
337 | 339 | ); ?> |
338 | 340 | |
339 | 341 | <?= $form->field($model, 'insurance') ?> |
... | ... | @@ -368,348 +370,348 @@ JS; |
368 | 370 | <br> |
369 | 371 | <br> |
370 | 372 | <div class="container"> |
371 | - <div class="row"> | |
372 | - <?php | |
373 | - echo GridView::widget( | |
374 | - [ | |
375 | - 'dataProvider' => $dataProvider, | |
376 | - 'rowOptions' => function($model) { | |
377 | - if ($model->removed) { | |
378 | - return [ 'class' => 'danger' ]; | |
379 | - } else { | |
380 | - return []; | |
381 | - } | |
382 | - }, | |
383 | - 'layout' => '{items}{pager}', | |
384 | - 'columns' => [ | |
385 | - [ | |
386 | - 'class' => SerialColumn::className(), | |
387 | - ], | |
388 | - 'sku', | |
389 | - [ | |
390 | - 'attribute' => 'product_name', | |
391 | - 'content' => function($model) { | |
392 | - if (!empty($model->product_name)) { | |
373 | + <div class="row"> | |
374 | + <?php | |
375 | + echo GridView::widget( | |
376 | + [ | |
377 | + 'dataProvider' => $dataProvider, | |
378 | + 'rowOptions' => function ($model) { | |
379 | + if ($model->removed) { | |
380 | + return [ 'class' => 'danger' ]; | |
381 | + } else { | |
382 | + return []; | |
383 | + } | |
384 | + }, | |
385 | + 'layout' => '{items}{pager}', | |
386 | + 'columns' => [ | |
387 | + [ | |
388 | + 'class' => SerialColumn::className(), | |
389 | + ], | |
390 | + 'sku', | |
391 | + [ | |
392 | + 'attribute' => 'product_name', | |
393 | + 'content' => function ($model) { | |
394 | + if (!empty( $model->product_name )) { | |
395 | + | |
396 | + if (empty( $model->productVariant )) { | |
397 | + return ''; | |
398 | + } | |
399 | + | |
400 | + return Html::a( | |
401 | + StringHelper::truncate($model->product_name, 10, '...'), | |
402 | + '#', | |
403 | + [ | |
404 | + 'onclick' => 'event.preventDefault();', | |
405 | + 'data-toggle' => 'popover', | |
406 | + 'data-placement' => 'right', | |
407 | + 'data-html' => 'true', | |
408 | + 'data-content' => Html::img( | |
409 | + $model->productVariant->imageUrl, | |
410 | + [ | |
411 | + 'class' => 'img-rounded', | |
412 | + ] | |
413 | + ) . Html::tag('p', $model->product_name), | |
414 | + ] | |
415 | + ); | |
416 | + } else { | |
417 | + return ''; | |
418 | + } | |
419 | + }, | |
420 | + ], | |
421 | + [ | |
422 | + 'attribute' => 'productVariant.product.brand.lang.title', | |
423 | + 'label' => 'Брэнд', | |
424 | + ], | |
425 | + [ | |
426 | + 'attribute' => 'productVariant.lang.title', | |
427 | + 'label' => \Yii::t('app', 'Цвет'), | |
428 | + 'content' => function ($model) { | |
393 | 429 | |
394 | - if (empty($model->productVariant)) { | |
430 | + if (empty( $model->productVariant )) { | |
395 | 431 | return ''; |
396 | - } | |
397 | - | |
398 | - return Html::a( | |
399 | - StringHelper::truncate($model->product_name, 10, '...'), | |
400 | - '#', | |
401 | - [ | |
402 | - 'onclick' => 'event.preventDefault();', | |
403 | - 'data-toggle' => 'popover', | |
404 | - 'data-placement' => 'right', | |
405 | - 'data-html' => 'true', | |
406 | - 'data-content' => Html::img( | |
407 | - $model->productVariant->imageUrl, | |
408 | - [ | |
409 | - 'class' => 'img-rounded', | |
410 | - ] | |
411 | - ) . Html::tag('p', $model->product_name), | |
412 | - ] | |
413 | - ); | |
414 | - } else { | |
415 | - return ''; | |
416 | - } | |
417 | - }, | |
418 | - ], | |
419 | - [ | |
420 | - 'attribute' => 'productVariant.product.brand.lang.title', | |
421 | - 'label' => 'Брэнд', | |
422 | - ], | |
423 | - [ | |
424 | - 'attribute' => 'productVariant.lang.title', | |
425 | - 'label' => \Yii::t('app', 'Цвет'), | |
426 | - 'content' => function($model) { | |
427 | - | |
428 | - if (empty($model->productVariant)) { | |
429 | - return ''; | |
430 | - } | |
431 | - | |
432 | - if (preg_match('@.*\.(png|jpg|gif)@i', $model->productVariant->lang->title)) { | |
433 | - return ''; | |
434 | - } else { | |
435 | - return $model->productVariant->lang->title; | |
436 | - } | |
437 | - }, | |
438 | - ], | |
439 | - [ | |
440 | - 'attribute' => 'productVariant.size', | |
441 | - 'label' => 'Размер', | |
442 | - ], | |
443 | - 'price', | |
444 | - [ | |
445 | - 'class' => 'kartik\grid\EditableColumn', | |
446 | - 'attribute' => 'count', | |
447 | - 'editableOptions' => [ | |
448 | - 'header' => \Yii::t('app', 'Количество'), | |
449 | - 'inputType' => kartik\editable\Editable::INPUT_SPIN, | |
450 | - 'options' => [ | |
451 | - 'pluginOptions' => [ | |
452 | - 'min' => 0, | |
453 | - 'max' => 5000, | |
454 | - ], | |
455 | - ], | |
456 | - 'pluginEvents' => [ | |
457 | - 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
458 | - ], | |
459 | - ], | |
460 | - 'format' => [ | |
461 | - 'decimal', | |
462 | - 0, | |
463 | - ], | |
464 | - 'pageSummary' => false, | |
465 | - ], | |
466 | - 'sum_cost', | |
467 | - [ | |
468 | - 'class' => 'kartik\grid\EditableColumn', | |
469 | - 'attribute' => 'booking', | |
470 | - 'editableOptions' => [ | |
471 | - 'header' => \Yii::t('app', 'Бронь'), | |
472 | - 'inputType' => kartik\editable\Editable::INPUT_TEXT, | |
473 | - 'options' => [ | |
474 | - 'class' => 'booking-typeahead', | |
475 | - 'pluginOptions' => [ | |
476 | - 'min' => 0, | |
477 | - 'max' => 20, | |
478 | - ], | |
479 | - ], | |
480 | - 'pluginEvents' => [ | |
481 | - 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
482 | - ], | |
483 | - ], | |
484 | - 'format' => [ | |
485 | - 'text', | |
486 | - ], | |
487 | - 'pageSummary' => false, | |
488 | - ], | |
489 | - [ | |
490 | - 'class' => 'kartik\grid\EditableColumn', | |
491 | - 'attribute' => 'status', | |
492 | - 'editableOptions' => [ | |
493 | - 'header' => \Yii::t('app', 'Статус'), | |
494 | - 'inputType' => kartik\editable\Editable::INPUT_TEXT, | |
495 | - 'options' => [ | |
496 | - 'class' => 'status-typeahead', | |
497 | - 'pluginOptions' => [ | |
498 | - 'min' => 0, | |
499 | - 'max' => 20, | |
500 | - ], | |
501 | - ], | |
502 | - 'pluginEvents' => [ | |
503 | - 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
504 | - ], | |
505 | - ], | |
506 | - 'format' => [ | |
507 | - 'text', | |
508 | - ], | |
509 | - 'pageSummary' => false, | |
510 | - ], | |
511 | - [ | |
512 | - 'class' => 'kartik\grid\EditableColumn', | |
513 | - 'attribute' => 'return', | |
514 | - 'editableOptions' => [ | |
515 | - 'header' => \Yii::t('app', 'Возврат'), | |
516 | - 'inputType' => kartik\editable\Editable::INPUT_CHECKBOX, | |
517 | - 'options' => [], | |
518 | - 'pluginEvents' => [ | |
519 | - 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
520 | - ], | |
521 | - ], | |
522 | - 'format' => [ | |
523 | - 'boolean', | |
524 | - ], | |
525 | - 'pageSummary' => false, | |
526 | - ], | |
527 | - [ | |
528 | - 'content' => function($model) { | |
529 | - | |
530 | - if (empty($model->productVariant)) { | |
531 | - return '<i class="glyphicon glyphicon-remove"></i>'; | |
532 | - } | |
533 | - | |
534 | - $content = '<table class="table"><tbody><tr><th>Склад</th><th>кол.</th></tr>'; | |
535 | - foreach ($model->productVariant->variantStocks as $stock) { | |
536 | - $content .= '<tr><td>' . $stock->stock->title . '</td><td>' . $stock->quantity . '</td></tr>'; | |
537 | - } | |
538 | - return Html::a( | |
539 | - '<i class="glyphicon glyphicon-home"></i>', | |
540 | - '#', | |
541 | - [ | |
542 | - 'onclick' => 'event.preventDefault();', | |
543 | - 'data-toggle' => 'popover', | |
544 | - 'data-placement' => 'left', | |
545 | - 'data-html' => 'true', | |
546 | - 'data-content' => $content . '</tbody></table>', | |
547 | - ] | |
548 | - ); | |
549 | - }, | |
550 | - ], | |
551 | - [ | |
552 | - 'class' => 'yii\grid\ActionColumn', | |
553 | - 'template' => '{delete}', | |
554 | - 'buttons' => [ | |
555 | - 'delete' => function($url, $product) { | |
556 | - if ($product->removed) { | |
557 | - return ''; | |
558 | - } else { | |
559 | - return Html::a( | |
560 | - Html::tag('span', '', [ 'class' => 'glyphicon glyphicon-trash' ]), | |
561 | - [ | |
562 | - 'delete-product', | |
563 | - 'id' => $product->id, | |
564 | - ], | |
565 | - [ | |
566 | - 'class' => 'delete-button', | |
567 | - // 'data' => [ | |
568 | - // 'confirm' => 'Вы уверены, что хотите удалить этот элемент?', | |
569 | - // 'method' => 'GET', | |
570 | - // ], | |
571 | - ] | |
572 | - ); | |
573 | - } | |
574 | - }, | |
575 | - ], | |
576 | - ], | |
577 | - ], | |
578 | - 'responsive' => true, | |
579 | - 'hover' => true, | |
580 | - 'pjax' => true, | |
581 | - 'pjaxSettings' => [ | |
582 | - 'options' => [ | |
583 | - 'scrollTo' => 'false', | |
584 | - 'id' => 'order-products-grid', | |
585 | - ], | |
586 | - ], | |
587 | - ] | |
588 | - ); | |
589 | - ?> | |
590 | - </div> | |
432 | + } | |
433 | + | |
434 | + if (preg_match('@.*\.(png|jpg|gif)@i', $model->productVariant->lang->title)) { | |
435 | + return ''; | |
436 | + } else { | |
437 | + return $model->productVariant->lang->title; | |
438 | + } | |
439 | + }, | |
440 | + ], | |
441 | + [ | |
442 | + 'attribute' => 'productVariant.size', | |
443 | + 'label' => 'Размер', | |
444 | + ], | |
445 | + 'price', | |
446 | + [ | |
447 | + 'class' => 'kartik\grid\EditableColumn', | |
448 | + 'attribute' => 'count', | |
449 | + 'editableOptions' => [ | |
450 | + 'header' => \Yii::t('app', 'Количество'), | |
451 | + 'inputType' => kartik\editable\Editable::INPUT_SPIN, | |
452 | + 'options' => [ | |
453 | + 'pluginOptions' => [ | |
454 | + 'min' => 0, | |
455 | + 'max' => 5000, | |
456 | + ], | |
457 | + ], | |
458 | + 'pluginEvents' => [ | |
459 | + 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
460 | + ], | |
461 | + ], | |
462 | + 'format' => [ | |
463 | + 'decimal', | |
464 | + 0, | |
465 | + ], | |
466 | + 'pageSummary' => false, | |
467 | + ], | |
468 | + 'sum_cost', | |
469 | + [ | |
470 | + 'class' => 'kartik\grid\EditableColumn', | |
471 | + 'attribute' => 'booking', | |
472 | + 'editableOptions' => [ | |
473 | + 'header' => \Yii::t('app', 'Бронь'), | |
474 | + 'inputType' => kartik\editable\Editable::INPUT_TEXT, | |
475 | + 'options' => [ | |
476 | + 'class' => 'booking-typeahead', | |
477 | + 'pluginOptions' => [ | |
478 | + 'min' => 0, | |
479 | + 'max' => 20, | |
480 | + ], | |
481 | + ], | |
482 | + 'pluginEvents' => [ | |
483 | + 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
484 | + ], | |
485 | + ], | |
486 | + 'format' => [ | |
487 | + 'text', | |
488 | + ], | |
489 | + 'pageSummary' => false, | |
490 | + ], | |
491 | + [ | |
492 | + 'class' => 'kartik\grid\EditableColumn', | |
493 | + 'attribute' => 'status', | |
494 | + 'editableOptions' => [ | |
495 | + 'header' => \Yii::t('app', 'Статус'), | |
496 | + 'inputType' => kartik\editable\Editable::INPUT_TEXT, | |
497 | + 'options' => [ | |
498 | + 'class' => 'status-typeahead', | |
499 | + 'pluginOptions' => [ | |
500 | + 'min' => 0, | |
501 | + 'max' => 20, | |
502 | + ], | |
503 | + ], | |
504 | + 'pluginEvents' => [ | |
505 | + 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
506 | + ], | |
507 | + ], | |
508 | + 'format' => [ | |
509 | + 'text', | |
510 | + ], | |
511 | + 'pageSummary' => false, | |
512 | + ], | |
513 | + [ | |
514 | + 'class' => 'kartik\grid\EditableColumn', | |
515 | + 'attribute' => 'return', | |
516 | + 'editableOptions' => [ | |
517 | + 'header' => \Yii::t('app', 'Возврат'), | |
518 | + 'inputType' => kartik\editable\Editable::INPUT_CHECKBOX, | |
519 | + 'options' => [], | |
520 | + 'pluginEvents' => [ | |
521 | + 'editableSuccess' => 'function(event) { $.pjax.reload({container:"#order-products-grid"}); }', | |
522 | + ], | |
523 | + ], | |
524 | + 'format' => [ | |
525 | + 'boolean', | |
526 | + ], | |
527 | + 'pageSummary' => false, | |
528 | + ], | |
529 | + [ | |
530 | + 'content' => function ($model) { | |
531 | + | |
532 | + if (empty( $model->productVariant )) { | |
533 | + return '<i class="glyphicon glyphicon-remove"></i>'; | |
534 | + } | |
535 | + | |
536 | + $content = '<table class="table"><tbody><tr><th>Склад</th><th>кол.</th></tr>'; | |
537 | + foreach ($model->productVariant->variantStocks as $stock) { | |
538 | + $content .= '<tr><td>' . $stock->stock->title . '</td><td>' . $stock->quantity . '</td></tr>'; | |
539 | + } | |
540 | + return Html::a( | |
541 | + '<i class="glyphicon glyphicon-home"></i>', | |
542 | + '#', | |
543 | + [ | |
544 | + 'onclick' => 'event.preventDefault();', | |
545 | + 'data-toggle' => 'popover', | |
546 | + 'data-placement' => 'left', | |
547 | + 'data-html' => 'true', | |
548 | + 'data-content' => $content . '</tbody></table>', | |
549 | + ] | |
550 | + ); | |
551 | + }, | |
552 | + ], | |
553 | + [ | |
554 | + 'class' => 'yii\grid\ActionColumn', | |
555 | + 'template' => '{delete}', | |
556 | + 'buttons' => [ | |
557 | + 'delete' => function ($url, $product) { | |
558 | + if ($product->removed) { | |
559 | + return ''; | |
560 | + } else { | |
561 | + return Html::a( | |
562 | + Html::tag('span', '', [ 'class' => 'glyphicon glyphicon-trash' ]), | |
563 | + [ | |
564 | + 'delete-product', | |
565 | + 'id' => $product->id, | |
566 | + ], | |
567 | + [ | |
568 | + 'class' => 'delete-button', | |
569 | + // 'data' => [ | |
570 | + // 'confirm' => 'Вы уверены, что хотите удалить этот элемент?', | |
571 | + // 'method' => 'GET', | |
572 | + // ], | |
573 | + ] | |
574 | + ); | |
575 | + } | |
576 | + }, | |
577 | + ], | |
578 | + ], | |
579 | + ], | |
580 | + 'responsive' => true, | |
581 | + 'hover' => true, | |
582 | + 'pjax' => true, | |
583 | + 'pjaxSettings' => [ | |
584 | + 'options' => [ | |
585 | + 'scrollTo' => 'false', | |
586 | + 'id' => 'order-products-grid', | |
587 | + ], | |
588 | + ], | |
589 | + ] | |
590 | + ); | |
591 | + ?> | |
592 | + </div> | |
591 | 593 | </div> |
592 | 594 | <div class="container"> |
593 | 595 | <?php Pjax::begin([ 'id' => 'total-cost' ]); ?> |
594 | - <h2>Сумма заказа : <span class="label label-success"><?php echo $model->total; ?><?php echo \Yii::t( | |
595 | - 'app', | |
596 | - 'грн' | |
597 | - ) ?></span></h2> | |
596 | + <h2>Сумма заказа : <span class="label label-success"><?php echo $model->total; ?><?php echo \Yii::t( | |
597 | + 'app', | |
598 | + 'грн' | |
599 | + ) ?></span></h2> | |
598 | 600 | <?php Pjax::end(); ?> |
599 | 601 | </div> |
600 | 602 | <div class="container"> |
601 | - <div class="row"> | |
602 | - <?php $newProductForm = ActiveForm::begin( | |
603 | - [ | |
604 | - 'action' => yii\helpers\Url::to([ 'add' ]), | |
605 | - 'id' => 'add-product-form', | |
606 | - ] | |
607 | - ); | |
608 | - $newOrderProduct = new OrderProduct(); | |
609 | - ?> | |
610 | - <div class="col-md-8"> | |
611 | - <?php echo $newProductForm->field($newOrderProduct, 'id') | |
612 | - ->widget( | |
613 | - Select2::className(), | |
614 | - [ | |
615 | - 'options' => [ 'placeholder' => 'Search for a product ...' ], | |
616 | - 'pluginOptions' => [ | |
617 | - 'allowClear' => true, | |
618 | - 'disabled' => $model->isNewRecord ? true : false, | |
619 | - 'minimumInputLength' => 3, | |
620 | - 'language' => [ | |
621 | - 'errorLoading' => new JsExpression( | |
622 | - "function () { return 'Waiting for results...'; }" | |
603 | + <div class="row"> | |
604 | + <?php $newProductForm = ActiveForm::begin( | |
605 | + [ | |
606 | + 'action' => yii\helpers\Url::to([ 'add' ]), | |
607 | + 'id' => 'add-product-form', | |
608 | + ] | |
609 | + ); | |
610 | + $newOrderProduct = new OrderProduct(); | |
611 | + ?> | |
612 | + <div class="col-md-8"> | |
613 | + <?php echo $newProductForm->field($newOrderProduct, 'id') | |
614 | + ->widget( | |
615 | + Select2::className(), | |
616 | + [ | |
617 | + 'options' => [ 'placeholder' => 'Search for a product ...' ], | |
618 | + 'pluginOptions' => [ | |
619 | + 'allowClear' => true, | |
620 | + 'disabled' => $model->isNewRecord ? true : false, | |
621 | + 'minimumInputLength' => 3, | |
622 | + 'language' => [ | |
623 | + 'errorLoading' => new JsExpression( | |
624 | + "function () { return 'Waiting for results...'; }" | |
625 | + ), | |
626 | + ], | |
627 | + 'ajax' => [ | |
628 | + 'url' => \yii\helpers\Url::to([ 'find-product' ]), | |
629 | + 'dataType' => 'json', | |
630 | + 'data' => new JsExpression( | |
631 | + 'function(params) { return {q:params.term}; }' | |
632 | + ), | |
633 | + ], | |
634 | + 'escapeMarkup' => new JsExpression( | |
635 | + 'function (markup) { return markup; }' | |
623 | 636 | ), |
624 | - ], | |
625 | - 'ajax' => [ | |
626 | - 'url' => \yii\helpers\Url::to([ 'find-product' ]), | |
627 | - 'dataType' => 'json', | |
628 | - 'data' => new JsExpression( | |
629 | - 'function(params) { return {q:params.term}; }' | |
637 | + 'templateResult' => new JsExpression( | |
638 | + 'function(data) { return data.sku; }' | |
639 | + ), | |
640 | + 'templateSelection' => new JsExpression( | |
641 | + 'function (data) { return data.sku; }' | |
630 | 642 | ), |
631 | 643 | ], |
632 | - 'escapeMarkup' => new JsExpression( | |
633 | - 'function (markup) { return markup; }' | |
634 | - ), | |
635 | - 'templateResult' => new JsExpression( | |
636 | - 'function(data) { return data.sku; }' | |
637 | - ), | |
638 | - 'templateSelection' => new JsExpression( | |
639 | - 'function (data) { return data.sku; }' | |
640 | - ), | |
641 | - ], | |
642 | - ] | |
643 | - ) | |
644 | - ->label('Артикул'); | |
645 | - | |
646 | - ?> | |
647 | - </div> | |
648 | - <div class="col-md-2"> | |
649 | - <?php echo $newProductForm->field( | |
650 | - $newOrderProduct, | |
651 | - 'count' | |
652 | - ) | |
653 | - ->input( | |
654 | - 'number', | |
644 | + ] | |
645 | + ) | |
646 | + ->label('Артикул'); | |
647 | + | |
648 | + ?> | |
649 | + </div> | |
650 | + <div class="col-md-2"> | |
651 | + <?php echo $newProductForm->field( | |
652 | + $newOrderProduct, | |
653 | + 'count' | |
654 | + ) | |
655 | + ->input( | |
656 | + 'number', | |
657 | + [ | |
658 | + 'disabled' => $model->isNewRecord ? true : false, | |
659 | + ] | |
660 | + ); ?> | |
661 | + </div> | |
662 | + <div class="col-md-2" style="margin-top: 23px"> | |
663 | + <?php echo Html::submitButton( | |
664 | + \Yii::t('app', 'Добавить'), | |
665 | + [ | |
666 | + 'class' => $model->isNewRecord ? 'btn btn-primary disabled' : 'btn btn-primary', | |
667 | + ] | |
668 | + ) ?> | |
669 | + </div> | |
670 | + <?php echo $newProductForm->field($newOrderProduct, 'order_id') | |
671 | + ->hiddenInput( | |
655 | 672 | [ |
656 | - 'disabled' => $model->isNewRecord ? true : false, | |
673 | + 'value' => $model->id, | |
657 | 674 | ] |
658 | - ); ?> | |
675 | + ) | |
676 | + ->label(false) ?> | |
677 | + <?php ActiveForm::end(); ?> | |
659 | 678 | </div> |
660 | - <div class="col-md-2" style="margin-top: 23px"> | |
661 | - <?php echo Html::submitButton( | |
662 | - \Yii::t('app', 'Добавить'), | |
679 | + | |
680 | + <br> | |
681 | + <div class="row"> | |
682 | + <?= Html::button( | |
683 | + $model->isNewRecord ? \Yii::t('app', 'Создать') : \Yii::t('app', 'Сохранить'), | |
684 | + [ | |
685 | + 'class' => $model->isNewRecord ? 'btn btn-success btn-lg' : 'btn btn-primary btn-lg', | |
686 | + 'id' => 'page-submit', | |
687 | + ] | |
688 | + ) ?> | |
689 | + <?= Html::a( | |
690 | + \Yii::t('app', 'Печать'), | |
691 | + yii\helpers\Url::to( | |
692 | + [ | |
693 | + 'order/print', | |
694 | + 'order_id' => $model->id, | |
695 | + ] | |
696 | + ), | |
697 | + [ | |
698 | + 'class' => $model->isNewRecord ? 'btn btn-info disabled btn-lg' : 'btn btn-info btn-lg', | |
699 | + 'target' => '_blank', | |
700 | + ] | |
701 | + ) ?> | |
702 | + <?= Html::a( | |
703 | + \Yii::t('app', 'Выйти'), | |
704 | + yii\helpers\Url::to( | |
705 | + [ | |
706 | + 'close-order', | |
707 | + 'id' => $model->id, | |
708 | + ] | |
709 | + ), | |
663 | 710 | [ |
664 | - 'class' => $model->isNewRecord ? 'btn btn-primary disabled' : 'btn btn-primary', | |
711 | + 'class' => $model->isNewRecord ? 'btn btn-info disabled btn-lg' : 'btn btn-info btn-lg', | |
665 | 712 | ] |
666 | 713 | ) ?> |
667 | 714 | </div> |
668 | - <?php echo $newProductForm->field($newOrderProduct, 'order_id') | |
669 | - ->hiddenInput( | |
670 | - [ | |
671 | - 'value' => $model->id, | |
672 | - ] | |
673 | - ) | |
674 | - ->label(false) ?> | |
675 | - <?php ActiveForm::end(); ?> | |
676 | - </div> | |
677 | - | |
678 | - <br> | |
679 | - <div class="row"> | |
680 | - <?= Html::button( | |
681 | - $model->isNewRecord ? \Yii::t('app', 'Создать') : \Yii::t('app', 'Сохранить'), | |
682 | - [ | |
683 | - 'class' => $model->isNewRecord ? 'btn btn-success btn-lg' : 'btn btn-primary btn-lg', | |
684 | - 'id' => 'page-submit', | |
685 | - ] | |
686 | - ) ?> | |
687 | - <?= Html::a( | |
688 | - \Yii::t('app', 'Печать'), | |
689 | - yii\helpers\Url::to( | |
690 | - [ | |
691 | - 'order/print', | |
692 | - 'order_id' => $model->id, | |
693 | - ] | |
694 | - ), | |
695 | - [ | |
696 | - 'class' => $model->isNewRecord ? 'btn btn-info disabled btn-lg' : 'btn btn-info btn-lg', | |
697 | - 'target' => '_blank', | |
698 | - ] | |
699 | - ) ?> | |
700 | - <?= Html::a( | |
701 | - \Yii::t('app', 'Выйти'), | |
702 | - yii\helpers\Url::to( | |
703 | - [ | |
704 | - 'close-order', | |
705 | - 'id' => $model->id, | |
706 | - ] | |
707 | - ), | |
708 | - [ | |
709 | - 'class' => $model->isNewRecord ? 'btn btn-info disabled btn-lg' : 'btn btn-info btn-lg', | |
710 | - ] | |
711 | - ) ?> | |
712 | - </div> | |
713 | 715 | |
714 | 716 | </div> |
715 | 717 | <br> | ... | ... |
1 | +<?php | |
2 | + /** | |
3 | + * @var OrderLog $model | |
4 | + * @var Order $order | |
5 | + */ | |
6 | + use artweb\artbox\ecommerce\models\Order; | |
7 | + use artweb\artbox\ecommerce\models\OrderLog; | |
8 | + use yii\helpers\Html; | |
9 | + use yii\helpers\Json; | |
10 | + | |
11 | +?> | |
12 | + | |
13 | +<!-- timeline item --> | |
14 | +<li> | |
15 | + <!-- timeline icon --> | |
16 | + <i class="fa fa-user bg-orange"></i> | |
17 | + <div class="timeline-item"> | |
18 | + <span class="time"><i class="fa fa-calendar"></i> <?= Yii::$app->formatter->asDatetime($model->created_at) ?></span> | |
19 | + | |
20 | + <h3 class="timeline-header">Пользователь: <span class="text-orange"><?= $model->user->username ?></span></h3> | |
21 | + | |
22 | + <div class="timeline-body"> | |
23 | + <table class="table table-bordered table-striped"> | |
24 | + <tr> | |
25 | + <th>Поле</th> | |
26 | + <th>Старое значение</th> | |
27 | + <th>Новое значение</th> | |
28 | + </tr> | |
29 | + <?php | |
30 | + foreach (Json::decode($model->data) as $key => $item) { | |
31 | + echo Html::tag( | |
32 | + 'tr', | |
33 | + Html::tag('td', $order->attributeLabels()[ $key ]) . Html::tag('td', $item[ 'old' ]) . Html::tag( | |
34 | + 'td', | |
35 | + $item[ 'new' ] | |
36 | + ) | |
37 | + ); | |
38 | + } | |
39 | + ?> | |
40 | + </table> | |
41 | + </div> | |
42 | + | |
43 | + </div> | |
44 | +</li> | ... | ... |
1 | +<?php | |
2 | + /** | |
3 | + * @var OrderLabelHistory $model | |
4 | + */ | |
5 | + use artweb\artbox\ecommerce\models\OrderLabelHistory; | |
6 | + use yii\helpers\Html; | |
7 | + | |
8 | +?> | |
9 | + | |
10 | +<!-- timeline item --> | |
11 | +<li> | |
12 | + <!-- timeline icon --> | |
13 | + <i class="fa fa-tag bg-blue"></i> | |
14 | + <div class="timeline-item"> | |
15 | + <span class="time"><i class="fa fa-calendar"></i> <?=Yii::$app->formatter->asDatetime($model->created_at)?></span> | |
16 | + | |
17 | + <h3 class="timeline-header"><?=$model->label->lang->title?></h3> | |
18 | + | |
19 | + <div class="timeline-body"> | |
20 | + <?php | |
21 | + if (empty($model->user)) { | |
22 | + echo Html::tag('p', 'Поступил с сайта', ['class' => 'text-green']); | |
23 | + } else { | |
24 | + echo 'Статус присвоил: ' . Html::tag('p', $model->user->username, [ | |
25 | + 'class' => 'text-blue' | |
26 | + ]); | |
27 | + } | |
28 | + ?> | |
29 | + </div> | |
30 | + | |
31 | + </div> | |
32 | +</li> | ... | ... |
views/order/index.php
... | ... | @@ -347,7 +347,7 @@ JS; |
347 | 347 | [ |
348 | 348 | 'class' => 'yii\grid\ActionColumn', |
349 | 349 | 'template' => \Yii::$app->user->identity->isAdmin( |
350 | - ) ? '{view} {update} {delete}' : '{view} {update}', | |
350 | + ) ? '{history} {view} {update} {delete}' : '{view} {update}', | |
351 | 351 | 'buttons' => [ |
352 | 352 | 'update' => function($url, $model) { |
353 | 353 | return Html::a( |
... | ... | @@ -359,6 +359,16 @@ JS; |
359 | 359 | ] |
360 | 360 | ); |
361 | 361 | }, |
362 | + 'history' => function($url, $model) { | |
363 | + return Html::a( | |
364 | + Html::tag('span', '', [ 'class' => 'glyphicon glyphicon-time' ]), | |
365 | + ['log', 'id' => $model->id], | |
366 | + [ | |
367 | + 'target' => '_blank', | |
368 | + 'data-pjax' => '0', | |
369 | + ] | |
370 | + ); | |
371 | + }, | |
362 | 372 | ], |
363 | 373 | ], |
364 | 374 | ], | ... | ... |
1 | +<?php | |
2 | + use artweb\artbox\ecommerce\models\Order; | |
3 | + use yii\data\ActiveDataProvider; | |
4 | + use yii\web\View; | |
5 | + use yii\widgets\ListView; | |
6 | + | |
7 | + /** | |
8 | + * @var View $this | |
9 | + * @var ActiveDataProvider $logData | |
10 | + * @var Order $model | |
11 | + */ | |
12 | + | |
13 | + $this->title = 'История заказа #' . $model->id; | |
14 | + | |
15 | + $this->params[ 'breadcrumbs' ][] = [ | |
16 | + 'url' => yii\helpers\Url::to([ '/ecommerce/order/index' ]), | |
17 | + 'label' => \Yii::t('app', 'Заказы'), | |
18 | + ]; | |
19 | + $this->params[ 'breadcrumbs' ][] = [ | |
20 | + 'url' => yii\helpers\Url::to([ '/ecommerce/order/view', 'id' => $model->id ]), | |
21 | + 'label' => \Yii::t('app', 'Заказ #') . $model->id, | |
22 | + ]; | |
23 | + $this->params[ 'breadcrumbs' ][] = $this->title; | |
24 | + | |
25 | +?> | |
26 | + | |
27 | +<div class="order-log"> | |
28 | + <div class="box box-default"> | |
29 | + <div class="box-header with-border"> | |
30 | + <h3 class="box-title">История</h3> | |
31 | + <div class="box-body"> | |
32 | + | |
33 | + <?php | |
34 | + echo ListView::widget( | |
35 | + [ | |
36 | + 'dataProvider' => $logData, | |
37 | + 'layout' => '{items}', | |
38 | + 'itemView' => '_log_item', | |
39 | + 'itemOptions' => [ | |
40 | + 'tag' => false, | |
41 | + ], | |
42 | + 'options' => [ | |
43 | + 'tag' => $logData->totalCount == 0 ? 'div' : 'ul', | |
44 | + 'class' => $logData->totalCount == 0 ? 'list-view' : 'list-view timeline', | |
45 | + ], | |
46 | + 'viewParams' => [ | |
47 | + 'order' => $model, | |
48 | + ], | |
49 | + 'emptyText' => 'У этого заказа пока нет истории', | |
50 | + 'emptyTextOptions' => [ | |
51 | + 'class' => 'callout callout-info' | |
52 | + ], | |
53 | + ] | |
54 | + ); | |
55 | + ?> | |
56 | + | |
57 | + </div><!-- /.box-body --> | |
58 | + </div><!-- /.box --> | |
59 | + </div> | ... | ... |
views/order/update.php
... | ... | @@ -10,11 +10,15 @@ |
10 | 10 | use yii\helpers\Html; |
11 | 11 | use yii\web\View; |
12 | 12 | |
13 | - $this->title = 'Заказ #' . $model->id; | |
13 | + $this->title = 'Обновить заказ #' . $model->id; | |
14 | 14 | $this->params[ 'breadcrumbs' ][] = [ |
15 | 15 | 'url' => yii\helpers\Url::to([ '/ecommerce/order/index' ]), |
16 | 16 | 'label' => \Yii::t('app', 'Заказы'), |
17 | 17 | ]; |
18 | + $this->params[ 'breadcrumbs' ][] = [ | |
19 | + 'url' => yii\helpers\Url::to([ '/ecommerce/order/view', 'id' => $model->id, ]), | |
20 | + 'label' => \Yii::t('app', 'Заказ #') . $model->id, | |
21 | + ]; | |
18 | 22 | $this->params[ 'breadcrumbs' ][] = $this->title; |
19 | 23 | |
20 | 24 | $js = ' |
... | ... | @@ -54,7 +58,18 @@ $.ajax({ |
54 | 58 | '; |
55 | 59 | |
56 | 60 | $this->registerJs($js, View::POS_READY); |
57 | - | |
61 | + | |
62 | + if (!empty(\Yii::$app->session->getFlash('label_update'))) { | |
63 | + $js = ' | |
64 | +$.notify({ | |
65 | + message: "Статус заказа обновлен" | |
66 | +}, { | |
67 | + type : "warning" | |
68 | +}) | |
69 | +'; | |
70 | + $this->registerJs($js, View::POS_READY); | |
71 | + } | |
72 | + | |
58 | 73 | ?> |
59 | 74 | <div class="order-update"> |
60 | 75 | <div class="container"> | ... | ... |
views/order/view.php
1 | 1 | <?php |
2 | 2 | |
3 | 3 | use artweb\artbox\ecommerce\models\Order; |
4 | + use common\components\CreditHelper; | |
4 | 5 | use kartik\grid\GridView; |
6 | + use yii\data\ActiveDataProvider; | |
7 | + use yii\grid\SerialColumn; | |
5 | 8 | use yii\helpers\Html; |
6 | 9 | use yii\web\View; |
7 | 10 | use yii\widgets\DetailView; |
11 | + use yii\widgets\ListView; | |
8 | 12 | |
9 | 13 | /** |
10 | - * @var View $this | |
11 | - * @var Order $model | |
14 | + * @var View $this | |
15 | + * @var Order $model | |
16 | + * @var ActiveDataProvider $products | |
17 | + * @var ActiveDataProvider $historyData | |
12 | 18 | */ |
13 | 19 | |
14 | 20 | $this->title = 'Заказ #' . $model->id; |
... | ... | @@ -17,65 +23,184 @@ |
17 | 23 | 'url' => [ 'index' ], |
18 | 24 | ]; |
19 | 25 | $this->params[ 'breadcrumbs' ][] = $this->title; |
26 | + | |
27 | + if (empty($model->payment)) { | |
28 | + $payment = ''; | |
29 | + } elseif ($model->payment == 10) { | |
30 | + $payment = Html::tag('h4', $model->orderPayment->lang->title, [ 'class' => 'text-navy' ]) . Html::beginTag( | |
31 | + 'table', | |
32 | + [ 'class' => 'table table-bordered' ] | |
33 | + ) . Html::tag( | |
34 | + 'tr', | |
35 | + Html::tag('td', $model->getAttributeLabel('credit_sum')) . Html::tag( | |
36 | + 'td', | |
37 | + CreditHelper::checkSum( | |
38 | + $model->credit_sum | |
39 | + ) | |
40 | + ) | |
41 | + ) . Html::tag( | |
42 | + 'tr', | |
43 | + Html::tag('td', $model->getAttributeLabel('credit_month')) . Html::tag( | |
44 | + 'td', | |
45 | + CreditHelper::checkMonth( | |
46 | + $model->credit_month | |
47 | + ) | |
48 | + ) | |
49 | + ) . Html::tag( | |
50 | + 'tr', | |
51 | + Html::tag('td', 'Кредит') . Html::tag('td', $model->total - $model->credit_sum) | |
52 | + ) . Html::tag( | |
53 | + 'tr', | |
54 | + Html::tag('td', 'Оплата в месяц') . Html::tag( | |
55 | + 'td', | |
56 | + CreditHelper::getCredit( | |
57 | + $model->total - $model->credit_sum, | |
58 | + $model->credit_month | |
59 | + ) . ' грн/мес' | |
60 | + ) | |
61 | + ) . Html::endTag('table'); | |
62 | + } else { | |
63 | + $payment = $model->orderPayment->lang->title; | |
64 | + } | |
65 | + | |
20 | 66 | ?> |
21 | 67 | <div class="order-view"> |
22 | - | |
23 | - <h1><?= Html::encode($this->title) ?></h1> | |
24 | - | |
25 | - <p> | |
26 | - <?= Html::a( | |
27 | - 'Update', | |
28 | - [ | |
29 | - 'update', | |
30 | - 'id' => $model->id, | |
31 | - ], | |
32 | - [ 'class' => 'btn btn-primary' ] | |
33 | - ) ?> | |
34 | - | |
35 | - </p> | |
36 | - | |
37 | - <?= DetailView::widget( | |
38 | - [ | |
39 | - 'model' => $model, | |
40 | - 'attributes' => [ | |
41 | - 'id', | |
42 | - 'deadline', | |
43 | - 'pay', | |
44 | - 'reason', | |
45 | - 'label', | |
46 | - 'name', | |
47 | - 'phone', | |
48 | - 'email', | |
49 | - 'comment', | |
50 | - 'delivery', | |
51 | - 'declaration', | |
52 | - 'stock', | |
53 | - 'payment', | |
54 | - 'insurance', | |
55 | - 'city', | |
56 | - 'adress', | |
57 | - 'body', | |
58 | - 'check', | |
59 | - 'sms', | |
60 | - ], | |
61 | - ] | |
62 | - ) ?> | |
63 | - | |
64 | - <?php | |
65 | - echo GridView::widget( | |
68 | + | |
69 | + <h1><?= Html::encode($this->title) ?></h1> | |
70 | + | |
71 | + <p> | |
72 | + <?= Html::a( | |
73 | + 'Обновить', | |
74 | + [ | |
75 | + 'update', | |
76 | + 'id' => $model->id, | |
77 | + ], | |
78 | + [ 'class' => 'btn btn-primary' ] | |
79 | + ) ?> | |
80 | + | |
81 | + <?= Html::a( | |
82 | + 'История', | |
83 | + [ | |
84 | + 'log', | |
85 | + 'id' => $model->id, | |
86 | + ], | |
87 | + [ 'class' => 'btn bg-orange' ] | |
88 | + ) ?> | |
89 | + </p> | |
90 | + | |
91 | + <div class="box box-default"> | |
92 | + <div class="box-header with-border"> | |
93 | + <h3 class="box-title">Данные заказа</h3> | |
94 | + <div class="box-tools pull-right"> | |
95 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
96 | + </div><!-- /.box-tools --> | |
97 | + </div><!-- /.box-header --> | |
98 | + <div class="box-body"> | |
99 | + <?= DetailView::widget( | |
66 | 100 | [ |
67 | - 'dataProvider' => $products, | |
68 | - 'columns' => [ | |
101 | + 'model' => $model, | |
102 | + 'attributes' => [ | |
69 | 103 | 'id', |
70 | - 'product_name', | |
104 | + 'deadline', | |
105 | + 'pay', | |
106 | + [ | |
107 | + 'label' => 'Причина', | |
108 | + 'value' => empty($model->reason) ? '' : Order::REASONS[ $model->reason ], | |
109 | + ], | |
110 | + [ | |
111 | + 'label' => 'Статус', | |
112 | + 'value' => empty($model->label) ? '' : $model->orderLabel->lang->title, | |
113 | + ], | |
71 | 114 | 'name', |
72 | - 'sku', | |
73 | - 'price', | |
74 | - 'count', | |
75 | - 'sum_cost', | |
115 | + 'phone', | |
116 | + 'email', | |
117 | + 'comment', | |
118 | + [ | |
119 | + 'label' => 'Способ доставки', | |
120 | + 'value' => empty($model->delivery) ? '' : $model->orderDelivery->lang->title, | |
121 | + ], | |
122 | + 'declaration', | |
123 | + 'stock', | |
124 | + [ | |
125 | + 'label' => 'Способ оплаты', | |
126 | + 'value' => $payment, | |
127 | + 'format' => 'html', | |
128 | + ], | |
129 | + 'insurance', | |
130 | + 'city', | |
131 | + 'adress', | |
132 | + 'body', | |
133 | + 'check', | |
134 | + 'sms', | |
76 | 135 | ], |
77 | 136 | ] |
78 | - ); | |
79 | - ?> | |
137 | + ) ?> | |
138 | + </div><!-- /.box-body --> | |
139 | + </div><!-- /.box --> | |
140 | + | |
141 | + | |
142 | + <div class="box box-default"> | |
143 | + <div class="box-header with-border"> | |
144 | + <h3 class="box-title">Товары</h3> | |
145 | + <div class="box-tools pull-right"> | |
146 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
147 | + </div><!-- /.box-tools --> | |
148 | + </div><!-- /.box-header --> | |
149 | + <div class="box-body"> | |
150 | + <?php | |
151 | + echo GridView::widget( | |
152 | + [ | |
153 | + 'dataProvider' => $products, | |
154 | + 'columns' => [ | |
155 | + [ | |
156 | + 'class' => SerialColumn::className(), | |
157 | + ], | |
158 | + 'product_name', | |
159 | + 'name', | |
160 | + 'sku', | |
161 | + 'price', | |
162 | + 'count', | |
163 | + 'sum_cost', | |
164 | + ], | |
165 | + ] | |
166 | + ); | |
167 | + ?> | |
168 | + </div><!-- /.box-body --> | |
169 | + </div><!-- /.box --> | |
170 | + | |
171 | + <div class="box box-default"> | |
172 | + <div class="box-header with-border"> | |
173 | + <h3 class="box-title">История</h3> | |
174 | + <div class="box-tools pull-right"> | |
175 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
176 | + </div><!-- /.box-tools --> | |
177 | + </div><!-- /.box-header --> | |
178 | + <div class="box-body"> | |
179 | + | |
180 | + | |
181 | + <?php | |
182 | + echo ListView::widget( | |
183 | + [ | |
184 | + 'dataProvider' => $historyData, | |
185 | + 'layout' => '{items}', | |
186 | + 'itemView' => '_timeline_item', | |
187 | + 'itemOptions' => [ | |
188 | + 'tag' => false, | |
189 | + ], | |
190 | + 'options' => [ | |
191 | + 'tag' => $historyData->totalCount == 0 ? 'div' : 'ul', | |
192 | + 'class' => $historyData->totalCount == 0 ? 'list-view' : 'list-view timeline', | |
193 | + ], | |
194 | + 'emptyText' => 'У этого заказа пока нет истории', | |
195 | + 'emptyTextOptions' => [ | |
196 | + 'class' => 'callout callout-info', | |
197 | + ], | |
198 | + ] | |
199 | + ); | |
200 | + ?> | |
201 | + | |
202 | + | |
203 | + </div><!-- /.box-body --> | |
204 | + </div><!-- /.box --> | |
80 | 205 | |
81 | 206 | </div> | ... | ... |
views/statistics/index.php
1 | 1 | <?php |
2 | 2 | use artweb\artbox\ecommerce\models\Label; |
3 | 3 | use artweb\artbox\ecommerce\models\Order; |
4 | + use artweb\artbox\ecommerce\models\ProductVariant; | |
5 | + use common\models\User; | |
4 | 6 | use kartik\daterange\DateRangePicker; |
5 | 7 | use kartik\grid\GridView; |
6 | 8 | use kartik\select2\Select2; |
... | ... | @@ -14,19 +16,30 @@ |
14 | 16 | /** |
15 | 17 | * @var View $this |
16 | 18 | * @var Label[] $labels |
19 | + * @var User[] $managers | |
17 | 20 | * @var array $labelStatistics |
18 | 21 | * @var array $rejectionStatistics |
19 | 22 | * @var ActiveDataProvider $dataProvider |
20 | - * @var array $labelChartData | |
23 | + * @var array $labelChartData1 | |
24 | + * @var array $labelChartData2 | |
25 | + * @var array $labelChartData3 | |
26 | + * @var array $rejectChartData1 | |
27 | + * @var array $rejectChartData2 | |
21 | 28 | * @var string $dateValue |
22 | 29 | * @var int | boolean $dataLabel |
30 | + * @var int | boolean $dataManager | |
23 | 31 | */ |
32 | + | |
33 | + $js = <<< JS | |
34 | +$('[data-toggle="popover"]').popover(); | |
35 | +JS; | |
36 | + $this->registerJs($js, View::POS_READY); | |
24 | 37 | |
25 | 38 | ?> |
26 | 39 | |
27 | 40 | <div class="box box-default"> |
28 | 41 | <div class="box-header with-border"> |
29 | - <h3 class="box-title">Collapsable</h3> | |
42 | + <h3 class="box-title">Поиск заказов</h3> | |
30 | 43 | <div class="box-tools pull-right"> |
31 | 44 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
32 | 45 | </div><!-- /.box-tools --> |
... | ... | @@ -37,7 +50,7 @@ |
37 | 50 | 'get' |
38 | 51 | ) ?> |
39 | 52 | <div class="row"> |
40 | - <div class="col-md-4"> | |
53 | + <div class="col-md-3"> | |
41 | 54 | <?= DateRangePicker::widget( |
42 | 55 | [ |
43 | 56 | 'name' => 'date_range', |
... | ... | @@ -51,12 +64,12 @@ |
51 | 64 | ] |
52 | 65 | ) ?> |
53 | 66 | </div> |
54 | - <div class="col-md-6"> | |
67 | + <div class="col-md-4"> | |
55 | 68 | <?= Select2::widget( |
56 | 69 | [ |
57 | - 'name' => 'label', | |
58 | - 'value' => $dataLabel, | |
59 | - 'data' => ArrayHelper::map( | |
70 | + 'name' => 'label', | |
71 | + 'value' => $dataLabel, | |
72 | + 'data' => ArrayHelper::map( | |
60 | 73 | $labels, |
61 | 74 | function($model) { |
62 | 75 | return $model->id; |
... | ... | @@ -65,18 +78,41 @@ |
65 | 78 | return $model->lang->title; |
66 | 79 | } |
67 | 80 | ), |
68 | - 'options' => [ | |
69 | - 'placeholder' => 'Все', | |
81 | + 'options' => [ | |
82 | + 'placeholder' => 'Все метки', | |
70 | 83 | ], |
71 | 84 | 'pluginOptions' => [ |
72 | - 'allowClear' => true, | |
85 | + 'allowClear' => true, | |
86 | + ], | |
87 | + ] | |
88 | + ) ?> | |
89 | + </div> | |
90 | + <div class="col-md-3"> | |
91 | + <?= Select2::widget( | |
92 | + [ | |
93 | + 'name' => 'manager', | |
94 | + 'value' => $dataManager, | |
95 | + 'data' => ArrayHelper::map( | |
96 | + $managers, | |
97 | + function(User $model) { | |
98 | + return $model->id; | |
99 | + }, | |
100 | + function(User $model) { | |
101 | + return $model->username; | |
102 | + } | |
103 | + ), | |
104 | + 'options' => [ | |
105 | + 'placeholder' => 'Все менеджеры', | |
106 | + ], | |
107 | + 'pluginOptions' => [ | |
108 | + 'allowClear' => true, | |
73 | 109 | ], |
74 | 110 | ] |
75 | 111 | ) ?> |
76 | 112 | </div> |
77 | 113 | <div class="col-md-2"> |
78 | 114 | <?= Html::submitButton( |
79 | - 'Go', | |
115 | + 'Поиск', | |
80 | 116 | [ |
81 | 117 | 'class' => 'btn btn-success', |
82 | 118 | ] |
... | ... | @@ -89,7 +125,7 @@ |
89 | 125 | |
90 | 126 | <div class="box box-default"> |
91 | 127 | <div class="box-header with-border"> |
92 | - <h3 class="box-title">Метки, статистика за </h3> | |
128 | + <h3 class="box-title">Метки, статистика за <?= empty($dateValue) ? 'всё время' : $dateValue ?></h3> | |
93 | 129 | <div class="box-tools pull-right"> |
94 | 130 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
95 | 131 | </div><!-- /.box-tools --> |
... | ... | @@ -104,7 +140,15 @@ |
104 | 140 | <td><b>Уникальных товаров, шт.</b></td> |
105 | 141 | </tr> |
106 | 142 | <?php |
143 | + $total_count = 0; | |
144 | + $total_sum = 0; | |
145 | + $total_products = 0; | |
146 | + $total_unique = 0; | |
107 | 147 | foreach ($labelStatistics as $name => $statistic) { |
148 | + $total_count += $statistic[ 'count' ]; | |
149 | + $total_sum += $statistic[ 'sum' ]; | |
150 | + $total_products += $statistic[ 'products' ]; | |
151 | + $total_unique += $statistic[ 'unique' ]; | |
108 | 152 | echo Html::tag( |
109 | 153 | 'tr', |
110 | 154 | Html::tag('td', $name) . Html::tag('td', $statistic[ 'count' ]) . Html::tag( |
... | ... | @@ -112,39 +156,116 @@ |
112 | 156 | $statistic[ 'sum' ] |
113 | 157 | ) . Html::tag('td', $statistic[ 'products' ]) . Html::tag('td', $statistic[ 'unique' ]) |
114 | 158 | ); |
115 | - } ?> | |
159 | + } | |
160 | + ?> | |
161 | + <tr> | |
162 | + <td><b>Всего</b></td> | |
163 | + <td><b><?=$total_count?></b></td> | |
164 | + <td><b><?=$total_sum?></b></td> | |
165 | + <td><b><?=$total_products?></b></td> | |
166 | + <td><b><?=$total_unique?></b></td> | |
167 | + </tr> | |
116 | 168 | </table> |
117 | - | |
118 | - <?= ChartJs::widget( | |
119 | - [ | |
120 | - 'type' => 'bar', | |
121 | - 'options' => [ | |
122 | - 'height' => 200, | |
123 | - 'width' => 600, | |
124 | - ], | |
125 | - 'data' => $labelChartData, | |
126 | - 'clientOptions' => [ | |
127 | - 'title' => [ | |
128 | - 'display' => true, | |
129 | - 'text' => 'Custom Chart Title', | |
130 | - ], | |
131 | - 'scales' => [ | |
132 | - 'xAxes' => [ | |
133 | - [ | |
134 | - 'display' => false, | |
135 | - ], | |
136 | - ], | |
137 | - ], | |
138 | - ], | |
139 | - ] | |
140 | - ); ?> | |
141 | - | |
142 | 169 | </div><!-- /.box-body --> |
170 | + | |
171 | + <div class="box-footer"> | |
172 | + <div class="nav-tabs-custom"> | |
173 | + | |
174 | + <!-- Nav tabs --> | |
175 | + <ul class="nav nav-tabs" role="tablist"> | |
176 | + <li role="presentation" class="active"> | |
177 | + <a href="#home" aria-controls="home" role="tab" data-toggle="tab">Заказы</a></li> | |
178 | + <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Сумма</a></li> | |
179 | + <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">Товары</a> | |
180 | + </li> | |
181 | + </ul> | |
182 | + | |
183 | + <!-- Tab panes --> | |
184 | + <div class="tab-content"> | |
185 | + <div role="tabpanel" class="tab-pane active" id="home"> | |
186 | + <?= ChartJs::widget( | |
187 | + [ | |
188 | + 'type' => 'bar', | |
189 | + 'options' => [ | |
190 | + 'height' => 200, | |
191 | + 'width' => 600, | |
192 | + ], | |
193 | + 'data' => $labelChartData1, | |
194 | + 'clientOptions' => [ | |
195 | + 'title' => [ | |
196 | + 'display' => true, | |
197 | + 'text' => 'Статистика меток', | |
198 | + ], | |
199 | + 'scales' => [ | |
200 | + 'xAxes' => [ | |
201 | + [ | |
202 | + 'display' => false, | |
203 | + ], | |
204 | + ], | |
205 | + ], | |
206 | + ], | |
207 | + ] | |
208 | + ); ?> | |
209 | + </div> | |
210 | + <div role="tabpanel" class="tab-pane" id="profile"> | |
211 | + <?= ChartJs::widget( | |
212 | + [ | |
213 | + 'type' => 'bar', | |
214 | + 'options' => [ | |
215 | + 'height' => 200, | |
216 | + 'width' => 600, | |
217 | + ], | |
218 | + 'data' => $labelChartData2, | |
219 | + 'clientOptions' => [ | |
220 | + 'title' => [ | |
221 | + 'display' => true, | |
222 | + 'text' => 'Статистика меток', | |
223 | + ], | |
224 | + 'scales' => [ | |
225 | + 'xAxes' => [ | |
226 | + [ | |
227 | + 'display' => false, | |
228 | + ], | |
229 | + ], | |
230 | + ], | |
231 | + ], | |
232 | + ] | |
233 | + ); ?> | |
234 | + </div> | |
235 | + <div role="tabpanel" class="tab-pane" id="messages"> | |
236 | + <?= ChartJs::widget( | |
237 | + [ | |
238 | + 'type' => 'bar', | |
239 | + 'options' => [ | |
240 | + 'height' => 200, | |
241 | + 'width' => 600, | |
242 | + ], | |
243 | + 'data' => $labelChartData3, | |
244 | + 'clientOptions' => [ | |
245 | + 'title' => [ | |
246 | + 'display' => true, | |
247 | + 'text' => 'Статистика меток', | |
248 | + ], | |
249 | + 'scales' => [ | |
250 | + 'xAxes' => [ | |
251 | + [ | |
252 | + 'display' => false, | |
253 | + ], | |
254 | + ], | |
255 | + ], | |
256 | + ], | |
257 | + ] | |
258 | + ); ?> | |
259 | + </div> | |
260 | + </div> | |
261 | + | |
262 | + </div> | |
263 | + </div> | |
143 | 264 | </div><!-- /.box --> |
144 | 265 | |
145 | 266 | <div class="box box-default"> |
146 | 267 | <div class="box-header with-border"> |
147 | - <h3 class="box-title">Метки, статистика за </h3> | |
268 | + <h3 class="box-title">Причины отказа, статистика за <?= empty($dateValue) ? 'всё время' : $dateValue ?></h3> | |
148 | 269 | <div class="box-tools pull-right"> |
149 | 270 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
150 | 271 | </div><!-- /.box-tools --> |
... | ... | @@ -169,77 +290,205 @@ |
169 | 290 | ?> |
170 | 291 | </table> |
171 | 292 | </div><!-- /.box-body --> |
172 | -</div><!-- /.box --> | |
173 | 293 | |
174 | -<?= GridView::widget( | |
175 | - [ | |
176 | - 'dataProvider' => $dataProvider, | |
177 | - 'columns' => [ | |
178 | - 'id', | |
179 | - 'created_at:datetime', | |
180 | - 'name', | |
181 | - 'city', | |
182 | - [ | |
183 | - 'attribute' => 'orderLabel.label', | |
184 | - 'label' => 'Метка', | |
185 | - ], | |
186 | - 'total', | |
187 | - [ | |
188 | - 'attribute' => 'reason', | |
189 | - 'content' => function($model) { | |
190 | - /** | |
191 | - * @var Order $model | |
192 | - */ | |
193 | - if (empty($model->reason)) { | |
194 | - return ''; | |
195 | - } else { | |
196 | - return Order::REASONS[ $model->reason ]; | |
197 | - } | |
198 | - }, | |
199 | - ], | |
200 | - [ | |
201 | - 'attribute' => 'manager.username', | |
202 | - 'label' => 'Менеджер', | |
203 | - ], | |
204 | - [ | |
205 | - 'attribute' => 'body', | |
206 | - 'content' => function($model) { | |
207 | - /** | |
208 | - * @var Order $model | |
209 | - */ | |
210 | - if (empty($model->body)) { | |
211 | - return ''; | |
212 | - } else { | |
213 | - return Html::a( | |
214 | - StringHelper::truncate($model->body, 10, '...'), | |
215 | - '#', | |
216 | - [ | |
217 | - 'data-toggle' => 'tooltip', | |
218 | - 'title' => $model->body, | |
219 | - 'onclick' => 'event.preventDefault();', | |
220 | - ] | |
221 | - ); | |
222 | - } | |
223 | - }, | |
224 | - ], | |
225 | - [ | |
226 | - 'content' => function($model) { | |
227 | - /** | |
228 | - * @var Order $model | |
229 | - */ | |
230 | - return Html::a( | |
231 | - Html::tag('i', '', [ 'class' => 'glyphicon glyphicon-eye-open' ]), | |
232 | - [ | |
233 | - '/ecommerce/order/view', | |
234 | - 'id' => $model->id, | |
294 | + <div class="box-footer"> | |
295 | + <div class="nav-tabs-custom"> | |
296 | + | |
297 | + <!-- Nav tabs --> | |
298 | + <ul class="nav nav-tabs" role="tablist"> | |
299 | + <li role="presentation" class="active"> | |
300 | + <a href="#count" aria-controls="count" role="tab" data-toggle="tab">Заказы</a></li> | |
301 | + <li role="presentation"><a href="#sum" aria-controls="sum" role="tab" data-toggle="tab">Сумма</a></li> | |
302 | + </ul> | |
303 | + | |
304 | + <!-- Tab panes --> | |
305 | + <div class="tab-content"> | |
306 | + <div role="tabpanel" class="tab-pane active" id="count"> | |
307 | + <?= ChartJs::widget( | |
308 | + [ | |
309 | + 'type' => 'bar', | |
310 | + 'options' => [ | |
311 | + 'height' => 200, | |
312 | + 'width' => 600, | |
313 | + ], | |
314 | + 'data' => $rejectChartData1, | |
315 | + 'clientOptions' => [ | |
316 | + 'title' => [ | |
317 | + 'display' => true, | |
318 | + 'text' => 'Статистика отказов', | |
319 | + ], | |
320 | + 'scales' => [ | |
321 | + 'xAxes' => [ | |
322 | + [ | |
323 | + 'display' => false, | |
324 | + ], | |
325 | + ], | |
326 | + ], | |
327 | + ], | |
328 | + ] | |
329 | + ); ?> | |
330 | + </div> | |
331 | + <div role="tabpanel" class="tab-pane" id="sum"> | |
332 | + <?= ChartJs::widget( | |
333 | + [ | |
334 | + 'type' => 'bar', | |
335 | + 'options' => [ | |
336 | + 'height' => 200, | |
337 | + 'width' => 600, | |
338 | + ], | |
339 | + 'data' => $rejectChartData2, | |
340 | + 'clientOptions' => [ | |
341 | + 'title' => [ | |
342 | + 'display' => true, | |
343 | + 'text' => 'Статистика отказов', | |
235 | 344 | ], |
236 | - [ | |
237 | - 'target' => '_blank', | |
238 | - 'data-pjax' => '0', | |
239 | - ] | |
240 | - ); | |
241 | - }, | |
242 | - ], | |
243 | - ], | |
244 | - ] | |
245 | -) ?> | |
345 | + 'scales' => [ | |
346 | + 'xAxes' => [ | |
347 | + [ | |
348 | + 'display' => false, | |
349 | + ], | |
350 | + ], | |
351 | + ], | |
352 | + ], | |
353 | + ] | |
354 | + ); ?> | |
355 | + </div> | |
356 | + </div> | |
357 | + | |
358 | + </div> | |
359 | + </div> | |
360 | + | |
361 | +</div><!-- /.box --> | |
362 | + | |
363 | + | |
364 | +<div class="box box-default"> | |
365 | + <div class="box-header with-border"> | |
366 | + <h3 class="box-title">Заказы</h3> | |
367 | + <div class="box-tools pull-right"> | |
368 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
369 | + </div><!-- /.box-tools --> | |
370 | + </div><!-- /.box-header --> | |
371 | + <div class="box-body table-responsive"> | |
372 | + <?= GridView::widget( | |
373 | + [ | |
374 | + 'dataProvider' => $dataProvider, | |
375 | + 'columns' => [ | |
376 | + 'id', | |
377 | + [ | |
378 | + 'label' => 'Дата добавления', | |
379 | + 'content' => function(Order $model) { | |
380 | + return \Yii::$app->formatter->asDate($model->created_at) . | |
381 | + '<br>' . \Yii::$app->formatter->asTime($model->created_at); | |
382 | + }, | |
383 | + ], | |
384 | + 'name', | |
385 | + [ | |
386 | + 'label' => 'Товары', | |
387 | + 'content' => function(Order $model) { | |
388 | + if (empty($model->products)) { | |
389 | + return ''; | |
390 | + } else { | |
391 | + $content = ''; | |
392 | + $i = 0; | |
393 | + foreach ($model->products as $product) { | |
394 | + if(empty($product->productVariant)){ | |
395 | + $image = ''; | |
396 | + } else { | |
397 | + $image = $product->productVariant->imageUrl; | |
398 | + } | |
399 | + $i++; | |
400 | + $content .= Html::a( | |
401 | + $product->sku, | |
402 | + '#', | |
403 | + [ | |
404 | + 'onclick' => 'event.preventDefault();', | |
405 | + 'data-toggle' => 'popover', | |
406 | + 'data-placement' => 'right', | |
407 | + 'data-html' => 'true', | |
408 | + 'data-content' => Html::img( | |
409 | + $image, | |
410 | + [ | |
411 | + 'class' => 'img-rounded', | |
412 | + ] | |
413 | + ) . Html::tag('p', $product->product_name), | |
414 | + ] | |
415 | + ); | |
416 | + if ($i != count($model->products)) { | |
417 | + $content .= ', '; | |
418 | + } | |
419 | + if ($i % 2 == 0) { | |
420 | + $content .= '<br>'; | |
421 | + } | |
422 | + } | |
423 | + return $content; | |
424 | + } | |
425 | + }, | |
426 | + ], | |
427 | + 'city', | |
428 | + [ | |
429 | + 'attribute' => 'orderLabel.label', | |
430 | + 'label' => 'Метка', | |
431 | + ], | |
432 | + 'total', | |
433 | + [ | |
434 | + 'attribute' => 'reason', | |
435 | + 'content' => function($model) { | |
436 | + /** | |
437 | + * @var Order $model | |
438 | + */ | |
439 | + if (empty($model->reason)) { | |
440 | + return ''; | |
441 | + } else { | |
442 | + return Order::REASONS[ $model->reason ]; | |
443 | + } | |
444 | + }, | |
445 | + ], | |
446 | + [ | |
447 | + 'attribute' => 'manager.username', | |
448 | + 'label' => 'Менеджер', | |
449 | + ], | |
450 | + [ | |
451 | + 'attribute' => 'body', | |
452 | + 'content' => function($model) { | |
453 | + /** | |
454 | + * @var Order $model | |
455 | + */ | |
456 | + if (empty($model->body)) { | |
457 | + return ''; | |
458 | + } else { | |
459 | + return Html::a( | |
460 | + StringHelper::truncate($model->body, 10, '...'), | |
461 | + '#', | |
462 | + [ | |
463 | + 'data-toggle' => 'tooltip', | |
464 | + 'title' => $model->body, | |
465 | + 'onclick' => 'event.preventDefault();', | |
466 | + ] | |
467 | + ); | |
468 | + } | |
469 | + }, | |
470 | + ], | |
471 | + [ | |
472 | + 'content' => function($model) { | |
473 | + /** | |
474 | + * @var Order $model | |
475 | + */ | |
476 | + return Html::a( | |
477 | + Html::tag('i', '', [ 'class' => 'glyphicon glyphicon-eye-open' ]), | |
478 | + [ | |
479 | + '/ecommerce/order/view', | |
480 | + 'id' => $model->id, | |
481 | + ], | |
482 | + [ | |
483 | + 'target' => '_blank', | |
484 | + 'data-pjax' => '0', | |
485 | + ] | |
486 | + ); | |
487 | + }, | |
488 | + ], | |
489 | + ], | |
490 | + ] | |
491 | + ) ?> | |
492 | + | |
493 | + </div><!-- /.box-body --> | |
494 | +</div><!-- /.box --> | ... | ... |