From c9c413974337815e2e2f66ca3843d3d19bbf4eef Mon Sep 17 00:00:00 2001 From: eileen Date: Wed, 7 Aug 2013 09:12:56 +1200 Subject: [PATCH] CRM-13159 enable 'membership_type' as a param on relationship get, display count of available relationships on back-office member form using this --- CRM/Contact/BAO/Relationship.php | 44 ++++++++ api/v3/Relationship.php | 4 + templates/CRM/Member/Form/Membership.tpl | 16 +++ tests/phpunit/api/v3/RelationshipTest.php | 121 +++++++++++++++++++++- 4 files changed, 180 insertions(+), 5 deletions(-) diff --git a/CRM/Contact/BAO/Relationship.php b/CRM/Contact/BAO/Relationship.php index 0078f89eac..9077f8f9b4 100644 --- a/CRM/Contact/BAO/Relationship.php +++ b/CRM/Contact/BAO/Relationship.php @@ -887,6 +887,9 @@ LEFT JOIN civicrm_country ON (civicrm_address.country_id = civicrm_country.id) // CRM-6181 $where .= ' AND civicrm_contact.is_deleted = 0'; + if(!empty($params['membership_type_id']) && empty($params['relationship_type_id'])) { + $where .= self::membershipTypeToRelationshipTypes($params, $direction); + } if(!empty($params['relationship_type_id'])) { if(is_array($params['relationship_type_id'])) { $where .= " AND " . CRM_Core_DAO::createSQLFilter('relationship_type_id', $params['relationship_type_id'], 'Integer'); @@ -1534,5 +1537,46 @@ cc.sort_name LIKE '%$name%'"; } return TRUE; } + + /** + * Function filters the query by possible relationships for the membership type + * It is intended to be called when constructing queries for the api (reciprocal & non-reciprocal) + * and to add clauses to limit the return to those relationships which COULD inherit a membership type + * (as opposed to those who inherit a particular membership + * + * @param array $params api input array + */ + static function membershipTypeToRelationshipTypes(&$params, $direction = NULL) { + $membershipType = civicrm_api3('membership_type', 'getsingle', array('id' => $params['membership_type_id'], 'return' => 'relationship_type_id, relationship_direction')); + $relationshipTypes = $membershipType['relationship_type_id']; + // if we don't have any contact data we can only filter on type + if(empty($params['contact_id']) && empty($params['contact_id_a']) && empty($params['contact_id_a'])) { + $params['relationship_type_id'] = array('IN' => $relationshipTypes); + return; + } + else { + $relationshipDirections = $membershipType['relationship_direction']; + // if we have contact_id_a OR contact_id_b we can make a call here + // if we have contact?? + foreach ($relationshipDirections as $index => $mtdirection) { + if(isset($params['contact_id_a']) && $mtdirection == 'a_b' || $direction == 'a_b') { + $types[] = $relationshipTypes[$index]; + } + if(isset($params['contact_id_b']) && $mtdirection == 'b_a' || $direction == 'b_a') { + $types[] = $relationshipTypes[$index]; + } + } + if(!empty($types)) { + $params['relationship_type_id'] = array('IN' => $types); + } + elseif(!empty($clauses)) { + return explode(' OR ', $clauses); + } + else{ + // effectively setting it to return no results + $params['relationship_type_id'] = 0; + } + } + } } diff --git a/api/v3/Relationship.php b/api/v3/Relationship.php index 0e754690da..6b41d5de2c 100644 --- a/api/v3/Relationship.php +++ b/api/v3/Relationship.php @@ -137,7 +137,11 @@ function civicrm_api3_relationship_delete($params) { */ function civicrm_api3_relationship_get($params) { $options = _civicrm_api3_get_options_from_params($params); + if (!CRM_Utils_Array::value('contact_id', $params)) { + if(!empty($params['membership_type_id']) && empty($params['relationship_type_id'])) { + CRM_Contact_BAO_Relationship::membershipTypeToRelationshipTypes($params); + } $relationships = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE); } else { diff --git a/templates/CRM/Member/Form/Membership.tpl b/templates/CRM/Member/Form/Membership.tpl index 45947d6ef5..7c0a2202a0 100644 --- a/templates/CRM/Member/Form/Membership.tpl +++ b/templates/CRM/Member/Form/Membership.tpl @@ -674,6 +674,22 @@ if ((memType > 0) && (allMemberships[memType]['has_related'])) { if (setDefault) cj('#max_related').val(allMemberships[memType]['max_related']); cj('#maxRelated').show(); + if(CRM.ids.contact > 0) { + CRM.api('relationship', 'getcount', {'contact_id' : CRM.ids.contact, 'membership_type_id' : memType}, { + success: function(result) { + var relatable = ' ' + result.result + ts(' contacts are '); + if(result.result === 0) { + relatable = ts(' No contacts are '); + } + if(result.result === 1) { + relatable = ts(' One contact is '); + } + + var others = relatable + ts('currently eligible to inherit this relationship'); + cj('#max_related').siblings('.description').append(others); + } + }); + } } else { cj('#max_related').val(''); cj('#maxRelated').hide(); diff --git a/tests/phpunit/api/v3/RelationshipTest.php b/tests/phpunit/api/v3/RelationshipTest.php index 08b98608dd..de8d3c3f48 100644 --- a/tests/phpunit/api/v3/RelationshipTest.php +++ b/tests/phpunit/api/v3/RelationshipTest.php @@ -34,6 +34,11 @@ require_once 'CiviTest/CiviUnitTestCase.php'; class api_v3_RelationshipTest extends CiviUnitTestCase { protected $_apiversion = 3; protected $_cId_a; + /** + * second individual + * @var integer + */ + protected $_cId_a_2; protected $_cId_b; protected $_cId_b2;// second org protected $_relTypeID; @@ -53,10 +58,11 @@ class api_v3_RelationshipTest extends CiviUnitTestCase { function setUp() { parent::setUp(); - $this->_cId_a = $this->individualCreate(); - $this->_cId_b = $this->organizationCreate(); - $this->_cId_b2 = $this->organizationCreate(array('organization_name' => ' Org 2')); - $this->_entity = 'relationship'; + $this->_cId_a = $this->individualCreate(); + $this->_cId_a_2 = $this->individualCreate(array('last_name' => 'c2', 'email' => 'c@w.com', 'contact_type' => 'Individual')); + $this->_cId_b = $this->organizationCreate(); + $this->_cId_b2 = $this->organizationCreate(array('organization_name' => ' Org 2')); + $this->_entity = 'relationship'; //Create a relationship type $relTypeParams = array( 'name_a_b' => 'Relation 1 for delete', @@ -81,6 +87,7 @@ class api_v3_RelationshipTest extends CiviUnitTestCase { function tearDown() { $this->contactDelete($this->_cId_a); + $this->contactDelete($this->_cId_a_2); $this->contactDelete($this->_cId_b); $this->contactDelete($this->_cId_b2); $this->quickCleanup(array('civicrm_relationship'), TRUE); @@ -962,5 +969,109 @@ class api_v3_RelationshipTest extends CiviUnitTestCase { $this->assertTrue(in_array($value['relationship_type_id'], array($this->_relTypeID, $relType3))); } } -} + /** + * Checks that passing in 'contact_id_b' + a relationship type + * will filter by relationship type for contact b + * + * We should get 1 result without or with correct relationship type id & 0 with + * an incorrect one + */ + function testGetRelationshipByMembershipTypeDAO() { + $created = $this->callAPISuccess($this->_entity, 'create', $this->_params); + $org3 = $this->organizationCreate(); + + $relType2 = 5; // lets just assume built in ones aren't being messed with! + $relType3 = 6; // lets just assume built in ones aren't being messed with! + $relType1 = 1; + $memberType = $this->membershipTypeCreate(array( + 'relationship_type_id' => CRM_Core_DAO::VALUE_SEPARATOR . $relType1 . CRM_Core_DAO::VALUE_SEPARATOR . $relType3 . CRM_Core_DAO::VALUE_SEPARATOR, + 'relationship_direction' => CRM_Core_DAO::VALUE_SEPARATOR . 'a_b' . CRM_Core_DAO::VALUE_SEPARATOR . 'b_a' . CRM_Core_DAO::VALUE_SEPARATOR, + )); + + //relationshp 2 + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType2, + 'contact_id_b' => $this->_cId_b2)) + ); + + //relationshp 3 + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType3, + 'contact_id_b' => $org3)) + ); + + //relationshp 4 with reveral + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType1, + 'contact_id_a' => $this->_cId_a, + 'contact_id_b' => $this->_cId_a_2)) + ); + + $result = $this->callAPISuccess($this->_entity, 'get', array( + 'contact_id_a' => $this->_cId_a, + 'membership_type_id' => $memberType, + )); + // although our contact has more than one relationship we have passed them in as contact_id_a & can't get reciprocal + $this->assertEquals(1, $result['count']); + foreach ($result['values'] as $key => $value) { + $this->assertTrue(in_array($value['relationship_type_id'], array($relType1))); + } + } + + /** + * Checks that passing in 'contact_id_b' + a relationship type + * will filter by relationship type for contact b + * + * We should get 1 result without or with correct relationship type id & 0 with + * an incorrect one + */ + function testGetRelationshipByMembershipTypeReciprocal() { + $created = $this->callAPISuccess($this->_entity, 'create', $this->_params); + $org3 = $this->organizationCreate(); + + $relType2 = 5; // lets just assume built in ones aren't being messed with! + $relType3 = 6; // lets just assume built in ones aren't being messed with! + $relType1 = 1; + $memberType = $this->membershipTypeCreate(array( + 'relationship_type_id' => CRM_Core_DAO::VALUE_SEPARATOR . $relType1 . CRM_Core_DAO::VALUE_SEPARATOR . $relType3 . CRM_Core_DAO::VALUE_SEPARATOR, + 'relationship_direction' => CRM_Core_DAO::VALUE_SEPARATOR . 'a_b' . CRM_Core_DAO::VALUE_SEPARATOR . 'b_a' . CRM_Core_DAO::VALUE_SEPARATOR, + )); + + //relationshp 2 + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType2, + 'contact_id_b' => $this->_cId_b2)) + ); + + //relationshp 3 + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType3, + 'contact_id_b' => $org3)) + ); + + //relationshp 4 with reveral + $this->callAPISuccess($this->_entity, 'create', + array_merge($this->_params, array( + 'relationship_type_id' => $relType1, + 'contact_id_a' => $this->_cId_a, + 'contact_id_b' => $this->_cId_a_2)) + ); + + $result = $this->callAPISuccess($this->_entity, 'get', array( + 'contact_id' => $this->_cId_a, + 'membership_type_id' => $memberType, + )); + // although our contact has more than one relationship we have passed them in as contact_id_a & can't get reciprocal + $this->assertEquals(2, $result['count']); + + foreach ($result['values'] as $key => $value) { + $this->assertTrue(in_array($value['relationship_type_id'], array($relType1, $relType3))); + } + } +} -- 2.25.1