From 669fc25ee8c2fad86e0bb8304c06d6516651b641 Mon Sep 17 00:00:00 2001 From: Camilo Rodriguez Date: Fri, 30 Mar 2018 15:24:11 +0000 Subject: [PATCH] CRM-38: Show Recurring Contributions on Membership Modal View Currently, when viewing a membership from contact's detailed view (on memberships tab), it is hard to tell if a membership has any recurring contributions associated to it, even though you can see all payments done for the membership. Added a recurring contributions section below the contributions table currently being shown, by loading recurring contributions using ajax call to load list of recurring contributions. Added recurring contributionslist to membership edit view using ajax call. --- CRM/Contribute/xml/Menu/Contribute.xml | 6 + CRM/Member/Form/MembershipView.php | 37 +++-- CRM/Member/Page/RecurringContributions.php | 155 ++++++++++++++++++ Civi/Test/Api3TestTrait.php | 6 +- templates/CRM/Member/Form/Membership.tpl | 28 +++- templates/CRM/Member/Form/MembershipView.tpl | 38 ++++- .../Member/Page/RecurringContributions.tpl | 6 + 7 files changed, 256 insertions(+), 20 deletions(-) create mode 100644 CRM/Member/Page/RecurringContributions.php create mode 100644 templates/CRM/Member/Page/RecurringContributions.tpl diff --git a/CRM/Contribute/xml/Menu/Contribute.xml b/CRM/Contribute/xml/Menu/Contribute.xml index 3b3d94a7b3..548902dbc0 100644 --- a/CRM/Contribute/xml/Menu/Contribute.xml +++ b/CRM/Contribute/xml/Menu/Contribute.xml @@ -329,4 +329,10 @@ CRM_Contribute_Page_ContributionRecurPayments access CiviContribute + + civicrm/membership/recurring-contributions + Membership Recurring Contributions + CRM_Member_Page_RecurringContributions + access CiviContribute + diff --git a/CRM/Member/Form/MembershipView.php b/CRM/Member/Form/MembershipView.php index ac54c6a506..75eec53687 100644 --- a/CRM/Member/Form/MembershipView.php +++ b/CRM/Member/Form/MembershipView.php @@ -35,7 +35,6 @@ /** * This class generates form components for Payment-Instrument - * */ class CRM_Member_Form_MembershipView extends CRM_Core_Form { @@ -46,6 +45,20 @@ class CRM_Member_Form_MembershipView extends CRM_Core_Form { */ static $_links = NULL; + /** + * The id of the membership being viewed. + * + * @var int + */ + private $membershipID; + + /** + * Contact's ID. + * + * @var int + */ + private $contactID; + /** * Add context information at the end of a link. * @@ -148,16 +161,16 @@ class CRM_Member_Form_MembershipView extends CRM_Core_Form { * @return void */ public function preProcess() { - $values = array(); - $id = CRM_Utils_Request::retrieve('id', 'Positive', $this); + $this->membershipID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + $this->contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this); // Make sure context is assigned to template for condition where we come here view civicrm/membership/view $context = CRM_Utils_Request::retrieve('context', 'String', $this); $this->assign('context', $context); - if ($id) { - $params = array('id' => $id); + if ($this->membershipID) { + $params = array('id' => $this->membershipID); CRM_Member_BAO_Membership::retrieve($params, $values); if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) { $finTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'financial_type_id'); @@ -181,12 +194,12 @@ class CRM_Member_Form_MembershipView extends CRM_Core_Form { $this->assign('accessContribution', FALSE); if (CRM_Core_Permission::access('CiviContribute')) { $this->assign('accessContribution', TRUE); - CRM_Member_Page_Tab::associatedContribution($values['contact_id'], $id); + CRM_Member_Page_Tab::associatedContribution($values['contact_id'], $this->membershipID); } //Provide information about membership source when it is the result of a relationship (CRM-1901) $values['owner_membership_id'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', - $id, + $this->membershipID, 'owner_membership_id' ); @@ -375,12 +388,12 @@ SELECT r.id, c.id as cid, c.display_name as name, c.job_title as comment, CRM_Member_Page_Tab::setContext($this, $values['contact_id']); - $memType = CRM_Core_DAO::getFieldValue("CRM_Member_DAO_Membership", $id, "membership_type_id"); + $memType = CRM_Core_DAO::getFieldValue("CRM_Member_DAO_Membership", $this->membershipID, "membership_type_id"); - $groupTree = CRM_Core_BAO_CustomGroup::getTree('Membership', NULL, $id, 0, $memType); - CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $id); + $groupTree = CRM_Core_BAO_CustomGroup::getTree('Membership', NULL, $this->membershipID, 0, $memType); + CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $this->membershipID); - $isRecur = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $id, 'contribution_recur_id'); + $isRecur = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->membershipID, 'contribution_recur_id'); $autoRenew = $isRecur ? TRUE : FALSE; } @@ -389,7 +402,7 @@ SELECT r.id, c.id as cid, c.display_name as name, c.job_title as comment, $values['membership_type'] .= ' (test) '; } - $subscriptionCancelled = CRM_Member_BAO_Membership::isSubscriptionCancelled($id); + $subscriptionCancelled = CRM_Member_BAO_Membership::isSubscriptionCancelled($this->membershipID); $values['auto_renew'] = ($autoRenew && !$subscriptionCancelled) ? 'Yes' : 'No'; //do check for campaigns diff --git a/CRM/Member/Page/RecurringContributions.php b/CRM/Member/Page/RecurringContributions.php new file mode 100644 index 0000000000..a91d224a7f --- /dev/null +++ b/CRM/Member/Page/RecurringContributions.php @@ -0,0 +1,155 @@ +membershipID = CRM_Utils_Request::retrieve('membershipID', 'Positive', $this); + $this->contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE); + + $this->loadRecurringContributions(); + + return parent::run(); + } + + /** + * Loads recurring contributions and assigns them to the form, to be used on + * the template. + */ + private function loadRecurringContributions() { + $recurringContributions = $this->getRecurContributions($this->membershipID); + + if (!empty($recurringContributions)) { + $this->assign('recurRows', $recurringContributions); + $this->assign('recur', TRUE); + } + } + + /** + * Obtains list of recurring contributions associated to a membership. + * + * @param int $membershipID + * + * @return array + */ + private function getRecurContributions($membershipID) { + $result = civicrm_api3('MembershipPayment', 'get', array( + 'sequential' => 1, + 'contribution_id.contribution_recur_id.id' => ['IS NOT NULL' => TRUE], + 'options' => ['limit' => 0], + 'return' => array( + 'contribution_id.contribution_recur_id.id', + 'contribution_id.contribution_recur_id.contact_id', + 'contribution_id.contribution_recur_id.start_date', + 'contribution_id.contribution_recur_id.end_date', + 'contribution_id.contribution_recur_id.next_sched_contribution_date', + 'contribution_id.contribution_recur_id.amount', + 'contribution_id.contribution_recur_id.currency', + 'contribution_id.contribution_recur_id.frequency_unit', + 'contribution_id.contribution_recur_id.frequency_interval', + 'contribution_id.contribution_recur_id.installments', + 'contribution_id.contribution_recur_id.contribution_status_id', + 'contribution_id.contribution_recur_id.is_test', + 'contribution_id.contribution_recur_id.payment_processor_id', + ), + 'membership_id' => $membershipID, + )); + $recurringContributions = array(); + $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(); + + foreach ($result['values'] as $payment) { + $recurringContributionID = $payment['contribution_id.contribution_recur_id.id']; + $alreadyProcessed = isset($recurringContributions[$recurringContributionID]); + + if ($alreadyProcessed) { + continue; + } + + foreach ($payment as $field => $value) { + $key = strtr($field, array('contribution_id.contribution_recur_id.' => '')); + $recurringContributions[$recurringContributionID][$key] = $value; + } + + $contactID = $recurringContributions[$recurringContributionID]['contact_id']; + $contributionStatusID = $recurringContributions[$recurringContributionID]['contribution_status_id']; + + $recurringContributions[$recurringContributionID]['id'] = $recurringContributionID; + $recurringContributions[$recurringContributionID]['contactId'] = $contactID; + $recurringContributions[$recurringContributionID]['contribution_status'] = CRM_Utils_Array::value($contributionStatusID, $contributionStatuses); + + $this->setActionsForRecurringContribution($recurringContributionID, $recurringContributions[$recurringContributionID]); + } + return $recurringContributions; + } + + /** + * Calculates and assigns the actions available for given recurring + * contribution. + * + * @param int $recurID + * @param array $recurringContribution + */ + private function setActionsForRecurringContribution($recurID, &$recurringContribution) { + $action = array_sum(array_keys($this->recurLinks($recurID))); + // no action allowed if it's not active + $recurringContribution['is_active'] = ($recurringContribution['contribution_status_id'] != 3); + if ($recurringContribution['is_active']) { + $details = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recurringContribution['id'], 'recur'); + $hideUpdate = $details->membership_id & $details->auto_renew; + if ($hideUpdate || empty($details->processor_id)) { + $action -= CRM_Core_Action::UPDATE; + } + $recurringContribution['action'] = CRM_Core_Action::formLink( + $this->recurLinks($recurID), + $action, + array( + 'cid' => $this->contactID, + 'crid' => $recurID, + 'cxt' => 'contribution', + ), + ts('more'), + FALSE, + 'contribution.selector.recurring', + 'Contribution', + $recurID + ); + } + } + + /** + * This method returns the links that are given for recur search row. + * currently the links added for each row are: + * - View + * - Edit + * - Cancel + * + * @param bool $id + * + * @return array + */ + private function recurLinks($id) { + return CRM_Contribute_Page_Tab::recurLinks($id, 'contribution'); + } + +} diff --git a/Civi/Test/Api3TestTrait.php b/Civi/Test/Api3TestTrait.php index 46880df32b..1efcd13ce6 100644 --- a/Civi/Test/Api3TestTrait.php +++ b/Civi/Test/Api3TestTrait.php @@ -160,7 +160,7 @@ trait Api3TestTrait { * @param string $entity * @param array $params * @param null $count - * @throws Exception + * @throws \Exception * @return array|int */ public function callAPISuccessGetCount($entity, $params, $count = NULL) { @@ -170,7 +170,7 @@ trait Api3TestTrait { ); $result = $this->civicrm_api($entity, 'getcount', $params); if (!is_int($result) || !empty($result['is_error']) || isset($result['values'])) { - throw new Exception('Invalid getcount result : ' . print_r($result, TRUE) . " type :" . gettype($result)); + throw new \Exception('Invalid getcount result : ' . print_r($result, TRUE) . " type :" . gettype($result)); } if (is_int($count)) { $this->assertEquals($count, $result, "incorrect count returned from $entity getcount"); @@ -193,7 +193,7 @@ trait Api3TestTrait { * - array * - object * - * @throws Exception + * @throws \Exception * @return array|int */ public function callAPISuccessGetSingle($entity, $params, $checkAgainst = NULL) { diff --git a/templates/CRM/Member/Form/Membership.tpl b/templates/CRM/Member/Form/Membership.tpl index 16b3f09012..683c543ea4 100644 --- a/templates/CRM/Member/Form/Membership.tpl +++ b/templates/CRM/Member/Form/Membership.tpl @@ -224,7 +224,33 @@ {if $accessContribution and $action eq 2 and $rows.0.contribution_id}
{ts}Related Contributions{/ts}
-
{include file="CRM/Contribute/Form/Selector.tpl" context="Search"}
+
+ {include file="CRM/Contribute/Form/Selector.tpl" context="Search"} + +
+
{/if} {if $softCredit} diff --git a/templates/CRM/Member/Form/MembershipView.tpl b/templates/CRM/Member/Form/MembershipView.tpl index a5d4ddaa40..87405f107a 100644 --- a/templates/CRM/Member/Form/MembershipView.tpl +++ b/templates/CRM/Member/Form/MembershipView.tpl @@ -73,11 +73,41 @@ {include file="CRM/Custom/Page/CustomDataView.tpl"} - {if $accessContribution and $rows.0.contribution_id} -
-
{ts}Related Contributions{/ts}
-
{include file="CRM/Contribute/Form/Selector.tpl" context="Search"}
+ {if $accessContribution} +
+
+ {ts}Related Contributions and Recurring Contributions{/ts} +
+
+ {if $rows.0.contribution_id} + {include file="CRM/Contribute/Form/Selector.tpl" context="Search"} + {/if} + +
+
{/if} {if $softCredit} diff --git a/templates/CRM/Member/Page/RecurringContributions.tpl b/templates/CRM/Member/Page/RecurringContributions.tpl new file mode 100644 index 0000000000..37dcdc227a --- /dev/null +++ b/templates/CRM/Member/Page/RecurringContributions.tpl @@ -0,0 +1,6 @@ +{if $recur} +
+
+
+ {include file="CRM/Contribute/Page/ContributionRecur.tpl" action=16} +{/if} -- 2.25.1