From a9f44ffb6649a07f634ce0549bee6e1ce3e14273 Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 26 Aug 2019 15:00:57 +1200 Subject: [PATCH] Prevent error on price set membership update --- CRM/Member/BAO/MembershipPayment.php | 4 + CRM/Price/BAO/LineItem.php | 3 + .../phpunit/CRM/Member/BAO/MembershipTest.php | 165 ++++++++++++++++++ 3 files changed, 172 insertions(+) diff --git a/CRM/Member/BAO/MembershipPayment.php b/CRM/Member/BAO/MembershipPayment.php index 7a509ec3e2..080fab308b 100644 --- a/CRM/Member/BAO/MembershipPayment.php +++ b/CRM/Member/BAO/MembershipPayment.php @@ -72,6 +72,10 @@ class CRM_Member_BAO_MembershipPayment extends CRM_Member_DAO_MembershipPayment // table. However, at this stage we have both - there is still quite a bit of refactoring to do to set the line_iten entity_id right the first time // however, we can assume at this stage that any contribution id will have only one line item with that membership type in the line item table // OR the caller will have taken responsibility for updating the line items themselves so we will update using SQL here + if (!empty($params['isSkipLineItem'])) { + // Caller has taken responsibility for updating the line items. + return $dao; + } if (!isset($params['membership_type_id'])) { $membership_type_id = civicrm_api3('membership', 'getvalue', [ 'id' => $dao->membership_id, diff --git a/CRM/Price/BAO/LineItem.php b/CRM/Price/BAO/LineItem.php index 04c5a5d3e2..e22915bd32 100644 --- a/CRM/Price/BAO/LineItem.php +++ b/CRM/Price/BAO/LineItem.php @@ -90,6 +90,9 @@ class CRM_Price_BAO_LineItem extends CRM_Price_DAO_LineItem { 'contribution_id' => $lineItemBAO->contribution_id, ]; if (!civicrm_api3('MembershipPayment', 'getcount', $membershipPaymentParams)) { + // If we are creating the membership payment row from the line item then we + // should have correct line item & membership payment should not need to fix. + $membershipPaymentParams['isSkipLineItem'] = TRUE; civicrm_api3('MembershipPayment', 'create', $membershipPaymentParams); } } diff --git a/tests/phpunit/CRM/Member/BAO/MembershipTest.php b/tests/phpunit/CRM/Member/BAO/MembershipTest.php index cf50231bba..1572dd1cae 100644 --- a/tests/phpunit/CRM/Member/BAO/MembershipTest.php +++ b/tests/phpunit/CRM/Member/BAO/MembershipTest.php @@ -778,4 +778,169 @@ class CRM_Member_BAO_MembershipTest extends CiviUnitTestCase { $this->assertEquals(1, $membershipAfterProcess['is_override']); } + /** + * @throws \CRM_Core_Exception + */ + public function testMembershipPaymentForSingleContributionMultipleMembership() { + $membershipTypeID1 = $this->membershipTypeCreate(['name' => 'Parent']); + $membershipTypeID2 = $this->membershipTypeCreate(['name' => 'Child']); + $financialTypeId = $this->getFinancialTypeId('Member Dues'); + $priceSet = $this->callAPISuccess('price_set', 'create', [ + 'is_quick_config' => 0, + 'extends' => 'CiviMember', + 'financial_type_id' => $financialTypeId, + 'title' => 'Family Membership', + ]); + $priceSetID = $priceSet['id']; + $priceField = $this->callAPISuccess('price_field', 'create', [ + 'price_set_id' => $priceSetID, + 'label' => 'Memberships', + 'html_type' => 'Radio', + ]); + $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', [ + 'price_set_id' => $priceSetID, + 'price_field_id' => $priceField['id'], + 'label' => 'Parent', + 'amount' => 100, + 'financial_type_id' => $financialTypeId, + 'membership_type_id' => $membershipTypeID1, + 'membership_num_terms' => 1, + ]); + $priceFieldValueId = [1 => $priceFieldValue['id']]; + $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', [ + 'price_set_id' => $priceSetID, + 'price_field_id' => $priceField['id'], + 'label' => 'Child', + 'amount' => 50, + 'financial_type_id' => $financialTypeId, + 'membership_type_id' => $membershipTypeID2, + 'membership_num_terms' => 1, + ]); + $priceFieldValueId[2] = $priceFieldValue['id']; + $parentContactId = $this->individualCreate(); + $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', [ + 'contact_id' => $parentContactId, + 'amount' => 200, + 'frequency_unit' => 'day', + 'frequency_interval' => 1, + 'installments' => 2, + 'start_date' => 'yesterday', + 'create_date' => 'yesterday', + 'modified_date' => 'yesterday', + 'cancel_date' => NULL, + 'end_date' => '+ 2 weeks', + 'processor_id' => '643411460836', + 'trxn_id' => 'e0d0808e26f3e661c6c18eb7c039d363', + 'invoice_id' => 'e0d0808e26f3e661c6c18eb7c039d363', + 'contribution_status_id' => 'In Progress', + 'cycle_day' => 1, + 'next_sched_contribution_date' => '+ 1 week', + 'auto_renew' => 0, + 'currency' => 'USD', + 'payment_processor_id' => $this->paymentProcessorCreate(), + 'financial_type_id' => $financialTypeId, + 'payment_instrument_id' => 'Credit Card', + ]); + $contribution = $this->callAPISuccess('contribution', 'create', [ + 'total_amount' => 200, + 'contribution_recur_id' => $contributionRecur['id'], + 'currency' => 'USD', + 'contact_id' => $parentContactId, + 'financial_type_id' => $financialTypeId, + 'contribution_status_id' => 'Completed', + 'skipLineItem' => TRUE, + 'is_recur' => TRUE, + ]); + $params[] = [ + 'contact_id' => $parentContactId, + 'membership_type_id' => $membershipTypeID1, + 'contribution_recur_id' => $contributionRecur['id'], + 'join_date' => date('Ymd', time()), + 'start_date' => date('Ymd', time()), + 'end_date' => date('Ymd', strtotime('+1 year')), + 'skipLineItem' => TRUE, + 'source' => 'Payment', + 'line_items' => [ + 'price_field_id' => $priceField['id'], + 'price_field_value_id' => $priceFieldValueId[1], + 'label' => 'Parent', + 'contribution_id' => $contribution['id'], + 'membership_type_id' => $membershipTypeID1, + 'qty' => 1, + 'unit_price' => 100, + 'line_total' => 100, + 'financial_type_id' => $financialTypeId, + 'entity_table' => 'civicrm_membership', + ], + ]; + $params[] = [ + 'contact_id' => $this->individualCreate(), + 'membership_type_id' => $membershipTypeID2, + 'contribution_recur_id' => $contributionRecur['id'], + 'join_date' => date('Ymd', time()), + 'start_date' => date('Ymd', time()), + 'end_date' => date('Ymd', strtotime('+1 year')), + 'skipLineItem' => TRUE, + 'source' => 'Payment', + 'line_items' => [ + 'price_field_id' => $priceField['id'], + 'price_field_value_id' => $priceFieldValueId[2], + 'label' => 'Child', + 'contribution_id' => $contribution['id'], + 'qty' => 1, + 'unit_price' => 50, + 'line_total' => 50, + 'membership_type_id' => $membershipTypeID2, + 'financial_type_id' => $financialTypeId, + 'entity_table' => 'civicrm_membership', + ], + ]; + $params[] = [ + 'contact_id' => $this->individualCreate(), + 'membership_type_id' => $membershipTypeID2, + 'contribution_recur_id' => $contributionRecur['id'], + 'join_date' => date('Ymd', time()), + 'start_date' => date('Ymd', time()), + 'skipLineItem' => TRUE, + 'end_date' => date('Ymd', strtotime('+1 year')), + 'source' => 'Payment', + 'line_items' => [ + 'price_field_id' => $priceField['id'], + 'price_field_value_id' => $priceFieldValueId[2], + 'label' => 'Child', + 'contribution_id' => $contribution['id'], + 'qty' => 1, + 'membership_type_id' => $membershipTypeID2, + 'unit_price' => 50, + 'line_total' => 50, + 'financial_type_id' => $financialTypeId, + 'entity_table' => 'civicrm_membership', + ], + ]; + + foreach ($params as $key => $param) { + $membership = $this->callAPISuccess('membership', 'create', $param); + $param['line_items']['entity_id'] = $membership['id']; + $memPayments = new CRM_Member_BAO_MembershipPayment(); + $paymentParams = [ + 'membership_id' => $membership['id'], + 'contribution_id' => $contribution['id'], + ]; + $memPayments->copyValues($paymentParams); + $memPayments->save(); + $lineItemBAO = new CRM_Price_BAO_LineItem(); + $lineItemBAO->copyValues($param['line_items']); + $lineItemBAO->save(); + } + $this->callAPISuccess('contribution', 'repeattransaction', [ + 'original_contribution_id' => $contribution['id'], + 'contribution_status_id' => 'Completed', + 'trxn_id' => uniqid(), + ]); + $this->callAPISuccessGetCount('Contribution', [], 2); + $this->callAPISuccessGetCount('LineItem', [], 6); + $this->membershipTypeDelete(['id' => $membershipTypeID1]); + $this->membershipTypeDelete(['id' => $membershipTypeID2]); + } + } -- 2.25.1