Skip to content

Commit

Permalink
Merge pull request #9492 from monishdeb/CRM-19325
Browse files Browse the repository at this point in the history
CRM-19325 : Search contributions that are not in any batch
  • Loading branch information
monishdeb authored Dec 9, 2016
2 parents 70fcfa2 + cbd44e9 commit efcfb86
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CRM/Batch/Form/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ public function preProcess() {

}

/**
* Used in test to set Batch ID
*/
public function setBatchID($id) {
$this->_batchId = $id;
}

/**
* Build the form object.
*/
Expand Down
25 changes: 17 additions & 8 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -5944,6 +5944,13 @@ public static function buildQillForFieldValue(
) {
$qillOperators = CRM_Core_SelectValues::getSearchBuilderOperators();

//API usually have fieldValue format as array(operator => array(values)),
//so we need to separate operator out of fieldValue param
if (is_array($fieldValue) && in_array(key($fieldValue), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
$op = key($fieldValue);
$fieldValue = $fieldValue[$op];
}

// if Operator chosen is NULL/EMPTY then
if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE) {
return array(CRM_Utils_Array::value($op, $qillOperators, $op), '');
Expand All @@ -5970,17 +5977,13 @@ public static function buildQillForFieldValue(
elseif ($daoName == 'CRM_Contact_DAO_Group' && $fieldName == 'id') {
$pseudoOptions = CRM_Core_PseudoConstant::group();
}
elseif ($daoName == 'CRM_Batch_BAO_EntityBatch' && $fieldName == 'batch_id') {
$pseudoOptions = CRM_Contribute_PseudoConstant::batch();
}
elseif ($daoName) {
$pseudoOptions = CRM_Core_PseudoConstant::get($daoName, $fieldName, $pseudoExtraParam);
}

//API usually have fieldValue format as array(operator => array(values)),
//so we need to separate operator out of fieldValue param
if (is_array($fieldValue) && in_array(key($fieldValue), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
$op = key($fieldValue);
$fieldValue = $fieldValue[$op];
}

if (is_array($fieldValue)) {
$qillString = array();
if (!empty($pseudoOptions)) {
Expand Down Expand Up @@ -6055,6 +6058,9 @@ public static function getWildCardedValue($wildcard, $op, $value) {
* Array of fields whose name should be changed
*/
public static function processSpecialFormValue(&$formValues, $specialFields, $changeNames = array()) {
// Array of special fields whose value are considered only for NULL or EMPTY operators
$nullableFields = array('contribution_batch_id');

foreach ($specialFields as $element) {
$value = CRM_Utils_Array::value($element, $formValues);
if ($value) {
Expand All @@ -6065,7 +6071,10 @@ public static function processSpecialFormValue(&$formValues, $specialFields, $ch
}
$formValues[$element] = array('IN' => $value);
}
else {
elseif (in_array($value, array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))) {
$formValues[$element] = array($value => 1);
}
elseif (!in_array($element, $nullableFields)) {
// if wildcard is already present return searchString as it is OR append and/or prepend with wildcard
$isWilcard = strstr($value, '%') ? FALSE : CRM_Core_Config::singleton()->includeWildCardInName;
$formValues[$element] = array('LIKE' => self::getWildCardedValue($isWilcard, 'LIKE', $value));
Expand Down
12 changes: 8 additions & 4 deletions CRM/Contribute/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,9 @@ public static function whereClauseSingle(&$values, &$query) {
return;

case 'contribution_batch_id':
$batches = CRM_Contribute_PseudoConstant::batch();
$query->_where[$grouping][] = " civicrm_entity_batch.batch_id $op $value";
$query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $op, 2 => $batches[$value]));
list($qillOp, $qillValue) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Batch_BAO_EntityBatch', 'batch_id', $value, $op);
$query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $qillOp, 2 => $qillValue));
$query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause('civicrm_entity_batch.batch_id', $op, $value);
$query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1;
$query->_tables['contribution_batch'] = $query->_whereTables['contribution_batch'] = 1;
return;
Expand Down Expand Up @@ -1123,7 +1123,11 @@ public static function buildSearchForm(&$form) {
if (!empty($batches)) {
$form->add('select', 'contribution_batch_id',
ts('Batch Name'),
array('' => ts('- any -')) + $batches,
array(
'' => ts('- any -'),
// CRM-19325
'IS NULL' => ts('None'),
) + $batches,
FALSE, array('class' => 'crm-select2')
);
}
Expand Down
1 change: 1 addition & 0 deletions CRM/Contribute/Form/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ public function postProcess() {
'contribution_product_id',
'invoice_id',
'payment_instrument_id',
'contribution_batch_id',
);
CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams);

Expand Down
170 changes: 170 additions & 0 deletions tests/phpunit/CRM/Contribute/Form/Search.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2016 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

/**
* Include parent class definition
*/

/**
* Test Contribution Search form filters
*
* @package CiviCRM
*/
class CRM_Contribute_Form_Search extends CiviUnitTestCase {

protected $_individual;
protected $_tablesToTruncate = array('civicrm_contribution');

public function setUp() {
$this->_individual = $this->individualCreate();
parent::setUp();
}

public function tearDown() {
}

/**
* CRM-19325: Test CRM_Contribute_Form_Search batch filters
*/
public function testBatchFilter() {
$this->quickCleanup($this->_tablesToTruncate);
$contactID1 = $this->individualCreate(array(), 1);
$contactID2 = $this->individualCreate(array(), 2);
$batchTitle = CRM_Batch_BAO_Batch::generateBatchName();

// create batch
$batch = civicrm_api3('Batch', 'create', array(
'created_id' => $this->_individual,
'created_date' => CRM_Utils_Date::processDate(date("Y-m-d"), date("H:i:s")),
'status_id' => CRM_Core_OptionGroup::getValue('batch_status', 'Data Entry', 'name'),
'title' => $batchTitle,
'item_count' => 2,
'total' => 100,
'type_id' => array_search('Contribution', CRM_Batch_BAO_Batch::buildOptions('type_id')),
));
$batchID = $batch['id'];

$batchEntry = array(
'primary_profiles' => array(1 => NULL, 2 => NULL, 3 => NULL),
'primary_contact_id' => array(
1 => $contactID1,
2 => $contactID2,
),
'field' => array(
1 => array(
'financial_type' => 1,
'total_amount' => 70,
'receive_date' => '07/24/2013',
'receive_date_time' => NULL,
'payment_instrument' => 1,
'check_number' => NULL,
'contribution_status_id' => 1,
),
2 => array(
'financial_type' => 1,
'total_amount' => 30,
'receive_date' => '07/24/2013',
'receive_date_time' => NULL,
'payment_instrument' => 1,
'check_number' => NULL,
'contribution_status_id' => 1,
),
),
'actualBatchTotal' => 100,
);

// create random contribution to check IS NULL filter more precisely
$nonBatchContri = civicrm_api3('Contribution', 'create', array(
'financial_type_id' => 1,
'total_amount' => 123,
'receive_date' => '07/24/2014',
'receive_date_time' => NULL,
'payment_instrument' => 1,
'check_number' => NULL,
'contribution_status_id' => 1,
'contact_id' => $this->_individual,
));
$nonBatchContriID = $nonBatchContri['id'];

// process batch entries
$form = new CRM_Batch_Form_Entry();
$form->setBatchID($batchID);
$form->testProcessContribution($batchEntry);

// fetch created contributions
$entities = civicrm_api3('EntityBatch', 'get', array('batch_id' => $batchID));
$ids = array();
foreach ($entities['values'] as $value) {
$ids[] = $value['entity_id'];
}
list($batchContriID1, $batchContriID2) = $ids;

$useCases = array(
// Case 1: Search for ONLY those contributions which are created from batch
array(
'form_value' => array('contribution_batch_id' => 'IS NOT NULL'),
'expected_count' => 2,
'expected_contribution' => array($batchContriID1, $batchContriID2),
'expected_qill' => 'Batch Name Not Null',
),
// Case 2: Search for ONLY those contributions which are NOT created from batch
array(
'form_value' => array('contribution_batch_id' => 'IS NULL'),
'expected_count' => 1,
'expected_contribution' => array($nonBatchContriID),
'expected_qill' => 'Batch Name Is Null',
),
// Case 3: Search for ONLY those contributions which are created from batch ID - $batchID
array(
'form_value' => array('contribution_batch_id' => $batchID),
'expected_count' => 2,
'expected_contribution' => array($batchContriID1, $batchContriID2),
'expected_qill' => 'Batch Name = ' . $batchTitle,
),
);
foreach ($useCases as $case) {
$fv = $case['form_value'];
CRM_Contact_BAO_Query::processSpecialFormValue($fv, array('contribution_batch_id'));
$query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($fv));
list($select, $from, $where, $having) = $query->query();

// get and assert contribution count
$contributions = CRM_Core_DAO::executeQuery(sprintf('SELECT DISTINCT civicrm_contribution.id %s %s AND civicrm_contribution.id IS NOT NULL', $from, $where))->fetchAll();
foreach ($contributions as $key => $value) {
$contributions[$key] = $value['id'];
}
// assert the contribution count
$this->assertEquals($case['expected_count'], count($contributions));
// assert the contribution IDs
$this->checkArrayEquals($case['expected_contribution'], $contributions);
// get and assert qill string
$qill = trim(implode($query->getOperator(), CRM_Utils_Array::value(0, $query->qill())));
$this->assertEquals($case['expected_qill'], $qill);
}
}

}

0 comments on commit efcfb86

Please sign in to comment.