/**
  * Access this bank account reference's bank account, instantiating it if it 
  * does not yet exist
  * 
  * @return CRM_Banking_BAO_BankAccount or null
  */
 function getBankAccount()
 {
     if ($this->ba_id) {
         $bank_bao = new CRM_Banking_BAO_BankAccount();
         $bank_bao->get('id', $this->ba_id);
         return $bank_bao;
     } else {
         return NULL;
     }
 }
 function run()
 {
     if (isset($_REQUEST['cid'])) {
         $contact_id = (int) $_REQUEST['cid'];
         $bank_accounts = array();
         $bank_account = new CRM_Banking_BAO_BankAccount();
         $bank_account->contact_id = $contact_id;
         $bank_account->find();
         while ($bank_account->fetch()) {
             $bank_account_data = $bank_account->toArray();
             $bank_account_data['references'] = $bank_account->getReferences();
             $bank_account_data['data_parsed'] = json_decode($bank_account->data_parsed, true);
             $bank_accounts[$bank_account->id] = $bank_account_data;
         }
         $this->assign('results', $bank_accounts);
         $this->assign('contact_id', $contact_id);
         // look up IBAN reference type FIXME: remove when we have proper account editor
         $result = civicrm_api('OptionValue', 'getsingle', array('version' => 3, 'name' => 'IBAN', 'value' => 'IBAN'));
         $this->assign('iban_type_id', $result['id']);
     }
     parent::run();
 }
 /**
  * Save presets and create/update account/reference
  */
 function postProcess()
 {
     $values = $this->exportValues();
     $was_created = FALSE;
     // save presets
     if (!empty($values['reference_type'])) {
         CRM_Core_BAO_Setting::setItem($values['reference_type'], 'CiviBanking', 'account.default_reference_id');
     }
     if (!empty($values['country'])) {
         CRM_Core_BAO_Setting::setItem($values['country'], 'CiviBanking', 'account.default_country');
     }
     // create bank account
     $ba_id = $values['ba_id'];
     if (empty($ba_id)) {
         $bank_account = civicrm_api3('BankingAccount', 'create', array('contact_id' => $values['contact_id'], 'data_parsed' => '{}'));
         $was_created = TRUE;
         $ba_id = $bank_account['id'];
     }
     // update bank account data
     $bank_data_attributes = array('bic' => 'BIC', 'bank_name' => 'name', 'country' => 'country');
     $bank_bao = new CRM_Banking_BAO_BankAccount();
     $bank_bao->get('id', $ba_id);
     $bank_data = $bank_bao->getDataParsed();
     foreach ($bank_data_attributes as $form_attribute => $bank_data_attribute) {
         if (empty($values[$form_attribute])) {
             unset($bank_data[$bank_data_attribute]);
         } else {
             $bank_data[$bank_data_attribute] = $values[$form_attribute];
         }
     }
     $bank_bao->setDataParsed($bank_data);
     $bank_bao->save();
     // update/create bank reference
     $reference_update = array('reference' => $values['reference'], 'reference_type_id' => $values['reference_type'], 'ba_id' => $ba_id);
     if (!empty($values['reference_id'])) {
         $reference_update['id'] = $values['reference_id'];
     }
     civicrm_api3('BankingAccountReference', 'create', $reference_update);
     if ($was_created) {
         CRM_Core_Session::setStatus(ts("Bank account '%1' was created.", $values['reference']), ts('Success'));
     } else {
         CRM_Core_Session::setStatus(ts("Bank account '%1' was updated.", $values['reference']), ts('Success'));
     }
     // return to accounts tab
     CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=2&selectedChild=bank_accounts"));
     parent::postProcess();
 }
 /**
  * If the payment was associated with a (source) account, this
  *  function looks up the account's owner contact ID
  * @deprecated use getAccountContacts()
  */
 public function getAccountContact()
 {
     $contact_id = $this->getCachedEntry('_account_contact_id');
     if ($contact_id === NULL) {
         if ($this->btx->party_ba_id) {
             $account = new CRM_Banking_BAO_BankAccount();
             $account->get('id', $this->btx->party_ba_id);
             if ($account->contact_id) {
                 $contact_id = $account->contact_id;
             } else {
                 $contact_id = 0;
             }
         } else {
             $contact_id = 0;
         }
         $this->setCachedEntry('_account_contact_id', $contact_id);
     }
     return $contact_id;
 }
 /**
  * Will store the donor's account data
  *
  * @todo move to post processors
  */
 function storeAccountWithContact($btx, $contact_id)
 {
     // find all reference types
     $reference_type_group = array('name' => 'civicrm_banking.reference_types');
     $reference_types = array();
     CRM_Core_OptionValue::getValues($reference_type_group, $reference_types);
     // gather the information
     $data = $btx->getDataParsed();
     $references = array();
     foreach ($reference_types as $reference_type) {
         $field_name = '_party_' . $reference_type['name'];
         if (!empty($data[$field_name])) {
             $references[$reference_type['id']] = $data[$field_name];
         }
     }
     // if we don't have references, there's nothing we can do...
     if (empty($references)) {
         return;
     }
     // gather account info
     $account_info = array();
     if (!empty($data['_party_BIC'])) {
         $account_info['BIC'] = $data['_party_BIC'];
     }
     if (!empty($data['_party_IBAN'])) {
         $account_info['country'] = substr($data['_party_IBAN'], 0, 2);
     }
     // copy all entries that start with _party_ba_ into the account info
     foreach ($data as $key => $value) {
         if ('_party_ba_' == substr($key, 0, 10)) {
             if (!empty($value)) {
                 $new_key = substr($key, 10);
                 $account_info[$new_key] = $value;
             }
         }
     }
     // find all referenced bank accounts
     $bank_accounts = array();
     $contact_bank_account_id = NULL;
     $contact_bank_account_created = false;
     $reference2instances = array();
     foreach ($references as $reference_type => $reference) {
         $reference2instances[$reference] = array();
         $query = array('version' => 3, 'reference' => $reference, 'reference_type_id' => $reference_type);
         $existing = civicrm_api('BankingAccountReference', 'get', $query);
         if (empty($existing['is_error'])) {
             foreach ($existing['values'] as $account_reference) {
                 array_push($reference2instances[$reference], $account_reference);
                 if (!isset($bank_accounts[$account_reference['ba_id']])) {
                     // load the bank account
                     $ba_bao = new CRM_Banking_BAO_BankAccount();
                     $ba_bao->get('id', $account_reference['ba_id']);
                     $bank_accounts[$account_reference['ba_id']] = $ba_bao;
                 }
                 // consider this bank account to be ours if the contact id matches
                 if (!$contact_bank_account_id && $ba_bao->contact_id == $contact_id) {
                     $contact_bank_account_id = $ba_bao->id;
                 }
             }
         }
     }
     // create new account if it does not yet exist
     if (!$contact_bank_account_id) {
         $ba_bao = new CRM_Banking_BAO_BankAccount();
         $ba_bao->contact_id = $contact_id;
         $ba_bao->description = ts("created by CiviBanking");
         $ba_bao->created_date = date('YmdHis');
         $ba_bao->modified_date = date('YmdHis');
         $ba_bao->data_raw = NULL;
         $ba_bao->data_parsed = "{}";
         $ba_bao->save();
         $contact_bank_account_id = $ba_bao->id;
         $bank_accounts[$contact_bank_account_id] = $ba_bao;
         $contact_bank_account_created = true;
     }
     // update bank account data
     $ba_bao = $bank_accounts[$contact_bank_account_id];
     $ba_data = $ba_bao->getDataParsed();
     foreach ($account_info as $key => $value) {
         $ba_data[$key] = $value;
     }
     $ba_bao->setDataParsed($ba_data);
     $ba_bao->save();
     // create references (warn if exists for another contact)
     foreach ($references as $reference_type => $reference) {
         // check the existing
         $reference_already_there = false;
         foreach ($reference2instances[$reference] as $reference_instance) {
             if ($reference_instance['ba_id'] == $contact_bank_account_id) {
                 // there is already a reference for 'our' bank account
                 $reference_already_there = true;
                 break;
             }
         }
         if (!$reference_already_there) {
             // there was no reference to 'our' bank account -> create!
             $query = array('version' => 3, 'reference' => $reference, 'reference_type_id' => $reference_type, 'ba_id' => $contact_bank_account_id);
             $result = civicrm_api('BankingAccountReference', 'create', $query);
             if (!empty($result['is_error'])) {
                 CRM_Core_Session::setStatus(ts("Couldn't create reference. Error was: '%1'", array(1 => $result['error_message'])), ts('Error'), 'alert');
             }
         }
     }
     // finally, create some feedback
     if ($contact_bank_account_created) {
         if (count($bank_accounts) > 1) {
             // there are mutiple acccounts referenced by this
             $message = ts("The account information of this contact was saved, but it is also used by the following contacts:<br/><ul>%s</ul>");
             $contacts = "";
             foreach ($bank_accounts as $ba_id => $ba_bao) {
                 if ($ba_id == $contact_bank_account_id) {
                     continue;
                 }
                 $contact = civicrm_api('Contact', 'getsingle', array('version' => 3, 'id' => $ba_bao->contact_id));
                 if (empty($contact['is_error'])) {
                     $url = CRM_Utils_System::url('civicrm/contact/view', 'cid=' . $ba_bao->contact_id);
                     $contacts .= "<li><a href='{$url}'>" . $contact['display_name'] . "</a></li>";
                 }
             }
             CRM_Core_Session::setStatus(sprintf($message, $contacts), ts('Warning'), 'warn');
         } else {
             CRM_Core_Session::setStatus(ts("The account information of this contact was saved."), ts('Account saved'), 'info');
         }
     }
 }
 /**
  * Will execute any dedupe/merge requests specified via the REQUEST params
  */
 function executeRequests($duplicates)
 {
     $refs_fixed = 0;
     $accounts_fixed = 0;
     $errors_ecountered = 0;
     $account_reflist = array();
     $reflist = array();
     // =========================
     // MERGE DUPLICATE ACCOUNTS
     // =========================
     if (!empty($_REQUEST['fixdupe'])) {
         if ($_REQUEST['fixdupe'] == 'all') {
             foreach ($duplicates['account'] as $reference => $info) {
                 if ((int) $info['reference_id']) {
                     $account_reflist[] = (int) $info['reference_id'];
                 }
             }
         } else {
             $parm_list = explode(',', $_REQUEST['fixdupe']);
             foreach ($parm_list as $reference_id) {
                 if ((int) $reference_id) {
                     $account_reflist[] = (int) $reference_id;
                 }
             }
         }
         // perform the changes
         foreach ($account_reflist as $reference_id) {
             // MERGE ACCOUNTS
             // first, find the account IDs to merge
             $bank_account_ids = array();
             $sql = "SELECT ba_id \n                FROM civicrm_bank_account_reference \n                WHERE reference = (SELECT reference FROM civicrm_bank_account_reference WHERE id={$reference_id})\n                ORDER BY ba_id ASC;";
             // use the oldest (lowest ID) as merge target
             $bank_account_query = CRM_Core_DAO::executeQuery($sql);
             while ($bank_account_query->fetch()) {
                 $bank_account_ids[] = $bank_account_query->ba_id;
             }
             if (count($bank_account_ids) < 2) {
                 // we need at least two bank accounts to merge...
                 $errors_ecountered += 1;
                 continue;
             }
             // now: load the first bank account...
             $main_ba = new CRM_Banking_BAO_BankAccount();
             $main_ba->get('id', $bank_account_ids[0]);
             $main_data_parsed = $main_ba->getDataParsed();
             // ...and try to merge the others into it
             $merge_failed = FALSE;
             for ($i = 1; $i < count($bank_account_ids); $i++) {
                 $merge_ba = new CRM_Banking_BAO_BankAccount();
                 $merge_ba->get('id', $bank_account_ids[$i]);
                 // merge created_date
                 if (isset($merge_ba->created_date) && $merge_ba->created_date < $main_ba->created_date) {
                     $main_ba->created_date = $merge_ba->created_date;
                 }
                 // merge description/data_raw
                 $replace_attributes = array('description', 'data_raw');
                 foreach ($replace_attributes as $attribute) {
                     if (!empty($merge_ba->{$attribute})) {
                         if (empty($main_ba->{$attribute})) {
                             // main_ba.$attribute not set, just overwrite
                             $main_ba->{$attribute} = $merge_ba->{$attribute};
                         } else {
                             // main_ba.$attribute set, check if identical
                             if ($main_ba->{$attribute} != $merge_ba->{$attribute}) {
                                 if (CIVIBANKING_MERGE_ACCOUNTS_CHECK_STRICT) {
                                     $merge_failed = TRUE;
                                     break;
                                 }
                             }
                         }
                     }
                 }
                 if ($merge_failed) {
                     break;
                 }
                 // merge data_parsed
                 $merge_data_parsed = $merge_ba->getDataParsed();
                 foreach ($merge_data_parsed as $key => $value) {
                     if (empty($main_data_parsed[$key])) {
                         $main_data_parsed[$key] = $value;
                     } else {
                         if ($main_data_parsed[$key] != $merge_data_parsed[$key]) {
                             if (CIVIBANKING_MERGE_ACCOUNTS_CHECK_STRICT) {
                                 $merge_failed = TRUE;
                                 break;
                             }
                         }
                     }
                 }
                 if ($merge_failed) {
                     break;
                 }
             }
             // MERGE NEXT ACCOUNT (for same target)
             if ($merge_failed) {
                 $errors_ecountered += 1;
             } else {
                 // SAVE THE MERGED OBJECT
                 $main_ba->setDataParsed($main_data_parsed);
                 $main_ba->modified_date = date('YmdHis');
                 $main_ba->save();
                 // DELETE THE OTHER, NOW OBSOLETE ACCOUNTS
                 $target_id = $bank_account_ids[0];
                 unset($bank_account_ids[0]);
                 $delete_ids = implode(',', $bank_account_ids);
                 CRM_Core_DAO::singleValueQuery("UPDATE civicrm_bank_account_reference SET ba_id={$target_id} WHERE ba_id IN ({$delete_ids});");
                 CRM_Core_DAO::singleValueQuery("UPDATE civicrm_bank_tx SET ba_id={$target_id} WHERE ba_id IN ({$delete_ids});");
                 CRM_Core_DAO::singleValueQuery("UPDATE civicrm_bank_tx SET party_ba_id={$target_id} WHERE party_ba_id IN ({$delete_ids});");
                 CRM_Core_DAO::singleValueQuery("DELETE FROM civicrm_bank_account WHERE id IN ({$delete_ids});");
                 $accounts_fixed += 1;
                 // finally, add the reference_ids to duplicate reference list,
                 //  in order to delete the resulting duplicate references
                 $reflist[] = $reference_id;
             }
         }
         if ($errors_ecountered) {
             CRM_Core_Session::setStatus(ts("%1 errors were encountered when trying to merge duplicate bank accounts, %2/%3 bank accounts were successfully merged.", array(1 => $errors_ecountered, 2 => $accounts_fixed, 3 => $errors_ecountered + $accounts_fixed)), ts('Errors encountered'), 'warn');
             $errors_ecountered = 0;
         } else {
             CRM_Core_Session::setStatus(ts("%1 duplicate bank accounts successfully merged.", array(1 => $accounts_fixed)), ts('Success'), 'info');
         }
     }
     // ============================
     // DELETE DUPLICATE REFERENCES.
     // ============================
     if (!empty($_REQUEST['fixref']) || !empty($reflist)) {
         //  They should be identical and can be safely removed
         if (!empty($_REQUEST['fixref'])) {
             if ($_REQUEST['fixref'] == 'all') {
                 foreach ($duplicates['reference'] as $reference => $info) {
                     if ((int) $info['reference_id']) {
                         $reflist[] = (int) $info['reference_id'];
                     }
                 }
             } else {
                 $parm_list = explode(',', $_REQUEST['fixref']);
                 foreach ($parm_list as $reference_id) {
                     if ((int) $reference_id) {
                         $reflist[] = (int) $reference_id;
                     }
                 }
             }
         }
         // perform the changes
         foreach ($reflist as $reference_id) {
             $sql = "SELECT ref_delete.id AS reference_id\n                FROM civicrm_bank_account_reference ref_delete\n                LEFT JOIN civicrm_bank_account_reference ref_keep ON ref_keep.id={$reference_id}\n                WHERE ref_keep.reference = ref_delete.reference\n                  AND ref_keep.ba_id = ref_delete.ba_id\n                  AND ref_keep.reference_type_id = ref_delete.reference_type_id\n                  AND ref_keep.id != ref_delete.id;";
             $reference_to_delete = CRM_Core_DAO::executeQuery($sql);
             while ($reference_to_delete->fetch()) {
                 $result = civicrm_api('BankingAccountReference', 'delete', array('id' => $reference_to_delete->reference_id, 'version' => 3));
                 if (empty($result['is_error'])) {
                     $refs_fixed += 1;
                 } else {
                     error_log("org.project60.banking.dedupe: Error while deleting dupe reference: " . $result['error_message']);
                     $errors_ecountered += 1;
                 }
             }
         }
         if ($errors_ecountered) {
             CRM_Core_Session::setStatus(ts("%1 errors were encountered when trying to delete duplicate references. %2/%3 references were successfully deleted.", array(1 => $errors_ecountered, 2 => $refs_fixed, 3 => $errors_ecountered + $refs_fixed)), ts('Errors encountered'), 'warn');
             $errors_ecountered = 0;
         } else {
             CRM_Core_Session::setStatus(ts("%1 duplicate references successfully deleted.", array(1 => $refs_fixed)), ts('Success'), 'info');
         }
     }
     return $refs_fixed + $accounts_fixed;
 }
 function run()
 {
     CRM_Utils_System::setTitle(ts('CiviBanking Dashboard'));
     $now = strtotime("now");
     $week_count = 7;
     $oldest_week = date('YW', strtotime("now -{$week_count} weeks"));
     $payment_states = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_tx_status');
     $account_names = array();
     // get the week based data
     $account_week_data = array();
     for ($i = $week_count; $i >= 0; $i--) {
         $weeks[] = date('YW', strtotime("now -{$i} weeks"));
     }
     $account_based_data_sql = "\n    SELECT\n      COUNT(*)               AS count,\n      YEARWEEK(value_date,3) AS year_week,\n      ba_id                  AS bank_account_id,\n      status_id              AS status_id\n    FROM\n      civicrm_bank_tx\n    GROUP BY\n      ba_id, year_week, status_id;\n    ";
     $results = CRM_Core_DAO::executeQuery($account_based_data_sql);
     while ($results->fetch()) {
         // get the account
         if (empty($results->bank_account_id)) {
             $account_id = 0;
         } else {
             $account_id = $results->bank_account_id;
         }
         if (!isset($account_week_data[$account_id])) {
             $account_week_data[$account_id] = array();
         }
         // get the week
         $week = $results->year_week;
         if ($week < $oldest_week) {
             $week = 'before';
         }
         if (!isset($account_week_data[$account_id][$week])) {
             $account_week_data[$account_id][$week] = array();
         }
         // get the status
         $status_id = $results->status_id;
         if ($results->status_id == $payment_states['processed']['id'] || $results->status_id == $payment_states['ignored']['id']) {
             if (!isset($account_week_data[$account_id][$week]['done'])) {
                 $account_week_data[$account_id][$week]['done'] = 0;
             }
             $account_week_data[$account_id][$week]['done'] += $results->count;
         }
         //if (!isset($account_week_data[$account_id][$week][$status_id])) $account_week_data[$account_id][$week][$status_id] = 0;
         //$account_week_data[$account_id][$week][$status_id] += 1;
         if (!isset($account_week_data[$account_id][$week]['sum'])) {
             $account_week_data[$account_id][$week]['sum'] = 0;
         }
         $account_week_data[$account_id][$week]['sum'] += $results->count;
     }
     // fill empty weeks
     foreach ($account_week_data as $account_id => $account_data) {
         for ($i = $week_count; $i >= 0; $i--) {
             $week = date('YW', strtotime("now -{$i} weeks"));
             if (!isset($account_data[$week])) {
                 $account_week_data[$account_id][$week] = array('sum' => 0);
             }
         }
         if (!isset($account_data['before'])) {
             $account_week_data[$account_id]['before'] = array('sum' => 0);
         }
         // look up account name
         if ($account_id == 0) {
             $account_names[0] = ts('Unknown');
         } else {
             $btx_bao = new CRM_Banking_BAO_BankAccount();
             $btx_bao->get('id', $account_id);
             $data_parsed = $btx_bao->getDataParsed();
             if (isset($data_parsed['name'])) {
                 $account_names[$account_id] = $data_parsed['name'];
             } else {
                 $account_names[$account_id] = ts('account') . " [{$account_id}]";
             }
         }
     }
     $this->assign('account_week_data', $account_week_data);
     $this->assign('account_names', $account_names);
     $this->assign('weeks', $weeks);
     // get statistics data
     $statistics = array();
     $statistics[] = $this->calculateStats(ts("Payments") . " (" . ts("current year") . ")", "YEAR(value_date) = '" . date('Y') . "'", $payment_states);
     $statistics[] = $this->calculateStats(ts("Payments") . " (" . ts("last year") . ")", "YEAR(value_date) = '" . date('Y', strtotime("-1 year")) . "'", $payment_states);
     $statistics[] = $this->calculateStats(ts("Payments") . " (" . ts("all times") . ")", "1", $payment_states);
     $this->assign('statistics', $statistics);
     parent::run();
 }
