diff --git a/api/v3/Membership.php b/api/v3/Membership.php index 52e64b8b741b..c7a3b1d5e478 100644 --- a/api/v3/Membership.php +++ b/api/v3/Membership.php @@ -90,9 +90,19 @@ function civicrm_api3_membership_create($params) { // Calculate membership dates // Fixme: This code belongs in the BAO - if (!empty($params['num_terms'])) { + if (empty($params['id']) || !empty($params['num_terms'])) { // If this is a new membership or we have a specified number of terms calculate membership dates. - if (!empty($params['id'])) { + if (empty($params['id'])) { + // This is a new membership, calculate the membership dates. + $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType( + $params['membership_type_id'], + CRM_Utils_Array::value('join_date', $params), + CRM_Utils_Array::value('start_date', $params), + CRM_Utils_Array::value('end_date', $params), + CRM_Utils_Array::value('num_terms', $params, 1) + ); + } + else { // This is an existing membership, calculate the membership dates after renewal // num_terms is treated as a 'special sauce' for is_renewal but this // isn't really helpful for completing pendings. @@ -102,10 +112,10 @@ function civicrm_api3_membership_create($params) { CRM_Utils_Array::value('membership_type_id', $params), $params['num_terms'] ); - foreach (['join_date', 'start_date', 'end_date'] as $date) { - if (empty($params[$date]) && isset($calcDates[$date])) { - $params[$date] = $calcDates[$date]; - } + } + foreach (['join_date', 'start_date', 'end_date'] as $date) { + if (empty($params[$date]) && isset($calcDates[$date])) { + $params[$date] = $calcDates[$date]; } } } diff --git a/tests/phpunit/api/v3/MembershipTest.php b/tests/phpunit/api/v3/MembershipTest.php index 83d7846f4c45..6ac84c70ebb5 100644 --- a/tests/phpunit/api/v3/MembershipTest.php +++ b/tests/phpunit/api/v3/MembershipTest.php @@ -846,12 +846,33 @@ public function testMembershipGetWithReturn() { ///////////////// civicrm_membership_create methods /** - * Test civicrm_contact_memberships_create with empty params. - * Error expected. + * Test dates are calculated for pending membership. */ - public function testCreateWithEmptyParams() { - $params = []; - $this->callAPIFailure('membership', 'create', $params); + public function testCreatePending(): void { + $membership = $this->callAPISuccess('Membership', 'create', [ + 'contact_id' => $this->individualCreate(), + 'membership_type_id' => 'General', + 'status_id' => 'Pending', + 'sequential' => 1, + ])['values'][0]; + $this->assertEquals(date('Ymd'), $membership['start_date']); + $this->assertEquals(date('Ymd', strtotime('+1 year -1 day')), $membership['end_date']); + } + + /** + * Test dates are calculated for pending membership. + */ + public function testCreatePendingWithSkipStatusCalc(): void { + $membership = $this->callAPISuccess('Membership', 'create', [ + 'contact_id' => $this->individualCreate(), + 'membership_type_id' => 'General', + 'status_id' => 'Pending', + 'sequential' => 1, + 'skipStatusCal' => TRUE, + ])['values'][0]; + $this->assertEquals(date('Ymd'), $membership['start_date']); + $this->assertEquals(date('Ymd'), $membership['join_date']); + $this->assertEquals(date('Ymd', strtotime('+1 year -1 day')), $membership['end_date']); } /**