Merge pull request #6058 from monishdeb/CRM-16575
[civicrm-core.git] / CRM / Report / Form / Contribute / Recur.php
CommitLineData
c1413e28
DG
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
c1413e28 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
c1413e28
DG
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
c1413e28
DG
27
28/**
29 *
30 * @package CRM
e7112fa7 31 * @copyright CiviCRM LLC (c) 2004-2015
c1413e28
DG
32 * $Id$
33 *
34 */
35class CRM_Report_Form_Contribute_Recur extends CRM_Report_Form {
36
ced9bfed
EM
37 /**
38 * Class constructor.
39 */
00be9182 40 public function __construct() {
c1413e28
DG
41 $this->_columns = array(
42 'civicrm_contact' => array(
43 'dao' => 'CRM_Contact_DAO_Contact',
44 'order_bys' => array(
45 'sort_name' => array(
46 'title' => ts("Last name, First name"),
47 ),
48 ),
49 'fields' => array(
50 'sort_name' => array(
51 'title' => ts('Contact Name'),
52 'no_repeat' => TRUE,
53 'default' => TRUE,
54 ),
55 'id' => array(
56 'no_display' => TRUE,
57 'required' => TRUE,
58 ),
59 ),
60 ),
61 'civicrm_email' => array(
62 'dao' => 'CRM_Core_DAO_Email',
63 'fields' => array(
64 'email' => array(
65 'title' => ts('Email'),
66 'no_repeat' => TRUE,
67 ),
68 ),
69 'grouping' => 'contact-fields',
70 ),
71 'civicrm_phone' => array(
72 'dao' => 'CRM_Core_DAO_Phone',
73 'fields' => array(
74 'phone' => array(
75 'title' => ts('Phone'),
76 'no_repeat' => TRUE,
77 ),
78 ),
79 'grouping' => 'contact-fields',
80 ),
81 'civicrm_contribution' => array(
82 'dao' => 'CRM_Contribute_DAO_Contribution',
83 'fields' => array(
84 'id' => array(
85 'no_display' => TRUE,
86 'required' => TRUE,
87 ),
88 'total_amount' => array(
89 'title' => ts('Amount Contributed to Date'),
90 'statistics' => array(
21dfd5f5 91 'sum' => ts("Total Amount Contributed"),
c1413e28
DG
92 ),
93 ),
94 ),
95 ),
96 'civicrm_contribution_recur' => array(
97 'dao' => 'CRM_Contribute_DAO_ContributionRecur',
98 'fields' => array(
99 'id' => array(
100 'no_display' => TRUE,
101 'required' => TRUE,
102 ),
103 'currency' => array(
104 'title' => ts("Currency"),
105 'required' => TRUE,
106 'no_display' => TRUE,
107 ),
108 'amount' => array(
109 'title' => ts('Amount'),
110 'default' => TRUE,
111 ),
112 'contribution_status_id' => array(
be205937 113 'title' => ts('Contribution Status'),
c1413e28
DG
114 ),
115 'frequency_interval' => array(
116 'title' => ts('Frequency interval'),
117 'default' => TRUE,
118 ),
119 'frequency_unit' => array(
120 'title' => ts('Frequency unit'),
121 'default' => TRUE,
122 ),
123 'installments' => array(
124 'title' => ts('Installments'),
125 'default' => TRUE,
126 ),
127 'start_date' => array(
128 'title' => ts('Start Date'),
129 ),
130 'create_date' => array(
131 'title' => ts('Create Date'),
132 ),
133 'modified_date' => array(
134 'title' => ts('Modified Date'),
135 ),
136 'cancel_date' => array(
137 'title' => ts('Cancel Date'),
138 ),
139 'end_date' => array(
140 'title' => ts('End Date'),
141 ),
142 'next_sched_contribution_date' => array(
143 'title' => ts('Next Scheduled Contribution Date'),
144 ),
145 'failure_count' => array(
146 'title' => ts('Failure Count'),
147 ),
148 'failure_retry_date' => array(
149 'title' => ts('Failure Retry Date'),
150 ),
151 ),
152 'filters' => array(
153 'contribution_status_id' => array(
be205937 154 'title' => ts('Contribution Status'),
c1413e28
DG
155 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
156 'options' => CRM_Contribute_PseudoConstant::contributionStatus(),
157 'default' => array(5),
158 'type' => CRM_Utils_Type::T_INT,
159 ),
160 'currency' => array(
161 'title' => 'Currency',
162 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
163 'options' => CRM_Core_OptionGroup::values('currencies_enabled'),
164 'default' => NULL,
165 'type' => CRM_Utils_Type::T_STRING,
166 ),
167 'financial_type_id' => array(
168 'title' => ts('Financial Type'),
169 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
353ffa53 170 'options' => CRM_Contribute_PseudoConstant::financialType(),
c1413e28
DG
171 'type' => CRM_Utils_Type::T_INT,
172 ),
173 'frequency_unit' => array(
174 'title' => ts('Frequency Unit'),
175 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
84178120 176 'options' => CRM_Core_OptionGroup::values('recur_frequency_units'),
c1413e28
DG
177 'type' => CRM_Utils_Type::T_INT,
178 ),
179 'frequency_interval' => array(
180 'title' => ts('Frequency Interval'),
181 'type' => CRM_Utils_Type::T_INT,
182 ),
183 'installments' => array(
184 'title' => ts('Installments'),
185 'type' => CRM_Utils_Type::T_INT,
186 ),
187 'start_date' => array(
188 'title' => ts('Start Date'),
189 'operatorType' => CRM_Report_Form::OP_DATE,
190 'type' => CRM_Utils_Type::T_TIME,
191 ),
192 'next_sched_contribution_date' => array(
193 'title' => ts('Next Scheduled Contribution Date'),
194 'operatorType' => CRM_Report_Form::OP_DATE,
195 'type' => CRM_Utils_Type::T_TIME,
196 ),
197 'end_date' => array(
198 'title' => ts('End Date'),
199 'operatorType' => CRM_Report_Form::OP_DATE,
200 'type' => CRM_Utils_Type::T_TIME,
201 ),
202 'calculated_end_date' => array(
203 'title' => ts('Calculated end date (either end date or date all installments will be made)'),
204 'description' => "does this work?",
205 'operatorType' => CRM_Report_Form::OP_DATE,
21dfd5f5 206 'pseudofield' => TRUE,
c1413e28
DG
207 ),
208 ),
21dfd5f5 209 ),
c1413e28
DG
210 );
211 $this->_currencyColumn = 'civicrm_contribution_recur_currency';
212 parent::__construct();
213 }
353ffa53 214
ced9bfed
EM
215 /**
216 * Get template file name.
217 *
218 * @return string
219 */
00be9182 220 public function getTemplateName() {
84178120 221 return 'CRM/Report/Form.tpl';
c1413e28
DG
222 }
223
ced9bfed
EM
224 /**
225 * Generate FROM SQL clause.
226 */
00be9182 227 public function from() {
c1413e28
DG
228 $this->_from = "
229 FROM civicrm_contact {$this->_aliases['civicrm_contact']}
230 INNER JOIN civicrm_contribution_recur {$this->_aliases['civicrm_contribution_recur']}
231 ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_contribution_recur']}.contact_id";
232 $this->_from .= "
233 LEFT JOIN civicrm_contribution {$this->_aliases['civicrm_contribution']}
234 ON {$this->_aliases['civicrm_contribution_recur']}.id = {$this->_aliases['civicrm_contribution']}.contribution_recur_id";
235 $this->_from .= "
236 LEFT JOIN civicrm_email {$this->_aliases['civicrm_email']}
14e99c8f
KG
237 ON ({$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_email']}.contact_id AND
238 {$this->_aliases['civicrm_email']}.is_primary = 1)";
c1413e28
DG
239 $this->_from .= "
240 LEFT JOIN civicrm_phone {$this->_aliases['civicrm_phone']}
241 ON ({$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_phone']}.contact_id AND
14e99c8f 242 {$this->_aliases['civicrm_phone']}.is_primary = 1)";
c1413e28
DG
243 }
244
00be9182 245 public function groupBy() {
c1413e28
DG
246 $this->_groupBy = "GROUP BY " . $this->_aliases['civicrm_contribution_recur'] . ".id";
247 }
248
00be9182 249 public function where() {
c1413e28
DG
250 parent::where();
251 // Handle calculated end date. This can come from one of two sources:
252 // Either there is a specified end date for the end_date field
253 // Or, we calculate the end date based on the start date +
254 // installments * intervals using the mysql date_add function, along
255 // with the interval unit (e.g. DATE_ADD(start_date, INTERVAL 12 * 1 MONTH)
256 $date_suffixes = array('relative', 'from', 'to');
22e263ad 257 while (list(, $suffix) = each($date_suffixes)) {
c1413e28 258 // Check to see if the user wants to search by calculated date.
22e263ad 259 if (!empty($this->_params['calculated_end_date_' . $suffix])) {
c1413e28
DG
260 // The calculated date field is in use - spring into action
261 // Gather values
262 $relative = CRM_Utils_Array::value("calculated_end_date_relative", $this->_params);
263 $from = CRM_Utils_Array::value("calculated_end_date_from", $this->_params);
264 $to = CRM_Utils_Array::value("calculated_end_date_to", $this->_params);
265 $end_date_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['end_date']['dbAlias'];
266 $end_date_type = $this->_columns['civicrm_contribution_recur']['filters']['end_date']['type'];
267 $start_date_type = $this->_columns['civicrm_contribution_recur']['filters']['start_date']['type'];
268 $frequency_unit_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['frequency_unit']['dbAlias'];
269 $frequency_interval_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['frequency_interval']['dbAlias'];
270 $installments_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['installments']['dbAlias'];
271 $start_date_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['start_date']['dbAlias'];
272
273 // The end date clause is simple to construct
353ffa53 274 $end_date_clause = $this->dateClause($end_date_db_alias, $relative, $from, $to, $end_date_type, NULL, NULL);
c1413e28
DG
275
276 // NOTE: For the calculation based on installment, there doesn't
277 // seem to be a way to include the interval unit (e.g. month,
278 // date, etc) as a field name - so we have to build a complex
279 // OR statement instead.
280
281 $installment_clause = '(' .
282 $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias,1) month)",
353ffa53 283 $relative, $from, $to, $start_date_type, NULL, NULL);
c1413e28
DG
284 $installment_clause .= " AND $frequency_unit_db_alias = 'month' ) OR \n";
285
286 $installment_clause .= '(' .
287 $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias,1) day)",
353ffa53 288 $relative, $from, $to, $start_date_type, NULL, NULL);
c1413e28
DG
289 $installment_clause .= " AND $frequency_unit_db_alias = 'day' ) OR \n";
290
291 $installment_clause .= '(' .
292 $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias, 1) week)",
353ffa53 293 $relative, $from, $to, $start_date_type, NULL, NULL);
c1413e28
DG
294 $installment_clause .= " AND $frequency_unit_db_alias = 'week' ) OR \n";
295
296 $installment_clause .= '(' .
297 $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias, 1) year)",
353ffa53 298 $relative, $from, $to, $start_date_type, NULL, NULL);
c1413e28
DG
299 $installment_clause .= " AND $frequency_unit_db_alias = 'year' )\n";
300
301 $this->_where .= " AND ";
302 $this->_where .= "(";
303 $this->_where .= "($end_date_db_alias IS NOT NULL AND $end_date_clause)\n";
304 $this->_where .= " OR \n";
305 $this->_where .= "($installments_db_alias IS NOT NULL AND ($installment_clause))\n";
306 $this->_where .= ')';
307 break;
308 }
309 }
310 }
311
312
ced9bfed
EM
313 /**
314 * Alter display of rows.
315 *
316 * Iterate through the rows retrieved via SQL and make changes for display purposes,
317 * such as rendering contacts as links.
318 *
319 * @param array $rows
320 * Rows generated by SQL, with an array for each row.
321 */
00be9182 322 public function alterDisplay(&$rows) {
c1413e28
DG
323 $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus();
324 foreach ($rows as $rowNum => $row) {
325 // convert display name to links
326 if (array_key_exists('civicrm_contact_sort_name', $row) &&
327 CRM_Utils_Array::value('civicrm_contact_sort_name', $rows[$rowNum]) &&
328 array_key_exists('civicrm_contact_id', $row)
329 ) {
330 $url = CRM_Utils_System::url('civicrm/contact/view',
331 'reset=1&cid=' . $row['civicrm_contact_id'],
332 $this->_absoluteUrl
333 );
334 $rows[$rowNum]['civicrm_contact_sort_name_link'] = $url;
335 $rows[$rowNum]['civicrm_contact_sort_name_hover'] = ts('View Contact Summary for this Contact.');
336 }
337
338 // handle contribution status id
339 if ($value = CRM_Utils_Array::value('civicrm_contribution_recur_contribution_status_id', $row)) {
340 $rows[$rowNum]['civicrm_contribution_recur_contribution_status_id'] = $contributionStatus[$value];
341 }
84178120 342
c1413e28 343 if ($value = CRM_Utils_Array::value('civicrm_contribution_recur_amount', $row)) {
84178120 344 $rows[$rowNum]['civicrm_contribution_recur_amount'] = CRM_Utils_Money::format($rows[$rowNum]['civicrm_contribution_recur_amount'], $rows[$rowNum]['civicrm_contribution_recur_currency']);
c1413e28 345 }
84178120 346
c1413e28
DG
347 }
348 }
96025800 349
ef10e0b5 350}