/**
  * Fix a "new houshold member" problem by connecting
  * the new contact to the household, unless he's already
  * connected
  */
 public static function fixHMNW($problem)
 {
     $activity_id = $problem->getActivityID();
     if (empty($activity_id)) {
         return FALSE;
     }
     // get all target contacts
     $contact_ids = CRM_Activity_BAO_ActivityTarget::retrieveTargetIdsByActivityId($activity_id);
     if (empty($contact_ids)) {
         return FALSE;
     }
     // load all contacts
     $new_contact_id = NULL;
     $contact_data = civicrm_api3('Contact', 'get', array('id' => array('IN' => $contact_ids)));
     foreach ($contact_data['values'] as $contact_id => $contact) {
         if ($contact['contact_type'] == 'Individual') {
             if ($new_contact_id === NULL) {
                 $new_contact_id = $contact['id'];
             } else {
                 // there are multiple new contacts here...
                 return FALSE;
             }
         }
     }
     if (empty($new_contact_id)) {
         // no contact found
         return FALSE;
     }
     // check if there is already a relationship
     $relation_ids[] = CRM_Householdmerge_Logic_Configuration::getMemberRelationID();
     $relation_ids[] = CRM_Householdmerge_Logic_Configuration::getHeadRelationID();
     $existing_relationship = civicrm_api3('Relationship', 'get', array('contact_id_a' => $new_contact_id, 'contact_id_b' => $problem->getHouseholdID(), 'relationship_type_id' => array('IN' => $relation_ids), 'is_active' => 1));
     if ($existing_relationship['count']) {
         // there already is a relationship, the problem IS fixed already...
     } else {
         // create a new relationship
         civicrm_api3('Relationship', 'create', array('contact_id_a' => $new_contact_id, 'contact_id_b' => $problem->getHouseholdID(), 'relationship_type_id' => CRM_Householdmerge_Logic_Configuration::getMemberRelationID(), 'is_active' => 1));
     }
     return TRUE;
 }
 /**
  * Will create a household
  * linking the member IDs (and head ID if present) to it.
  *
  * @return int household_id
  */
 public function createLinkedHousehold($last_name, $member_ids, $household_address, $head_id = NULL)
 {
     // create household
     $household = civicrm_api3('Contact', 'create', array('contact_type' => 'Household', 'household_name' => $last_name));
     $household_id = $household['id'];
     // also, create the address
     if ($household_address) {
         $address = civicrm_api3('Address', 'create', array('contact_id' => $household_id, 'location_type_id' => $this->getHHAddressLocationTypeID(), 'street_address' => $household_address['street_address'], 'supplemental_address_1' => $household_address['supplemental_address_1'], 'supplemental_address_2' => $household_address['supplemental_address_2'], 'city' => $household_address['city'], 'postal_code' => $household_address['postal_code'], 'country_id' => $household_address['country_id']));
     }
     // link head (if present)
     if ($head_id) {
         $head_relation_id = CRM_Householdmerge_Logic_Configuration::getHeadRelationID();
         if (!$head_relation_id) {
             throw new CRM_Core_Exception("Cannot create Household: head realation not set.");
         }
         $this->linkContactToHousehold($head_id, $household_id, $head_relation_id);
     }
     // link members
     $member_relation_id = CRM_Householdmerge_Logic_Configuration::getMemberRelationID();
     foreach ($member_ids as $member_id) {
         $this->linkContactToHousehold($member_id, $household_id, $member_relation_id);
     }
     return $household_id;
 }
 function preProcess()
 {
     $this->setDefaults(array('hh_mode' => CRM_Householdmerge_Logic_Configuration::getHouseholdMode(), 'hh_head_mode' => CRM_Householdmerge_Logic_Configuration::getHouseholdHeadMode(), 'hh_member_relation' => CRM_Householdmerge_Logic_Configuration::getHeadRelationID(), 'hh_head_relation' => CRM_Householdmerge_Logic_Configuration::getMemberRelationID()));
 }
 /**
  * Load all the household members
  */
 protected function getMembers($household_id)
 {
     $member_relation_id = CRM_Householdmerge_Logic_Configuration::getMemberRelationID();
     $head_relation_id = CRM_Householdmerge_Logic_Configuration::getHeadRelationID();
     $head_ids = array();
     $member_ids = array();
     // load the relationships (both ways)
     $query = array('relationship_type_id' => array('IN' => array($member_relation_id, $head_relation_id)), 'is_active' => 1, 'contact_id_a' => $household_id, 'option.limit' => 99999);
     $member_query = civicrm_api3('Relationship', 'get', $query);
     foreach ($member_query['values'] as $relationship) {
         $member_ids[] = $relationship['contact_id_b'];
         if ($relationship['relationship_type_id'] == $head_relation_id) {
             $head_ids[] = $relationship['contact_id_b'];
         }
     }
     $query['contact_id_b'] = $household_id;
     unset($query['contact_id_a']);
     $member_query = civicrm_api3('Relationship', 'get', $query);
     foreach ($member_query['values'] as $relationship) {
         $member_ids[] = $relationship['contact_id_a'];
         if ($relationship['relationship_type_id'] == $head_relation_id) {
             $head_ids[] = $relationship['contact_id_a'];
         }
     }
     if (!empty($member_ids)) {
         // and load the memeber contacts
         $contact_query = civicrm_api3('Contact', 'get', array('id' => array('IN' => $member_ids), 'contact_type' => 'Individual', 'is_deleted' => 0));
         $members = $contact_query['values'];
         // set the relationship type
         foreach ($members as &$member) {
             if (in_array($member['id'], $head_ids)) {
                 $member['hh_relation'] = 'head';
             } else {
                 $member['hh_relation'] = 'member';
             }
         }
         return $members;
     }
     return array();
 }
 /**
  * find the contact_ids of some potential candidates
  */
 protected function findCandidates($count)
 {
     $minimum_member_count = (int) CRM_Householdmerge_Logic_Configuration::getMinimumMemberCount();
     if ($count == 'all') {
         $limit_clause = '';
     } else {
         $count = (int) $count;
         $limit_clause = "LIMIT {$count}";
     }
     // compile relationship conditions ("NOT ALREADY MEMBER OF")
     $RELATIONSHIP_CONDITION = $RELATIONSHIP_JOIN = '';
     $member_relation_id = CRM_Householdmerge_Logic_Configuration::getMemberRelationID();
     $head_relation_id = CRM_Householdmerge_Logic_Configuration::getHeadRelationID();
     if ($member_relation_id) {
         $relationship_ids = array($member_relation_id);
         if ($head_relation_id) {
             $relationship_ids[] = $head_relation_id;
         }
         $relationship_id_list = implode(',', $relationship_ids);
         //  try joining valid, active household relationships...
         $RELATIONSHIP_JOIN = "\n              LEFT JOIN civicrm_relationship relation_ab ON contact_id = relation_ab.contact_id_a AND relation_ab.relationship_type_id IN ({$relationship_id_list}) AND (relation_ab.end_date IS NULL OR relation_ab.end_date > NOW())\n              LEFT JOIN civicrm_relationship relation_ba ON contact_id = relation_ba.contact_id_b AND relation_ba.relationship_type_id IN ({$relationship_id_list}) AND (relation_ba.end_date IS NULL OR relation_ba.end_date > NOW())\n        ";
         // ...and then make sure there are none
         $RELATIONSHIP_CONDITION = "\n              AND relation_ab.id IS NULL AND relation_ba.id IS NULL\n        ";
     }
     $candidates = array();
     $scanner_sql = "\n      SELECT *\n        FROM (SELECT civicrm_contact.id AS contact_id,\n                     GROUP_CONCAT(civicrm_contact.id SEPARATOR '||') AS contact_ids,\n                     GROUP_CONCAT(civicrm_contact.display_name SEPARATOR '||') AS display_names,\n                     GROUP_CONCAT(civicrm_contact.gender_id SEPARATOR '||') AS gender_ids,\n                     civicrm_contact.last_name AS last_name,\n                     civicrm_address.street_address AS street_address,\n                     civicrm_address.supplemental_address_1 AS supplemental_address_1,\n                     civicrm_address.supplemental_address_2 AS supplemental_address_2,\n                     civicrm_address.postal_code AS postal_code,\n                     civicrm_address.city AS city,\n                     civicrm_address.country_id AS country_id,\n                     COUNT(DISTINCT(civicrm_contact.id)) AS mitgliederzahl\n              FROM civicrm_contact\n              LEFT JOIN civicrm_address ON civicrm_address.contact_id = civicrm_contact.id\n              {$RELATIONSHIP_JOIN}\n              WHERE (civicrm_contact.is_deleted IS NULL OR civicrm_contact.is_deleted = 0)\n                AND civicrm_contact.contact_type = 'Individual'\n                AND civicrm_address.id IS NOT NULL\n                AND (civicrm_address.street_address IS NOT NULL AND civicrm_address.street_address != '')\n                AND (civicrm_address.postal_code IS NOT NULL AND civicrm_address.postal_code != '')\n                AND (civicrm_address.city IS NOT NULL AND civicrm_address.city != '')\n                {$RELATIONSHIP_CONDITION}\n              GROUP BY civicrm_contact.last_name, civicrm_address.street_address, civicrm_address.postal_code, civicrm_address.city) households\n        WHERE mitgliederzahl >= {$minimum_member_count}\n        {$limit_clause};\n      ";
     $scanner = CRM_Core_DAO::executeQuery($scanner_sql);
     while ($scanner->fetch()) {
         $candidates[$scanner->contact_id] = array('contact_ids' => $scanner->contact_ids, 'display_names' => $scanner->display_names, 'gender_ids' => $scanner->gender_ids, 'street_address' => $scanner->street_address, 'supplemental_address_1' => $scanner->supplemental_address_1, 'supplemental_address_2' => $scanner->supplemental_address_2, 'postal_code' => $scanner->postal_code, 'city' => $scanner->city, 'country_id' => $scanner->country_id, 'last_name' => $scanner->last_name);
     }
     return $candidates;
 }