ShopPeriodReport   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 102
c 3
b 0
f 0
dl 0
loc 191
rs 9.92
wmc 31

10 Methods

Rating   Name   Duplication   Size   Complexity  
A parameterFields() 0 37 5
A getReportField() 0 13 2
A description() 0 3 1
A formatDateForGrouping() 0 8 2
A canView() 0 6 2
A title() 0 3 1
C query() 0 51 14
A sourceRecords() 0 15 2
A provideI18nEntities() 0 11 1
A fd() 0 3 1
1
<?php
2
3
namespace SilverShop\Reports;
4
5
use SilverShop\Model\Order;
6
use SilverShop\SQLQueryList\SQLQueryList;
7
use SilverStripe\Forms\CheckboxField;
8
use SilverStripe\Forms\DateField;
9
use SilverStripe\Forms\DropdownField;
10
use SilverStripe\Forms\FieldList;
11
use SilverStripe\Forms\GridField\GridFieldConfig;
12
use SilverStripe\Forms\GridField\GridFieldDataColumns;
13
use SilverStripe\Forms\GridField\GridFieldExportButton;
14
use SilverStripe\i18n\i18nEntityProvider;
15
use SilverStripe\ORM\DataObject;
16
use SilverStripe\ORM\DB;
17
use SilverStripe\Reports\Report;
18
use SilverStripe\Security\Member;
19
use SilverStripe\Security\Security;
20
21
/**
22
 * Base class for creating reports that can be filtered to a specific range.
23
 * Record grouping is also supported.
24
 */