Example #8
0
 public function getOrCreateBankAccount(&$coda_tx)
 {
     $refs = array();
     if (isset($coda_tx->iban) && !empty($coda_tx->iban)) {
         $refs['iban'] = $coda_tx->iban;
     }
     if (isset($coda_tx->bban) && !empty($coda_tx->bban)) {
         $refs['bban'] = $coda_tx->bban;
     }
     if (!array_key_exists('iban', $refs) || !array_key_exists('bban', $refs)) {
         //todo take the main ba
     }
     foreach ($refs as $type => $ref) {
         $bank_account_refs = array();
         $breftypeid = $this->_ba_ref_types[$type]['value'];
         $options = array('reference_type_id' => $breftypeid, 'reference' => $ref, 'version' => 3);
         $result = civicrm_api('banking_account_reference', 'get', $options);
         if ($result['count'] != 0) {
             $bank_account_refs[$type] = $result['values'][$result['id']];
         }
     }
     /*
         if(isset($coda_tx->bic) && !empty($coda_tx->bic)){
        $refs['bic'] = $coda_tx->bic;
         }   
     */
     if (empty($bank_account_refs)) {
         $bank_account = new CRM_Banking_BAO_BankAccount();
         $bank_account->description = $coda_tx->name;
         $data_raw = array('name' => $coda_tx->name, 'info_msg' => $coda_tx->info_message);
         $data_parsed = array('name' => $coda_tx->name, 'street_address' => trim($coda_tx->streetname . ' ' . $coda_tx->streetnumber), 'postal_code' => $coda_tx->postal_code, 'city' => $coda_tx->city, 'country_code' => $coda_tx->country_code, 'bic' => $coda_tx->bic);
         $bank_account->created_date = date('YmdHis');
         $bank_account->modified_date = date('YmdHis');
         $bank_account->data_raw = json_encode($data_raw);
         $bank_account->data_parsed = json_encode($data_parsed);
         $bank_account->save();
         $ma = new CRM_Banking_Helpers_MatchAddress($bank_account);
         if ($ma->findAddress()) {
             $ma->updateDataParsed();
         }
     } else {
         $ba_ref = each($bank_account_refs);
         $result = civicrm_api('banking_account', 'get', array('id' => $ba_ref['id'], 'version' => 3));
         $bank_account = (object) $result['values'][$result['id']];
     }
     foreach ($refs as $type => $ref) {
         if (!array_key_exists($type, $bank_account_refs)) {
             $bank_account_ref = new CRM_Banking_BAO_BankAccountReference();
             $bank_account_ref->reference = $coda_tx->{$type};
             $bank_account_ref->reference_type_id = $this->_ba_ref_types[$type]['value'];
             $bank_account_ref->ba_id = $bank_account->id;
             $bank_account_ref->save();
         }
     }
     return $bank_account->id;
 }
