copyright and version fixes
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / ContributionAggregate.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
232624b1 4 | CiviCRM version 4.4 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35class CRM_Contact_Form_Search_Custom_ContributionAggregate implements CRM_Contact_Form_Search_Interface {
36
4e54c348
PJ
37 protected $_formValues;
38 public $_permissionedComponent;
6a488035 39
4e54c348
PJ
40 function __construct(&$formValues) {
41 $this->_formValues = $formValues;
6a488035
TO
42 /**
43 * Define the columns for search result rows
44 */
4e54c348 45
6a488035
TO
46 $this->_columns = array(
47 ts('Contact Id') => 'contact_id',
48 ts('Name') => 'sort_name',
49 ts('Donation Count') => 'donation_count',
50 ts('Donation Amount') => 'donation_amount',
51 );
4e54c348
PJ
52
53 // define component access permission needed
54 $this->_permissionedComponent = 'CiviContribute';
6a488035
TO
55 }
56
57 function buildForm(&$form) {
58
59 /**
60 * You can define a custom title for the search form
61 */
62 $this->setTitle('Find Contributors by Aggregate Totals');
63
64 /**
65 * Define the search form fields here
66 */
67 $form->add('text',
68 'min_amount',
69 ts('Aggregate Total Between $')
70 );
71 $form->addRule('min_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
72
73 $form->add('text',
74 'max_amount',
75 ts('...and $')
76 );
77 $form->addRule('max_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
78
79 $form->addDate('start_date', ts('Contribution Date From'), FALSE, array('formatType' => 'custom'));
80 $form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
81
82 $financial_types = CRM_Contribute_PseudoConstant::financialType();
83 foreach($financial_types as $financial_type_id => $financial_type) {
84 $form->addElement('checkbox', "financial_type_id[{$financial_type_id}]", 'Financial Type', $financial_type);
85 }
86
87 /**
88 * If you are using the sample template, this array tells the template fields to render
89 * for the search form.
90 */
91 $form->assign('elements', array('min_amount', 'max_amount', 'start_date', 'end_date', 'financial_type_id'));
92 }
93
94 /**
95 * Define the smarty template used to layout the search form and results listings.
96 */
97 function templateFile() {
98 return 'CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl';
99 }
100
101 /**
102 * Construct the search query
103 */
104 function all($offset = 0, $rowcount = 0, $sort = NULL,
105 $includeContactIDs = FALSE, $justIDs = FALSE
106 ) {
107
108 // SELECT clause must include contact_id as an alias for civicrm_contact.id
109 if ($justIDs) {
110 $select = "contact_a.id as contact_id";
111 }
112 else {
113 $select = "
114DISTINCT contact_a.id as contact_id,
115contact_a.sort_name as sort_name,
116sum(contrib.total_amount) AS donation_amount,
117count(contrib.id) AS donation_count
118";
119 }
120 $from = $this->from();
121
122 $where = $this->where($includeContactIDs);
123
124 $having = $this->having();
125 if ($having) {
126 $having = " HAVING $having ";
127 }
128
129 $sql = "
130SELECT $select
131FROM $from
132WHERE $where
133GROUP BY contact_a.id
134$having
135";
136 //for only contact ids ignore order.
137 if (!$justIDs) {
138 // Define ORDER BY for query in $sort, with default value
139 if (!empty($sort)) {
140 if (is_string($sort)) {
bf00d1b6 141 $sort = CRM_Utils_Type::escape($sort, 'String');
6a488035
TO
142 $sql .= " ORDER BY $sort ";
143 }
144 else {
145 $sql .= " ORDER BY " . trim($sort->orderBy());
146 }
147 }
148 else {
149 $sql .= "ORDER BY donation_amount desc";
150 }
151 }
152
153 if ($rowcount > 0 && $offset >= 0) {
bf00d1b6 154 $offset = CRM_Utils_Type::escape($offset, 'Int');
dd3a4117 155 $rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
6a488035
TO
156 $sql .= " LIMIT $offset, $rowcount ";
157 }
158 return $sql;
159 }
160
161 function from() {
162 return "
163civicrm_contribution AS contrib,
164civicrm_contact AS contact_a
165";
166 }
167
168 /*
169 * WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values
170 *
171 */
172 function where($includeContactIDs = FALSE) {
173 $clauses = array();
174
175 $clauses[] = "contrib.contact_id = contact_a.id";
176 $clauses[] = "contrib.is_test = 0";
177
178 $startDate = CRM_Utils_Date::processDate($this->_formValues['start_date']);
179 if ($startDate) {
180 $clauses[] = "contrib.receive_date >= $startDate";
181 }
182
183 $endDate = CRM_Utils_Date::processDate($this->_formValues['end_date']);
184 if ($endDate) {
185 $clauses[] = "contrib.receive_date <= $endDate";
186 }
187
188 if ($includeContactIDs) {
189 $contactIDs = array();
190 foreach ($this->_formValues as $id => $value) {
191 if ($value &&
192 substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
193 ) {
194 $contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
195 }
196 }
197
198 if (!empty($contactIDs)) {
199 $contactIDs = implode(', ', $contactIDs);
200 $clauses[] = "contact_a.id IN ( $contactIDs )";
201 }
202 }
203
204 if (!empty($this->_formValues['financial_type_id'])) {
205 $financial_type_ids = implode(',', array_keys($this->_formValues['financial_type_id']));
206 $clauses[] = "contrib.financial_type_id IN ($financial_type_ids)";
207 }
208
209 return implode(' AND ', $clauses);
210 }
211
212 function having($includeContactIDs = FALSE) {
213 $clauses = array();
214 $min = CRM_Utils_Array::value('min_amount', $this->_formValues);
215 if ($min) {
216 $min = CRM_Utils_Rule::cleanMoney($min);
217 $clauses[] = "sum(contrib.total_amount) >= $min";
218 }
219
220 $max = CRM_Utils_Array::value('max_amount', $this->_formValues);
221 if ($max) {
222 $max = CRM_Utils_Rule::cleanMoney($max);
223 $clauses[] = "sum(contrib.total_amount) <= $max";
224 }
225
226 return implode(' AND ', $clauses);
227 }
228
229 /*
230 * Functions below generally don't need to be modified
231 */
232 function count() {
233 $sql = $this->all();
234
235 $dao = CRM_Core_DAO::executeQuery($sql,
236 CRM_Core_DAO::$_nullArray
237 );
238 return $dao->N;
239 }
240
241 function contactIDs($offset = 0, $rowcount = 0, $sort = NULL) {
242 return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
243 }
244
245 function &columns() {
246 return $this->_columns;
247 }
248
249 function setTitle($title) {
250 if ($title) {
251 CRM_Utils_System::setTitle($title);
252 }
253 else {
254 CRM_Utils_System::setTitle(ts('Search'));
255 }
256 }
257
258 function summary() {
259 return NULL;
260 }
261}
262