/** 
  * Generate html code to visualize the given match. The visualization may also provide interactive form elements.
  * 
  * @val $match    match data as previously generated by this plugin instance
  * @val $btx      the bank transaction the match refers to
  * @return html code snippet
  */
 function visualize_match(CRM_Banking_Matcher_Suggestion $match, $btx)
 {
     $smarty_vars = array();
     $btx_data = array();
     CRM_Core_DAO::storeValues($btx, $btx_data);
     $smarty_vars['btx'] = $btx_data;
     $smarty_vars['mode'] = $match->getId();
     $smarty_vars['contact_ids'] = $match->getParameter('contact_ids');
     $smarty_vars['contact_ids2probablility'] = $match->getParameter('contact_ids2probablility');
     $smarty_vars['ignore_message'] = $this->_plugin_config->ignore_message;
     $smarty_vars['booking_date'] = date('YmdHis', strtotime($btx->booking_date));
     $smarty_vars['status_pending'] = banking_helper_optionvalue_by_groupname_and_name('contribution_status', 'Pending');
     $smarty_vars['manual_default_source'] = $this->_plugin_config->manual_default_source;
     $smarty_vars['manual_default_financial_type_id'] = $this->_plugin_config->manual_default_financial_type_id;
     $smarty_vars['create_propagation'] = $this->getPropagationSet($btx, $match, 'contribution', $this->_plugin_config->createnew_value_propagation);
     // assign to smarty and compile HTML
     $smarty = CRM_Banking_Helpers_Smarty::singleton();
     $smarty->pushScope($smarty_vars);
     $html_snippet = $smarty->fetch('CRM/Banking/PluginImpl/Matcher/DefaultOptions.suggestion.tpl');
     $smarty->popScope();
     return $html_snippet;
 }
 /**
  * Handle the different actions, should probably be handles at base class level ...
  * 
  * @param type $match
  * @param type $btx
  */
 public function execute($suggestion, $btx)
 {
     $config = $this->_plugin_config;
     $smarty_vars = array();
     // load the recurring contribution
     $rcontribution_id = $suggestion->getParameter('recurring_contribution_id');
     $rcontribution = civicrm_api3('ContributionRecur', 'getsingle', array('id' => $rcontribution_id));
     $last_contribution = NULL;
     $due_date = self::getExpectedDate($rcontribution, $btx, $config->recurring_mode, $last_contribution);
     if ($due_date) {
         $current_due_date = date('Y-m-d', $due_date);
     } else {
         $current_due_date = ts('None');
     }
     $recorded_due_date = $suggestion->getParameter('expected_date');
     if ($recorded_due_date != $current_due_date) {
         // something changed...
         CRM_Core_Session::setStatus(ts('The situation for the recurring contribution seems to have changed. Please analyse transaction again.'), ts('Recurring contributtion changed'), 'alert');
         return false;
     }
     // go ahead and create the contribution
     $contribution = array();
     $contribution['contact_id'] = $suggestion->getParameter('contact_id');
     $contribution['total_amount'] = $btx->amount;
     $contribution['receive_date'] = $btx->booking_date;
     $contribution['currency'] = $btx->currency;
     $contribution['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $rcontribution);
     $contribution['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $rcontribution);
     $contribution['campaign_id'] = CRM_Utils_Array::value('campaign_id', $rcontribution);
     $contribution['contribution_recur_id'] = $rcontribution_id;
     $contribution['contribution_status_id'] = banking_helper_optionvalue_by_groupname_and_name('contribution_status', $config->created_contribution_status);
     $contribution = array_merge($contribution, $this->getPropagationSet($btx, $suggestion, 'contribution'));
     $contribution['version'] = 3;
     $result = civicrm_api('Contribution', 'create', $contribution);
     if (isset($result['is_error']) && $result['is_error']) {
         CRM_Core_Session::setStatus(ts("Couldn't create contribution.") . "<br/>" . ts("Error was: ") . $result['error_message'], ts('Error'), 'error');
         return false;
     }
     // success!
     $suggestion->setParameter('contribution_id', $result['id']);
     // save the account
     $this->storeAccountWithContact($btx, $suggestion->getParameter('contact_id'));
     $newStatus = banking_helper_optionvalueid_by_groupname_and_name('civicrm_banking.bank_tx_status', 'Processed');
     $btx->setStatus($newStatus);
     parent::execute($suggestion, $btx);
     return true;
 }
 /**
  * Handle the different actions, should probably be handles at base class level ...
  * 
  * @param type $match
  * @param type $btx
  */
 public function executeCancellation($match, $btx)
 {
     $config = $this->_plugin_config;
     $contribution_id = $match->getParameter('contribution_id');
     $mandate_id = $match->getParameter('mandate_id');
     $status_cancelled = banking_helper_optionvalue_by_groupname_and_name('contribution_status', 'Cancelled');
     // set the status to 'Cancelled'
     $query = array('version' => 3, 'id' => $contribution_id);
     $query['contribution_status_id'] = $status_cancelled;
     $query['cancel_date'] = date('Ymdhis', strtotime($btx->value_date));
     $query = array_merge($query, $this->getPropagationSet($btx, $match, 'contribution', $config->cancellation_value_propagation));
     // add propagated values
     if (empty($query['cancel_reason'])) {
         // add default values
         $query['cancel_reason'] = $config->cancellation_default_reason;
     }
     if ($config->cancellation_cancel_reason) {
         $query['cancel_reason'] = $match->getParameter('cancel_reason');
     }
     $result = civicrm_api('Contribution', 'create', $query);
     if (isset($result['is_error']) && $result['is_error']) {
         error_log("org.project60.sepa: matcher_sepa: Couldn't modify contribution, error was: " . $result['error_message']);
         CRM_Core_Session::setStatus(ts("Couldn't modify contribution."), ts('Error'), 'error');
     } else {
         // now for the mandate...
         $contribution = civicrm_api('Contribution', 'getsingle', array('version' => 3, 'id' => $contribution_id));
         if (!empty($contribution['is_error'])) {
             error_log("org.project60.sepa: matcher_sepa: Couldn't load contribution, error was: " . $result['error_message']);
             CRM_Core_Session::setStatus(ts("Couldn't modify contribution."), ts('Error'), 'error');
         } else {
             if ('OOFF' == $contribution['contribution_payment_instrument'] && !empty($config->cancellation_update_mandate_status_OOFF)) {
                 // everything seems fine, adjust the mandate's status
                 $query = array('version' => 3, 'id' => $mandate_id);
                 $query['status'] = $config->cancellation_update_mandate_status_OOFF;
                 $query = array_merge($query, $this->getPropagationSet($btx, $match, 'mandate'));
                 // add propagated values
                 $result = civicrm_api('SepaMandate', 'create', $query);
                 if (!empty($result['is_error'])) {
                     error_log("org.project60.sepa: matcher_sepa: Couldn't modify mandate, error was: " . $result['error_message']);
                     CRM_Core_Session::setStatus(ts("Couldn't modify mandate."), ts('Error'), 'error');
                 }
             } elseif ('RCUR' == $contribution['contribution_payment_instrument'] && !empty($config->cancellation_update_mandate_status_RCUR)) {
                 // everything seems fine, adjust the mandate's status
                 $query = array('version' => 3, 'id' => $mandate_id);
                 $query['status'] = $config->cancellation_update_mandate_status_RCUR;
                 $query = array_merge($query, $this->getPropagationSet($btx, $match, 'mandate'));
                 // add propagated values
                 $result = civicrm_api('SepaMandate', 'create', $query);
                 if (!empty($result['is_error'])) {
                     error_log("org.project60.sepa: matcher_sepa: Couldn't modify mandate, error was: " . $result['error_message']);
                     CRM_Core_Session::setStatus(ts("Couldn't modify mandate."), ts('Error'), 'error');
                 }
             }
         }
     }
     // create activity if wanted
     if ($config->cancellation_create_activity) {
         // gather some information to put in the text
         $smarty_vars = array();
         $smarty_vars['contribution'] = $contribution;
         $smarty_vars['cancel_fee'] = $match->getParameter('cancel_fee');
         $smarty_vars['cancel_reason'] = $match->getParameter('cancel_reason');
         // load the mandate
         $mandate = civicrm_api('SepaMandate', 'getsingle', array('id' => $mandate_id, 'version' => 3));
         $smarty_vars['mandate'] = $mandate;
         // load the contact
         $contact = civicrm_api('Contact', 'getsingle', array('id' => $contribution['contact_id'], 'version' => 3));
         $smarty_vars['contact'] = $contact;
         // count the cancelled contributions connected to this mandate
         $cancelled_contribution_count = 0;
         $current_contribution_date = date('Ymdhis', strtotime($contribution['receive_date']));
         if ($mandate['type'] == 'RCUR') {
             $query = "SELECT contribution_status_id\n                  FROM civicrm_contribution\n                  WHERE contribution_recur_id = {$mandate['entity_id']}\n                    AND receive_date <= '{$current_contribution_date}'\n                  ORDER BY receive_date DESC;";
             $status_list = CRM_Core_DAO::executeQuery($query);
             while ($status_list->fetch()) {
                 if ($status_list->contribution_status_id == $status_cancelled) {
                     $cancelled_contribution_count += 1;
                 } else {
                     break;
                 }
             }
         }
         $smarty_vars['cancelled_contribution_count'] = $cancelled_contribution_count;
         // look up contact if not set
         $user_id = CRM_Core_Session::singleton()->get('userID');
         if (empty($config->cancellation_create_activity_assignee_id)) {
             $assignedTo = $user_id;
         } else {
             $assignedTo = (int) $config->cancellation_create_activity_assignee_id;
         }
         // compile the text
         $smarty = CRM_Banking_Helpers_Smarty::singleton();
         $smarty->pushScope($smarty_vars);
         if (empty($config->cancellation_create_activity_text)) {
             $details = $smarty->fetch('CRM/Banking/PluginImpl/Matcher/SepaMandate.activity.tpl');
         } else {
             $details = $smarty->fetch("string:" . $config->cancellation_create_activity_text);
         }
         $smarty->popScope();
         $activity_parameters = array('version' => 3, 'activity_type_id' => $config->cancellation_create_activity_type_id, 'subject' => $config->cancellation_create_activity_subject, 'status_id' => 1, 'activity_date_time' => date('YmdHis'), 'source_contact_id' => $user_id, 'target_contact_id' => $contact['id'], 'details' => $details);
         $activity = CRM_Activity_BAO_Activity::create($activity_parameters);
         $assignment_parameters = array('activity_id' => $activity->id, 'contact_id' => $assignedTo, 'record_type_id' => 1);
         $assignment = CRM_Activity_BAO_ActivityContact::create($assignment_parameters);
     }
     $newStatus = banking_helper_optionvalueid_by_groupname_and_name('civicrm_banking.bank_tx_status', 'Processed');
     $btx->setStatus($newStatus);
     parent::execute($match, $btx);
     return true;
 }
 /**
  * Handle the different actions, should probably be handles at base class level ...
  * 
  * @param type $match
  * @param type $btx
  */
 public function execute($suggestion, $btx)
 {
     $config = $this->_plugin_config;
     $contribution_id = $suggestion->getParameter('contribution_id');
     $query = array('version' => 3, 'id' => $contribution_id);
     $query = array_merge($query, $this->getPropagationSet($btx, $suggestion, 'contribution'));
     // add propagated values
     // double check contribution (see https://github.com/Project60/CiviBanking/issues/61)
     $contribution = civicrm_api('Contribution', 'getsingle', array('id' => $contribution_id, 'version' => 3));
     if (!empty($contribution['is_error'])) {
         CRM_Core_Session::setStatus(ts('Contribution has disappeared.') . ' ' . ts('Error was:') . ' ' . $contribution['error_message'], ts('Execution Failure'), 'alert');
         return false;
     }
     $accepted_status_ids = $this->getAcceptedContributionStatusIDs();
     if (!in_array($contribution['contribution_status_id'], $accepted_status_ids)) {
         CRM_Core_Session::setStatus(ts('Contribution status has been modified.'), ts('Execution Failure'), 'alert');
         return false;
     }
     // depending on mode...
     if ($this->_plugin_config->mode != "cancellation") {
         $query['contribution_status_id'] = banking_helper_optionvalue_by_groupname_and_name('contribution_status', 'Completed');
         $query['receive_date'] = date('YmdHis', strtotime($btx->booking_date));
     } else {
         $query['contribution_status_id'] = banking_helper_optionvalue_by_groupname_and_name('contribution_status', 'Cancelled');
         $query['cancel_date'] = date('YmdHis', strtotime($btx->booking_date));
         if ($config->cancellation_cancel_reason) {
             $query['cancel_reason'] = $suggestion->getParameter('cancel_reason');
         }
     }
     $result = civicrm_api('Contribution', 'create', $query);
     if (isset($result['is_error']) && $result['is_error']) {
         CRM_Core_Session::setStatus(ts("Couldn't modify contribution.") . "<br/>" . $result['error_message'], ts('Error'), 'error');
         return false;
     } else {
         // everything seems fine, save the account
         if (!empty($result['values'][$contribution_id]['contact_id'])) {
             $this->storeAccountWithContact($btx, $result['values'][$contribution_id]['contact_id']);
         } elseif (!empty($result['values'][0]['contact_id'])) {
             $this->storeAccountWithContact($btx, $result['values'][0]['contact_id']);
         }
     }
     $newStatus = banking_helper_optionvalueid_by_groupname_and_name('civicrm_banking.bank_tx_status', 'Processed');
     $btx->setStatus($newStatus);
     parent::execute($suggestion, $btx);
     return true;
 }
 /**
  * will get all IDs of the batch's contributions that are not in the state pending.
  */
 function getNonPendingContributionIDs($batch_id)
 {
     $nonPendingContributionIDs = array();
     $contribution_status_pending = banking_helper_optionvalue_by_groupname_and_name('contribution_status', 'Pending');
     $query = "SELECT contribution.id as contribution_id FROM civicrm_entity_batch AS batch " . "INNER JOIN civicrm_entity_financial_trxn  AS trxn2c       ON batch.entity_id=trxn2c.financial_trxn_id AND batch.entity_table='civicrm_financial_trxn' " . "INNER JOIN civicrm_contribution           AS contribution ON trxn2c.entity_id=contribution.id AND trxn2c.entity_table='civicrm_contribution' " . "WHERE batch.batch_id = {$batch_id} \n         AND contribution.contribution_status_id != '{$contribution_status_pending}';";
     $result = CRM_Core_DAO::executeQuery($query);
     while ($result->fetch()) {
         array_push($nonPendingContributionIDs, $result->contribution_id);
     }
     return $nonPendingContributionIDs;
 }