From 5af1389d5be14bb56f3429145e7952e20075e102 Mon Sep 17 00:00:00 2001 From: Victor Huang Date: Fri, 6 Oct 2017 16:21:00 -0600 Subject: [PATCH] Add field in "Advanced Search" to search for contacts with specific recurring contribution status(es). CRM_Contribute_BAO_ContributionRecur: add multi-select dropdown field to select recurring contribution status. CRM_Contribute_BAO_Query: add case to construct where clause for recurring contribution status. templates/CRM/Contribute/Form/Search/ContributionRecur.tpl: add recurring contribution status field in template. civicrm/civicrm-core#11080 Add quotes around recurring contribution status qill. civicrm/civicrm-core#11080 Directly use CRM_Contribute_PseudoConstant::contributionStatus() instead of creating variable that is not used anywhere else. Remove space after closing ) to comply with coding standard Remove comma after closing ) to comply with coding standard Add unit test for recurring contribution status filter Fix coding style error: The closing brace for the class must have an empty line before it Do not use variable replacement in qill for static text "Recurring Contribution Status". --- CRM/Contribute/BAO/ContributionRecur.php | 6 + CRM/Contribute/BAO/Query.php | 7 ++ .../Form/Search/ContributionRecur.tpl | 7 ++ .../CRM/Contribute/Form/SearchTest.php | 116 ++++++++++++++++++ 4 files changed, 136 insertions(+) diff --git a/CRM/Contribute/BAO/ContributionRecur.php b/CRM/Contribute/BAO/ContributionRecur.php index bb6d30b735..9ea55f7714 100644 --- a/CRM/Contribute/BAO/ContributionRecur.php +++ b/CRM/Contribute/BAO/ContributionRecur.php @@ -777,6 +777,12 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) CRM_Core_Form_Date::buildDateRange($form, 'contribution_recur_next_sched_contribution_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth'); CRM_Core_Form_Date::buildDateRange($form, 'contribution_recur_failure_retry_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth'); CRM_Core_Form_Date::buildDateRange($form, 'contribution_recur_cancel_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth'); + + // Add field for contribution status + $form->addSelect('contribution_recur_contribution_status_id', + array('entity' => 'contribution', 'multiple' => 'multiple', 'context' => 'search', 'options' => CRM_Contribute_PseudoConstant::contributionStatus()) + ); + $form->addElement('text', 'contribution_recur_processor_id', ts('Processor ID'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionRecur', 'processor_id')); $form->addElement('text', 'contribution_recur_trxn_id', ts('Transaction ID'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionRecur', 'trxn_id')); diff --git a/CRM/Contribute/BAO/Query.php b/CRM/Contribute/BAO/Query.php index e402e7c213..8e5e1b06cd 100644 --- a/CRM/Contribute/BAO/Query.php +++ b/CRM/Contribute/BAO/Query.php @@ -386,6 +386,13 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_tables['civicrm_contribution_recur'] = $query->_whereTables['civicrm_contribution_recur'] = 1; return; + case 'contribution_recur_contribution_status_id': + $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution_recur.contribution_status_id", $op, $value, 'String'); + list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contribute_DAO_ContributionRecur', 'contribution_status_id', $value, $op, $pseudoExtraParam); + $query->_qill[$grouping][] = ts("Recurring Contribution Status %1 '%2'", array(1 => $op, 2 => $value)); + $query->_tables['civicrm_contribution_recur'] = $query->_whereTables['civicrm_contribution_recur'] = 1; + return; + case 'contribution_note': $value = $strtolower(CRM_Core_DAO::escapeString($value)); if ($wildcard) { diff --git a/templates/CRM/Contribute/Form/Search/ContributionRecur.tpl b/templates/CRM/Contribute/Form/Search/ContributionRecur.tpl index ca8e0fed9c..0da3209080 100644 --- a/templates/CRM/Contribute/Form/Search/ContributionRecur.tpl +++ b/templates/CRM/Contribute/Form/Search/ContributionRecur.tpl @@ -70,6 +70,13 @@ {include file="CRM/Core/DateRange.tpl" fieldName="contribution_recur_cancel_date" from='_low' to='_high'} + + {ts}Recurring Contribution Status{/ts} + + + {$form.contribution_recur_contribution_status_id.html|crmAddClass:twenty} + + {if $contributionRecurGroupTree} diff --git a/tests/phpunit/CRM/Contribute/Form/SearchTest.php b/tests/phpunit/CRM/Contribute/Form/SearchTest.php index 5d948a0e69..780ab5f21a 100644 --- a/tests/phpunit/CRM/Contribute/Form/SearchTest.php +++ b/tests/phpunit/CRM/Contribute/Form/SearchTest.php @@ -372,4 +372,120 @@ class CRM_Contribute_Form_SearchTest extends CiviUnitTestCase { } } + /** + * Test CRM_Contribute_Form_Search Recurring Contribution Status Id filters + */ + public function testContributionRecurStatusFilter() { + $this->quickCleanup($this->_tablesToTruncate); + $contactID1 = $this->individualCreate(array(), 1); + $contactID2 = $this->individualCreate(array(), 2); + // "In Progress" recurring contribution for contactID1 + $ContributionRecur1 = $this->callAPISuccess('ContributionRecur', 'create', array( + 'sequential' => 1, + 'contact_id' => $contactID1, + 'frequency_interval' => 1, + 'frequency_unit' => "month", + 'amount' => 11, + 'currency' => "CAD", + 'payment_instrument_id' => 1, + 'contribution_status_id' => 5, + 'financial_type_id' => "Donation", + )); + $Contribution1 = $this->callAPISuccess('Contribution', 'create', array( + 'financial_type_id' => 1, + 'total_amount' => 11, + 'receive_date' => date('Ymd'), + 'receive_date_time' => NULL, + 'payment_instrument_id' => 1, + 'contribution_status_id' => 1, + 'contact_id' => $contactID1, + 'contribution_recur_id' => $ContributionRecur1['id'], + 'financial_type_id' => "Donation", + )); + $params = array( + 'to_financial_account_id' => 1, + 'status_id' => 1, + 'contribution_id' => $Contribution1['id'], + 'payment_instrument_id' => 1, + 'card_type_id' => 1, + 'total_amount' => 11, + ); + CRM_Core_BAO_FinancialTrxn::create($params); + // "Completed" recurring contribution for contactID2 + $ContributionRecur2 = $this->callAPISuccess('ContributionRecur', 'create', array( + 'sequential' => 1, + 'contact_id' => $contactID2, + 'frequency_interval' => 1, + 'frequency_unit' => "month", + 'amount' => 22, + 'currency' => "CAD", + 'payment_instrument_id' => 1, + 'contribution_status_id' => 1, + 'financial_type_id' => "Donation", + )); + $Contribution2 = $this->callAPISuccess('Contribution', 'create', array( + 'financial_type_id' => 1, + 'total_amount' => 22, + 'receive_date' => date('Ymd'), + 'receive_date_time' => NULL, + 'payment_instrument' => 1, + 'contribution_status_id' => 1, + 'contact_id' => $contactID2, + 'contribution_recur_id' => $ContributionRecur2['id'], + 'financial_type_id' => "Donation", + )); + $params = array( + 'to_financial_account_id' => 1, + 'status_id' => 1, + 'contribution_id' => $Contribution2['id'], + 'payment_instrument_id' => 1, + 'card_type_id' => 1, + 'total_amount' => 22, + ); + CRM_Core_BAO_FinancialTrxn::create($params); + + $useCases = array( + // Case 1: Search for ONLY those recurring contributions with status "In Progress" + array( + 'form_value' => array('contribution_recur_contribution_status_id' => 5), + 'expected_count' => 1, + 'expected_contact' => array($contactID1), + 'expected_qill' => "Recurring Contribution Status = 'In Progress'", + ), + // Case 2: Search for ONLY those recurring contributions with status "Completed" + array( + 'form_value' => array('contribution_recur_contribution_status_id' => 1), + 'expected_count' => 1, + 'expected_contact' => array($contactID2), + 'expected_qill' => "Recurring Contribution Status = 'Completed'", + ), + // Case 3: Search for ONLY those recurring contributions with status "Cancelled" + array( + 'form_value' => array('contribution_recur_contribution_status_id' => 3), + 'expected_count' => 0, + 'expected_contact' => array(), + 'expected_qill' => "Recurring Contribution Status = 'Cancelled'", + ), + ); + + foreach ($useCases as $case) { + $fv = $case['form_value']; + $query = new CRM_Contact_BAO_Query(CRM_Contact_BAO_Query::convertFormValues($fv)); + list($select, $from, $where, $having) = $query->query(); + + // get and assert contribution count + $contacts = CRM_Core_DAO::executeQuery(sprintf('SELECT DISTINCT contact_a.id %s %s AND contact_a.id IS NOT NULL', $from, $where))->fetchAll(); + foreach ($contacts as $key => $value) { + $contacts[$key] = $value['id']; + } + // assert the contribution count + $this->assertEquals($case['expected_count'], count($contacts)); + // assert the contribution IDs + $this->checkArrayEquals($case['expected_contact'], $contacts); + // get and assert qill string + $qill = trim(implode($query->getOperator(), CRM_Utils_Array::value(0, $query->qill()))); + $this->assertEquals($case['expected_qill'], $qill); + } + } + } -- 2.25.1