Merge pull request #2548 from rcsheets/doc_improvements
[civicrm-core.git] / CRM / Contribute / BAO / Query.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_Contribute_BAO_Query {
36
37 /**
38 * static field for all the export/import contribution fields
39 *
40 * @var array
41 * @static
42 */
43 static $_contributionFields = NULL;
44
45 /**
46 * Function get the import/export fields for contribution
47 *
48 * @return array self::$_contributionFields associative array of contribution fields
49 * @static
50 */
51 static function &getFields() {
52 if (!self::$_contributionFields) {
53 self::$_contributionFields = array();
54
55 $fields = CRM_Contribute_BAO_Contribution::exportableFields();
56
57 unset($fields['contribution_contact_id']);
58
59 self::$_contributionFields = $fields;
60 }
61 return self::$_contributionFields;
62 }
63
64 /**
65 * if contributions are involved, add the specific contribute fields
66 *
67 * @return void
68 * @access public
69 */
70 static function select(&$query) {
71 // if contribute mode add contribution id
72 if ($query->_mode & CRM_Contact_BAO_Query::MODE_CONTRIBUTE) {
73 $query->_select['contribution_id'] = "civicrm_contribution.id as contribution_id";
74 $query->_element['contribution_id'] = 1;
75 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
76 }
77
78 // get financial_type
a7488080 79 if (!empty($query->_returnProperties['financial_type'])) {
6a488035
TO
80 $query->_select['financial_type'] = "civicrm_financial_type.name as financial_type";
81 $query->_element['financial_type'] = 1;
82 $query->_tables['civicrm_contribution'] = 1;
83 $query->_tables['civicrm_financial_type'] = 1;
84 }
85
86 // get accounting code
a7488080 87 if (!empty($query->_returnProperties['accounting_code'])) {
6a488035
TO
88 $query->_select['accounting_code'] = "civicrm_financial_account.accounting_code as accounting_code";
89 $query->_element['accounting_code'] = 1;
90 $query->_tables['civicrm_accounting_code'] = 1;
91 $query->_tables['civicrm_financial_account'] = 1;
92 }
39b795ba 93
a7488080 94 if (!empty($query->_returnProperties['contribution_note'])) {
6a488035
TO
95 $query->_select['contribution_note'] = "civicrm_note.note as contribution_note";
96 $query->_element['contribution_note'] = 1;
97 $query->_tables['contribution_note'] = 1;
98 }
99
a7488080 100 if (!empty($query->_returnProperties['contribution_batch'])) {
6a488035
TO
101 $query->_select['contribution_batch'] = "civicrm_batch.title as contribution_batch";
102 $query->_element['contribution_batch'] = 1;
103 $query->_tables['contribution_batch'] = 1;
104 }
105
106 // get contribution_status
a7488080 107 if (!empty($query->_returnProperties['contribution_status_id'])) {
6a488035
TO
108 $query->_select['contribution_status_id'] = "contribution_status.value as contribution_status_id";
109 $query->_element['contribution_status_id'] = 1;
110 $query->_tables['civicrm_contribution'] = 1;
111 $query->_tables['contribution_status'] = 1;
112 }
113
114 // get contribution_status label
a7488080 115 if (!empty($query->_returnProperties['contribution_status'])) {
6a488035
TO
116 $query->_select['contribution_status'] = "contribution_status.label as contribution_status";
117 $query->_element['contribution_status'] = 1;
118 $query->_tables['civicrm_contribution'] = 1;
119 $query->_tables['contribution_status'] = 1;
120 }
121
122 // get payment instruments
a7488080 123 if (!empty($query->_returnProperties['payment_instrument'])) {
6a488035
TO
124 $query->_select['contribution_payment_instrument'] = "payment_instrument.name as contribution_payment_instrument";
125 $query->_element['contribution_payment_instrument'] = 1;
126 $query->_tables['civicrm_contribution'] = 1;
127 $query->_tables['contribution_payment_instrument'] = 1;
128 }
129
a7488080 130 if (!empty($query->_returnProperties['check_number'])) {
6a488035
TO
131 $query->_select['contribution_check_number'] = "civicrm_contribution.check_number as contribution_check_number";
132 $query->_element['contribution_check_number'] = 1;
133 $query->_tables['civicrm_contribution'] = 1;
134 }
135
a7488080 136 if (!empty($query->_returnProperties['contribution_campaign_id'])) {
6a488035
TO
137 $query->_select['contribution_campaign_id'] = 'civicrm_contribution.campaign_id as contribution_campaign_id';
138 $query->_element['contribution_campaign_id'] = 1;
139 $query->_tables['civicrm_contribution'] = 1;
140 }
141
142 // LCD 716
a7488080 143 if (!empty($query->_returnProperties['soft_credit_name'])) {
6a488035
TO
144 $query->_select['contribution_soft_credit_name'] = "civicrm_contact_d.display_name as contribution_soft_credit_name";
145 $query->_element['contribution_soft_credit_name'] = 1;
146 $query->_tables['civicrm_contribution'] = 1;
147 $query->_tables['civicrm_contribution_soft'] = 1;
148 $query->_tables['civicrm_contribution_soft_contact'] = 1;
149 }
150
a7488080 151 if (!empty($query->_returnProperties['soft_credit_email'])) {
6a488035
TO
152 $query->_select['contribution_soft_credit_email'] = "soft_email.email as contribution_soft_credit_email";
153 $query->_element['contribution_soft_credit_email'] = 1;
154 $query->_tables['civicrm_contribution'] = 1;
155 $query->_tables['civicrm_contribution_soft'] = 1;
156 $query->_tables['civicrm_contribution_soft_contact'] = 1;
157 $query->_tables['civicrm_contribution_soft_email'] = 1;
158 }
159
a7488080 160 if (!empty($query->_returnProperties['soft_credit_phone'])) {
6a488035
TO
161 $query->_select['contribution_soft_credit_email'] = "soft_phone.phone as contribution_soft_credit_phone";
162 $query->_element['contribution_soft_credit_phone'] = 1;
163 $query->_tables['civicrm_contribution'] = 1;
164 $query->_tables['civicrm_contribution_soft'] = 1;
165 $query->_tables['civicrm_contribution_soft_contact'] = 1;
166 $query->_tables['civicrm_contribution_soft_phone'] = 1;
167 }
168 // LCD 716 END
169 }
170
171 static function where(&$query) {
4b58de38 172 $grouping = NULL;
6a488035 173 foreach (array_keys($query->_params) as $id) {
a7488080 174 if (empty($query->_params[$id][0])) {
6a488035
TO
175 continue;
176 }
177 if (substr($query->_params[$id][0], 0, 13) == 'contribution_' || substr($query->_params[$id][0], 0, 10) == 'financial_') {
178 if ($query->_mode == CRM_Contact_BAO_QUERY::MODE_CONTACTS) {
179 $query->_useDistinct = TRUE;
180 }
39b795ba
DL
181 // CRM-12065
182 if (
183 $query->_params[$id][0] == 'contribution_type_id' ||
184 $query->_params[$id][0] == 'contribution_type'
185 ) {
186 CRM_Core_Session::setStatus(
187 ts('The contribution type criteria is now obsolete, please update your smart group'),
188 '',
189 'alert'
190 );
191 continue;
192 }
193
6a488035
TO
194 $grouping = $query->_params[$id][3];
195 self::whereClauseSingle($query->_params[$id], $query);
196 }
197 }
6a488035
TO
198 }
199
200 static function whereClauseSingle(&$values, &$query) {
201 list($name, $op, $value, $grouping, $wildcard) = $values;
202
6a488035 203 $fields = self::getFields();
163b1da9
KJ
204
205 if (!empty($value) && !is_array($value)) {
6a488035
TO
206 $quoteValue = "\"$value\"";
207 }
208
209 $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
b32bc653 210 foreach (self::getRecurringFields() as $dateField => $dateFieldTitle) {
a91e698a 211 if(self::buildDateWhere($values, $query, $name, $dateField, $dateFieldTitle)) {
212 return;
213 }
214 }
6a488035
TO
215 switch ($name) {
216 case 'contribution_date':
217 case 'contribution_date_low':
218 case 'contribution_date_low_time':
219 case 'contribution_date_high':
220 case 'contribution_date_high_time':
221 // process to / from date
222 $query->dateQueryBuilder($values,
223 'civicrm_contribution', 'contribution_date', 'receive_date', 'Contribution Date'
224 );
225 return;
226
227 case 'contribution_amount':
228 case 'contribution_amount_low':
229 case 'contribution_amount_high':
230 // process min/max amount
231 $query->numberRangeBuilder($values,
232 'civicrm_contribution', 'contribution_amount',
233 'total_amount', 'Contribution Amount',
234 NULL
235 );
236 return;
237
238 case 'contribution_total_amount':
239 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.total_amount",
240 $op, $value, "Money"
241 );
242 $query->_qill[$grouping][] = ts('Contribution Total Amount %1 %2', array(1 => $op, 2 => $value));
243 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
244 return;
245
246 case 'contribution_thankyou_date_is_not_null':
247 if ($value) {
248 $op = "IS NOT NULL";
249 $query->_qill[$grouping][] = ts('Contribution Thank-you Sent');
250 }
251 else {
252 $op = "IS NULL";
253 $query->_qill[$grouping][] = ts('Contribution Thank-you Not Sent');
254 }
255 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.thankyou_date", $op);
256 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
257 return;
258
259 case 'contribution_receipt_date_is_not_null':
260 if ($value) {
261 $op = "IS NOT NULL";
262 $query->_qill[$grouping][] = ts('Contribution Receipt Sent');
263 }
264 else {
265 $op = "IS NULL";
266 $query->_qill[$grouping][] = ts('Contribution Receipt Not Sent');
267 }
268 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.receipt_date", $op);
269 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
270 return;
271
4ca8b3e8
JM
272 case 'financial_type_id':
273 case 'financial_type':
5bbd985a
JM
274 // The financial_type_id might be an array (from aggregate contributions custom search)
275 // In this case, we need to change the query.
276 if (is_array($value)) {
277 $val = array();
278 // Rebuild the array to get the data we're interested in as array
279 // values not array keys.
280 foreach ($value as $k => $v) {
281 if ($v) {
282 $val[] = $k;
283 }
284 }
1f0d8c92 285 if (count($val) > 0) {
5bbd985a
JM
286 // Overwrite $value so it works with an IN where statement.
287 $op = 'IN';
288 $value = '(' . implode(',', $val) . ')';
289 }
290 else {
291 // If we somehow have an empty array, just return
292 return;
293 }
294 }
295
289c8051 296 $types = CRM_Contribute_PseudoConstant::financialType();
5bbd985a
JM
297
298 // Ensure we have a sensible string to display to the user.
299 $names = array();
300 if (isset($val) && is_array($val)) {
301 foreach($val as $id) {
1f0d8c92 302 $names[] = CRM_Utils_Array::value($id, $types);
5bbd985a
JM
303 }
304 }
305 else {
306 $names[] = $types[$value];
307 }
308
289c8051 309 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.financial_type_id",
6a488035
TO
310 $op, $value, "Integer"
311 );
5bbd985a 312 $query->_qill[$grouping][] = ts('Financial Type %1', array(1 => $op)) . ' ' . implode(' ' . ts('or') . ' ', $names);
6a488035
TO
313 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
314 return;
315
316 case 'contribution_page_id':
317 $cPage = $value;
318 $pages = CRM_Contribute_PseudoConstant::contributionPage();
319 $query->_where[$grouping][] = "civicrm_contribution.contribution_page_id = $cPage";
320 $query->_qill[$grouping][] = ts('Contribution Page - %1', array(1 => $pages[$cPage]));
321 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
322 return;
323
324 case 'contribution_pcp_made_through_id':
325 $pcPage = $value;
326 $pcpages = CRM_Contribute_PseudoConstant::pcPage();
327 $query->_where[$grouping][] = "civicrm_contribution_soft.pcp_id = $pcPage";
328 $query->_qill[$grouping][] = ts('Personal Campaign Page - %1', array(1 => $pcpages[$pcPage]));
329 $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1;
330 return;
331
332 case 'contribution_payment_instrument_id':
333 case 'contribution_payment_instrument':
334 $pi = $value;
335 $pis = CRM_Contribute_PseudoConstant::paymentInstrument();
336 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.payment_instrument_id",
337 $op, $value, "Integer"
338 );
339
340 $query->_qill[$grouping][] = ts('Paid By - %1', array(1 => $pis[$pi]));
341 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
342 return;
343
6a488035
TO
344 case 'contribution_status':
345 case 'contribution_status_id':
346 if (is_array($value)) {
347 foreach ($value as $k => $v) {
348 if ($v) {
349 $val[$k] = $k;
350 }
351 }
352
353 $status = implode(',', $val);
354
355 if (count($val) > 1) {
356 $op = 'IN';
357 $status = "({$status})";
358 }
359 }
360 else {
361 $op = '=';
362 $status = $value;
363 }
364
365 $statusValues = CRM_Core_OptionGroup::values("contribution_status");
366
367 $names = array();
368 if (isset($val) &&
369 is_array($val)
370 ) {
371 foreach ($val as $id => $dontCare) {
372 $names[] = $statusValues[$id];
373 }
374 }
375 else {
376 $names[] = $statusValues[$value];
377 }
378
379 $query->_qill[$grouping][] = ts('Contribution Status %1', array(1 => $op)) . ' ' . implode(' ' . ts('or') . ' ', $names);
380 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.contribution_status_id",
381 $op,
382 $status,
383 "Integer"
384 );
385 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
386 return;
387
388 case 'contribution_source':
389 $value = $strtolower(CRM_Core_DAO::escapeString($value));
390 if ($wildcard) {
391 $value = "%$value%";
392 $op = 'LIKE';
393 }
394 $wc = ($op != 'LIKE') ? "LOWER(civicrm_contribution.source)" : "civicrm_contribution.source";
395 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String");
396 $query->_qill[$grouping][] = ts('Contribution Source %1 %2', array(1 => $op, 2 => $quoteValue));
397 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
398 return;
399
400 case 'contribution_trxn_id':
401 case 'contribution_transaction_id':
402 $wc = ($op != 'LIKE') ? "LOWER(civicrm_contribution.trxn_id)" : "civicrm_contribution.trxn_id";
403 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String");
404 $query->_qill[$grouping][] = ts('Transaction ID %1 %2', array(1 => $op, 2 => $quoteValue));
405 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
406 return;
407
408 case 'contribution_check_number':
409 $wc = ($op != 'LIKE') ? "LOWER(civicrm_contribution.check_number)" : "civicrm_contribution.check_number";
410 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String");
411 $query->_qill[$grouping][] = ts('Check Number %1 %2', array(1 => $op, 2 => $quoteValue));
412 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
413 return;
414
415 case 'contribution_is_test':
416 case 'contribution_test':
4b58de38
CW
417 // We dont want to include all tests for sql OR CRM-7827
418 if (!$value || $query->getOperator() != 'OR') {
419 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.is_test", $op, $value, "Boolean");
420 if ($value) {
421 $query->_qill[$grouping][] = ts("Only Display Test Contributions");
422 }
423 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
6a488035 424 }
6a488035
TO
425 return;
426
427 case 'contribution_is_pay_later':
428 case 'contribution_pay_later':
429 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.is_pay_later", $op, $value, "Boolean");
430 if ($value) {
431 $query->_qill[$grouping][] = ts("Find Pay Later Contributions");
432 }
433 else {
434 $query->_qill[$grouping][] = ts("Exclude Pay Later Contributions");
435 }
436 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
437 return;
438
439 case 'contribution_recurring':
440 if ($value) {
441 $query->_where[$grouping][] = "civicrm_contribution.contribution_recur_id IS NOT NULL";
442 $query->_qill[$grouping][] = ts("Find Recurring Contributions");
443 $query->_tables['civicrm_contribution_recur'] = $query->_whereTables['civicrm_contribution_recur'] = 1;
444 }
445 else {
446 $query->_where[$grouping][] = "civicrm_contribution.contribution_recur_id IS NULL";
447 $query->_qill[$grouping][] = ts("Exclude Recurring Contributions");
448 }
449 return;
450
451 case 'contribution_recur_id':
452 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.contribution_recur_id",
453 $op, $value, "Integer"
454 );
455 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
456 return;
457
458 case 'contribution_id':
459 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.id", $op, $value, "Integer");
460 $query->_qill[$grouping][] = ts('Contribution ID %1 %2', array(1 => $op, 2 => $quoteValue));
461 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
462 return;
463
464 case 'contribution_note':
465 $value = $strtolower(CRM_Core_DAO::escapeString($value));
466 if ($wildcard) {
467 $value = "%$value%";
468 $op = 'LIKE';
469 }
470 $wc = ($op != 'LIKE') ? "LOWER(civicrm_note.note)" : "civicrm_note.note";
471 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String");
472 $query->_qill[$grouping][] = ts('Contribution Note %1 %2', array(1 => $op, 2 => $quoteValue));
473 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = $query->_whereTables['contribution_note'] = 1;
474 return;
475
476 case 'contribution_membership_id':
477 $query->_where[$grouping][] = " civicrm_membership.id $op $value";
478 $query->_tables['contribution_membership'] = $query->_whereTables['contribution_membership'] = 1;
479
480 return;
481
482 case 'contribution_participant_id':
483 $query->_where[$grouping][] = " civicrm_participant.id $op $value";
484 $query->_tables['contribution_participant'] = $query->_whereTables['contribution_participant'] = 1;
485 return;
486
487 case 'contribution_pcp_display_in_roll':
488 $query->_where[$grouping][] = " civicrm_contribution_soft.pcp_display_in_roll $op '$value'";
489 if ($value) {
490 $query->_qill[$grouping][] = ts("Personal Campaign Page Honor Roll");
491 }
492 else {
493 $query->_qill[$grouping][] = ts("NOT Personal Campaign Page Honor Roll");
494 }
495 $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1;
496 return;
497
498 // Supporting search for currency type -- CRM-4711
499
500 case 'contribution_currency_type':
bd44e0df 501 $currencySymbol = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'currency', array('labelColumn' => 'name'));
6a488035
TO
502 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.currency",
503 $op, $currencySymbol[$value], "String"
504 );
505 $query->_qill[$grouping][] = ts('Currency Type - %1', array(1 => $currencySymbol[$value]));
506 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
507 return;
508
509 case 'contribution_campaign_id':
510 $campParams = array(
511 'op' => $op,
512 'campaign' => $value,
513 'grouping' => $grouping,
514 'tableName' => 'civicrm_contribution',
515 );
516 CRM_Campaign_BAO_Query::componentSearchClause($campParams, $query);
517 return;
518
519 case 'contribution_batch_id':
91aff94c 520 $batches = CRM_Contribute_PseudoConstant::batch();
6a488035
TO
521 $query->_where[$grouping][] = " civicrm_entity_batch.batch_id $op $value";
522 $query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $op, 2 => $batches[$value]));
39b795ba 523 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
6a488035
TO
524 $query->_tables['contribution_batch'] = $query->_whereTables['contribution_batch'] = 1;
525 return;
526
527 default:
528 //all other elements are handle in this case
529 $fldName = substr($name, 13);
ec8c4582
DL
530 if (!isset($fields[$fldName])) {
531 // CRM-12597
532 CRM_Core_Session::setStatus(ts(
fb5b081b 533 'We did not recognize the search field: %1. Please check and fix your contribution related smart groups.',
ec8c4582
DL
534 array(1 => $fldName)
535 )
536 );
537 return;
538 }
6a488035
TO
539 $whereTable = $fields[$fldName];
540 $value = trim($value);
541
542 //contribution fields (decimal fields) which don't require a quote in where clause.
543 $moneyFields = array('non_deductible_amount', 'fee_amount', 'net_amount');
544 //date fields
545 $dateFields = array('receive_date', 'cancel_date', 'receipt_date', 'thankyou_date', 'fulfilled_date');
546
547 if (in_array($fldName, $dateFields)) {
548 $dataType = "Date";
549 }
550 elseif (in_array($fldName, $moneyFields)) {
551 $dataType = "Money";
552 }
553 else {
554 $dataType = "String";
555 }
556
557 $wc = ($op != 'LIKE' && $dataType != 'Date') ? "LOWER($whereTable[where])" : "$whereTable[where]";
558 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, $dataType);
559 $query->_qill[$grouping][] = "$whereTable[title] $op $quoteValue";
560 list($tableName, $fieldName) = explode('.', $whereTable['where'], 2);
561 $query->_tables[$tableName] = $query->_whereTables[$tableName] = 1;
562 if ($tableName == 'civicrm_contribution_product') {
563 $query->_tables['civicrm_product'] = $query->_whereTables['civicrm_product'] = 1;
564 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
565 }
566 else {
567 $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
568 }
569 }
570 }
571
572 static function from($name, $mode, $side) {
573 $from = NULL;
574 switch ($name) {
575 case 'civicrm_contribution':
576 $from = " $side JOIN civicrm_contribution ON civicrm_contribution.contact_id = contact_a.id ";
577 break;
578
579 case 'civicrm_contribution_recur':
86845f9b 580 if ($mode == 1) {
581 // in contact mode join directly onto profile - in case no contributions exist yet
582 $from = " $side JOIN civicrm_contribution_recur ON contact_a.id = civicrm_contribution_recur.contact_id ";
583 }
584 else {
585 $from = " $side JOIN civicrm_contribution_recur ON civicrm_contribution.contribution_recur_id = civicrm_contribution_recur.id ";
586 }
6a488035
TO
587 break;
588
589 case 'civicrm_financial_type':
590 if ($mode & CRM_Contact_BAO_Query::MODE_CONTRIBUTE) {
591 $from = " INNER JOIN civicrm_financial_type ON civicrm_contribution.financial_type_id = civicrm_financial_type.id ";
592 }
593 else {
594 $from = " $side JOIN civicrm_financial_type ON civicrm_contribution.financial_type_id = civicrm_financial_type.id ";
595 }
596 break;
597
598 case 'civicrm_accounting_code':
289c8051 599 $from = " $side JOIN civicrm_entity_financial_account ON civicrm_entity_financial_account.entity_id = civicrm_contribution.financial_type_id AND civicrm_entity_financial_account.entity_table = 'civicrm_financial_type' ";
6a488035
TO
600 $from .= " INNER JOIN civicrm_financial_account ON civicrm_financial_account.id = civicrm_entity_financial_account.financial_account_id ";
601 $from .= " INNER JOIN civicrm_option_value cov ON cov.value = civicrm_entity_financial_account.account_relationship AND cov.name = 'Income Account is' ";
602 $from .= " INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id AND cog.name = 'account_relationship' ";
39b795ba 603 break;
6a488035
TO
604
605 case 'civicrm_contribution_page':
606 $from = " $side JOIN civicrm_contribution_page ON civicrm_contribution.contribution_page ON civicrm_contribution.contribution_page.id";
607 break;
608
609 case 'civicrm_product':
610 $from = " $side JOIN civicrm_contribution_product ON civicrm_contribution_product.contribution_id = civicrm_contribution.id";
611 $from .= " $side JOIN civicrm_product ON civicrm_contribution_product.product_id =civicrm_product.id ";
612 break;
613
614 case 'contribution_payment_instrument':
615 $from = " $side JOIN civicrm_option_group option_group_payment_instrument ON ( option_group_payment_instrument.name = 'payment_instrument')";
616 $from .= " $side JOIN civicrm_option_value payment_instrument ON (civicrm_contribution.payment_instrument_id = payment_instrument.value
617 AND option_group_payment_instrument.id = payment_instrument.option_group_id ) ";
618 break;
619
6a488035
TO
620 case 'contribution_status':
621 $from = " $side JOIN civicrm_option_group option_group_contribution_status ON (option_group_contribution_status.name = 'contribution_status')";
622 $from .= " $side JOIN civicrm_option_value contribution_status ON (civicrm_contribution.contribution_status_id = contribution_status.value
623 AND option_group_contribution_status.id = contribution_status.option_group_id ) ";
624 break;
625
626 case 'contribution_note':
627 $from .= " $side JOIN civicrm_note ON ( civicrm_note.entity_table = 'civicrm_contribution' AND
628 civicrm_contribution.id = civicrm_note.entity_id )";
629 break;
630
6a488035
TO
631 case 'contribution_membership':
632 $from = " $side JOIN civicrm_membership_payment ON civicrm_membership_payment.contribution_id = civicrm_contribution.id";
633 $from .= " $side JOIN civicrm_membership ON civicrm_membership_payment.membership_id = civicrm_membership.id ";
634 break;
635
636 case 'contribution_participant':
637 $from = " $side JOIN civicrm_participant_payment ON civicrm_participant_payment.contribution_id = civicrm_contribution.id";
638 $from .= " $side JOIN civicrm_participant ON civicrm_participant_payment.participant_id = civicrm_participant.id ";
639 break;
640
641 case 'civicrm_contribution_soft':
642 $from = " $side JOIN civicrm_contribution_soft ON civicrm_contribution_soft.contribution_id = civicrm_contribution.id";
643 break;
644
645 case 'civicrm_contribution_soft_contact':
646 $from .= " $side JOIN civicrm_contact civicrm_contact_d ON (civicrm_contribution_soft.contact_id = civicrm_contact_d.id )";
647 break;
648
649 case 'civicrm_contribution_soft_email':
650 $from .= " $side JOIN civicrm_email as soft_email ON (civicrm_contact_d.id = soft_email.contact_id )";
651 break;
652
653 case 'civicrm_contribution_soft_phone':
654 $from .= " $side JOIN civicrm_phone as soft_phone ON (civicrm_contact_d.id = soft_phone.contact_id )";
655 break;
39b795ba 656
6a488035 657 case 'contribution_batch':
61412579 658 $from .= " $side JOIN civicrm_entity_financial_trxn ON (
659 civicrm_entity_financial_trxn.entity_table = 'civicrm_contribution'
660 AND civicrm_contribution.id = civicrm_entity_financial_trxn.entity_id )";
661
662 $from .= " $side JOIN civicrm_financial_trxn ON (
663 civicrm_entity_financial_trxn.financial_trxn_id = civicrm_financial_trxn.id )";
664
665 $from .= " $side JOIN civicrm_entity_batch ON ( civicrm_entity_batch.entity_table = 'civicrm_financial_trxn'
666 AND civicrm_financial_trxn.id = civicrm_entity_batch.entity_id )";
667
6a488035
TO
668 $from .= " $side JOIN civicrm_batch ON civicrm_entity_batch.batch_id = civicrm_batch.id";
669 break;
670 }
671 return $from;
672 }
673
674 static function defaultReturnProperties($mode, $includeCustomFields = TRUE) {
675 $properties = NULL;
676 if ($mode & CRM_Contact_BAO_Query::MODE_CONTRIBUTE) {
677 $properties = array(
678 'contact_type' => 1,
679 'contact_sub_type' => 1,
680 'sort_name' => 1,
681 'display_name' => 1,
682 'financial_type' => 1,
683 'contribution_source' => 1,
684 'receive_date' => 1,
685 'thankyou_date' => 1,
686 'cancel_date' => 1,
687 'total_amount' => 1,
688 'accounting_code' => 1,
689 'payment_instrument' => 1,
690 'check_number' => 1,
691 'non_deductible_amount' => 1,
692 'fee_amount' => 1,
693 'net_amount' => 1,
694 'trxn_id' => 1,
695 'invoice_id' => 1,
696 'currency' => 1,
697 'cancel_reason' => 1,
698 'receipt_date' => 1,
699 'product_name' => 1,
700 'sku' => 1,
701 'product_option' => 1,
702 'fulfilled_date' => 1,
703 'contribution_start_date' => 1,
704 'contribution_end_date' => 1,
705 'is_test' => 1,
706 'is_pay_later' => 1,
707 'contribution_status' => 1,
708 'contribution_status_id' => 1,
709 'contribution_recur_id' => 1,
710 'amount_level' => 1,
711 'contribution_note' => 1,
712 'contribution_batch' => 1,
713 'contribution_campaign_id' => 1
714 );
715
716 if ($includeCustomFields) {
717 // also get all the custom contribution properties
718 $fields = CRM_Core_BAO_CustomField::getFieldsForImport('Contribution');
719 if (!empty($fields)) {
720 foreach ($fields as $name => $dontCare) {
721 $properties[$name] = 1;
722 }
723 }
724 }
725 }
726 return $properties;
727 }
728
729 /**
730 * add all the elements shared between contribute search and advnaced search
731 *
732 * @access public
733 *
734 * @return void
735 * @static
736 */
737 static function buildSearchForm(&$form) {
738
739 // Added contribution source
740 $form->addElement('text', 'contribution_source', ts('Contribution Source'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution', 'source'));
741
bc3f7f04 742 CRM_Core_Form_Date::buildDateRange($form, 'contribution_date', 1, '_low', '_high', ts('From:'), FALSE);
6a488035
TO
743
744 $form->add('text', 'contribution_amount_low', ts('From'), array('size' => 8, 'maxlength' => 8));
745 $form->addRule('contribution_amount_low', ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('9.99', ' '))), 'money');
746
747 $form->add('text', 'contribution_amount_high', ts('To'), array('size' => 8, 'maxlength' => 8));
748 $form->addRule('contribution_amount_high', ts('Please enter a valid money value (e.g. %1).', array(1 => CRM_Utils_Money::format('99.99', ' '))), 'money');
749
750 // Adding select option for curreny type -- CRM-4711
751 $form->add('select', 'contribution_currency_type',
752 ts('Currency Type'),
753 array(
754 '' => ts('- any -')) +
ab345ca5
CW
755 CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'currency', array('labelColumn' => 'name')),
756 FALSE, array('class' => 'crm-select2')
6a488035
TO
757 );
758
1f0d8c92 759 // CRM-13848
15cf9198
CW
760 $form->addSelect('financial_type_id',
761 array('entity' => 'contribution', 'multiple' => 'multiple', 'option_url' => NULL, 'placeholder' => ts('- any -'))
6a488035
TO
762 );
763
764 $form->add('select', 'contribution_page_id',
765 ts('Contribution Page'),
766 array(
767 '' => ts('- any -')) +
ab345ca5
CW
768 CRM_Contribute_PseudoConstant::contributionPage(),
769 FALSE, array('class' => 'crm-select2')
6a488035
TO
770 );
771
772
773 $form->add('select', 'contribution_payment_instrument_id',
774 ts('Payment Instrument'),
775 array(
776 '' => ts('- any -')) +
ab345ca5
CW
777 CRM_Contribute_PseudoConstant::paymentInstrument(),
778 FALSE, array('class' => 'crm-select2')
6a488035
TO
779 );
780
781 $form->add('select', 'contribution_pcp_made_through_id',
782 ts('Personal Campaign Page'),
783 array(
784 '' => ts('- any -')) +
ab345ca5
CW
785 CRM_Contribute_PseudoConstant::pcPage(),
786 FALSE, array('class' => 'crm-select2')
6a488035
TO
787 );
788
789 $status = array();
790
791 $statusValues = CRM_Core_OptionGroup::values("contribution_status");
792 // Remove status values that are only used for recurring contributions or pledges (In Progress, Overdue).
793 unset($statusValues['5'], $statusValues['6']);
794
795 foreach ($statusValues as $key => $val) {
796 $status[] = $form->createElement('advcheckbox', $key, NULL, $val);
797 }
798
799 $form->addGroup($status, 'contribution_status_id', ts('Contribution Status'));
800
801 // Add fields for thank you and receipt
8a4f27dc
CW
802 $form->addYesNo('contribution_thankyou_date_is_not_null', ts('Thank-you sent?'), TRUE);
803 $form->addYesNo('contribution_receipt_date_is_not_null', ts('Receipt sent?'), TRUE);
6a488035 804
8a4f27dc
CW
805 $form->addYesNo('contribution_pay_later', ts('Contribution is Pay Later?'), TRUE);
806 $form->addYesNo('contribution_recurring', ts('Contribution is Recurring?'), TRUE);
b32bc653
CW
807
808 // Recurring contribution fields
809 foreach (self::getRecurringFields() as $key => $label) {
15cf9198 810 CRM_Core_Form_Date::buildDateRange($form, $key, 1, '_low', '_high');
b32bc653
CW
811 // If data has been entered for a recurring field, tell the tpl layer to open the pane
812 if (!empty($form->_formValues[$key . '_relative']) || !empty($form->_formValues[$key . '_low']) || !empty($form->_formValues[$key . '_high'])) {
813 $form->assign('contribution_recur_pane_open', TRUE);
814 }
815 }
a91e698a 816
8a4f27dc 817 $form->addYesNo('contribution_test', ts('Contribution is a Test?'), TRUE);
6a488035
TO
818
819 // Add field for transaction ID search
820 $form->addElement('text', 'contribution_transaction_id', ts("Transaction ID"));
821
822 $form->addElement('text', 'contribution_check_number', ts('Check Number'));
823
824 // Add field for pcp display in roll search
8a4f27dc 825 $form->addYesNo('contribution_pcp_display_in_roll', ts('Personal Campaign Page Honor Roll?'), TRUE);
6a488035
TO
826
827 // Add all the custom searchable fields
828 $contribution = array('Contribution');
829 $groupDetails = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, TRUE, $contribution);
830 if ($groupDetails) {
831 $form->assign('contributeGroupTree', $groupDetails);
832 foreach ($groupDetails as $group) {
833 foreach ($group['fields'] as $field) {
834 $fieldId = $field['id'];
835 $elementName = 'custom_' . $fieldId;
836 CRM_Core_BAO_CustomField::addQuickFormElement($form,
837 $elementName,
838 $fieldId,
839 FALSE, FALSE, TRUE
840 );
841 }
842 }
843 }
844
845 CRM_Campaign_BAO_Campaign::addCampaignInComponentSearch($form, 'contribution_campaign_id');
846
847 // Add batch select
91aff94c 848 $batches = CRM_Contribute_PseudoConstant::batch();
39b795ba 849
6a488035
TO
850 if ( !empty( $batches ) ) {
851 $form->add('select', 'contribution_batch_id',
852 ts('Batch Name'),
ab345ca5
CW
853 array('' => ts('- any -')) + $batches,
854 FALSE, array('class' => 'crm-select2')
855 );
6a488035
TO
856 }
857
858 $form->assign('validCiviContribute', TRUE);
859 $form->setDefaults(array('contribution_test' => 0));
860 }
861
6a488035
TO
862 static function searchAction(&$row, $id) {
863 }
864
865 static function tableNames(&$tables) {
866 // Add contribution table
a7488080 867 if (!empty($tables['civicrm_product'])) {
6a488035
TO
868 $tables = array_merge(array('civicrm_contribution' => 1), $tables);
869 }
870
8cc574cf 871 if (!empty($tables['civicrm_contribution_product']) && empty($tables['civicrm_product'])) {
6a488035
TO
872 $tables['civicrm_product'] = 1;
873 }
874 }
a91e698a 875
876 /**
877 * Add the where for dates
878 * @param array $values array of query values
879 * @param object $query the query object
880 * @param string $name query field that is set
881 * @param string $field name of field to be set
882 * @param string $title title of the field
883 */
884 static function buildDateWhere(&$values, $query, $name, $field, $title) {
885 $fieldPart = strpos($name, $field);
886 if($fieldPart === FALSE) {
887 return;
888 }
889 // we only have recurring dates using this ATM so lets' short cut to find the table name
890 $table = 'contribution_recur';
891 $fieldName = split($table . '_', $field);
892 $query->dateQueryBuilder($values,
893 'civicrm_' . $table, $field, $fieldName[1], $title
894 );
895 return TRUE;
896 }
b32bc653
CW
897
898 static function getRecurringFields() {
899 return array(
900 'contribution_recur_start_date' => ts('Recurring Contribution Start Date'),
901 'contribution_recur_next_sched_contribution_date' => ts('Next Scheduled Recurring Contribution'),
902 'contribution_recur_cancel_date' => ts('Recurring Contribution Cancel Date'),
903 'contribution_recur_end_date' => ts('Recurring Contribution End Date'),
904 'contribution_recur_create_date' => ('Recurring Contribution Create Date'),
905 'contribution_recur_modified_date' => ('Recurring Contribution Modified Date'),
906 'contribution_recur_failure_retry_date' => ts('Failed Recurring Contribution Retry Date'),
907 );
908 }
6a488035
TO
909}
910