Commit bfd986312e53156499a3584eee479724eeee979e
Merge remote-tracking branch 'origin/master' into Credits
Showing
4 changed files
with
265 additions
and
12 deletions
Show diff stats
controllers/StatisticsController.php
... | ... | @@ -2,15 +2,76 @@ |
2 | 2 | |
3 | 3 | namespace artweb\artbox\ecommerce\controllers; |
4 | 4 | |
5 | + use artweb\artbox\ecommerce\models\Label; | |
6 | + use artweb\artbox\ecommerce\models\Order; | |
7 | + use yii\data\ActiveDataProvider; | |
8 | + use yii\helpers\ArrayHelper; | |
9 | + use yii\helpers\VarDumper; | |
5 | 10 | use yii\web\Controller; |
6 | 11 | |
7 | - /** | |
8 | - * BrandController implements the CRUD actions for Brand model. | |
9 | - */ | |
10 | 12 | class StatisticsController extends Controller |
11 | 13 | { |
12 | - public function actionIndex() | |
14 | + public function actionIndex($date_range = NULL, $label = NULL) | |
13 | 15 | { |
14 | - return $this->render('index'); | |
16 | + /** | |
17 | + * Get a dates range | |
18 | + */ | |
19 | + if (!empty($date_range)) { | |
20 | + $arr = []; | |
21 | + preg_match('@(.*)\s:\s(.*)@', $date_range, $arr); | |
22 | + $dateFilter = [ | |
23 | + 'between', | |
24 | + 'created_at', | |
25 | + strtotime($arr[1]), | |
26 | + strtotime($arr[2]), | |
27 | + ]; | |
28 | + } else { | |
29 | + $dateFilter = []; | |
30 | + } | |
31 | + | |
32 | + if (!empty($label)) { | |
33 | + $labelFilter = ['label' => $label]; | |
34 | + } else { | |
35 | + $labelFilter = []; | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * Get labels | |
40 | + */ | |
41 | + $labels = Label::find() | |
42 | + ->with('lang') | |
43 | + ->all(); | |
44 | + | |
45 | + /** | |
46 | + * Generate statistics | |
47 | + */ | |
48 | + $labelStatistics = ArrayHelper::map( | |
49 | + $labels, | |
50 | + function($model) { | |
51 | + /** | |
52 | + * @var Label $model | |
53 | + */ | |
54 | + return $model->lang->title; | |
55 | + }, | |
56 | + function($model) use ($dateFilter) { | |
57 | + /** | |
58 | + * @var Label $model | |
59 | + */ | |
60 | + return $model->getStatistics($dateFilter);} | |
61 | + ); | |
62 | + | |
63 | + $dataProvider = new ActiveDataProvider([ | |
64 | + 'query' => Order::find()->filterWhere($dateFilter)->andFilterWhere($labelFilter), | |
65 | + ]); | |
66 | + | |
67 | + return $this->render( | |
68 | + 'index', | |
69 | + [ | |
70 | + 'labels' => $labels, | |
71 | + 'labelStatistics' => $labelStatistics, | |
72 | + 'rejectionStatistics' => Order::getRejectionStatistics($dateFilter), | |
73 | + 'dataProvider' => $dataProvider, | |
74 | + ] | |
75 | + ); | |
15 | 76 | } |
16 | 77 | } | ... | ... |
models/Label.php
... | ... | @@ -5,6 +5,8 @@ |
5 | 5 | use artweb\artbox\language\behaviors\LanguageBehavior; |
6 | 6 | use yii\db\ActiveQuery; |
7 | 7 | use yii\db\ActiveRecord; |
8 | + use yii\db\Query; | |
9 | + use yii\helpers\VarDumper; | |
8 | 10 | use yii\web\Request; |
9 | 11 | |
10 | 12 | /** |
... | ... | @@ -62,4 +64,41 @@ |
62 | 64 | ], |
63 | 65 | ]; |
64 | 66 | } |
67 | + | |
68 | + public function getStatistics(array $where = []) | |
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 | + | |
102 | + return $query->one(); | |
103 | + } | |
65 | 104 | } | ... | ... |
models/Order.php
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | use Yii; |
8 | 8 | use yii\behaviors\TimestampBehavior; |
9 | 9 | use yii\db\ActiveRecord; |
10 | + use yii\db\Query; | |
10 | 11 | |
11 | 12 | /** |
12 | 13 | * Class Order |
... | ... | @@ -93,6 +94,32 @@ |
93 | 94 | { |
94 | 95 | return 'order'; |
95 | 96 | } |
97 | + | |
98 | + /** | |
99 | + * @param array $where | |
100 | + * | |
101 | + * @return array | |
102 | + */ | |
103 | + public static function getRejectionStatistics(array $where = []) | |
104 | + { | |
105 | + $result = []; | |
106 | + foreach (self::REASONS as $id => $reason) { | |
107 | + $result[ $reason ] = ( new Query() )->select( | |
108 | + [ | |
109 | + 'sum' => 'SUM(total)', | |
110 | + 'count' => 'COUNT(*)', | |
111 | + ] | |
112 | + ) | |
113 | + ->from(self::tableName()) | |
114 | + ->where( | |
115 | + [ | |
116 | + 'reason' => $id, | |
117 | + ] | |
118 | + )->andFilterWhere($where)->one(); | |
119 | + } | |
120 | + | |
121 | + return $result; | |
122 | + } | |
96 | 123 | |
97 | 124 | public function behaviors() |
98 | 125 | { |
... | ... | @@ -203,7 +230,7 @@ |
203 | 230 | public function afterFind() |
204 | 231 | { |
205 | 232 | parent::afterFind(); |
206 | - $this->deadline = !empty( $this->deadline ) ? date('d.m.Y', $this->deadline) : ''; | |
233 | + $this->deadline = !empty($this->deadline) ? date('d.m.Y', $this->deadline) : ''; | |
207 | 234 | |
208 | 235 | } |
209 | 236 | |
... | ... | @@ -220,7 +247,7 @@ |
220 | 247 | |
221 | 248 | protected function convertDate() |
222 | 249 | { |
223 | - if (!empty( $this->deadline )) { | |
250 | + if (!empty($this->deadline)) { | |
224 | 251 | $date = new \DateTime(); |
225 | 252 | $date->setTimestamp(strtotime($this->deadline)); |
226 | 253 | $date->format("d.m.Y"); |
... | ... | @@ -311,8 +338,8 @@ |
311 | 338 | */ |
312 | 339 | public function getDeliveryString() |
313 | 340 | { |
314 | - if (!empty( $this->orderDelivery )) { | |
315 | - if (!empty( $this->orderDelivery->parent )) { | |
341 | + if (!empty($this->orderDelivery)) { | |
342 | + if (!empty($this->orderDelivery->parent)) { | |
316 | 343 | return $this->orderDelivery->parent->lang->title . ': ' . $this->orderDelivery->lang->title; |
317 | 344 | } else { |
318 | 345 | return $this->orderDelivery->lang->title; |
... | ... | @@ -330,7 +357,7 @@ |
330 | 357 | */ |
331 | 358 | public function getWasted() |
332 | 359 | { |
333 | - if (empty( $this->deadline )) { | |
360 | + if (empty($this->deadline)) { | |
334 | 361 | return false; |
335 | 362 | } else { |
336 | 363 | return time() > strtotime($this->deadline); | ... | ... |
views/statistics/index.php
1 | 1 | <?php |
2 | + use artweb\artbox\ecommerce\models\Label; | |
3 | + use kartik\daterange\DateRangePicker; | |
4 | + use kartik\grid\GridView; | |
5 | + use kartik\select2\Select2; | |
6 | + use yii\data\ActiveDataProvider; | |
7 | + use yii\helpers\ArrayHelper; | |
8 | + use yii\helpers\Html; | |
2 | 9 | use yii\web\View; |
3 | 10 | |
4 | 11 | /** |
5 | - * @var View $this | |
12 | + * @var View $this | |
13 | + * @var Label[] $labels | |
14 | + * @var array $labelStatistics | |
15 | + * @var array $rejectionStatistics | |
16 | + * @var ActiveDataProvider $dataProvider | |
6 | 17 | */ |
7 | 18 | |
8 | 19 | ?> |
... | ... | @@ -15,6 +26,121 @@ |
15 | 26 | </div><!-- /.box-tools --> |
16 | 27 | </div><!-- /.box-header --> |
17 | 28 | <div class="box-body"> |
18 | - The body of the box | |
29 | + <?= Html::beginForm( | |
30 | + [ '/ecommerce/statistics' ], | |
31 | + 'get' | |
32 | + ) ?> | |
33 | + <div class="row"> | |
34 | + <div class="col-md-4"> | |
35 | + <?= DateRangePicker::widget( | |
36 | + [ | |
37 | + 'name' => 'date_range', | |
38 | + 'pluginOptions' => [ | |
39 | + 'locale' => [ | |
40 | + 'format' => 'DD-MM-Y', | |
41 | + 'separator' => ' : ', | |
42 | + ], | |
43 | + ], | |
44 | + ] | |
45 | + ) ?> | |
46 | + </div> | |
47 | + <div class="col-md-6"> | |
48 | + <?= Select2::widget( | |
49 | + [ | |
50 | + 'name' => 'label', | |
51 | + 'data' => ArrayHelper::map( | |
52 | + $labels, | |
53 | + function($model) { | |
54 | + return $model->id; | |
55 | + }, | |
56 | + function($model) { | |
57 | + return $model->lang->title; | |
58 | + } | |
59 | + ), | |
60 | + 'options' => [ | |
61 | + 'placeholder' => 'Все', | |
62 | + ], | |
63 | + ] | |
64 | + ) ?> | |
65 | + </div> | |
66 | + <div class="col-md-2"> | |
67 | + <?= Html::submitButton( | |
68 | + 'Go', | |
69 | + [ | |
70 | + 'class' => 'btn btn-success', | |
71 | + ] | |
72 | + ) ?> | |
73 | + </div> | |
74 | + </div> | |
75 | + <?= Html::endForm() ?> | |
19 | 76 | </div><!-- /.box-body --> |
20 | 77 | </div><!-- /.box --> |
78 | + | |
79 | +<div class="box box-default"> | |
80 | + <div class="box-header with-border"> | |
81 | + <h3 class="box-title">Метки, статистика за </h3> | |
82 | + <div class="box-tools pull-right"> | |
83 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
84 | + </div><!-- /.box-tools --> | |
85 | + </div><!-- /.box-header --> | |
86 | + <div class="box-body table-responsive no-padding"> | |
87 | + <table class="table table-hover"> | |
88 | + <tr> | |
89 | + <td><b>Метка</b></td> | |
90 | + <td><b>Заказов, шт.</b></td> | |
91 | + <td><b>На сумму, грн.</b></td> | |
92 | + <td><b>Заказано товаров, шт.</b></td> | |
93 | + <td><b>Уникальных товаров, шт.</b></td> | |
94 | + </tr> | |
95 | + <?php | |
96 | + foreach ($labelStatistics as $name => $statistic) { | |
97 | + ?> | |
98 | + <tr> | |
99 | + <td><?= $name ?></td> | |
100 | + <td><?= $statistic[ 'count' ] ?></td> | |
101 | + <td><?= $statistic[ 'sum' ] ?></td> | |
102 | + <td><?= $statistic[ 'products' ] ?></td> | |
103 | + <td><?= $statistic[ 'unique' ] ?></td> | |
104 | + </tr> | |
105 | + <?php } ?> | |
106 | + </table> | |
107 | + </div><!-- /.box-body --> | |
108 | +</div><!-- /.box --> | |
109 | + | |
110 | +<div class="box box-default"> | |
111 | + <div class="box-header with-border"> | |
112 | + <h3 class="box-title">Метки, статистика за </h3> | |
113 | + <div class="box-tools pull-right"> | |
114 | + <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | |
115 | + </div><!-- /.box-tools --> | |
116 | + </div><!-- /.box-header --> | |
117 | + <div class="box-body table-responsive no-padding"> | |
118 | + <table class="table table-hover"> | |
119 | + <tr> | |
120 | + <td><b>Причина</b></td> | |
121 | + <td><b>Заказов, шт.</b></td> | |
122 | + <td><b>На сумму, грн.</b></td> | |
123 | + </tr> | |
124 | + <?php | |
125 | + foreach ($rejectionStatistics as $name => $statistic) { | |
126 | + ?> | |
127 | + <tr> | |
128 | + <td><?= $name ?></td> | |
129 | + <td><?= $statistic[ 'count' ] ?></td> | |
130 | + <td><?= $statistic[ 'sum' ] ?></td> | |
131 | + </tr> | |
132 | + <?php } ?> | |
133 | + </table> | |
134 | + </div><!-- /.box-body --> | |
135 | +</div><!-- /.box --> | |
136 | + | |
137 | +<?=GridView::widget([ | |
138 | + 'dataProvider' => $dataProvider, | |
139 | + 'columns' => [ | |
140 | + 'id', | |
141 | + 'created_at:datetime', | |
142 | + 'name', | |
143 | + 'city', | |
144 | + | |
145 | + ], | |
146 | + ])?> | ... | ... |