3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2016
33 class CRM_Contact_Form_Search_Custom_ContribSYBNT
extends CRM_Contact_Form_Search_Custom_Base
implements CRM_Contact_Form_Search_Interface
{
35 protected $_formValues;
36 protected $_aclFrom = NULL;
37 protected $_aclWhere = NULL;
38 public $_permissionedComponent;
45 public function __construct(&$formValues) {
46 $this->_formValues
= $formValues;
47 $this->_permissionedComponent
= 'CiviContribute';
49 $this->_columns
= array(
50 ts('Contact ID') => 'contact_id',
51 ts('Name') => 'display_name',
52 ts('Contribution Count') => 'donation_count',
53 ts('Contribution Amount') => 'donation_amount',
56 $this->_amounts
= array(
57 'min_amount_1' => ts('Min Amount One'),
58 'max_amount_1' => ts('Max Amount One'),
59 'min_amount_2' => ts('Min Amount Two'),
60 'max_amount_2' => ts('Max Amount Two'),
61 'exclude_min_amount' => ts('Exclusion Min Amount'),
62 'exclude_max_amount' => ts('Exclusion Max Amount'),
65 $this->_dates
= array(
66 'start_date_1' => ts('Start Date One'),
67 'end_date_1' => ts('End Date One'),
68 'start_date_2' => ts('Start Date Two'),
69 'end_date_2' => ts('End Date Two'),
70 'exclude_start_date' => ts('Exclusion Start Date'),
71 'exclude_end_date' => ts('Exclusion End Date'),
74 $this->_checkboxes
= array('is_first_amount' => ts('First Donation?'));
76 foreach ($this->_amounts
as $name => $title) {
77 $this->{$name} = CRM_Utils_Array
::value($name, $this->_formValues
);
80 foreach ($this->_checkboxes
as $name => $title) {
81 $this->{$name} = CRM_Utils_Array
::value($name, $this->_formValues
, FALSE);
84 foreach ($this->_dates
as $name => $title) {
85 if (!empty($this->_formValues
[$name])) {
86 $this->{$name} = CRM_Utils_Date
::processDate($this->_formValues
[$name]);
92 * @param CRM_Core_Form $form
94 public function buildForm(&$form) {
96 foreach ($this->_amounts
as $name => $title) {
103 foreach ($this->_dates
as $name => $title) {
104 $form->addDate($name, $title, FALSE, array('formatType' => 'custom'));
107 foreach ($this->_checkboxes
as $name => $title) {
108 $form->add('checkbox',
114 $this->setTitle('Contributions made in Year X and not Year Y');
115 // @TODO: Decide on better names for "Exclusion"
116 // @TODO: Add rule to ensure that exclusion dates are not in the inclusion range
122 public function count() {
125 $dao = CRM_Core_DAO
::executeQuery($sql);
131 * @param int $rowcount
133 * @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
137 public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
138 return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
143 * @param int $rowcount
145 * @param bool $includeContactIDs
146 * @param bool $justIDs
154 $includeContactIDs = FALSE,
158 $where = $this->where();
159 if (!empty($where)) {
160 $where = " AND $where";
163 $having = $this->having();
165 $having = " HAVING $having ";
168 $from = $this->from();
170 $select = $this->select();
172 $select .= ', contact_a.id, display_name';
176 DISTINCT contact_a.id as contact_id,
177 contact_a.display_name as display_name,
180 $this->buildACLClause('contact_a');
183 FROM civicrm_contact AS contact_a {$this->_aclFrom}
184 LEFT JOIN civicrm_contribution contrib_1 ON contrib_1.contact_id = contact_a.id
186 WHERE contrib_1.contact_id = contact_a.id
187 AND contrib_1.is_test = 0
189 GROUP BY contact_a.id
191 ORDER BY donation_amount desc
195 CRM_Core_DAO
::executeQuery("DROP TEMPORARY TABLE IF EXISTS CustomSearch_SYBNT_temp");
196 $query = "CREATE TEMPORARY TABLE CustomSearch_SYBNT_temp AS ({$sql})";
197 $dao = CRM_Core_DAO
::executeQuery($query);
198 $sql = "SELECT contact_a.id as contact_id FROM CustomSearch_SYBNT_temp as contact_a";
206 public function select() {
207 if (!empty($this->start_date_2
) ||
!empty($this->end_date_2
)) {
209 sum(contrib_1.total_amount) + sum(contrib_2.total_amount) AS donation_amount,
210 count(contrib_1.id) + count(contrib_1.id) AS donation_count
215 sum(contrib_1.total_amount) AS donation_amount,
216 count(contrib_1.id) AS donation_count
222 * @return null|string
224 public function from() {
226 if (!empty($this->start_date_2
) ||
!empty($this->end_date_2
)) {
227 $from .= " LEFT JOIN civicrm_contribution contrib_2 ON contrib_2.contact_id = contact_a.id ";
230 if (!empty($this->exclude_start_date
) ||
231 !empty($this->exclude_end_date
) ||
232 !empty($this->is_first_amount
)
234 $from .= " LEFT JOIN XG_CustomSearch_SYBNT xg ON xg.contact_id = contact_a.id ";
241 * @param bool $includeContactIDs
245 public function where($includeContactIDs = FALSE) {
248 if (!empty($this->start_date_1
)) {
249 $clauses[] = "contrib_1.receive_date >= {$this->start_date_1}";
252 if (!empty($this->end_date_1
)) {
253 $clauses[] = "contrib_1.receive_date <= {$this->end_date_1}";
256 if (!empty($this->start_date_2
) ||
!empty($this->end_date_2
)) {
257 $clauses[] = "contrib_2.is_test = 0";
259 if (!empty($this->start_date_2
)) {
260 $clauses[] = "contrib_2.receive_date >= {$this->start_date_2}";
263 if (!empty($this->end_date_2
)) {
264 $clauses[] = "contrib_2.receive_date <= {$this->end_date_2}";
268 if (!empty($this->exclude_start_date
) ||
269 !empty($this->exclude_end_date
) ||
270 !empty($this->is_first_amount
)
273 // first create temp table to store contact ids
274 $sql = "DROP TEMPORARY TABLE IF EXISTS XG_CustomSearch_SYBNT";
275 CRM_Core_DAO
::executeQuery($sql);
277 $sql = "CREATE TEMPORARY TABLE XG_CustomSearch_SYBNT ( contact_id int primary key) ENGINE=HEAP";
278 CRM_Core_DAO
::executeQuery($sql);
280 $excludeClauses = array();
281 if ($this->exclude_start_date
) {
282 $excludeClauses[] = "c.receive_date >= {$this->exclude_start_date}";
285 if ($this->exclude_end_date
) {
286 $excludeClauses[] = "c.receive_date <= {$this->exclude_end_date}";
289 $excludeClause = NULL;
290 if ($excludeClauses) {
291 $excludeClause = ' AND ' . implode(' AND ', $excludeClauses);
295 if ($this->exclude_min_amount
) {
296 $having[] = "sum(c.total_amount) >= {$this->exclude_min_amount}";
299 if ($this->exclude_max_amount
) {
300 $having[] = "sum(c.total_amount) <= {$this->exclude_max_amount}";
303 $havingClause = NULL;
304 if (!empty($having)) {
305 $havingClause = "HAVING " . implode(' AND ', $having);
308 if ($excludeClause ||
$havingClause) {
311 REPLACE INTO XG_CustomSearch_SYBNT
312 SELECT DISTINCT contact_id AS contact_id
313 FROM civicrm_contribution c
316 GROUP BY c.contact_id
320 $dao = CRM_Core_DAO
::executeQuery($query);
323 // now ensure we dont consider donors that are not first time
324 if ($this->is_first_amount
) {
326 REPLACE INTO XG_CustomSearch_SYBNT
327 SELECT DISTINCT contact_id AS contact_id
328 FROM civicrm_contribution c
330 AND c.receive_date < {$this->start_date_1}
332 $dao = CRM_Core_DAO
::executeQuery($query);
335 $clauses[] = " xg.contact_id IS NULL ";
337 if ($this->_aclWhere
) {
338 $clauses[] .= " {$this->_aclWhere} ";
340 return implode(' AND ', $clauses);
344 * @param bool $includeContactIDs
348 public function having($includeContactIDs = FALSE) {
350 $min = CRM_Utils_Array
::value('min_amount', $this->_formValues
);
352 $clauses[] = "sum(contrib_1.total_amount) >= $min";
355 $max = CRM_Utils_Array
::value('max_amount', $this->_formValues
);
357 $clauses[] = "sum(contrib_1.total_amount) <= $max";
360 return implode(' AND ', $clauses);
366 public function &columns() {
367 return $this->_columns
;
373 public function templateFile() {
374 return 'CRM/Contact/Form/Search/Custom/ContribSYBNT.tpl';
380 public function summary() {
387 public function setTitle($title) {
389 CRM_Utils_System
::setTitle($title);
392 CRM_Utils_System
::setTitle(ts('Search'));
397 * @param string $tableAlias
399 public function buildACLClause($tableAlias = 'contact') {
400 list($this->_aclFrom
, $this->_aclWhere
) = CRM_Contact_BAO_Contact_Permission
::cacheClause($tableAlias);