Skip to content

Commit e1c2f8f

Browse files
committed
Allow reporting by a list of order numbers
fixes #86
1 parent f7c91ed commit e1c2f8f

File tree

12 files changed

+332
-103
lines changed

12 files changed

+332
-103
lines changed

codeception.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
bootstrap: bootstrap.php
12
paths:
23
tests: tests
34
output: tests/_output

console/jobs/CreateReportJob.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class CreateReportJob extends BaseObject implements RetryableJobInterface
4949
*/
5050
public bool $items;
5151

52+
/**
53+
* @var array if set, the report will be generated on order numbers instead of date range.
54+
*/
55+
public array $order_nrs;
56+
5257
/**
5358
* @inheritDoc
5459
*/
@@ -77,8 +82,6 @@ public function isFailed(int $currentAttempt): int
7782
protected function processReport(): string
7883
{
7984
$ordersQuery = \frontend\models\Order::find()
80-
->where(['customer_id' => $this->customer])
81-
->andWhere(['between', 'created_date', $this->start_date, $this->end_date])
8285
->with(
8386
[
8487
'items',
@@ -91,6 +94,14 @@ protected function processReport(): string
9194
)
9295
->orderBy('created_date');
9396

97+
if (is_array($this->order_nrs)) {
98+
$ordersQuery->where(['customer_reference' => $this->order_nrs]);
99+
} else {
100+
$ordersQuery->where(['customer_id' => $this->customer]);
101+
$ordersQuery->andWhere(['between', 'created_date', $this->start_date, $this->end_date])
102+
}
103+
104+
94105
$dir = Yii::getAlias('@console') . '/runtime/reports/';
95106
FileHelper::createDirectory($dir);
96107
$filename = time() . '_' . $this->user_id . "_report.csv";

frontend/controllers/ReportController.php

+16-17
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,36 @@ public function behaviors()
3737
* @return string|void
3838
* @throws \yii\base\InvalidConfigException
3939
*/
40-
public function actionIndex()
40+
public function actionIndex($scenario = null)
4141
{
4242
$model = new ReportForm();
4343

44+
// select model scenario from GET or POST
45+
$model->scenario = ReportForm::SCENARIO_BY_DATE;
46+
$scenario = $this->request->post('scenario', $scenario);
47+
if (in_array($scenario, [ReportForm::SCENARIO_BY_DATE, ReportForm::SCENARIO_BY_ORDER_NR])) {
48+
$model->scenario = $scenario;
49+
}
50+
4451
// Generate Report
45-
if (Yii::$app->request->post()) {
52+
if ($this->request->post()) {
4653
$model->load(Yii::$app->request->post());
47-
// Always set for beginning of day and end of day for query
48-
$model->start_date = Yii::$app->formatter->asDate($model->start_date, 'php:Y-m-d 00:00:00');
49-
$model->end_date = Yii::$app->formatter->asDate($model->end_date, 'php:Y-m-d 23:59:59');
5054

51-
Yii::$app->queue->push(new CreateReportJob([
52-
'customer' => $model->customer,
53-
'user_id' => Yii::$app->user->id,
54-
'user_email' => User::findone(['id' => Yii::$app->user->id])->email,
55-
'start_date' => $model->start_date,
56-
'end_date' => $model->end_date,
57-
'items' => $model->items,
58-
]));
55+
if ($model->validate()) {
56+
57+
$model->pushReportQueueJob();
5958

60-
Yii::$app->getSession()->setFlash('success', 'The report is being generated. Please check your email in a few minutes.');
59+
Yii::$app->getSession()->setFlash('success', 'The report is being generated. Please check your email in a few minutes.');
60+
return $this->redirect(['report/index', 'scenario' => $model->scenario]);
61+
}
6162
}
6263

6364

6465
return $this->render(
6566
'index',
6667
[
6768
'model' => $model,
68-
'customers' => Yii::$app->user->identity->isAdmin
69-
? Customer::getList()
70-
: Yii::$app->user->identity->getCustomerList(),
69+
'customers' => $model->getCustomerList(),
7170
]
7271
);
7372
}

frontend/models/forms/ReportForm.php

+87-7
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace frontend\models\forms;
44

5+
use console\jobs\CreateReportJob;
56
use frontend\models\Customer;
67
use Yii;
8+
use yii\base\InvalidCallException;
79
use yii\base\Model;
810

911
/**
@@ -17,28 +19,106 @@
1719
*/
1820
class ReportForm extends Model
1921
{
22+
public const SCENARIO_BY_DATE = 'date';
23+
public const SCENARIO_BY_ORDER_NR = 'order_nr';
2024

2125
public $start_date;
2226
public $end_date;
2327
public $customer;
2428
public $items = true;
29+
public $order_nrs;
30+
2531

2632
public function rules()
2733
{
2834
return [
29-
[['start_date', 'end_date', 'customer'], 'required'],
30-
[['items'], 'boolean'],
35+
[['start_date', 'end_date', 'customer'], 'default', 'value' => null],
36+
[['start_date', 'end_date', 'customer'], 'required', 'on' => self::SCENARIO_BY_DATE],
37+
38+
['start_date', 'date', 'on' => self::SCENARIO_BY_DATE,
39+
'timestampAttribute' => 'start_date',
40+
// Always set for beginning of day and end of day for query
41+
'timestampAttributeFormat' => 'php:Y-m-d 00:00:00'
42+
],
43+
['end_date', 'date', 'on' => self::SCENARIO_BY_DATE,
44+
'timestampAttribute' => 'end_date',
45+
// Always set for beginning of day and end of day for query
46+
'timestampAttributeFormat' => 'php:Y-m-d 23:59:59'
47+
],
48+
49+
['end_date', 'compare', 'operator' => '>=', 'compareAttribute' => 'start_date', 'on' => self::SCENARIO_BY_DATE, 'enableClientValidation' => false],
50+
3151
[
3252
'customer',
3353
'in',
34-
'range' => array_keys(
35-
Yii::$app->user->identity->isAdmin
36-
? Customer::getList()
37-
: Yii::$app->user->identity->getCustomerList()
38-
),
54+
'range' => array_keys($this->getCustomerList()),
55+
'on' => self::SCENARIO_BY_DATE
3956
],
57+
58+
[['order_nrs'], 'required', 'on' => self::SCENARIO_BY_ORDER_NR],
59+
60+
[['items'], 'boolean'],
4061
];
4162
}
4263

64+
public function attributeLabels()
65+
{
66+
return [
67+
'order_nrs' => 'Order Numbers',
68+
];
69+
}
4370

71+
public function scenarios()
72+
{
73+
return [
74+
self::SCENARIO_BY_DATE => ['start_date', 'end_date', 'customer', 'items'],
75+
self::SCENARIO_BY_ORDER_NR => ['order_nrs', 'items'],
76+
];
77+
}
78+
79+
public function getOrderNrs()
80+
{
81+
return preg_split('~[;,\s]+~', $this->order_nrs, -1, PREG_SPLIT_NO_EMPTY);
82+
}
83+
84+
private $_customerList;
85+
/**
86+
* @return array
87+
*/
88+
public function getCustomerList(): array
89+
{
90+
if ($this->_customerList !== null) {
91+
return $this->_customerList;
92+
}
93+
return $this->_customerList = Yii::$app->user->identity->isAdmin
94+
? Customer::getList()
95+
: Yii::$app->user->identity->getCustomerList();
96+
}
97+
98+
public function pushReportQueueJob()
99+
{
100+
switch ($this->scenario) {
101+
case self::SCENARIO_BY_DATE:
102+
$job = new CreateReportJob([
103+
'customer' => $this->customer,
104+
'start_date' => $this->start_date,
105+
'end_date' => $this->end_date,
106+
'items' => $this->items,
107+
]);
108+
break;
109+
case self::SCENARIO_BY_ORDER_NR:
110+
$job = new CreateReportJob([
111+
'order_nrs' => $this->getOrderNrs(),
112+
'items' => $this->items,
113+
]);
114+
break;
115+
default:
116+
throw new InvalidCallException('Unknown model scenario: ' . $this->scenario);
117+
}
118+
119+
$job->user_id = Yii::$app->user->id;
120+
$job->user_email = Yii::$app->user->identity->email;
121+
122+
Yii::$app->queue->push($job);
123+
}
44124
}

frontend/views/report/_tabDate.php

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
use frontend\assets\DatePickerAsset;
4+
use yii\helpers\Html;
5+
use yii\bootstrap\ActiveForm;
6+
7+
/* @var $this yii\web\View */
8+
/* @var $model \frontend\models\forms\ReportForm */
9+
/* @var $form ActiveForm */
10+
/* @var $customers array of customers */
11+
12+
DatePickerAsset::register($this);
13+
$this->registerJs('
14+
// Datepicker
15+
$(\'.date\').datepicker({
16+
todayBtn : \'linked\',
17+
keyboardNavigation : false,
18+
forceParse : false,
19+
autoclose : true,
20+
format : \'mm/dd/yyyy\',
21+
todayHighlight : true,
22+
});');
23+
?>
24+
25+
<?php $form = ActiveForm::begin(); ?>
26+
27+
<p>
28+
Choose the date range below.
29+
We will generate a CSV file for you after clicking export.
30+
</p>
31+
32+
<?= Html::hiddenInput('scenario', \frontend\models\forms\ReportForm::SCENARIO_BY_DATE) ?>
33+
34+
<?= $form->field($model, 'start_date', [
35+
'inputTemplate' =>
36+
'<div class="input-group date"><span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>{input}</div>',
37+
'inputOptions' => ['autocomplete' => 'off']
38+
])->textInput([
39+
'value' => (isset($model->start_date)) ? Yii::$app->formatter->asDate($model->start_date) : '',
40+
]); ?>
41+
<?= $form->field($model, 'end_date', [
42+
'inputTemplate' =>
43+
'<div class="input-group date"><span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>{input}</div>',
44+
'inputOptions' => ['autocomplete' => 'off']
45+
])->textInput([
46+
'value' => (isset($model->end_date)) ? Yii::$app->formatter->asDate($model->end_date) : '',
47+
]); ?>
48+
<?php echo $form->field($model, 'customer')->dropdownList($customers, ['prompt' => ' Please select']); ?>
49+
50+
<?php echo $form->field($model, 'items')->checkbox(['id' => 'include_items_date'])->label('Include items in report?'); ?>
51+
52+
<div class="form-group">
53+
<?= Html::submitButton('Export', ['class' => 'btn btn-primary']) ?>
54+
</div>
55+
56+
<?php ActiveForm::end(); ?>

frontend/views/report/_tabOrderNr.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use frontend\assets\DatePickerAsset;
4+
use yii\helpers\Html;
5+
use yii\bootstrap\ActiveForm;
6+
7+
/* @var $this yii\web\View */
8+
/* @var $model \frontend\models\forms\ReportForm */
9+
/* @var $form ActiveForm */
10+
11+
?>
12+
13+
<?php $form = ActiveForm::begin(); ?>
14+
15+
<p>
16+
Enter a list of order numbers below.
17+
Order numbers can be separated by <code>,</code>, <code>;</code> or spaces and newlines.<br>
18+
We will generate a CSV file for you after clicking export.
19+
</p>
20+
21+
<?= Html::hiddenInput('scenario', \frontend\models\forms\ReportForm::SCENARIO_BY_ORDER_NR) ?>
22+
23+
<?php echo $form->field($model, 'order_nrs')->textarea(['rows' => 10]) ?>
24+
25+
<?php echo $form->field($model, 'items')->checkbox(['id' => 'include_items_order_nr'])->label('Include items in report?'); ?>
26+
27+
<div class="form-group">
28+
<?= Html::submitButton('Export', ['class' => 'btn btn-primary']) ?>
29+
</div>
30+
31+
<?php ActiveForm::end(); ?>

frontend/views/report/index.php

+20-22
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,29 @@
2525

2626
<div class="body-content">
2727
<h1>Reports</h1>
28-
<p>Choose the date range below. We will generate a CSV file for you after clicking export.</p>
28+
2929
<div class="report-form">
30-
<?php $form = ActiveForm::begin(); ?>
3130

32-
<?= $form->field($model, 'start_date', [
33-
'inputTemplate' =>
34-
'<div class="input-group date"><span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>{input}</div>',
35-
'inputOptions' => ['autocomplete' => 'off']
36-
])->textInput([
37-
'value' => (isset($model->start_date)) ? Yii::$app->formatter->asDate($model->start_date) : '',
38-
]); ?>
39-
<?= $form->field($model, 'end_date', [
40-
'inputTemplate' =>
41-
'<div class="input-group date"><span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>{input}</div>',
42-
'inputOptions' => ['autocomplete' => 'off']
43-
])->textInput([
44-
'value' => (isset($model->end_date)) ? Yii::$app->formatter->asDate($model->end_date) : '',
45-
]); ?>
46-
<?php echo $form->field($model, 'customer')->dropdownList($customers, ['prompt' => ' Please select']); ?>
47-
<?php echo $form->field($model, 'items')->checkbox()->label('Include items in report?'); ?>
31+
<?= \yii\bootstrap\Tabs::widget([
32+
'items' => [
33+
[
34+
'label' => 'By Date',
35+
'content' => $this->render('_tabDate', [
36+
'model' => $model,
37+
'customers' => $customers,
38+
]),
39+
'active' => $model->scenario === \frontend\models\forms\ReportForm::SCENARIO_BY_DATE,
40+
],
41+
[
42+
'label' => 'By Order #',
43+
'content' => $this->render('_tabOrderNr', [
44+
'model' => $model,
45+
]),
46+
'active' => $model->scenario === \frontend\models\forms\ReportForm::SCENARIO_BY_ORDER_NR,
47+
],
4848

49-
<div class="form-group">
50-
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
51-
</div>
52-
<?php ActiveForm::end(); ?>
49+
],
50+
])?>
5351
</div>
5452
</div>
5553
</div>

frontend/web/css/site.css

+16
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,22 @@ ul.auth-clients {
371371
font-size: 16px;
372372
}
373373

374+
.tab-content {
375+
padding: 15px;
376+
border-left: solid 1px #ddd;
377+
border-right: solid 1px #ddd;
378+
border-bottom: solid 1px #ddd;
379+
border-radius: 0 0 4px 4px;
380+
}
381+
382+
#reportform-order_nrs {
383+
min-height: 50px;
384+
min-width: 100%;
385+
max-width: 100%;
386+
resize: vertical;
387+
}
388+
389+
374390
pre {
375391
border: none;
376392
padding: 5px;

tests/bootstrap.php

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
require __DIR__ . '/../vendor/autoload.php';
4+
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
5+
require __DIR__ . '/../common/config/bootstrap.php';

0 commit comments

Comments
 (0)