Beispiel #1
0
 /**
  * Create memberships for related contacts, taking into account the maximum related memberships.
  *
  * @param array $params
  *   Array of key - value pairs.
  * @param CRM_Core_DAO $dao
  *   Membership object.
  *
  * @param bool $reset
  *
  * @return array|null
  *   Membership details, if created.
  *
  * @throws \CRM_Core_Exception
  */
 public static function createRelatedMemberships(&$params, &$dao, $reset = FALSE)
 {
     static $relatedContactIds = array();
     if ($reset) {
         // not sure why a static var is in use here - we need a way to reset it from the test suite
         $relatedContactIds = array();
         return FALSE;
     }
     $membership = new CRM_Member_DAO_Membership();
     $membership->id = $dao->id;
     // required since create method doesn't return all the
     // parameters in the returned membership object
     if (!$membership->find(TRUE)) {
         return;
     }
     $deceasedStatusId = array_search('Deceased', CRM_Member_PseudoConstant::membershipStatus());
     // FIXME : While updating/ renewing the
     // membership, if the relationship is PAST then
     // the membership of the related contact must be
     // expired.
     // For that, getting Membership Status for which
     // is_current_member is 0. It works for the
     // generated data as there is only one membership
     // status having is_current_member = 0.
     // But this wont work exactly if there will be
     // more than one status having is_current_member = 0.
     $membershipStatus = new CRM_Member_DAO_MembershipStatus();
     $membershipStatus->is_current_member = 0;
     if ($membershipStatus->find(TRUE)) {
         $expiredStatusId = $membershipStatus->id;
     } else {
         $expiredStatusId = array_search('Expired', CRM_Member_PseudoConstant::membershipStatus());
     }
     $allRelatedContacts = array();
     $relatedContacts = array();
     if (!is_a($membership, 'CRM_Core_Error')) {
         $allRelatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membership->id, $membership->contact_id, CRM_Utils_Array::value('action', $params));
     }
     // check for loops. CRM-4213
     // remove repeated related contacts, which already inherited membership.
     $relatedContactIds[$membership->contact_id] = TRUE;
     foreach ($allRelatedContacts as $cid => $status) {
         if (empty($relatedContactIds[$cid])) {
             $relatedContactIds[$cid] = TRUE;
             //don't create membership again for owner contact.
             $nestedRelationship = FALSE;
             if ($membership->owner_membership_id) {
                 $nestedRelMembership = new CRM_Member_DAO_Membership();
                 $nestedRelMembership->id = $membership->owner_membership_id;
                 $nestedRelMembership->contact_id = $cid;
                 $nestedRelationship = $nestedRelMembership->find(TRUE);
                 $nestedRelMembership->free();
             }
             if (!$nestedRelationship) {
                 $relatedContacts[$cid] = $status;
             }
         }
     }
     //lets cleanup related membership if any.
     if (empty($relatedContacts)) {
         self::deleteRelatedMemberships($membership->id);
     } else {
         // Edit the params array
         unset($params['id']);
         // Reminder should be sent only to the direct membership
         unset($params['reminder_date']);
         // unset the custom value ids
         if (is_array(CRM_Utils_Array::value('custom', $params))) {
             foreach ($params['custom'] as $k => $v) {
                 unset($params['custom'][$k]['id']);
             }
         }
         if (!isset($params['membership_type_id'])) {
             $params['membership_type_id'] = $membership->membership_type_id;
         }
         // max_related should be set in the parent membership
         unset($params['max_related']);
         // Number of inherited memberships available - NULL is interpreted as unlimited, '0' as none
         $available = $membership->max_related == NULL ? PHP_INT_MAX : $membership->max_related;
         // will be used to queue potential memberships to be created.
         $queue = array();
         foreach ($relatedContacts as $contactId => $relationshipStatus) {
             //use existing membership record.
             $relMembership = new CRM_Member_DAO_Membership();
             $relMembership->contact_id = $contactId;
             $relMembership->owner_membership_id = $membership->id;
             $relMemIds = array();
             if ($relMembership->find(TRUE)) {
                 $params['id'] = $relMemIds['membership'] = $relMembership->id;
             }
             $params['contact_id'] = $contactId;
             $params['owner_membership_id'] = $membership->id;
             // set status_id as it might have been changed for
             // past relationship
             $params['status_id'] = $membership->status_id;
             if ($deceasedStatusId && CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'is_deceased')) {
                 $params['status_id'] = $deceasedStatusId;
             } elseif (CRM_Utils_Array::value('action', $params) & CRM_Core_Action::UPDATE && $relationshipStatus == CRM_Contact_BAO_Relationship::PAST) {
                 $params['status_id'] = $expiredStatusId;
             }
             //don't calculate status again in create( );
             $params['skipStatusCal'] = TRUE;
             //do create activity if we changed status.
             if ($params['status_id'] != $relMembership->status_id) {
                 $params['createActivity'] = TRUE;
             }
             // we should not created contribution record for related contacts, CRM-3371
             unset($params['contribution_status_id']);
             //CRM-16857: Do not create multiple line-items for inherited membership through priceset.
             unset($params['lineItems']);
             unset($params['line_item']);
             if ($params['status_id'] == $deceasedStatusId || $params['status_id'] == $expiredStatusId) {
                 // related membership is not active so does not count towards maximum
                 CRM_Member_BAO_Membership::create($params, $relMemIds);
             } else {
                 // related membership already exists, so this is just an update
                 if (isset($params['id'])) {
                     if ($available > 0) {
                         CRM_Member_BAO_Membership::create($params, $relMemIds);
                         $available--;
                     } else {
                         // we have run out of inherited memberships, so delete extras
                         self::deleteMembership($params['id']);
                     }
                     // we need to first check if there will remain inherited memberships, so queue it up
                 } else {
                     $queue[] = $params;
                 }
             }
         }
         // now go over the queue and create any available related memberships
         reset($queue);
         while ($available > 0 && ($params = each($queue))) {
             CRM_Member_BAO_Membership::create($params['value'], $relMemIds);
             $available--;
         }
     }
 }
 /**
  * function to create memberships for related contacts
  *
  * @param  array      $params       array of key - value pairs
  * @param  object     $membership   membership object
  *
  * @return null|relatedMembership     array of memberships if created
  * @static
  * @access public
  */
 static function createRelatedMemberships(&$params, &$membership)
 {
     static $relatedContactIds = array();
     // required since create method doesn't return all the
     // parameters in the returned membership object
     if (!$membership->find(true)) {
         return;
     }
     require_once 'CRM/Member/PseudoConstant.php';
     $deceasedStatusId = array_search('Deceased', CRM_Member_PseudoConstant::membershipStatus());
     $allRelatedContacts = array();
     $relatedContacts = array();
     if (!is_a($membership, 'CRM_Core_Error')) {
         $allRelatedContacts = CRM_Member_BAO_Membership::checkMembershipRelationship($membership->id, $membership->contact_id, CRM_Utils_Array::value('action', $params));
     }
     // check for loops. CRM-4213
     // remove repeated related contacts, which already inherited membership.
     $relatedContactIds[$membership->contact_id] = true;
     foreach ($allRelatedContacts as $cid => $status) {
         if (!CRM_Utils_Array::value($cid, $relatedContactIds)) {
             $relatedContactIds[$cid] = true;
             //don't create membership again for owner contact.
             $nestedRelationship = false;
             if ($membership->owner_membership_id) {
                 $nestedRelMembership = new CRM_Member_DAO_Membership();
                 $nestedRelMembership->id = $membership->owner_membership_id;
                 $nestedRelMembership->contact_id = $cid;
                 $nestedRelationship = $nestedRelMembership->find(true);
                 $nestedRelMembership->free();
             }
             if (!$nestedRelationship) {
                 $relatedContacts[$cid] = $status;
             }
         }
     }
     //lets cleanup related membership if any.
     if (empty($relatedContacts)) {
         require_once 'CRM/Member/BAO/Membership.php';
         CRM_Member_BAO_Membership::deleteRelatedMemberships($membership->id);
     } else {
         // Edit the params array
         unset($params['id']);
         // Reminder should be sent only to the direct membership
         unset($params['reminder_date']);
         // unset the custom value ids
         if (is_array(CRM_Utils_Array::value('custom', $params))) {
             foreach ($params['custom'] as $k => $v) {
                 unset($params['custom'][$k]['id']);
             }
         }
         if (!isset($params['membership_type_id'])) {
             $params['membership_type_id'] = $membership->membership_type_id;
         }
         foreach ($relatedContacts as $contactId => $relationshipStatus) {
             //use existing membership record.
             $relMembership = new CRM_Member_DAO_Membership();
             $relMembership->contact_id = $contactId;
             $relMembership->owner_membership_id = $membership->id;
             $relMemIds = array();
             if ($relMembership->find(true)) {
                 $params['id'] = $relMemIds['membership'] = $relMembership->id;
             }
             $params['contact_id'] = $contactId;
             $params['owner_membership_id'] = $membership->id;
             // set status_id as it might have been changed for
             // past relationship
             $params['status_id'] = $membership->status_id;
             if ($deceasedStatusId && CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'is_deceased')) {
                 $params['status_id'] = $deceasedStatusId;
             } else {
                 if (CRM_Utils_Array::value('action', $params) & CRM_Core_Action::UPDATE && $relationshipStatus == CRM_Contact_BAO_Relationship::PAST) {
                     // FIXME : While updating/ renewing the
                     // membership, if the relationship is PAST then
                     // the membership of the related contact must be
                     // expired.
                     // For that, getting Membership Status for which
                     // is_current_member is 0. It works for the
                     // generated data as there is only one membership
                     // status having is_current_member = 0.
                     // But this wont work exactly if there will be
                     // more than one status having is_current_member = 0.
                     require_once 'CRM/Member/DAO/MembershipStatus.php';
                     $membershipStatus = new CRM_Member_DAO_MembershipStatus();
                     $membershipStatus->is_current_member = 0;
                     if ($membershipStatus->find(true)) {
                         $params['status_id'] = $membershipStatus->id;
                     }
                 }
             }
             //don't calculate status again in create( );
             $params['skipStatusCal'] = true;
             //do create activity if we changed status.
             if ($params['status_id'] != $relMembership->status_id) {
                 $params['createActivity'] = true;
             }
             // we should not created contribution record for related contacts, CRM-3371
             unset($params['contribution_status_id']);
             CRM_Member_BAO_Membership::create($params, $relMemIds);
         }
     }
 }