Commit b1cc502ffc0d194269e0d8caff7a4a91b25a311f
Merge branch 'statistics'
# Conflicts: # controllers/OrderController.php
Showing
15 changed files
with
1743 additions
and
509 deletions
Show diff stats
controllers/OrderController.php
| @@ -3,19 +3,21 @@ | @@ -3,19 +3,21 @@ | ||
| 3 | namespace artweb\artbox\ecommerce\controllers; | 3 | namespace artweb\artbox\ecommerce\controllers; |
| 4 | 4 | ||
| 5 | use artweb\artbox\components\SmsSender; | 5 | use artweb\artbox\components\SmsSender; |
| 6 | + use artweb\artbox\ecommerce\models\OrderLabelHistory; | ||
| 7 | + use artweb\artbox\ecommerce\models\OrderLog; | ||
| 6 | use artweb\artbox\ecommerce\models\OrderSearch; | 8 | use artweb\artbox\ecommerce\models\OrderSearch; |
| 9 | + use common\components\CreditHelper; | ||
| 7 | use common\models\User; | 10 | use common\models\User; |
| 8 | - use phpDocumentor\Reflection\Types\Null_; | ||
| 9 | use Yii; | 11 | use Yii; |
| 10 | use yii\data\ArrayDataProvider; | 12 | use yii\data\ArrayDataProvider; |
| 11 | - use yii\helpers\ArrayHelper; | 13 | + use yii\db\ActiveQuery; |
| 12 | use yii\helpers\Json; | 14 | use yii\helpers\Json; |
| 13 | use yii\helpers\VarDumper; | 15 | use yii\helpers\VarDumper; |
| 16 | + use yii\validators\NumberValidator; | ||
| 14 | use yii\web\Controller; | 17 | use yii\web\Controller; |
| 15 | use yii\filters\VerbFilter; | 18 | use yii\filters\VerbFilter; |
| 16 | use yii\data\ActiveDataProvider; | 19 | use yii\data\ActiveDataProvider; |
| 17 | use yii\web\ForbiddenHttpException; | 20 | use yii\web\ForbiddenHttpException; |
| 18 | - use yii\web\HttpException; | ||
| 19 | use artweb\artbox\ecommerce\models\Order; | 21 | use artweb\artbox\ecommerce\models\Order; |
| 20 | use artweb\artbox\ecommerce\models\OrderProduct; | 22 | use artweb\artbox\ecommerce\models\OrderProduct; |
| 21 | use artweb\artbox\ecommerce\models\ProductVariant; | 23 | use artweb\artbox\ecommerce\models\ProductVariant; |
| @@ -107,6 +109,14 @@ | @@ -107,6 +109,14 @@ | ||
| 107 | public function actionView($id) | 109 | public function actionView($id) |
| 108 | { | 110 | { |
| 109 | $model = $this->findModel($id); | 111 | $model = $this->findModel($id); |
| 112 | + | ||
| 113 | + $historyData = new ActiveDataProvider( | ||
| 114 | + [ | ||
| 115 | + 'query' => $model->getLabelsHistory() | ||
| 116 | + ->with('order', 'label', 'user'), | ||
| 117 | + ] | ||
| 118 | + ); | ||
| 119 | + | ||
| 110 | $dataProvider = new ActiveDataProvider( | 120 | $dataProvider = new ActiveDataProvider( |
| 111 | [ | 121 | [ |
| 112 | 'query' => $model->getProducts(), | 122 | 'query' => $model->getProducts(), |
| @@ -115,8 +125,9 @@ | @@ -115,8 +125,9 @@ | ||
| 115 | return $this->render( | 125 | return $this->render( |
| 116 | 'view', | 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,6 +139,25 @@ | ||
| 128 | $model->save(); | 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 | public function actionDelete($id) | 161 | public function actionDelete($id) |
| 132 | { | 162 | { |
| 133 | if (\Yii::$app->user->identity->isAdmin()) { | 163 | if (\Yii::$app->user->identity->isAdmin()) { |
| @@ -151,10 +181,10 @@ | @@ -151,10 +181,10 @@ | ||
| 151 | 181 | ||
| 152 | public function actionAdd() | 182 | public function actionAdd() |
| 153 | { | 183 | { |
| 154 | - if (!empty( \Yii::$app->request->post() )) { | 184 | + if (!empty(\Yii::$app->request->post())) { |
| 155 | $id = \Yii::$app->request->post('OrderProduct')[ 'id' ]; | 185 | $id = \Yii::$app->request->post('OrderProduct')[ 'id' ]; |
| 156 | $order_id = \Yii::$app->request->post('OrderProduct')[ 'order_id' ]; | 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 | $count = \Yii::$app->request->post('OrderProduct')[ 'count' ]; | 188 | $count = \Yii::$app->request->post('OrderProduct')[ 'count' ]; |
| 159 | } else { | 189 | } else { |
| 160 | $count = 1; | 190 | $count = 1; |
| @@ -174,7 +204,7 @@ | @@ -174,7 +204,7 @@ | ||
| 174 | ) | 204 | ) |
| 175 | ->one(); | 205 | ->one(); |
| 176 | 206 | ||
| 177 | - if (!empty( $model )) { | 207 | + if (!empty($model)) { |
| 178 | $model->count += $count; | 208 | $model->count += $count; |
| 179 | $model->removed = false; | 209 | $model->removed = false; |
| 180 | } else { | 210 | } else { |
| @@ -221,7 +251,7 @@ | @@ -221,7 +251,7 @@ | ||
| 221 | if ($orderProduct->load($post)) { | 251 | if ($orderProduct->load($post)) { |
| 222 | $orderProduct->save(); | 252 | $orderProduct->save(); |
| 223 | $output = ''; | 253 | $output = ''; |
| 224 | - if (isset( $posted[ 'count' ] )) { | 254 | + if (isset($posted[ 'count' ])) { |
| 225 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); | 255 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); |
| 226 | } | 256 | } |
| 227 | $out = Json::encode( | 257 | $out = Json::encode( |
| @@ -283,7 +313,7 @@ | @@ -283,7 +313,7 @@ | ||
| 283 | return $this->renderPartial( | 313 | return $this->renderPartial( |
| 284 | 'print', | 314 | 'print', |
| 285 | [ | 315 | [ |
| 286 | - 'order' => $order, | 316 | + 'order' => $order, |
| 287 | 'dataProvider' => $dataProvider, | 317 | 'dataProvider' => $dataProvider, |
| 288 | ] | 318 | ] |
| 289 | ); | 319 | ); |
| @@ -309,7 +339,7 @@ | @@ -309,7 +339,7 @@ | ||
| 309 | $orderProduct->save(); | 339 | $orderProduct->save(); |
| 310 | $orderProduct->order->totalRecount(); | 340 | $orderProduct->order->totalRecount(); |
| 311 | $output = ''; | 341 | $output = ''; |
| 312 | - if (isset( $posted[ 'count' ] )) { | 342 | + if (isset($posted[ 'count' ])) { |
| 313 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); | 343 | $output = Yii::$app->formatter->asDecimal($orderProduct->count, 0); |
| 314 | } | 344 | } |
| 315 | $out = Json::encode( | 345 | $out = Json::encode( |
| @@ -322,9 +352,21 @@ | @@ -322,9 +352,21 @@ | ||
| 322 | 352 | ||
| 323 | return $out; | 353 | return $out; |
| 324 | } | 354 | } |
| 325 | - | 355 | + |
| 326 | $model = $this->findModel($id); | 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 | * @var User $user | 371 | * @var User $user |
| 330 | */ | 372 | */ |
| @@ -334,7 +376,7 @@ | @@ -334,7 +376,7 @@ | ||
| 334 | throw new ForbiddenHttpException(); | 376 | throw new ForbiddenHttpException(); |
| 335 | } | 377 | } |
| 336 | } | 378 | } |
| 337 | - | 379 | + |
| 338 | $dataProvider = new ActiveDataProvider( | 380 | $dataProvider = new ActiveDataProvider( |
| 339 | [ | 381 | [ |
| 340 | 'query' => $model->getProducts() | 382 | 'query' => $model->getProducts() |
| @@ -344,10 +386,10 @@ | @@ -344,10 +386,10 @@ | ||
| 344 | ] | 386 | ] |
| 345 | ); | 387 | ); |
| 346 | 388 | ||
| 347 | - if (empty( $model->manager_id )) { | 389 | + if (empty($model->manager_id)) { |
| 348 | $model->manager_id = \Yii::$app->user->id; | 390 | $model->manager_id = \Yii::$app->user->id; |
| 349 | } | 391 | } |
| 350 | - | 392 | + |
| 351 | $headers = \Yii::$app->response->headers; | 393 | $headers = \Yii::$app->response->headers; |
| 352 | $headers->set('Access-Control-Allow-Origin', '*'); | 394 | $headers->set('Access-Control-Allow-Origin', '*'); |
| 353 | 395 | ||
| @@ -392,7 +434,7 @@ | @@ -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 | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | 439 | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; |
| 398 | $out = [ | 440 | $out = [ |
| @@ -452,7 +494,7 @@ | @@ -452,7 +494,7 @@ | ||
| 452 | 494 | ||
| 453 | protected function findModel($id) | 495 | protected function findModel($id) |
| 454 | { | 496 | { |
| 455 | - if (( $model = Order::findOne($id) ) !== null) { | 497 | + if (( $model = Order::findOne($id) ) !== NULL) { |
| 456 | return $model; | 498 | return $model; |
| 457 | } else { | 499 | } else { |
| 458 | throw new NotFoundHttpException('The requested page does not exist.'); | 500 | throw new NotFoundHttpException('The requested page does not exist.'); |
| @@ -469,7 +511,7 @@ | @@ -469,7 +511,7 @@ | ||
| 469 | if ($model->edit_id == \Yii::$app->user->id) { | 511 | if ($model->edit_id == \Yii::$app->user->id) { |
| 470 | $this->unblockOrder(\Yii::$app->request->post('id')); | 512 | $this->unblockOrder(\Yii::$app->request->post('id')); |
| 471 | } | 513 | } |
| 472 | - | 514 | + |
| 473 | if (!$model->published) { | 515 | if (!$model->published) { |
| 474 | $model->deleteUnpublished(); | 516 | $model->deleteUnpublished(); |
| 475 | } | 517 | } |
| @@ -495,7 +537,7 @@ | @@ -495,7 +537,7 @@ | ||
| 495 | 537 | ||
| 496 | public function actionBlockOrder() | 538 | public function actionBlockOrder() |
| 497 | { | 539 | { |
| 498 | - if (!empty( \Yii::$app->request->post() )) { | 540 | + if (!empty(\Yii::$app->request->post())) { |
| 499 | \Yii::$app->response->format = Response::FORMAT_JSON; | 541 | \Yii::$app->response->format = Response::FORMAT_JSON; |
| 500 | 542 | ||
| 501 | $model = $this->findModel(\Yii::$app->request->post('id')); | 543 | $model = $this->findModel(\Yii::$app->request->post('id')); |
| @@ -512,7 +554,7 @@ | @@ -512,7 +554,7 @@ | ||
| 512 | if ($model->save()) { | 554 | if ($model->save()) { |
| 513 | return [ | 555 | return [ |
| 514 | 'time' => $date, | 556 | 'time' => $date, |
| 515 | - 'user' => !empty( $user ) ? $user->username : '', | 557 | + 'user' => !empty($user) ? $user->username : '', |
| 516 | ]; | 558 | ]; |
| 517 | } else { | 559 | } else { |
| 518 | return [ | 560 | return [ |
| @@ -540,6 +582,18 @@ | @@ -540,6 +582,18 @@ | ||
| 540 | } | 582 | } |
| 541 | $model->published = true; | 583 | $model->published = true; |
| 542 | $model->save(); | 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 | * @var SmsSender $sender | 598 | * @var SmsSender $sender |
| 545 | */ | 599 | */ |
controllers/StatisticsController.php
| @@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
| 4 | 4 | ||
| 5 | use artweb\artbox\ecommerce\models\Label; | 5 | use artweb\artbox\ecommerce\models\Label; |
| 6 | use artweb\artbox\ecommerce\models\Order; | 6 | use artweb\artbox\ecommerce\models\Order; |
| 7 | + use common\models\User; | ||
| 7 | use yii\data\ActiveDataProvider; | 8 | use yii\data\ActiveDataProvider; |
| 8 | use yii\helpers\ArrayHelper; | 9 | use yii\helpers\ArrayHelper; |
| 9 | use yii\helpers\VarDumper; | 10 | use yii\helpers\VarDumper; |
| @@ -11,7 +12,7 @@ | @@ -11,7 +12,7 @@ | ||
| 11 | 12 | ||
| 12 | class StatisticsController extends Controller | 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 | * Get a dates range | 18 | * Get a dates range |
| @@ -19,21 +20,27 @@ | @@ -19,21 +20,27 @@ | ||
| 19 | if (!empty($date_range)) { | 20 | if (!empty($date_range)) { |
| 20 | $arr = []; | 21 | $arr = []; |
| 21 | preg_match('@(.*)\s:\s(.*)@', $date_range, $arr); | 22 | preg_match('@(.*)\s:\s(.*)@', $date_range, $arr); |
| 22 | - $dateFilter = [ | ||
| 23 | - 'between', | ||
| 24 | - 'created_at', | ||
| 25 | - strtotime($arr[1]), | ||
| 26 | - strtotime($arr[2]), | ||
| 27 | - ]; | 23 | + $dateFilter = [ |
| 24 | + 'between', | ||
| 25 | + 'created_at', | ||
| 26 | + strtotime($arr[ 1 ]), | ||
| 27 | + strtotime($arr[ 2 ]), | ||
| 28 | + ]; | ||
| 28 | } else { | 29 | } else { |
| 29 | $dateFilter = []; | 30 | $dateFilter = []; |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | if (!empty($label)) { | 33 | if (!empty($label)) { |
| 33 | - $labelFilter = ['label' => $label]; | 34 | + $labelFilter = [ 'label' => $label ]; |
| 34 | } else { | 35 | } else { |
| 35 | $labelFilter = []; | 36 | $labelFilter = []; |
| 36 | } | 37 | } |
| 38 | + | ||
| 39 | + if (!empty($manager)) { | ||
| 40 | + $managerFilter = [ 'manager_id' => $manager ]; | ||
| 41 | + } else { | ||
| 42 | + $managerFilter = []; | ||
| 43 | + } | ||
| 37 | 44 | ||
| 38 | /** | 45 | /** |
| 39 | * Get labels | 46 | * Get labels |
| @@ -41,36 +48,137 @@ | @@ -41,36 +48,137 @@ | ||
| 41 | $labels = Label::find() | 48 | $labels = Label::find() |
| 42 | ->with('lang') | 49 | ->with('lang') |
| 43 | ->all(); | 50 | ->all(); |
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Get user | ||
| 54 | + */ | ||
| 55 | + $managers = User::find() | ||
| 56 | + ->all(); | ||
| 44 | 57 | ||
| 45 | /** | 58 | /** |
| 46 | * Generate statistics | 59 | * Generate statistics |
| 47 | */ | 60 | */ |
| 48 | $labelStatistics = ArrayHelper::map( | 61 | $labelStatistics = ArrayHelper::map( |
| 49 | $labels, | 62 | $labels, |
| 50 | - function($model) { | ||
| 51 | - /** | ||
| 52 | - * @var Label $model | ||
| 53 | - */ | 63 | + function(Label $model) { |
| 54 | return $model->lang->title; | 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); | ||
| 68 | + } | ||
| 69 | + ); | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Data provider for table | ||
| 73 | + */ | ||
| 74 | + $dataProvider = new ActiveDataProvider( | ||
| 75 | + [ | ||
| 76 | + 'query' => Order::find() | ||
| 77 | + ->filterWhere($dateFilter) | ||
| 78 | + ->andFilterWhere($managerFilter) | ||
| 79 | + ->andFilterWhere($labelFilter), | ||
| 80 | + ] | ||
| 61 | ); | 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 | + ]; | ||
| 98 | + | ||
| 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), | ||
| 114 | + 'datasets' => [ | ||
| 115 | + [ | ||
| 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, | ||
| 128 | + ], | ||
| 129 | + ], | ||
| 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 | + ]; | ||
| 62 | 152 | ||
| 63 | - $dataProvider = new ActiveDataProvider([ | ||
| 64 | - 'query' => Order::find()->filterWhere($dateFilter)->andFilterWhere($labelFilter), | ||
| 65 | - ]); | 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 | + ]; | ||
| 66 | 165 | ||
| 67 | return $this->render( | 166 | return $this->render( |
| 68 | 'index', | 167 | 'index', |
| 69 | [ | 168 | [ |
| 70 | - 'labels' => $labels, | ||
| 71 | - 'labelStatistics' => $labelStatistics, | ||
| 72 | - 'rejectionStatistics' => Order::getRejectionStatistics($dateFilter), | ||
| 73 | - 'dataProvider' => $dataProvider, | 169 | + 'labels' => $labels, |
| 170 | + 'managers' => $managers, | ||
| 171 | + 'labelStatistics' => $labelStatistics, | ||
| 172 | + 'rejectionStatistics' => $rejectStatistics, | ||
| 173 | + 'dataProvider' => $dataProvider, | ||
| 174 | + 'labelChartData1' => $labelChartData1, | ||
| 175 | + 'labelChartData2' => $labelChartData2, | ||
| 176 | + 'labelChartData3' => $labelChartData3, | ||
| 177 | + 'rejectChartData1' => $rejectChartData1, | ||
| 178 | + 'rejectChartData2' => $rejectChartData2, | ||
| 179 | + 'dateValue' => empty($date_range) ? '' : $date_range, | ||
| 180 | + 'dataLabel' => empty($label) ? false : $label, | ||
| 181 | + 'dataManager' => empty($manager) ? false : $manager, | ||
| 74 | ] | 182 | ] |
| 75 | ); | 183 | ); |
| 76 | } | 184 | } |
models/Basket.php
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | /** | 10 | /** |
| 11 | * Class Basket to work with basket | 11 | * Class Basket to work with basket |
| 12 | * | 12 | * |
| 13 | + * @property bool isCredit | ||
| 13 | * @package artweb\artbox\ecommerce\models | 14 | * @package artweb\artbox\ecommerce\models |
| 14 | */ | 15 | */ |
| 15 | class Basket extends Component | 16 | class Basket extends Component |
| @@ -32,7 +33,7 @@ | @@ -32,7 +33,7 @@ | ||
| 32 | $this->session = \Yii::$app->session; | 33 | $this->session = \Yii::$app->session; |
| 33 | if (!$this->session->has('basket')) { | 34 | if (!$this->session->has('basket')) { |
| 34 | $this->session->set('basket', []); | 35 | $this->session->set('basket', []); |
| 35 | - } elseif(!empty($this->session->get('basket'))) { | 36 | + } elseif (!empty( $this->session->get('basket') )) { |
| 36 | $cookies = \Yii::$app->response->cookies; | 37 | $cookies = \Yii::$app->response->cookies; |
| 37 | $cookies->add( | 38 | $cookies->add( |
| 38 | new Cookie( | 39 | new Cookie( |
| @@ -144,8 +145,9 @@ | @@ -144,8 +145,9 @@ | ||
| 144 | { | 145 | { |
| 145 | $this->session->set('basket', $data); | 146 | $this->session->set('basket', $data); |
| 146 | $cookies = \Yii::$app->response->cookies; | 147 | $cookies = \Yii::$app->response->cookies; |
| 147 | - if(empty($data)) { | 148 | + if (empty( $data )) { |
| 148 | $cookies->remove('basket'); | 149 | $cookies->remove('basket'); |
| 150 | + $cookies->remove('isCredit'); | ||
| 149 | } else { | 151 | } else { |
| 150 | $cookies->add( | 152 | $cookies->add( |
| 151 | new Cookie( | 153 | new Cookie( |
| @@ -247,6 +249,23 @@ | @@ -247,6 +249,23 @@ | ||
| 247 | public function clear() | 249 | public function clear() |
| 248 | { | 250 | { |
| 249 | $this->setData([]); | 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,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 | return $query->one(); | 105 | return $query->one(); |
| 103 | } | 106 | } |
| 104 | } | 107 | } |
models/Order.php
| @@ -8,6 +8,8 @@ | @@ -8,6 +8,8 @@ | ||
| 8 | use yii\behaviors\TimestampBehavior; | 8 | use yii\behaviors\TimestampBehavior; |
| 9 | use yii\db\ActiveRecord; | 9 | use yii\db\ActiveRecord; |
| 10 | use yii\db\Query; | 10 | use yii\db\Query; |
| 11 | + use yii\helpers\Json; | ||
| 12 | + use yii\helpers\VarDumper; | ||
| 11 | 13 | ||
| 12 | /** | 14 | /** |
| 13 | * Class Order | 15 | * Class Order |
| @@ -55,6 +57,12 @@ | @@ -55,6 +57,12 @@ | ||
| 55 | * @property string $city | 57 | * @property string $city |
| 56 | * @property string $deliveryString | 58 | * @property string $deliveryString |
| 57 | * @property boolean $published | 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 | class Order extends ActiveRecord | 67 | class Order extends ActiveRecord |
| 60 | { | 68 | { |
| @@ -92,13 +100,14 @@ | @@ -92,13 +100,14 @@ | ||
| 92 | { | 100 | { |
| 93 | return 'order'; | 101 | return 'order'; |
| 94 | } | 102 | } |
| 95 | - | 103 | + |
| 96 | /** | 104 | /** |
| 97 | - * @param array $where | 105 | + * @param array $date |
| 106 | + * @param array $manager | ||
| 98 | * | 107 | * |
| 99 | * @return array | 108 | * @return array |
| 100 | */ | 109 | */ |
| 101 | - public static function getRejectionStatistics(array $where = []) | 110 | + public static function getRejectionStatistics(array $date = [], array $manager = []) |
| 102 | { | 111 | { |
| 103 | $result = []; | 112 | $result = []; |
| 104 | foreach (self::REASONS as $id => $reason) { | 113 | foreach (self::REASONS as $id => $reason) { |
| @@ -113,12 +122,87 @@ | @@ -113,12 +122,87 @@ | ||
| 113 | [ | 122 | [ |
| 114 | 'reason' => $id, | 123 | 'reason' => $id, |
| 115 | ] | 124 | ] |
| 116 | - )->andFilterWhere($where)->one(); | 125 | + ) |
| 126 | + ->andFilterWhere($date) | ||
| 127 | + ->andFilterWhere($manager) | ||
| 128 | + ->one(); | ||
| 117 | } | 129 | } |
| 118 | 130 | ||
| 119 | return $result; | 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 | public function behaviors() | 206 | public function behaviors() |
| 123 | { | 207 | { |
| 124 | return [ | 208 | return [ |
| @@ -131,6 +215,9 @@ | @@ -131,6 +215,9 @@ | ||
| 131 | ]; | 215 | ]; |
| 132 | } | 216 | } |
| 133 | 217 | ||
| 218 | + /** | ||
| 219 | + * @inheritdoc | ||
| 220 | + */ | ||
| 134 | public function rules() | 221 | public function rules() |
| 135 | { | 222 | { |
| 136 | return [ | 223 | return [ |
| @@ -188,6 +275,21 @@ | @@ -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 | 'deadline', | 293 | 'deadline', |
| 192 | 'name', | 294 | 'name', |
| 193 | 'numbercard', | 295 | 'numbercard', |
| @@ -209,6 +311,49 @@ | @@ -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 | public function afterFind() | 357 | public function afterFind() |
| 213 | { | 358 | { |
| 214 | parent::afterFind(); | 359 | parent::afterFind(); |
| @@ -216,6 +361,9 @@ | @@ -216,6 +361,9 @@ | ||
| 216 | 361 | ||
| 217 | } | 362 | } |
| 218 | 363 | ||
| 364 | + /** | ||
| 365 | + * @inheritdoc | ||
| 366 | + */ | ||
| 219 | public function beforeSave($insert) | 367 | public function beforeSave($insert) |
| 220 | { | 368 | { |
| 221 | if (parent::beforeSave($insert)) { | 369 | if (parent::beforeSave($insert)) { |
| @@ -227,6 +375,9 @@ | @@ -227,6 +375,9 @@ | ||
| 227 | 375 | ||
| 228 | } | 376 | } |
| 229 | 377 | ||
| 378 | + /** | ||
| 379 | + * Convert some date | ||
| 380 | + */ | ||
| 230 | protected function convertDate() | 381 | protected function convertDate() |
| 231 | { | 382 | { |
| 232 | if (!empty($this->deadline)) { | 383 | if (!empty($this->deadline)) { |
| @@ -239,6 +390,9 @@ | @@ -239,6 +390,9 @@ | ||
| 239 | 390 | ||
| 240 | } | 391 | } |
| 241 | 392 | ||
| 393 | + /** | ||
| 394 | + * @inheritdoc | ||
| 395 | + */ | ||
| 242 | public function attributeLabels() | 396 | public function attributeLabels() |
| 243 | { | 397 | { |
| 244 | return [ | 398 | return [ |
| @@ -273,9 +427,14 @@ | @@ -273,9 +427,14 @@ | ||
| 273 | 'shipping_by' => Yii::t('app', 'Отправка за счет'), | 427 | 'shipping_by' => Yii::t('app', 'Отправка за счет'), |
| 274 | 'city' => Yii::t('app', 'Город'), | 428 | 'city' => Yii::t('app', 'Город'), |
| 275 | 'numbercard' => Yii::t('app', '№ карточки'), | 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 | public function getUser() | 438 | public function getUser() |
| 280 | { | 439 | { |
| 281 | return $this->hasOne(Customer::className(), [ 'id' => 'user_id' ]); | 440 | return $this->hasOne(Customer::className(), [ 'id' => 'user_id' ]); |
| @@ -314,6 +473,14 @@ | @@ -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 | * @return string | 484 | * @return string |
| 318 | */ | 485 | */ |
| 319 | public function getDeliveryString() | 486 | public function getDeliveryString() |
| @@ -330,6 +497,14 @@ | @@ -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 | * If deadline is fucked up returns true, | 508 | * If deadline is fucked up returns true, |
| 334 | * if deadline is not setted return false, like everything is ok | 509 | * if deadline is not setted return false, like everything is ok |
| 335 | * | 510 | * |
| @@ -345,13 +520,18 @@ | @@ -345,13 +520,18 @@ | ||
| 345 | } | 520 | } |
| 346 | 521 | ||
| 347 | /** | 522 | /** |
| 348 | - * | 523 | + * @return \yii\db\ActiveQuery |
| 349 | */ | 524 | */ |
| 350 | public function getManager() | 525 | public function getManager() |
| 351 | { | 526 | { |
| 352 | return $this->hasOne(User::className(), [ 'id' => 'manager_id' ]); | 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 | public function isBlocked() | 535 | public function isBlocked() |
| 356 | { | 536 | { |
| 357 | if ($this->edit_id === 0) { | 537 | if ($this->edit_id === 0) { |
| @@ -365,6 +545,9 @@ | @@ -365,6 +545,9 @@ | ||
| 365 | } | 545 | } |
| 366 | } | 546 | } |
| 367 | 547 | ||
| 548 | + /** | ||
| 549 | + * If order products changed recount te total value | ||
| 550 | + */ | ||
| 368 | public function totalRecount() | 551 | public function totalRecount() |
| 369 | { | 552 | { |
| 370 | $products = $this->products; | 553 | $products = $this->products; |
| @@ -379,6 +562,9 @@ | @@ -379,6 +562,9 @@ | ||
| 379 | $this->save(); | 562 | $this->save(); |
| 380 | } | 563 | } |
| 381 | 564 | ||
| 565 | + /** | ||
| 566 | + * If exit unpublished order - delete it | ||
| 567 | + */ | ||
| 382 | public function deleteUnpublished() | 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 | + } |
views/order/_form.php
| @@ -146,8 +146,7 @@ JS; | @@ -146,8 +146,7 @@ JS; | ||
| 146 | 146 | ||
| 147 | <?php $form = ActiveForm::begin( | 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 | <div class="container"> | 152 | <div class="container"> |
| @@ -333,7 +332,10 @@ JS; | @@ -333,7 +332,10 @@ JS; | ||
| 333 | 'id', | 332 | 'id', |
| 334 | 'short' | 333 | 'short' |
| 335 | ), | 334 | ), |
| 336 | - [ 'prompt' => 'Способ оплаты ...' ] | 335 | + [ |
| 336 | + 'prompt' => 'Способ оплаты ...', | ||
| 337 | + 'disabled' => $model->payment == 10 ? 'disabled' : false, | ||
| 338 | + ] | ||
| 337 | ); ?> | 339 | ); ?> |
| 338 | 340 | ||
| 339 | <?= $form->field($model, 'insurance') ?> | 341 | <?= $form->field($model, 'insurance') ?> |
| @@ -368,348 +370,348 @@ JS; | @@ -368,348 +370,348 @@ JS; | ||
| 368 | <br> | 370 | <br> |
| 369 | <br> | 371 | <br> |
| 370 | <div class="container"> | 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 | return ''; | 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 | </div> | 593 | </div> |
| 592 | <div class="container"> | 594 | <div class="container"> |
| 593 | <?php Pjax::begin([ 'id' => 'total-cost' ]); ?> | 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 | <?php Pjax::end(); ?> | 600 | <?php Pjax::end(); ?> |
| 599 | </div> | 601 | </div> |
| 600 | <div class="container"> | 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 | </div> | 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 | </div> | 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 | </div> | 716 | </div> |
| 715 | <br> | 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,7 +347,7 @@ JS; | ||
| 347 | [ | 347 | [ |
| 348 | 'class' => 'yii\grid\ActionColumn', | 348 | 'class' => 'yii\grid\ActionColumn', |
| 349 | 'template' => \Yii::$app->user->identity->isAdmin( | 349 | 'template' => \Yii::$app->user->identity->isAdmin( |
| 350 | - ) ? '{view} {update} {delete}' : '{view} {update}', | 350 | + ) ? '{history} {view} {update} {delete}' : '{view} {update}', |
| 351 | 'buttons' => [ | 351 | 'buttons' => [ |
| 352 | 'update' => function($url, $model) { | 352 | 'update' => function($url, $model) { |
| 353 | return Html::a( | 353 | return Html::a( |
| @@ -359,6 +359,16 @@ JS; | @@ -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,11 +10,15 @@ | ||
| 10 | use yii\helpers\Html; | 10 | use yii\helpers\Html; |
| 11 | use yii\web\View; | 11 | use yii\web\View; |
| 12 | 12 | ||
| 13 | - $this->title = 'Заказ #' . $model->id; | 13 | + $this->title = 'Обновить заказ #' . $model->id; |
| 14 | $this->params[ 'breadcrumbs' ][] = [ | 14 | $this->params[ 'breadcrumbs' ][] = [ |
| 15 | 'url' => yii\helpers\Url::to([ '/ecommerce/order/index' ]), | 15 | 'url' => yii\helpers\Url::to([ '/ecommerce/order/index' ]), |
| 16 | 'label' => \Yii::t('app', 'Заказы'), | 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 | $this->params[ 'breadcrumbs' ][] = $this->title; | 22 | $this->params[ 'breadcrumbs' ][] = $this->title; |
| 19 | 23 | ||
| 20 | $js = ' | 24 | $js = ' |
| @@ -54,7 +58,18 @@ $.ajax({ | @@ -54,7 +58,18 @@ $.ajax({ | ||
| 54 | '; | 58 | '; |
| 55 | 59 | ||
| 56 | $this->registerJs($js, View::POS_READY); | 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 | <div class="order-update"> | 74 | <div class="order-update"> |
| 60 | <div class="container"> | 75 | <div class="container"> |
views/order/view.php
| 1 | <?php | 1 | <?php |
| 2 | 2 | ||
| 3 | use artweb\artbox\ecommerce\models\Order; | 3 | use artweb\artbox\ecommerce\models\Order; |
| 4 | + use common\components\CreditHelper; | ||
| 4 | use kartik\grid\GridView; | 5 | use kartik\grid\GridView; |
| 6 | + use yii\data\ActiveDataProvider; | ||
| 7 | + use yii\grid\SerialColumn; | ||
| 5 | use yii\helpers\Html; | 8 | use yii\helpers\Html; |
| 6 | use yii\web\View; | 9 | use yii\web\View; |
| 7 | use yii\widgets\DetailView; | 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 | $this->title = 'Заказ #' . $model->id; | 20 | $this->title = 'Заказ #' . $model->id; |
| @@ -17,65 +23,184 @@ | @@ -17,65 +23,184 @@ | ||
| 17 | 'url' => [ 'index' ], | 23 | 'url' => [ 'index' ], |
| 18 | ]; | 24 | ]; |
| 19 | $this->params[ 'breadcrumbs' ][] = $this->title; | 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 | <div class="order-view"> | 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 | 'id', | 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 | 'name', | 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 | </div> | 206 | </div> |
views/statistics/index.php
| 1 | <?php | 1 | <?php |
| 2 | use artweb\artbox\ecommerce\models\Label; | 2 | use artweb\artbox\ecommerce\models\Label; |
| 3 | + use artweb\artbox\ecommerce\models\Order; | ||
| 4 | + use artweb\artbox\ecommerce\models\ProductVariant; | ||
| 5 | + use common\models\User; | ||
| 3 | use kartik\daterange\DateRangePicker; | 6 | use kartik\daterange\DateRangePicker; |
| 4 | use kartik\grid\GridView; | 7 | use kartik\grid\GridView; |
| 5 | use kartik\select2\Select2; | 8 | use kartik\select2\Select2; |
| 6 | use yii\data\ActiveDataProvider; | 9 | use yii\data\ActiveDataProvider; |
| 7 | use yii\helpers\ArrayHelper; | 10 | use yii\helpers\ArrayHelper; |
| 8 | use yii\helpers\Html; | 11 | use yii\helpers\Html; |
| 12 | + use yii\helpers\StringHelper; | ||
| 9 | use yii\web\View; | 13 | use yii\web\View; |
| 14 | + use yiier\chartjs\ChartJs; | ||
| 10 | 15 | ||
| 11 | /** | 16 | /** |
| 12 | - * @var View $this | ||
| 13 | - * @var Label[] $labels | ||
| 14 | - * @var array $labelStatistics | ||
| 15 | - * @var array $rejectionStatistics | 17 | + * @var View $this |
| 18 | + * @var Label[] $labels | ||
| 19 | + * @var User[] $managers | ||
| 20 | + * @var array $labelStatistics | ||
| 21 | + * @var array $rejectionStatistics | ||
| 16 | * @var ActiveDataProvider $dataProvider | 22 | * @var ActiveDataProvider $dataProvider |
| 23 | + * @var array $labelChartData1 | ||
| 24 | + * @var array $labelChartData2 | ||
| 25 | + * @var array $labelChartData3 | ||
| 26 | + * @var array $rejectChartData1 | ||
| 27 | + * @var array $rejectChartData2 | ||
| 28 | + * @var string $dateValue | ||
| 29 | + * @var int | boolean $dataLabel | ||
| 30 | + * @var int | boolean $dataManager | ||
| 17 | */ | 31 | */ |
| 32 | + | ||
| 33 | + $js = <<< JS | ||
| 34 | +$('[data-toggle="popover"]').popover(); | ||
| 35 | +JS; | ||
| 36 | + $this->registerJs($js, View::POS_READY); | ||
| 18 | 37 | ||
| 19 | ?> | 38 | ?> |
| 20 | 39 | ||
| 21 | <div class="box box-default"> | 40 | <div class="box box-default"> |
| 22 | <div class="box-header with-border"> | 41 | <div class="box-header with-border"> |
| 23 | - <h3 class="box-title">Collapsable</h3> | 42 | + <h3 class="box-title">Поиск заказов</h3> |
| 24 | <div class="box-tools pull-right"> | 43 | <div class="box-tools pull-right"> |
| 25 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | 44 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
| 26 | </div><!-- /.box-tools --> | 45 | </div><!-- /.box-tools --> |
| @@ -31,10 +50,11 @@ | @@ -31,10 +50,11 @@ | ||
| 31 | 'get' | 50 | 'get' |
| 32 | ) ?> | 51 | ) ?> |
| 33 | <div class="row"> | 52 | <div class="row"> |
| 34 | - <div class="col-md-4"> | 53 | + <div class="col-md-3"> |
| 35 | <?= DateRangePicker::widget( | 54 | <?= DateRangePicker::widget( |
| 36 | [ | 55 | [ |
| 37 | 'name' => 'date_range', | 56 | 'name' => 'date_range', |
| 57 | + 'value' => $dateValue, | ||
| 38 | 'pluginOptions' => [ | 58 | 'pluginOptions' => [ |
| 39 | 'locale' => [ | 59 | 'locale' => [ |
| 40 | 'format' => 'DD-MM-Y', | 60 | 'format' => 'DD-MM-Y', |
| @@ -44,11 +64,12 @@ | @@ -44,11 +64,12 @@ | ||
| 44 | ] | 64 | ] |
| 45 | ) ?> | 65 | ) ?> |
| 46 | </div> | 66 | </div> |
| 47 | - <div class="col-md-6"> | 67 | + <div class="col-md-4"> |
| 48 | <?= Select2::widget( | 68 | <?= Select2::widget( |
| 49 | [ | 69 | [ |
| 50 | - 'name' => 'label', | ||
| 51 | - 'data' => ArrayHelper::map( | 70 | + 'name' => 'label', |
| 71 | + 'value' => $dataLabel, | ||
| 72 | + 'data' => ArrayHelper::map( | ||
| 52 | $labels, | 73 | $labels, |
| 53 | function($model) { | 74 | function($model) { |
| 54 | return $model->id; | 75 | return $model->id; |
| @@ -57,15 +78,41 @@ | @@ -57,15 +78,41 @@ | ||
| 57 | return $model->lang->title; | 78 | return $model->lang->title; |
| 58 | } | 79 | } |
| 59 | ), | 80 | ), |
| 60 | - 'options' => [ | ||
| 61 | - 'placeholder' => 'Все', | 81 | + 'options' => [ |
| 82 | + 'placeholder' => 'Все метки', | ||
| 83 | + ], | ||
| 84 | + 'pluginOptions' => [ | ||
| 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, | ||
| 62 | ], | 109 | ], |
| 63 | ] | 110 | ] |
| 64 | ) ?> | 111 | ) ?> |
| 65 | </div> | 112 | </div> |
| 66 | <div class="col-md-2"> | 113 | <div class="col-md-2"> |
| 67 | <?= Html::submitButton( | 114 | <?= Html::submitButton( |
| 68 | - 'Go', | 115 | + 'Поиск', |
| 69 | [ | 116 | [ |
| 70 | 'class' => 'btn btn-success', | 117 | 'class' => 'btn btn-success', |
| 71 | ] | 118 | ] |
| @@ -78,7 +125,7 @@ | @@ -78,7 +125,7 @@ | ||
| 78 | 125 | ||
| 79 | <div class="box box-default"> | 126 | <div class="box box-default"> |
| 80 | <div class="box-header with-border"> | 127 | <div class="box-header with-border"> |
| 81 | - <h3 class="box-title">Метки, статистика за </h3> | 128 | + <h3 class="box-title">Метки, статистика за <?= empty($dateValue) ? 'всё время' : $dateValue ?></h3> |
| 82 | <div class="box-tools pull-right"> | 129 | <div class="box-tools pull-right"> |
| 83 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | 130 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
| 84 | </div><!-- /.box-tools --> | 131 | </div><!-- /.box-tools --> |
| @@ -93,23 +140,132 @@ | @@ -93,23 +140,132 @@ | ||
| 93 | <td><b>Уникальных товаров, шт.</b></td> | 140 | <td><b>Уникальных товаров, шт.</b></td> |
| 94 | </tr> | 141 | </tr> |
| 95 | <?php | 142 | <?php |
| 143 | + $total_count = 0; | ||
| 144 | + $total_sum = 0; | ||
| 145 | + $total_products = 0; | ||
| 146 | + $total_unique = 0; | ||
| 96 | foreach ($labelStatistics as $name => $statistic) { | 147 | 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 } ?> | 148 | + $total_count += $statistic[ 'count' ]; |
| 149 | + $total_sum += $statistic[ 'sum' ]; | ||
| 150 | + $total_products += $statistic[ 'products' ]; | ||
| 151 | + $total_unique += $statistic[ 'unique' ]; | ||
| 152 | + echo Html::tag( | ||
| 153 | + 'tr', | ||
| 154 | + Html::tag('td', $name) . Html::tag('td', $statistic[ 'count' ]) . Html::tag( | ||
| 155 | + 'td', | ||
| 156 | + $statistic[ 'sum' ] | ||
| 157 | + ) . Html::tag('td', $statistic[ 'products' ]) . Html::tag('td', $statistic[ 'unique' ]) | ||
| 158 | + ); | ||
| 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> | ||
| 106 | </table> | 168 | </table> |
| 107 | </div><!-- /.box-body --> | 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> | ||
| 108 | </div><!-- /.box --> | 264 | </div><!-- /.box --> |
| 109 | 265 | ||
| 110 | <div class="box box-default"> | 266 | <div class="box box-default"> |
| 111 | <div class="box-header with-border"> | 267 | <div class="box-header with-border"> |
| 112 | - <h3 class="box-title">Метки, статистика за </h3> | 268 | + <h3 class="box-title">Причины отказа, статистика за <?= empty($dateValue) ? 'всё время' : $dateValue ?></h3> |
| 113 | <div class="box-tools pull-right"> | 269 | <div class="box-tools pull-right"> |
| 114 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> | 270 | <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button> |
| 115 | </div><!-- /.box-tools --> | 271 | </div><!-- /.box-tools --> |
| @@ -123,24 +279,216 @@ | @@ -123,24 +279,216 @@ | ||
| 123 | </tr> | 279 | </tr> |
| 124 | <?php | 280 | <?php |
| 125 | foreach ($rejectionStatistics as $name => $statistic) { | 281 | 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 } ?> | 282 | + echo Html::tag( |
| 283 | + 'tr', | ||
| 284 | + Html::tag('td', $name) . Html::tag('td', $statistic[ 'count' ]) . Html::tag( | ||
| 285 | + 'td', | ||
| 286 | + $statistic[ 'sum' ] | ||
| 287 | + ) | ||
| 288 | + ); | ||
| 289 | + } | ||
| 290 | + ?> | ||
| 133 | </table> | 291 | </table> |
| 134 | </div><!-- /.box-body --> | 292 | </div><!-- /.box-body --> |
| 135 | -</div><!-- /.box --> | ||
| 136 | 293 | ||
| 137 | -<?=GridView::widget([ | ||
| 138 | - 'dataProvider' => $dataProvider, | ||
| 139 | - 'columns' => [ | ||
| 140 | - 'id', | ||
| 141 | - 'created_at:datetime', | ||
| 142 | - 'name', | ||
| 143 | - 'city', | ||
| 144 | - | 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' => 'Статистика отказов', | ||
| 344 | + ], | ||
| 345 | + 'scales' => [ | ||
| 346 | + 'xAxes' => [ | ||
| 347 | + [ | ||
| 348 | + 'display' => false, | ||
| 349 | + ], | ||
| 350 | + ], | ||
| 145 | ], | 351 | ], |
| 146 | - ])?> | 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 --> |