Completed
Push — master ( f771fd...dd2eec )
by Dmitry
10:15
created

ServerGridView::formatTariff()   B

Complexity

Conditions 11
Paths 36

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 37
ccs 0
cts 35
cp 0
rs 7.3166
c 0
b 0
f 0
cc 11
nc 36
nop 1
crap 132

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Server module for HiPanel
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-module-server
6
 * @package   hipanel-module-server
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\modules\server\grid;
12
13
use hipanel\base\Model;
14
use hipanel\grid\MainColumn;
15
use hipanel\grid\RefColumn;
16
use hipanel\grid\XEditableColumn;
17
use hipanel\helpers\StringHelper;
18
use hipanel\helpers\Url;
19
use hipanel\modules\finance\models\Sale;
20
use hipanel\modules\hosting\controllers\AccountController;
0 ignored issues
show
Bug introduced by
The type hipanel\modules\hosting\...llers\AccountController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use hipanel\modules\hosting\controllers\IpController;
0 ignored issues
show
Bug introduced by
The type hipanel\modules\hosting\controllers\IpController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use hipanel\modules\server\menus\ServerActionsMenu;
23
use hipanel\modules\server\models\Consumption;
24
use hipanel\modules\server\models\Server;
25
use hipanel\modules\server\widgets\DiscountFormatter;
26
use hipanel\modules\server\widgets\Expires;
27
use hipanel\modules\server\widgets\OSFormatter;
28
use hipanel\modules\server\widgets\ResourceConsumptionTable;
29
use hipanel\modules\server\widgets\State;
30
use hipanel\widgets\ArraySpoiler;
31
use hipanel\widgets\gridLegend\ColorizeGrid;
32
use hipanel\widgets\gridLegend\GridLegend;
33
use hipanel\widgets\Label;
34
use hiqdev\yii2\menus\grid\MenuColumn;
35
use Tuck\Sort\Sort;
36
use Yii;
37
use yii\data\ArrayDataProvider;
38
use yii\helpers\ArrayHelper;
39
use yii\helpers\Html;
40
use yii\widgets\ListView;
41
42
class ServerGridView extends \hipanel\grid\BoxedGridView
43
{
44
    use ColorizeGrid;
0 ignored issues
show
introduced by
The trait hipanel\widgets\gridLegend\ColorizeGrid requires some properties which are not provided by hipanel\modules\server\grid\ServerGridView: $controller, $module
Loading history...
45
46
    public $controllerUrl = '@server';
47
48
    /**
49
     * @var array
50
     */
51
    public $osImages;
52
53
    public function init()
54
    {
55
        parent::init();
56
57
        $this->view->registerCss('
58
        .tariff-chain {
59
            list-style: none;
60
            background-color: #f5f5f5;
61
        }
62
        .tariff-chain > li {
63
            display: inline-block;
64
        }
65
        .tariff-chain > li + li:before {
66
            font: normal normal normal 14px/1 FontAwesome;
67
            content: "\f178\00a0";
68
            padding: 0 5px;
69
            color: #ccc;
70
        }
71
        ');
72
    }
73
74
    protected function formatTariff($model)
75
    {
76
        $user = Yii::$app->user;
77
        $models = [];
78
        $html = '';
79
        if ($user->can('support') && isset($model->sales)) {
0 ignored issues
show
Bug introduced by
The method can() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

79
        if ($user->/** @scrutinizer ignore-call */ can('support') && isset($model->sales)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
80
            foreach ($model->sales as $sale) {
81
                $models[] = $sale;
82
            }
83
        }
84
        if ($user->can('plan.manager')) {
85
            if (!empty($model->parent_tariff)) {
86
                $title = $model->parent_tariff;
87
            } else {
88
                $title = $model->tariff;
89
            }
90
91
            $models[] = new Sale(['tariff' => $title, 'tariff_id' => $model->tariff_id]);
92
        } else {
93
            $models[] = new Sale(['tariff' => !empty($model->parent_tariff) ? $model->parent_tariff : $model->tariff]);
94
        }
95
96
        foreach ($models as $model) {
0 ignored issues
show
introduced by
$model is overwriting one of the parameters of this function.
Loading history...
97
            if ($model->tariff) {
98
                $tariff = $model->tariff_id ? Html::a($model->tariff, [
99
                    '@plan/view',
100
                    'id' => $model->tariff_id
101
                ]) : $model->tariff;
102
                $client = $model->seller ? '(' . Html::a($model->seller, [
103
                    '@client/view', 'id' => $model->seller_id
104
                ]) . ')' : '';
105
106
                $html .= Html::tag('li', $tariff . '&nbsp;' . $client);
107
            }
108
        }
109
110
        return Html::tag('ul', $html, ['class' => 'tariff-chain', 'style' => 'margin: 0; padding: 0;']);
111
    }
112
113
    public function columns()
114
    {
115
        $canAdmin = Yii::$app->user->can('admin');
0 ignored issues
show
Unused Code introduced by
The assignment to $canAdmin is dead and can be removed.
Loading history...
Bug introduced by
The method can() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
        /** @scrutinizer ignore-call */ 
116
        $canAdmin = Yii::$app->user->can('admin');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
116
        $canSupport = Yii::$app->user->can('support');
117
118
        return array_merge(parent::columns(), [
119
            'server' => [
120
                'class' => MainColumn::class,
121
                'attribute' => 'name',
122
                'filterAttribute' => 'name_like',
123
                'note' => Yii::$app->user->can('server.set-label') ? 'label' : 'note',
124
                'noteOptions' => [
125
                    'url' => Yii::$app->user->can('server.set-label') ? Url::to('set-label') : (Yii::$app->user->can('server.set-note') ? Url::to('set-note') : ''),
126
                ],
127
                'badges' => function ($model) use ($canSupport) {
128
                    $badges = '';
129
                    if ($canSupport) {
130
                        if ($model->wizzarded) {
131
                            $badges .= Label::widget(['label' => 'W', 'tag' => 'sup', 'color' => 'success']);
132
                        }
133
                    }
134
135
                    return $badges;
136
                },
137
            ],
138
            'dc' => [
139
                'attribute' => 'dc',
140
                'filter' => false,
141
            ],
142
            'state' => [
143
                'class' => RefColumn::class,
144
                'filterOptions' => ['class' => 'narrow-filter'],
145
                'i18nDictionary' => 'hipanel:server',
146
                'format' => 'raw',
147
                'gtype' => 'state,device',
148
                'value' => function ($model) {
149
                    $html = State::widget(compact('model'));
150
                    if ($model->status_time) {
151
                        $html .= ' ' . Html::tag('nobr', Yii::t('hipanel:server', 'since {date}', ['date' => Yii::$app->formatter->asDate($model->status_time)]));
152
                    }
153
154
                    return $html;
155
                },
156
            ],
157
            'panel' => [
158
                'attribute' => 'panel',
159
                'format' => 'html',
160
                'contentOptions' => ['class' => 'text-uppercase'],
161
                'value' => function ($model) use ($canSupport) {
162
                    $value = $model->getPanel() ? Yii::t('hipanel:server:panel', $model->getPanel()) : Yii::t('hipanel:server:panel', 'No control panel');
163
                    if ($canSupport) {
164
                        $value .= $model->wizzarded ? Label::widget([
165
                            'label' => 'W', 'tag' => 'sup', 'color' => 'success',
166
                        ]) : '';
167
                    }
168
169
                    return $value;
170
                },
171
            ],
172
            'os' => [
173
                'attribute' => 'os',
174
                'format' => 'raw',
175
                'value' => function ($model) {
176
                    return OSFormatter::widget([
177
                        'osimages' => $this->osImages,
178
                        'imageName' => $model->osimage,
179
                    ]);
180
                },
181
            ],
182
            'os_and_panel' => [
183
                'attribute' => 'os',
184
                'format' => 'raw',
185
                'value' => function ($model) {
186
                    $html = OSFormatter::widget([
187
                        'osimages' => $this->osImages,
188
                        'imageName' => $model->osimage,
189
                    ]);
190
                    $html .= ' ' . ($model->panel ?: '');
191
192
                    return $html;
193
                },
194
            ],
195
            'discount' => [
196
                'attribute' => 'discount',
197
                'label' => Yii::t('hipanel:server', 'Discount'),
198
                'format' => 'raw',
199
                'headerOptions' => ['style' => 'width: 1em'],
200
                'value' => function ($model) {
201
                    return DiscountFormatter::widget([
202
                        'current' => $model->discounts['fee']['current'],
203
                        'next' => $model->discounts['fee']['next'],
204
                    ]);
205
                },
206
            ],
207
            'expires' => [
208
                'filter' => false,
209
                'format' => 'raw',
210
                'headerOptions' => ['style' => 'width: 1em'],
211
                'value' => function ($model) {
212
                    return Expires::widget(compact('model'));
213
                },
214
            ],
215
            'tariff' => [
216
                'format' => 'raw',
217
                'filterAttribute' => 'tariff_like',
218
                'value' => function ($model) {
219
                    return $this->formatTariff($model);
220
                },
221
            ],
222
            'tariff_and_discount' => [
223
                'attribute' => 'tariff',
224
                'filterAttribute' => 'tariff_like',
225
                'format' => 'raw',
226
                'value' => function ($model) {
227
                    return $this->formatTariff($model) . ' ' . DiscountFormatter::widget([
228
                            'current' => $model->discounts['fee']['current'],
229
                            'next' => $model->discounts['fee']['next'],
230
                        ]);
231
                },
232
            ],
233
            'ip' => [
234
                'filter' => false,
235
            ],
236
            'mac' => [
237
                'filter' => false,
238
            ],
239
            'ips' => [
240
                'format' => 'raw',
241
                'attribute' => 'ips',
242
                'filter' => false,
243
                'contentOptions' => [
244
                    'class' => 'text-center',
245
                    'style' => 'width:1%; white-space:nowrap;',
246
                ],
247
                'value' => function ($model) {
248
                    return ArraySpoiler::widget([
249
                        'data' => ArrayHelper::getColumn($model->ips, 'ip'),
250
                        'delimiter' => '<br />',
251
                        'visibleCount' => 1,
252
                        'formatter' => function ($ip, $idx) use ($model) {
253
                            if ($idx === 0) {
254
                                return Html::a($ip, IpController::getSearchUrl(['server_in' => $model->name]), [
255
                                    'class' => 'text-bold',
256
                                    'target' => '_blank',
257
                                ]);
258
                            }
259
260
                            return $ip;
261
                        },
262
                        'button' => [
263
                            'label' => Yii::t('hipanel:server', '') . ' +' . (count($model->ips) - 1),
264
                            'tag' => 'button',
265
                            'type' => 'button',
266
                            'class' => 'btn btn-xs btn-flat',
267
                            'style' => 'font-size: 10px',
268
                            'popoverOptions' => [
269
                                'html' => true,
270
                                'placement' => 'bottom',
271
                                'title' => Yii::t('hipanel:server', 'IPs'),
272
                                'template' => '
273
                                    <div class="popover" role="tooltip">
274
                                        <div class="arrow"></div>
275
                                        <h3 class="popover-title"></h3>
276
                                        <div class="popover-content" style="min-width: 15rem; height: 15rem; overflow-x: scroll;"></div>
277
                                    </div>
278
                                ',
279
                            ],
280
                        ]
281
                    ]);
282
                },
283
            ],
284
            'sale_time' => [
285
                'attribute' => 'sale_time',
286
                'format' => 'datetime',
287
            ],
288
            'note' => [
289
                'class' => XEditableColumn::class,
290
                'pluginOptions' => [
291
                    'url' => Url::to('set-note'),
292
                ],
293
                'widgetOptions' => [
294
                    'linkOptions' => [
295
                        'data-type' => 'textarea',
296
                    ],
297
                ],
298
                'visible' => Yii::$app->user->can('server.set-note'),
299
            ],
300
            'label' => [
301
                'class' => XEditableColumn::class,
302
                'pluginOptions' => [
303
                    'url' => Url::to('set-label'),
304
                ],
305
                'widgetOptions' => [
306
                    'linkOptions' => [
307
                        'data-type' => 'textarea',
308
                    ],
309
                ],
310
                'visible' => Yii::$app->user->can('server.set-label'),
311
            ],
312
            'type' => [
313
                'format' => 'html',
314
                'filter' => false,
315
                'value' => function ($model) {
316
                    return Html::tag('span', $model->type_label, ['class' => 'label label-default']);
317
                },
318
            ],
319
            'detailed_type' => [
320
                'label' => Yii::t('hipanel', 'Type'),
321
                'format' => 'html',
322
                'filter' => false,
323
                'value' => function ($model) {
324
                    return Html::tag('span', $model->type_label, ['class' => 'label label-default']);
325
                },
326
                'contentOptions' => function ($model) {
327
                    return GridLegend::create($this->findOrFailGridLegend($model))->gridColumnOptions('actions');
328
                },
329
            ],
330
            'rack' => [
331
                'class' => BindingColumn::class,
332
            ],
333
            'net' => [
334
                'class' => BindingColumn::class,
335
            ],
336
            'kvm' => [
337
                'class' => BindingColumn::class,
338
            ],
339
            'pdu' => [
340
                'class' => BindingColumn::class,
341
            ],
342
            'ipmi' => [
343
                'class' => BindingColumn::class,
344
            ],
345
            'nums' => [
346
                'label' => '',
347
                'format' => 'raw',
348
                'value' => function ($model) {
349
                    $ips_num = $model->ips_num;
350
                    $ips = $ips_num ? Html::a("$ips_num ips", IpController::getSearchUrl(['server' => $model->name])) : 'no ips';
351
                    $act_acs_num = $model->acs_num - $model->del_acs_num;
352
                    $del_acs_num = $model->del_acs_num;
353
                    $acs_num = $act_acs_num . ($del_acs_num ? "+$del_acs_num" : '');
354
                    $acs = $acs_num ? Html::a("$acs_num acc", AccountController::getSearchUrl(['server' => $model->name])) : 'no acc';
355
356
                    return Html::tag('nobr', $ips) . ' ' . Html::tag('nobr', $acs);
357
                },
358
            ],
359
            'monthly_fee' => [
360
                'label' => Yii::t('hipanel:finance', 'Monthly fee'),
361
                'format' => 'html',
362
                'filter' => false,
363
                'value' => function ($model) {
364
                    return $this->getMonthlyFee($model);
365
                },
366
                'visible' => Yii::$app->user->can('consumption.read'),
367
            ],
368
            'traffic' => [
369
                'label' => Yii::t('hipanel:server', 'Traffic'),
370
                'format' => 'html',
371
                'filter' => false,
372
                'value' => function ($model) {
373
                    return isset($model->consumptions['overuse,server_traf_max']) ? $this->getFormattedConsumptionFor($model->consumptions['overuse,server_traf_max']) : null;
374
                },
375
                'visible' => Yii::$app->user->can('consumption.read'),
376
            ],
377
            'additional_services' => [
378
                'label' => Yii::t('hipanel:server', 'Additional services'),
379
                'format' => 'raw',
380
                'filter' => false,
381
                'contentOptions' => ['class' => 'no-padding'],
382
                'value' => function ($model) {
383
                    return $this->getAdditionalServices($model);
384
                },
385
                'visible' => Yii::$app->user->can('consumption.read'),
386
            ],
387
            'type_of_sale' => [
388
                'label' => Yii::t('hipanel:server', 'Type of sale'),
389
                'format' => 'raw',
390
                'filter' => false,
391
                'value' => function (Server $model) {
392
                    return $this->getTypeOfSale($model);
393
                },
394
                'visible' => Yii::$app->user->can('consumption.read'),
395
            ],
396
            'actions' => [
397
                'class' => MenuColumn::class,
398
                'menuClass' => ServerActionsMenu::class,
399
                'contentOptions' => [
400
                    'class' => 'text-center',
401
                    'style' => 'width:1%; white-space:nowrap;',
402
                ],
403
            ],
404
        ]);
405
    }
406
407
    private function getFormattedConsumptionFor(Consumption $consumption): string
408
    {
409
        $result = '';
410
        $widget = Yii::createObject(['class' => ResourceConsumptionTable::class, 'model' => $consumption]);
411
412
        if ($limit = $widget->getFormatted($consumption, $consumption->limit)) {
0 ignored issues
show
Bug Best Practice introduced by
The property limit does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
413
            $result .= sprintf('%s: %s<br />',
414
                Html::tag('b', Yii::t('hipanel:server', 'included')),
415
                $limit
416
            );
417
        }
418
        if ($price = $consumption->getFormattedPrice()) {
419
            $result .= sprintf('%s: %s',
420
                Html::tag('b', Yii::t('hipanel:server', 'price')),
421
                $price
422
            );
423
        }
424
425
        return $result;
426
    }
427
428
    private function getMonthlyFee($model): string
429
    {
430
        $unionConsumption = new Consumption();
431
        $prices = [];
432
        if ($model->consumptions) {
433
            array_walk($model->consumptions, function (Consumption $consumption) use (&$prices) {
434
                if ($consumption->type && $consumption->hasFormattedAttributes() && StringHelper::startsWith($consumption->type, 'monthly,')) {
435
                    if ($consumption->price) {
0 ignored issues
show
Bug Best Practice introduced by
The property price does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
436
                        $consumption->setAttribute('prices', [$consumption->currency => $consumption->price]);
0 ignored issues
show
Bug Best Practice introduced by
The property currency does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
437
                    }
438
                    foreach ($consumption->prices as $currency => $price) {
0 ignored issues
show
Bug Best Practice introduced by
The property prices does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
439
                        $prices[$currency] += $price;
440
                    }
441
                }
442
            });
443
        }
444
        $unionConsumption->setAttribute('prices', $prices);
445
446
        return $unionConsumption->getFormattedPrice();
447
    }
448
449
    private function getAdditionalServices($model): string
450
    {
451
        $additional = new class() extends Model
452
        {
453
            /**
454
             * @var string
455
             */
456
            public $typeLabel;
457
458
            /**
459
             * @var string
460
             */
461
            public $value;
462
        };
463
        $models = [];
464
        foreach (['overuse,support_time', 'overuse,backup_du', 'monthly,win_license'] as $type) {
465
            if (isset($model->consumptions[$type]) && $model->consumptions[$type]->hasFormattedAttributes()) {
466
                $consumption = $model->consumptions[$type];
467
                $models[] = new $additional([
468
                    'typeLabel' => Yii::t('hipanel.server.consumption.type', $consumption->typeLabel),
469
                    'value' => $this->getFormattedConsumptionFor($consumption),
470
                ]);
471
            }
472
        }
473
474
        return \yii\grid\GridView::widget([
475
            'layout' => '{items}',
476
            'showOnEmpty' => false,
477
            'emptyText' => '',
478
            'tableOptions' => ['class' => 'table table-striped table-condensed'],
479
            'headerRowOptions' => [
480
                'style' => 'display: none;',
481
            ],
482
            'dataProvider' => new ArrayDataProvider(['allModels' => $models, 'pagination' => false]),
483
            'columns' => [
484
                [
485
                    'attribute' => 'typeLabel',
486
                ],
487
                [
488
                    'attribute' => 'value',
489
                    'format' => 'html',
490
                ],
491
            ],
492
        ]);
493
    }
494
495
    private function getTypeOfSale($model): string
496
    {
497
        $html = '';
498
        $badgeColors = [
499
            'leasing' => 'bg-orange',
500
            'rent' => 'bg-purple',
501
            'sold' => 'bg-olive',
502
        ];
503
504
        if (empty($model->hardwareSales)) {
505
            return $html;
506
        }
507
508
        foreach ($model->hardwareSales as $saleType => $sales) {
509
            $html .= ArraySpoiler::widget([
510
                'data' => Sort::by($sales, function ($sale) {
511
                    $order = ['CHASSIS', 'MOTHERBOARD', 'CPU', 'RAM', 'HDD', 'SSD'];
512
                    $type = substr($sale['part'], 0, strpos($sale['part'], ':'));
513
                    $key = array_search($type, $order, true);
514
                    if ($key !== false) {
515
                        return $key;
516
                    }
517
518
                    return INF;
519
                }),
520
                'delimiter' => '<br/>',
521
                'visibleCount' => 0,
522
                'button' => [
523
                    'label' => (function() use ($saleType, $sales) {
524
                        if ($saleType === 'leasing') {
525
                            /** @var \DateTime $maxLeasingDate */
526
                            $maxLeasingDate = array_reduce($sales, function (\DateTime $max, $item) {
527
                                $date = new \DateTime($item['leasing_till']);
528
                                return $date > $max ? $date : $max;
529
                            }, new \DateTime());
530
531
                            return Yii::t('hipanel:server', $saleType) . ' ' . \count($sales)
532
                                . '<br />' . $maxLeasingDate->format('d.m.Y');
533
                        }
534
535
                        return Yii::t('hipanel:server', $saleType) . ' ' . \count($sales);
536
                    })(),
537
                    'tag' => 'button',
538
                    'type' => 'button',
539
                    'class' => "btn btn-xs {$badgeColors[$saleType]}",
540
                    'popoverOptions' => [
541
                        'html' => true,
542
                        'placement' => 'bottom',
543
                        'title' => Yii::t('hipanel:stock', 'Parts'),
544
                        'template' => '
545
                            <div class="popover" role="tooltip">
546
                                <div class="arrow"></div>
547
                                <h3 class="popover-title"></h3>
548
                                <div class="popover-content" style="height: 25rem; overflow-x: scroll;"></div>
549
                            </div>
550
                        ',
551
552
                    ],
553
                ],
554
                'formatter' => function ($item) {
555
                    $additionalInfo = null;
556
                    $title = $item['part'];
557
                    if (isset($item['serialno'])) {
558
                        $title .= ': ' .$item['serialno'];
559
                    }
560
561
                    if (isset($item['leasing_till'])) {
562
                        $additionalInfo = Yii::t('hipanel:server', '{since} &mdash; {till}', [
563
                            'since' => Yii::$app->formatter->asDate($item['leasing_since'], 'short'),
564
                            'till' => Yii::$app->formatter->asDate($item['leasing_till'], 'short'),
565
                        ]);
566
                    }
567
568
                    if (isset($item['sale_time'])) {
569
                        $additionalInfo = Yii::t('hipanel:server', 'since {date}', [
570
                            'date' => Yii::$app->formatter->asDate($item['sale_time'], 'short'),
571
                        ]);
572
                    }
573
574
                    return Html::a(
575
                        $title,
576
                        ['@part/view', 'id' => $item['part_id']],
577
                        ['class' => 'text-nowrap', 'target' => '_blank']
578
                    ) . ($additionalInfo ? " ($additionalInfo)" : '');
579
                },
580
            ]);
581
        }
582
583
        return $html;
584
    }
585
}
586