25
abstract class ShopPeriodReport extends Report implements i18nEntityProvider
26
{
27
    private static $display_uncategorised_data = false;
28
29
    protected $dataClass = Order::class;
30
31
    protected $periodfield = '"SilverShop_Order"."Created"';
32
33
    protected $grouping = false;
34
35
    protected $pagesize = 30;
36
37
    private static $groupingdateformats = [
38
        'Year' => 'Y',
39
        'Month' => 'Y - F',
40
        'Day' => 'd F Y - l',
41
    ];
42
43
    public function title()
44
    {
45
        return _t(static::class . ".Title", $this->title);
46
    }
47
48
    public function description()
49
    {
50
        return _t(static::class . ".Description", $this->description);
51
    }
52
53
    public function parameterFields()
54
    {
55
        $member = Security::getCurrentUser() ? Security::getCurrentUser() : Member::create();
56
        $dateformat = $member->getDateFormat();
57
        $fields = FieldList::create(
58
            $start = DateField::create('StartPeriod', 'Start Date'),
59
            $end = DateField::create('EndPeriod', 'End Date')
60
        );
61
        if ($this->grouping) {
62
            $fields->push(
63
                DropdownField::create(
64
                    'Grouping',
65
                    'Group By',
66
                    [
67
                        'Year' => 'Year',
68
                        'Month' => 'Month',
69
                        'Day' => 'Day',
70
                    ],
71
                    'Month'
72
                )
73
            );
74
            if (self::config()->display_uncategorised_data) {
75
                $fields->push(
76
                    CheckboxField::create('IncludeUncategorised', 'Include Uncategorised Data')
77
                        ->setDescription('Display data that doesn\'t have a date.')
78
                );
79
            }
80
        }
81
82
        // When using silverware/calendar package, setting the date format breaks the admin interface.  Leave default
83
        // behavior as was, but allow the date format not to be set as a config override
84
        if ($this->config()->get('disable_set_date_format') != true) {
85
            $start->setDateFormat($dateformat);
86
            $end->setDateFormat($dateformat);
87
        }
88
89
        return $fields;
90
    }
91
92
    public function canView($member = null)
93
    {
94
        if (static::class === self::class) {
0 ignored issues
show
introduced by
The condition static::class === self::class is always true.
Loading history...
95
            return false;
96
        }
97
        return parent::canView($member);
98
    }
99
100
    public function getReportField()
101
    {
102
        $field = parent::getReportField();
103
        /**
104
         * @var GridFieldConfig $config
105
         */
106
        $config = $field->getConfig();
107
        if ($dataColumns = $config->getComponentByType(GridFieldDataColumns::class)) {
108
            $config->getComponentByType(GridFieldExportButton::class)
109
                ->setExportColumns($dataColumns->getDisplayFields($field));
0 ignored issues
show
Bug introduced by
The method getDisplayFields() does not exist on SilverStripe\Forms\GridField\GridFieldComponent. It seems like you code against a sub-type of SilverStripe\Forms\GridField\GridFieldComponent such as SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or Symbiote\GridFieldExtens...ridFieldEditableColumns or Symbiote\GridFieldExtens...\GridFieldOrderableRows or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldDataColumns or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or Symbiote\GridFieldExtens...ridFieldEditableColumns or SilverStripe\Forms\GridField\GridFieldDetailForm or Symbiote\GridFieldExtens...\GridFieldOrderableRows or Symbiote\GridFieldExtens...ridFieldEditableColumns. ( Ignorable by Annotation )

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

109
                ->setExportColumns($dataColumns->/** @scrutinizer ignore-call */ getDisplayFields($field));
Loading history...
Bug introduced by
The method setExportColumns() does not exist on SilverStripe\Forms\GridField\GridFieldComponent. It seems like you code against a sub-type of SilverStripe\Forms\GridField\GridFieldComponent such as SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldExportButton or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldExportButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldDetailForm or SilverStripe\Forms\GridField\GridFieldExportButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows. ( Ignorable by Annotation )

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

109
                ->/** @scrutinizer ignore-call */ setExportColumns($dataColumns->getDisplayFields($field));
Loading history...
110
        }
111
112
        return $field;
113
    }
114
115
    public function sourceRecords($params)
116
    {
117
        isset($params['Grouping']) || $params['Grouping'] = 'Month';
118
        $list = SQLQueryList::create($this->query($params));
119
        $grouping = $params['Grouping'];
120
        $self = $this;
121
        $list->setOutputClosure(
122
            function ($row) use ($grouping, $self) {
123
                $row['FilterPeriod'] = $self->formatDateForGrouping($row['FilterPeriod'], $grouping);
124
125
                return new $self->dataClass($row);
126
            }
127
        );
128
129
        return $list;
130
    }
131
132
    public function formatDateForGrouping($date, $grouping)
133
    {
134
        if (!$date) {
135
            return $date;
136
        }
137
        $formats = self::config()->groupingdateformats;
138
        $dformat = $formats[$grouping];
139
        return date($dformat, strtotime($date));
140
    }
141
142
    public function query($params)
143
    {
144
        //convert dates to correct format
145
        $fields = $this->parameterFields();
146
        $fields->setValues($params);
147
        $start = $fields->fieldByName('StartPeriod')->dataValue();
148
        $end = $fields->fieldByName('EndPeriod')->dataValue();
149
        //include the entire end day
150
        if ($end) {
151
            $end = date('Y-m-d', strtotime($end) + 86400);
152
        }
153
        $filterperiod = $this->periodfield;
154
        $query = new ShopReportQuery();
155
        $query->setSelect(['FilterPeriod' => "MIN($filterperiod)"]);
156
157
        $table = DataObject::getSchema()->tableName($this->dataClass);
158
159
        $query->setFrom('"' . $table . '"');
160
161
        if ($start && $end) {
162
            $query->addWhere("$filterperiod BETWEEN '$start' AND '$end'");
163
        } elseif ($start) {
164
            $query->addWhere("$filterperiod > '$start'");
165
        } elseif ($end) {
166
            $query->addWhere("$filterperiod <= '$end'");
167
        }
168
        if ($start || $end || !self::config()->display_uncategorised_data || !isset($params['IncludeUncategorised'])) {
169
            $query->addWhere("$filterperiod IS NOT NULL");
170
        }
171
        if ($this->grouping) {
172
            switch ($params['Grouping']) {
173
                case 'Year':
174
                    $query->addGroupBy($this->fd($filterperiod, '%Y'));
175
                    break;
176
                case 'Month':
177
                default:
178
                    $query->addGroupBy($this->fd($filterperiod, '%Y') . ',' . $this->fd($filterperiod, '%m'));
179
                    break;
180
                case 'Day':
181
                    $query->addGroupBy(
182
                        $this->fd($filterperiod, '%Y') . ',' . $this->fd($filterperiod, '%m') . ',' . $this->fd(
183
                            $filterperiod,
184
                            '%d'
185
                        )
186
                    );
187
                    break;
188
            }
189
        }
190
        $query->setOrderBy('"FilterPeriod"', 'ASC');
191
192
        return $query;
193
    }
194
195
    protected function fd($date, $format)
196
    {
197
        return DB::get_conn()->formattedDatetimeClause($date, $format);
198
    }
199
200
    /**
201
     * Provide translatable entities for this class and all subclasses
202
     *
203
     * @return array
204
     */
205
    public function provideI18nEntities()
206
    {
207
        $cls = static::class;
208
        return [
209
            "{$cls}.Title" => [
210
                $this->title,
211
                "Title for the {$cls} report",
212
            ],
213
            "{$cls}.Description" => [
214
                $this->description,
215
                "Description for the {$cls} report",
216
            ],
217
        ];
218
    }
219
}
220