|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Base class for creating reports that can be filtered to a specific range. |
|
5
|
|
|
* Record grouping is also supported. |
|
6
|
|
|
*/ |
|
7
|
|
|
class ShopPeriodReport extends SS_Report implements i18nEntityProvider |
|
8
|
|
|
{ |
|
9
|
|
|
private static $display_uncategorised_data = false; |
|
10
|
|
|
|
|
11
|
|
|
protected $dataClass = 'Order'; |
|
12
|
|
|
|
|
13
|
|
|
protected $periodfield = "\"Order\".\"Created\""; |
|
14
|
|
|
|
|
15
|
|
|
protected $grouping = false; |
|
16
|
|
|
|
|
17
|
|
|
protected $pagesize = 30; |
|
18
|
|
|
|
|
19
|
|
|
private static $groupingdateformats = array( |
|
20
|
|
|
"Year" => "Y", |
|
21
|
|
|
"Month" => "Y - F", |
|
22
|
|
|
"Day" => "d F Y - l", |
|
23
|
|
|
); |
|
24
|
|
|
|
|
25
|
|
|
public function title() |
|
26
|
|
|
{ |
|
27
|
|
|
return _t($this->class . ".Title", $this->title); |
|
28
|
|
|
} |
|
29
|
|
|
|
|
30
|
|
|
public function description() |
|
31
|
|
|
{ |
|
32
|
|
|
return _t($this->class . ".Description", $this->description); |
|
33
|
|
|
} |
|
34
|
|
|
|
|
35
|
1 |
|
public function parameterFields() |
|
36
|
|
|
{ |
|
37
|
1 |
|
$member = Member::currentUserID() ? Member::currentUser() : Member::create(); |
|
38
|
1 |
|
$dateformat = $member->getDateFormat(); |
|
39
|
1 |
|
$fields = FieldList::create( |
|
40
|
1 |
|
$start = DateField::create("StartPeriod", "Start Date"), |
|
41
|
1 |
|
$end = DateField::create("EndPeriod", "End Date") |
|
42
|
1 |
|
); |
|
43
|
1 |
|
if ($this->grouping) { |
|
44
|
1 |
|
$fields->push( |
|
45
|
1 |
|
DropdownField::create( |
|
46
|
1 |
|
"Grouping", |
|
47
|
1 |
|
"Group By", |
|
48
|
|
|
array( |
|
49
|
1 |
|
"Year" => "Year", |
|
50
|
1 |
|
"Month" => "Month", |
|
51
|
1 |
|
"Day" => "Day", |
|
52
|
1 |
|
), |
|
53
|
|
|
'Month' |
|
54
|
1 |
|
) |
|
55
|
1 |
|
); |
|
56
|
1 |
|
if (self::config()->display_uncategorised_data) { |
|
57
|
|
|
$fields->push( |
|
58
|
|
|
CheckboxField::create("IncludeUncategorised", "Include Uncategorised Data") |
|
59
|
|
|
->setDescription("Display data that doesn't have a date.") |
|
60
|
|
|
); |
|
61
|
|
|
} |
|
62
|
1 |
|
} |
|
63
|
1 |
|
$start->setConfig("dateformat", $dateformat); |
|
64
|
1 |
|
$end->setConfig("dateformat", $dateformat); |
|
65
|
1 |
|
$start->setConfig("showcalendar", true); |
|
66
|
1 |
|
$end->setConfig("showcalendar", true); |
|
67
|
1 |
|
return $fields; |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
public function canView($member = null) |
|
71
|
|
|
{ |
|
72
|
|
|
if (get_class($this) == "ShopPeriodReport") { |
|
73
|
|
|
return false; |
|
74
|
|
|
} |
|
75
|
|
|
return parent::canView($member); |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
public function getReportField() |
|
79
|
|
|
{ |
|
80
|
|
|
$field = parent::getReportField(); |
|
81
|
|
|
$config = $field->getConfig(); |
|
82
|
|
|
$columns = $config->getComponentByType("GridFieldDataColumns") |
|
83
|
|
|
->getDisplayFields($field); |
|
84
|
|
|
$config->getComponentByType('GridFieldExportButton') |
|
85
|
|
|
->setExportColumns($columns); |
|
86
|
|
|
return $field; |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
1 |
|
public function sourceRecords($params) |
|
90
|
|
|
{ |
|
91
|
1 |
|
isset($params['Grouping']) || $params['Grouping'] = "Month"; |
|
92
|
1 |
|
$list = new SQLQueryList($this->query($params)); |
|
93
|
1 |
|
$grouping = $params['Grouping']; |
|
94
|
1 |
|
$self = $this; |
|
95
|
1 |
|
$list->setOutputClosure( |
|
96
|
|
|
function ($row) use ($grouping, $self) { |
|
97
|
1 |
|
$row['FilterPeriod'] = $self->formatDateForGrouping($row['FilterPeriod'], $grouping); |
|
98
|
|
|
|
|
99
|
1 |
|
return new $self->dataClass($row); |
|
100
|
|
|
} |
|
101
|
1 |
|
); |
|
102
|
|
|
|
|
103
|
1 |
|
return $list; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
1 |
|
public function formatDateForGrouping($date, $grouping) |
|
107
|
|
|
{ |
|
108
|
1 |
|
if (!$date) { |
|
109
|
|
|
return $date; |
|
110
|
|
|
} |
|
111
|
1 |
|
$formats = self::config()->groupingdateformats; |
|
112
|
1 |
|
$dformat = $formats[$grouping]; |
|
113
|
1 |
|
return date($dformat, strtotime($date)); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
1 |
|
public function query($params) |
|
|
|
|
|
|
117
|
|
|
{ |
|
118
|
|
|
//convert dates to correct format |
|
119
|
1 |
|
$fields = $this->parameterFields(); |
|
120
|
1 |
|
$fields->setValues($params); |
|
121
|
1 |
|
$start = $fields->fieldByName("StartPeriod")->dataValue(); |
|
122
|
1 |
|
$end = $fields->fieldByName("EndPeriod")->dataValue(); |
|
123
|
|
|
//include the entire end day |
|
124
|
1 |
|
if ($end) { |
|
125
|
1 |
|
$end = date('Y-m-d', strtotime($end) + 86400); |
|
126
|
1 |
|
} |
|
127
|
1 |
|
$filterperiod = $this->periodfield; |
|
128
|
1 |
|
$query = new ShopReport_Query(); |
|
129
|
1 |
|
$query->setSelect(array("FilterPeriod" => "MIN($filterperiod)")); |
|
130
|
|
|
|
|
131
|
1 |
|
$query->setFrom('"' . $this->dataClass . '"'); |
|
132
|
|
|
|
|
133
|
1 |
|
if ($start && $end) { |
|
134
|
1 |
|
$query->addWhere("$filterperiod BETWEEN '$start' AND '$end'"); |
|
135
|
1 |
|
} elseif ($start) { |
|
136
|
|
|
$query->addWhere("$filterperiod > '$start'"); |
|
137
|
1 |
|
} elseif ($end) { |
|
138
|
|
|
$query->addWhere("$filterperiod <= '$end'"); |
|
139
|
|
|
} |
|
140
|
1 |
|
if ($start || $end || !self::config()->display_uncategorised_data || !isset($params['IncludeUncategorised'])) { |
|
141
|
1 |
|
$query->addWhere("$filterperiod IS NOT NULL"); |
|
142
|
1 |
|
} |
|
143
|
1 |
|
if ($this->grouping) { |
|
144
|
1 |
|
switch ($params['Grouping']) { |
|
145
|
1 |
|
case "Year": |
|
146
|
1 |
|
$query->addGroupBy($this->fd($filterperiod, '%Y')); |
|
147
|
1 |
|
break; |
|
148
|
1 |
|
case "Month": |
|
149
|
1 |
|
default: |
|
150
|
1 |
|
$query->addGroupBy($this->fd($filterperiod, '%Y') . "," . $this->fd($filterperiod, '%m')); |
|
151
|
1 |
|
break; |
|
152
|
1 |
|
case "Day": |
|
|
|
|
|
|
153
|
1 |
|
$query->addGroupBy( |
|
154
|
1 |
|
$this->fd($filterperiod, '%Y') . "," . $this->fd($filterperiod, '%m') . "," . $this->fd( |
|
155
|
1 |
|
$filterperiod, |
|
156
|
|
|
'%d' |
|
157
|
1 |
|
) |
|
158
|
1 |
|
); |
|
159
|
1 |
|
break; |
|
160
|
1 |
|
} |
|
161
|
1 |
|
} |
|
162
|
1 |
|
$query->setOrderBy("\"FilterPeriod\"", "ASC"); |
|
163
|
|
|
|
|
164
|
1 |
|
return $query; |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
1 |
|
protected function fd($date, $format) |
|
168
|
|
|
{ |
|
169
|
1 |
|
return DB::getConn()->formattedDatetimeClause($date, $format); |
|
|
|
|
|
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
/** |
|
173
|
|
|
* Provide translatable entities for this class and all subclasses |
|
174
|
|
|
* |
|
175
|
|
|
* @return array |
|
176
|
|
|
*/ |
|
177
|
|
|
public function provideI18nEntities() |
|
178
|
|
|
{ |
|
179
|
|
|
return array( |
|
180
|
|
|
"{$this->class}.Title" => array( |
|
181
|
|
|
$this->title, |
|
182
|
|
|
"Title for the {$this->class} report", |
|
183
|
|
|
), |
|
184
|
|
|
"{$this->class}.Description" => array( |
|
185
|
|
|
$this->description, |
|
186
|
|
|
"Description for the {$this->class} report", |
|
187
|
|
|
), |
|
188
|
|
|
); |
|
189
|
|
|
} |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
class ShopReport_Query extends SQLQuery |
|
|
|
|
|
|
193
|
|
|
{ |
|
194
|
|
|
public function canSortBy($fieldName) |
|
195
|
|
|
{ |
|
196
|
|
|
return true; |
|
197
|
|
|
} |
|
198
|
|
|
} |
|
199
|
|
|
|
A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.
You can also find more information in the “Code” section of your repository.