1
|
|
|
<?php |
2
|
1 |
|
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
3
|
|
|
/********************************************************************************* |
4
|
|
|
* SugarCRM Community Edition is a customer relationship management program developed by |
5
|
|
|
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
6
|
|
|
|
7
|
|
|
* SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
8
|
|
|
* Copyright (C) 2011 - 2014 Salesagility Ltd. |
9
|
|
|
* |
10
|
|
|
* This program is free software; you can redistribute it and/or modify it under |
11
|
|
|
* the terms of the GNU Affero General Public License version 3 as published by the |
12
|
|
|
* Free Software Foundation with the addition of the following permission added |
13
|
|
|
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
14
|
|
|
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
15
|
|
|
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
16
|
|
|
* |
17
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT |
18
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
19
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
20
|
|
|
* details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU Affero General Public License along with |
23
|
|
|
* this program; if not, see http://www.gnu.org/licenses or write to the Free |
24
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
25
|
|
|
* 02110-1301 USA. |
26
|
|
|
* |
27
|
|
|
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
28
|
|
|
* SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
29
|
|
|
* |
30
|
|
|
* The interactive user interfaces in modified source and object code versions |
31
|
|
|
* of this program must display Appropriate Legal Notices, as required under |
32
|
|
|
* Section 5 of the GNU Affero General Public License version 3. |
33
|
|
|
* |
34
|
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
35
|
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by |
36
|
|
|
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
37
|
|
|
* reasonably feasible for technical reasons, the Appropriate Legal Notices must |
38
|
|
|
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
39
|
|
|
********************************************************************************/ |
40
|
|
|
|
41
|
|
|
|
42
|
|
|
|
43
|
|
|
|
44
|
|
|
|
45
|
|
|
|
46
|
1 |
|
$used_aliases = array(); |
47
|
1 |
|
$alias_map = array(); |
48
|
|
|
|
49
|
|
|
class SugarWidgetReportField extends SugarWidgetField |
50
|
|
|
{ |
51
|
|
|
/** |
52
|
|
|
* Layout manager reporter attribute |
53
|
|
|
* @var SugarBean |
54
|
|
|
*/ |
55
|
|
|
protected $reporter; |
56
|
|
|
|
57
|
1 |
|
function __construct(&$layout_manager) { |
58
|
1 |
|
parent::__construct($layout_manager); |
59
|
1 |
|
$this->reporter = $this->layout_manager->getAttribute("reporter"); |
60
|
1 |
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
64
|
|
|
*/ |
65
|
|
|
function SugarWidgetReportField(&$layout_manager){ |
66
|
|
|
$deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
67
|
|
|
if(isset($GLOBALS['log'])) { |
68
|
|
|
$GLOBALS['log']->deprecated($deprecatedMessage); |
69
|
|
|
} |
70
|
|
|
else { |
71
|
|
|
trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
72
|
|
|
} |
73
|
|
|
self::__construct($layout_manager); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
|
77
|
|
|
function getSubClass($layout_def) |
78
|
|
|
{ |
79
|
|
|
if (! empty($layout_def['type'])) |
80
|
|
|
{ |
81
|
|
|
|
82
|
|
|
if ($layout_def['type'] == 'time') { |
83
|
|
|
$layout_def['widget_class'] = 'Fielddate'; |
84
|
|
|
} else { |
85
|
|
|
$layout_def['widget_class'] = 'Field'.$layout_def['type']; |
86
|
|
|
} |
87
|
|
|
return $this->layout_manager->getClassFromWidgetDef($layout_def); |
88
|
|
|
} else { |
89
|
|
|
return $this; |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
|
94
|
|
|
function display($layout_def) |
95
|
|
|
{ |
96
|
|
|
$obj = $this->getSubClass($layout_def); |
97
|
|
|
|
98
|
|
|
$context = $this->layout_manager->getAttribute('context');//_ppd($context); |
99
|
|
|
$func_name = 'display'.$context; |
100
|
|
|
|
101
|
|
|
|
102
|
|
|
if ( ! empty($context) && method_exists($obj,$func_name)) |
103
|
|
|
{ |
104
|
|
|
return $obj->$func_name($layout_def); |
105
|
|
|
} else |
106
|
|
|
{ |
107
|
|
|
return 'display not found:'.$func_name; |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
function _get_column_select_special($layout_def) |
112
|
|
|
{ |
113
|
|
|
$alias = ''; |
114
|
|
|
if ( ! empty($layout_def['table_alias'])) |
115
|
|
|
{ |
116
|
|
|
$alias = $layout_def['table_alias']; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
if ($layout_def['name'] == 'weighted_sum' ) |
120
|
|
|
{ |
121
|
|
|
return sprintf("SUM(%s * %s * 0.01)", $this->reporter->db->convert("$alias.probability","IFNULL", array(0)), |
122
|
|
|
$this->reporter->db->convert("$alias.amount_usdollar","IFNULL", array(0))); |
123
|
|
|
} |
124
|
|
|
if ($layout_def['name'] == 'weighted_amount' ) |
125
|
|
|
{ |
126
|
|
|
return sprintf("AVG(%s * %s * 0.01)", $this->reporter->db->convert("$alias.probability","IFNULL", array(0)), |
127
|
|
|
$this->reporter->db->convert("$alias.amount_usdollar","IFNULL", array(0))); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
1 |
|
function _get_column_select($layout_def) |
132
|
|
|
{ |
133
|
1 |
|
global $reportAlias; |
134
|
1 |
|
if (!isset($reportAlias)) { |
135
|
1 |
|
$reportAlias = array(); |
136
|
|
|
} |
137
|
|
|
|
138
|
1 |
|
if ( ! empty($layout_def['table_alias'])) { |
139
|
1 |
|
$alias = $layout_def['table_alias'].".".$layout_def['name']; |
140
|
|
|
} else if (! empty($layout_def['name'])) { |
141
|
|
|
$alias = $layout_def['name']; |
142
|
|
|
} else { |
143
|
|
|
$alias = "*"; |
144
|
|
|
} |
145
|
|
|
|
146
|
1 |
|
if ( ! empty($layout_def['group_function']) ) |
147
|
|
|
{ |
148
|
|
|
if ($layout_def['name'] == 'weighted_sum' || $layout_def['name'] == 'weighted_amount') |
149
|
|
|
{ |
150
|
|
|
$alias = $this->_get_column_select_special($layout_def); |
151
|
|
|
$reportAlias[$alias] = $layout_def; |
152
|
|
|
return $alias; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
// Use IFNULL only if it's not AVG aggregate |
156
|
|
|
// because it adds NULL rows to the count when it should not, thus getting wrong result |
157
|
|
|
if ($layout_def['group_function'] != 'avg') { |
158
|
|
|
$alias = $this->reporter->db->convert($alias, 'IFNULL', array(0)); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
// for a field with type='currency' conversion of values into a user-preferred currency |
162
|
|
|
if ($layout_def['type'] == 'currency' && strpos($layout_def['name'], '_usdoll') === false) { |
163
|
|
|
$currency = $this->reporter->currency_obj; |
164
|
|
|
$currency_alias = isset($layout_def['currency_alias']) |
165
|
|
|
? $layout_def['currency_alias'] : $currency->table_name; |
166
|
|
|
$query = $this->reporter->db->convert($currency_alias.".conversion_rate", "IFNULL", array(1)); |
167
|
|
|
// We need to use convert() for AVG because of Oracle |
168
|
|
|
if ($layout_def['group_function'] != 'avg') { |
169
|
|
|
$alias = "{$layout_def['group_function']}($alias/{$query})*{$currency->conversion_rate}"; |
170
|
|
|
} else { |
171
|
|
|
$alias = $this->reporter->db->convert("$alias/$query", "AVG") . " * {$currency->conversion_rate}"; |
172
|
|
|
} |
173
|
|
|
} else { |
174
|
|
|
// We need to use convert() for AVG because of Oracle |
175
|
|
|
if ($layout_def['group_function'] != 'avg') { |
176
|
|
|
$alias = "{$layout_def['group_function']}($alias)"; |
177
|
|
|
} else { |
178
|
|
|
$alias = $this->reporter->db->convert($alias, "AVG"); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|
184
|
1 |
|
$reportAlias[$alias] = $layout_def; |
185
|
1 |
|
return $alias; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
function querySelect(&$layout_def) |
189
|
|
|
{ |
190
|
|
|
return $this->_get_column_select($layout_def)." ".$this->_get_column_alias($layout_def)."\n"; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
function queryGroupBy($layout_def) |
194
|
|
|
{ |
195
|
|
|
return $this->_get_column_select($layout_def)." \n"; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
|
199
|
|
|
function queryOrderBy($layout_def) |
200
|
|
|
{ |
201
|
|
|
$field_def = array(); |
202
|
|
|
if(!empty($this->reporter->all_fields[$layout_def['column_key']])) $field_def = $this->reporter->all_fields[$layout_def['column_key']]; |
203
|
|
|
|
204
|
|
|
if (!empty($layout_def['group_function'])) |
205
|
|
|
{ |
206
|
|
|
$order_by = $this->_get_column_alias($layout_def); |
207
|
|
|
} |
208
|
|
|
elseif (!empty($field_def['sort_on'])) |
209
|
|
|
{ |
210
|
|
|
$order_by = $layout_def['table_alias'].".".$field_def['sort_on']; |
211
|
|
|
if(!empty($field_def['sort_on2'])) |
212
|
|
|
$order_by .= ', ' . $layout_def['table_alias'].".".$field_def['sort_on2']; |
213
|
|
|
} |
214
|
|
|
else { |
215
|
|
|
$order_by = $this->_get_column_alias($layout_def)." \n"; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
//use sugar db function convert on order by string to convert to varchar. This is mainly for db's |
219
|
|
|
//that do not allow sorting on clob/text fields |
220
|
|
|
if ($this->reporter->db->isTextType($this->reporter->db->getFieldType($field_def))) { |
221
|
|
|
$order_by = $this->reporter->db->convert($order_by,'text2char', array(10000)); // array(10000) is for db2 only |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
if ( empty($layout_def['sort_dir']) || $layout_def['sort_dir'] == 'a') |
225
|
|
|
{ |
226
|
|
|
return $order_by." ASC"; |
227
|
|
|
} else { |
228
|
|
|
return $order_by." DESC"; |
229
|
|
|
} |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
|
233
|
|
|
function queryFilter($layout_def) |
234
|
|
|
{ |
235
|
|
|
$method_name = "queryFilter".$layout_def['qualifier_name']; |
236
|
|
|
return $this->$method_name($layout_def); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
function displayHeaderCell($layout_def) |
240
|
|
|
{ |
241
|
|
|
global $start_link_wrapper,$end_link_wrapper; |
242
|
|
|
|
243
|
|
|
|
244
|
|
|
// don't show sort links if name isn't defined |
245
|
|
|
$no_sort = $this->layout_manager->getAttribute('no_sort'); |
246
|
|
|
if(empty($layout_def['name']) || ! empty($no_sort) || ! empty($layout_def['no_sort'])) |
247
|
|
|
{ |
248
|
|
|
return $layout_def['label']; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
|
252
|
|
|
|
253
|
|
|
$sort_by =''; |
254
|
|
|
if ( ! empty($layout_def['table_key']) && ! empty($layout_def['name']) ) { |
255
|
|
|
if (! empty($layout_def['group_function']) && $layout_def['group_function'] == 'count') { |
256
|
|
|
$sort_by = $layout_def['table_key'].":".'count'; |
257
|
|
|
} else { |
258
|
|
|
$sort_by = $layout_def['table_key'].":".$layout_def['name']; |
259
|
|
|
if ( ! empty($layout_def['column_function'])) { |
260
|
|
|
$sort_by .= ':'.$layout_def['column_function']; |
261
|
|
|
} else if ( ! empty($layout_def['group_function']) ) { |
262
|
|
|
$sort_by .= ':'.$layout_def['group_function']; |
263
|
|
|
} |
264
|
|
|
} |
265
|
|
|
} else { |
266
|
|
|
return $this->displayHeaderCellPlain($layout_def); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
$start = empty($start_link_wrapper) ? '': $start_link_wrapper; |
270
|
|
|
$end = empty($end_link_wrapper) ? '': $end_link_wrapper; |
271
|
|
|
|
272
|
|
|
// unable to retrieve the vardef here, exclude columns of type clob/text from being sortable |
273
|
|
|
|
274
|
|
|
if(!in_array($layout_def['name'], array('description', 'account_description', 'lead_source_description', 'status_description', 'to_addrs', 'cc_addrs', 'bcc_addrs', 'work_log', 'objective', 'resolution'))) { |
275
|
|
|
$header_cell = "<a class=\"listViewThLinkS1\" href=\"".$start.$sort_by.$end."\">"; |
276
|
|
|
$header_cell .= $this->displayHeaderCellPlain($layout_def); |
277
|
|
|
$objListView = new ListView(); |
278
|
|
|
$header_cell .= $objListView->getArrowUpDownStart(isset($layout_def['sort']) ? $layout_def['sort'] : ''); |
279
|
|
|
$header_cell .= $objListView->getArrowUpDownEnd(isset($layout_def['sort']) ? $layout_def['sort'] : ''); |
280
|
|
|
$header_cell .= "</a>"; |
281
|
|
|
return $header_cell; |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
return $this->displayHeaderCellPlain($layout_def); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
function query($layout_def) |
288
|
|
|
{ |
289
|
|
|
$obj = $this->getSubClass($layout_def); |
290
|
|
|
|
291
|
|
|
$context = $this->layout_manager->getAttribute('context'); |
292
|
|
|
$func_name = 'query'.$context; |
293
|
|
|
|
294
|
|
|
if ( ! empty($context) && method_exists($obj,$func_name)) |
295
|
|
|
{ |
296
|
|
|
return $obj->$func_name($layout_def); |
297
|
|
|
} else |
298
|
|
|
{ |
299
|
|
|
return ''; |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
function _get_column_alias($layout_def) |
304
|
|
|
{ |
305
|
|
|
$alias_arr = array(); |
306
|
|
|
|
307
|
|
|
if (!empty($layout_def['table_key']) && $layout_def['table_key'] == 'self' && !empty($layout_def['name']) && $layout_def['name'] == 'id') |
308
|
|
|
{ |
309
|
|
|
return 'primaryid'; |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
// Bug: 44605 |
313
|
|
|
// this comment is being added to trigger the upgrade package |
314
|
|
|
if ( ! empty($layout_def['group_function']) && $layout_def['group_function']=='count') |
315
|
|
|
{ |
316
|
|
|
return $layout_def['table_alias'] . '__count'; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
if ( ! empty($layout_def['table_alias'])) |
320
|
|
|
{ |
321
|
|
|
array_push($alias_arr,$layout_def['table_alias']); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
if ( ! empty($layout_def['group_function']) && $layout_def['group_function'] != 'weighted_amount' && $layout_def['group_function'] != 'weighted_sum') |
325
|
|
|
{ |
326
|
|
|
array_push($alias_arr,$layout_def['group_function']); |
327
|
|
|
} else if ( ! empty($layout_def['column_function'])) |
328
|
|
|
{ |
329
|
|
|
array_push($alias_arr,$layout_def['column_function']); |
330
|
|
|
} else if ( ! empty($layout_def['qualifier'])) |
331
|
|
|
{ |
332
|
|
|
array_push($alias_arr,$layout_def['qualifier']); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
if ( ! empty($layout_def['name'])) |
336
|
|
|
{ |
337
|
|
|
array_push($alias_arr,$layout_def['name']); |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
global $used_aliases, $alias_map; |
341
|
|
|
|
342
|
|
|
$alias = strtolower(implode("_",$alias_arr)); |
343
|
|
|
|
344
|
|
|
$short_alias = $this->getTruncatedColumnAlias($alias); |
345
|
|
|
|
346
|
|
|
if ( empty($used_aliases[$short_alias])) |
347
|
|
|
{ |
348
|
|
|
$alias_map[$alias] = $short_alias; |
349
|
|
|
$used_aliases[$short_alias] = 1; |
350
|
|
|
return $short_alias; |
351
|
|
|
} else if ( ! empty($alias_map[$alias]) ) |
352
|
|
|
{ |
353
|
|
|
return $alias_map[$alias]; |
354
|
|
|
} else { |
355
|
|
|
$alias_map[$alias] = $short_alias.'_'.$used_aliases[$short_alias]; |
356
|
|
|
$used_aliases[$short_alias]++; |
357
|
|
|
return $alias_map[$alias]; |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
function queryFilterEmpty($layout_def) |
362
|
|
|
{ |
363
|
|
|
$column = $this->_get_column_select($layout_def); |
364
|
|
|
return "($column IS NULL OR $column = ".$this->reporter->db->emptyValue($layout_def['type']).")"; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
function queryFilterIs($layout_def) |
368
|
|
|
{ |
369
|
|
|
return '( '.$this->_get_column_select($layout_def)."='".$GLOBALS['db']->quote($layout_def['input_name0'])."')\n"; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
function queryFilteris_not($layout_def) |
373
|
|
|
{ |
374
|
|
|
return '( '.$this->_get_column_select($layout_def)."<>'".$GLOBALS['db']->quote($layout_def['input_name0'])."')\n"; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
function queryFilterNot_Empty($layout_def) |
378
|
|
|
{ |
379
|
|
|
/** @var $db DBManager */ |
380
|
|
|
$db = $this->reporter->db; |
381
|
|
|
$column = $this->_get_column_select($layout_def); |
382
|
|
|
return "(coalesce(" . $db->convert($column, "length") . ",0) > 0)\n"; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
} |
386
|
|
|
|