/** * Creates a new household according to the specs */ function civicrm_api3_contact_create_household($params) { if (empty($params['mode'])) { $params['mode'] = CRM_Householdmerge_Logic_Configuration::getHouseholdMode(); } $head_id = NULL; switch ($params['mode']) { case 'hierarchy': $head_id = (int) $params['head_id']; case 'link': // get member IDs $member_ids = $params['member_ids']; if (is_string($member_ids)) { $member_ids = explode(',', $member_ids); } // sanitise member IDs $sanitised_member_ids = array(); foreach ($member_ids as $member_id) { $sanitised_member_id = (int) $member_id; if ($sanitised_member_id) { $sanitised_member_ids[] = $sanitised_member_id; } } // now pass the work on the the worker $worker = new CRM_Householdmerge_Logic_Worker(); $household_id = $worker->createLinkedHousehold($params['household_name'], $sanitised_member_ids, $params['address'], $head_id); return civicrm_api3_create_success(); default: return civicrm_api3_create_error("Contact.create_household cannot process mode '{$params['mode']}'."); } }
function postProcess() { // define some stats $activities_total = count($this->_activityHolderIds); $activities_processed = 0; $activities_detected = 0; $activities_fixed = 0; // filter for relevant activities $activity_type_id = (int) CRM_Householdmerge_Logic_Configuration::getCheckHouseholdActivityTypeID(); $activity_status_ids = CRM_Householdmerge_Logic_Configuration::getFixableActivityStatusIDs(); $activity_ids = implode(',', $this->_activityHolderIds); $filter_query = "SELECT id AS activity_id FROM civicrm_activity\n WHERE civicrm_activity.activity_type_id = {$activity_type_id} \n AND civicrm_activity.status_id IN ({$activity_status_ids})\n AND civicrm_activity.id IN ({$activity_ids});"; $filtered_activities = CRM_Core_DAO::executeQuery($filter_query); // go through all activites and try to fix them while ($filtered_activities->fetch()) { $activities_processed += 1; $problem = CRM_Householdmerge_Logic_Problem::extractProblem($filtered_activities->activity_id); if ($problem) { $activities_detected += 1; if ($problem->fix()) { $activities_fixed += 1; } } } // show stats CRM_Core_Session::setStatus(ts('%1 of the %2 selected activities were processed, %3 of them could be fixed.', array(1 => $activities_detected, 2 => $activities_total, 3 => $activities_fixed, 'domain' => 'de.systopia.householdmerge')), ts('%1 Household Problems Fixed', array(1 => $activities_fixed, 'domain' => 'de.systopia.householdmerge')), $activities_fixed > 0 ? 'info' : 'warn'); parent::postProcess(); }
public function postProcess() { $values = $this->exportValues(); // store settings $expected_values = array('hh_mode', 'hh_head_mode', 'hh_member_relation', 'hh_head_relation'); foreach ($expected_values as $key) { if (isset($values[$key])) { CRM_Householdmerge_Logic_Configuration::setConfigValue($key, $values[$key]); } } parent::postProcess(); }
/** * Will link the contact to the given household * If $relation_type_id is empty, the default member relation will be used */ public function linkContactToHousehold($contact_id, $household_id, $relation_type_id = NULL) { if (!$relation_type_id) { $relation_type_id = CRM_Householdmerge_Logic_Configuration::getMemberRelationID(); } // look up the right parameters (direction) if (!isset($this->_relationID2fields[$relation_type_id])) { $relation_type = civicrm_api3('RelationshipType', 'getsingle', array('id' => $relation_type_id)); if ($relation_type['contact_type_a'] == 'Household') { $this->_relationID2fields[$relation_type_id] = array('household' => 'contact_id_a', 'contact' => 'contact_id_b'); } else { $this->_relationID2fields[$relation_type_id] = array('household' => 'contact_id_b', 'contact' => 'contact_id_a'); } } // finally create the relationship $rspec = $this->_relationID2fields[$relation_type_id]; civicrm_api3('Relationship', 'create', array('relationship_type_id' => $relation_type_id, $rspec['household'] => $household_id, $rspec['contact'] => $contact_id, 'is_active' => 1)); }
/** * 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; }
/** * get the activty status IDs that are considered to be live and fixable * * @return string comma separated ids */ public static function getFixableActivityStatusIDs() { if (self::$fixable_activity_status_ids === NULL) { $status_ids = array(); $status_ids[] = CRM_Core_OptionGroup::getValue('activity_status', 'Scheduled', 'name'); self::$fixable_activity_status_ids = implode(',', $status_ids); } return self::$fixable_activity_status_ids; }
/** * 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(); }
/** * Identify the contact to be considered the HEAD under the given member_data objects * * @return int contact_id of the head */ protected function identifyHead(&$members) { $method = CRM_Householdmerge_Logic_Configuration::getHouseholdHeadMode(); if ($method == 'topdonor2y_m') { // init donations array $donations = array(); foreach ($members as $member_id => $member) { $donations[$member_id] = 0; } $contact_ids = implode(',', array_keys($members)); $td_amounts_sql = "\n SELECT contact_id AS contact_id, \n SUM(total_amount) AS amount\n FROM civicrm_contribution\n WHERE contact_id IN ({$contact_ids})\n AND (is_test IS NULL OR is_test = 0)\n AND (contribution_status_id = 1)\n AND (receive_date BETWEEN (NOW() - INTERVAL 2 YEAR) AND NOW())\n GROUP BY contact_id;\n "; $td_amounts = CRM_Core_DAO::executeQuery($td_amounts_sql); while ($td_amounts->fetch()) { $donations[$td_amounts->contact_id] = $td_amounts->amount; } // now determin the head $topdonor_id = NULL; $topdonor_amount = NULL; foreach ($donations as $member_id => $donation_amount) { if ($donation_amount > $topdonor_amount || $topdonor_amount === NULL) { $topdonor_id = $member_id; $topdonor_amount = $donation_amount; } elseif ($donation_amount == $topdonor_amount) { if ($members[$member_id]['gender_id'] == 2) { // if donor has same amount and is male => take over $topdonor_id = $member_id; $topdonor_amount = $donation_amount; } } } // now $topdonor_id should be the HEAD return $topdonor_id; } else { error_log("UNDEFINED METHOD TO DETERMINE HEAD: {$method}"); return reset(array_keys($members)); } }
/** * Check if there alread is an (active) 'check' activity with this household */ protected function hasLiveActivity() { $activity_type_id = (int) CRM_Householdmerge_Logic_Configuration::getCheckHouseholdActivityTypeID(); $household_id = (int) $this->household_id; $activity_status_ids = CRM_Householdmerge_Logic_Configuration::getLiveActivityStatusIDs(); $sentinel = "[{$this->code}] %"; if (empty($this->params['member_id'])) { $member_clause = ""; } else { $member_id = (int) $this->params['member_id']; $member_clause = "AND EXISTS (SELECT id FROM civicrm_activity_contact WHERE activity_id = civicrm_activity.id AND contact_id = {$member_id} AND record_type_id = 3)"; } $selector_sql = "SELECT civicrm_activity.id AS activity_id\n FROM civicrm_activity\n LEFT JOIN civicrm_activity_contact target ON target.activity_id = civicrm_activity.id AND target.record_type_id = 3\n WHERE civicrm_activity.activity_type_id = {$activity_type_id} \n AND civicrm_activity.status_id IN ({$activity_status_ids})\n AND civicrm_activity.subject LIKE %1\n AND target.contact_id = {$household_id}\n {$member_clause} ;"; $selector_params = array(1 => array($sentinel, 'String')); $query = CRM_Core_DAO::executeQuery($selector_sql, $selector_params); return $query->fetch(); }
/** * Set permissions for runner/engine API call */ function householdmerge_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions) { $permissions['contact']['create_household'] = CRM_Householdmerge_Logic_Configuration::getCreateHouseholdPermission(); }