Example #9
0
 function run()
 {
     // set this variable to request a redirect
     $url_redirect = NULL;
     // Get the current ID
     if (isset($_REQUEST['list'])) {
         $list = explode(",", $_REQUEST['list']);
     } else {
         if (isset($_REQUEST['s_list'])) {
             $list = CRM_Banking_Page_Payments::getPaymentsForStatements($_REQUEST['s_list']);
             $list = explode(",", $list);
         } else {
             $list = array();
             array_push($list, $_REQUEST['id']);
         }
     }
     if (isset($_REQUEST['id'])) {
         $pid = $_REQUEST['id'];
     } else {
         $pid = $list[0];
     }
     // find position in the list
     $index = array_search($pid, $list);
     if ($index >= 0) {
         if (isset($list[$index + 1])) {
             $next_pid = $list[$index + 1];
         }
         if (isset($list[$index - 1])) {
             $prev_pid = $list[$index - 1];
         }
     }
     $btx_bao = new CRM_Banking_BAO_BankTransaction();
     $btx_bao->get('id', $pid);
     // read the list of BTX statuses
     $choices = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_tx_status');
     // If the exercution was triggered, run that first
     if (isset($_REQUEST['execute'])) {
         $execute_bao = $_REQUEST['execute'] == $pid ? $btx_bao : NULL;
         $this->execute_suggestion($_REQUEST['execute_suggestion'], $_REQUEST, $execute_bao, $choices);
         // after execution -> exit if this was the last in the list
         if (!isset($next_pid) && $_REQUEST['execute'] == $pid) {
             $url_redirect = banking_helper_buildURL('civicrm/banking/payments', $this->_pageParameters());
         }
     }
     // look up some stuff regarding this btx
     $my_bao = new CRM_Banking_BAO_BankAccount();
     $my_bao->get('id', $btx_bao->ba_id);
     if ($btx_bao->party_ba_id) {
         $ba_bao = new CRM_Banking_BAO_BankAccount();
         $ba_bao->get('id', $btx_bao->party_ba_id);
         $this->assign('party_ba', $ba_bao);
         $this->assign('party_ba_data_parsed', json_decode($ba_bao->data_parsed, true));
         $this->assign('party_ba_references', $ba_bao->getReferences());
         // deprecated: contact can also be indetified via other means, see below
         if ($ba_bao->contact_id) {
             $contact = civicrm_api('Contact', 'getsingle', array('version' => 3, 'id' => $ba_bao->contact_id));
         }
     }
     // parse structured data
     $this->assign('btxstatus', $choices[$btx_bao->status_id]);
     $this->assign('payment', $btx_bao);
     $this->assign('my_bao', $my_bao);
     $this->assign('payment_data_raw', json_decode($btx_bao->data_raw, true));
     $data_parsed = json_decode($btx_bao->data_parsed, true);
     $this->assign('payment_data_parsed', $data_parsed);
     if (!empty($data_parsed['iban'])) {
         $data_parsed['iban'] = CRM_Banking_BAO_BankAccountReference::format('iban', $data_parsed['iban']);
     }
     if (empty($contact) && !empty($data_parsed['contact_id'])) {
         // convention: the contact was identified with acceptable precision
         $contact = civicrm_api('Contact', 'getsingle', array('version' => 3, 'id' => $data_parsed['contact_id']));
     }
     if (!empty($contact)) {
         $this->assign('contact', $contact);
     } else {
         $this->assign('contact', NULL);
     }
     $extra_data = array();
     $_data_raw = json_decode($btx_bao->data_raw, true);
     if (is_array($_data_raw)) {
         $extra_data = $_data_raw;
     } else {
         $extra_data['raw'] = $btx_bao->data_raw;
     }
     if (is_array($btx_bao->getDataParsed())) {
         $extra_data = array_merge($extra_data, $btx_bao->getDataParsed());
     }
     $this->assign('extra_data', $extra_data);
     // check if closed ('processed' or 'ignored')
     if ($choices[$btx_bao->status_id]['name'] == 'processed' || $choices[$btx_bao->status_id]['name'] == 'ignored') {
         // this is a closed BTX, generate execution information
         $execution_info = array();
         $execution_info['status'] = $choices[$btx_bao->status_id]['name'];
         $suggestion_objects = $btx_bao->getSuggestionList();
         foreach ($suggestion_objects as $suggestion) {
             if ($suggestion->isExecuted()) {
                 $execution_info['date'] = $suggestion->isExecuted();
                 $execution_info['visualization'] = $suggestion->visualize_execution($btx_bao);
                 $execution_info['executed_by'] = $suggestion->getParameter('executed_by');
                 $execution_info['executed_automatically'] = $suggestion->getParameter('executed_automatically');
                 break;
             }
         }
         $this->assign('execution_info', $execution_info);
         // generate message
         if (!empty($execution_info['date'])) {
             $execution_date = CRM_Utils_Date::customFormat($execution_info['date'], CRM_Core_Config::singleton()->dateformatFull);
         } else {
             $execution_date = ts("<i>unknown date</i>");
         }
         if (!empty($execution_info['executed_by'])) {
             // visualize more info, see https://github.com/Project60/CiviBanking/issues/71
             // try to load contact
             $user_id = $execution_info['executed_by'];
             $user = civicrm_api('Contact', 'getsingle', array('id' => $user_id, 'version' => 3));
             if (empty($user['is_error'])) {
                 $user_link = CRM_Utils_System::url("civicrm/contact/view", "&reset=1&cid={$user_id}");
                 $user_string = "<a href='{$user_link}'>" . $user['display_name'] . "</a>";
             } else {
                 $user_string = ts('Unknown User') . ' [' . $user_id . ']';
             }
             if (empty($execution_info['executed_automatically'])) {
                 $automated = '';
             } else {
                 $automated = ts('automatically');
             }
             if ($choices[$btx_bao->status_id]['name'] == 'processed') {
                 $message = sprintf(ts("This transaction was <b>%s processed</b> on %s by %s."), $automated, $execution_date, $user_string);
             } else {
                 $message = sprintf(ts("This transaction was <b>%s ignored</b> on %s by %s."), $automated, $execution_date, $user_string);
             }
         } else {
             // visualize the previous, reduced information
             if ($choices[$btx_bao->status_id]['name'] == 'processed') {
                 $message = sprintf(ts("This transaction was <b>processed</b> on %s."), $execution_date);
             } else {
                 $message = sprintf(ts("This transaction was marked to be <b>ignored</b> on %s."), $execution_date);
             }
         }
         $this->assign('status_message', $message);
     } else {
         // this is an open (new or analysed) BTX:  create suggestion list
         $suggestions = array();
         $suggestion_objects = $btx_bao->getSuggestionList();
         foreach ($suggestion_objects as $suggestion) {
             $color = $this->translateProbability($suggestion->getProbability() * 100);
             array_push($suggestions, array('hash' => $suggestion->getHash(), 'probability' => sprintf('%d&nbsp;%%', $suggestion->getProbability() * 100), 'color' => $color, 'visualization' => $suggestion->visualize($btx_bao), 'title' => $suggestion->getTitle(), 'actions' => $suggestion->getActions()));
         }
         $this->assign('suggestions', $suggestions);
     }
     // URLs & stats
     $unprocessed_count = 0;
     $this->assign('url_back', banking_helper_buildURL('civicrm/banking/payments', $this->_pageParameters()));
     if (isset($next_pid)) {
         $this->assign('url_skip_forward', banking_helper_buildURL('civicrm/banking/review', $this->_pageParameters(array('id' => $next_pid))));
         $this->assign('url_execute', banking_helper_buildURL('civicrm/banking/review', $this->_pageParameters(array('id' => $next_pid, 'execute' => $pid))));
         $unprocessed_info = $this->getUnprocessedInfo($list, $next_pid, $choices);
         if ($unprocessed_info) {
             $this->assign('url_skip_processed', banking_helper_buildURL('civicrm/banking/review', $this->_pageParameters(array('id' => $unprocessed_info['next_unprocessed_pid']))));
             $unprocessed_count = $unprocessed_info['unprocessed_count'];
         }
     } else {
         $this->assign('url_execute', banking_helper_buildURL('civicrm/banking/review', $this->_pageParameters(array('execute' => $pid))));
     }
     if (isset($prev_pid)) {
         $this->assign('url_skip_back', banking_helper_buildURL('civicrm/banking/review', $this->_pageParameters(array('id' => $prev_pid))));
     }
     $this->assign('url_show_payments', banking_helper_buildURL('civicrm/banking/payments', array('show' => 'payments')));
     global $base_url;
     $this->assign('base_url', $base_url);
     // Set the page-title dynamically
     if (count($list) > 1) {
         CRM_Utils_System::setTitle(ts("Review Bank Transaction %1 of %2 (%3 unprocessed ahead)", array(1 => $index + 1, 2 => count($list), 3 => $unprocessed_count)));
     } else {
         CRM_Utils_System::setTitle(ts("Review Bank Transaction"));
     }
     // perform redirect, if requested
     if ($url_redirect) {
         CRM_Utils_System::redirect($url_redirect);
     }
     parent::run();
 }