function run() { // Example: Set the page-title dynamically; alternatively, declare a static title in xml/Menu/*.xml CRM_Utils_System::setTitle(ts('Bank Transactions')); // look up the payment states $payment_states = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_tx_status'); if (!isset($_REQUEST['status_ids'])) { $_REQUEST['status_ids'] = $payment_states['new']['id']; } if (isset($_REQUEST['show']) && $_REQUEST['show'] == "payments") { // PAYMENT MODE REQUESTED $this->build_paymentPage($payment_states); $list_type = 'list'; } else { // STATEMENT MODE REQUESTED $this->build_statementPage($payment_states); $list_type = 's_list'; } // URLs global $base_url; $this->assign('base_url', $base_url); $this->assign('url_show_payments', banking_helper_buildURL('civicrm/banking/payments', array('show' => 'payments', $list_type => "__selected__"), array('status_ids'))); $this->assign('url_show_statements', banking_helper_buildURL('civicrm/banking/payments', array('show' => 'statements'), array('status_ids'))); $this->assign('url_show_payments_new', banking_helper_buildURL('civicrm/banking/payments', $this->_pageParameters(array('status_ids' => $payment_states['new']['id'])))); $this->assign('url_show_payments_analysed', banking_helper_buildURL('civicrm/banking/payments', $this->_pageParameters(array('status_ids' => $payment_states['suggestions']['id'])))); $this->assign('url_show_payments_completed', banking_helper_buildURL('civicrm/banking/payments', $this->_pageParameters(array('status_ids' => $payment_states['processed']['id'] . "," . $payment_states['ignored']['id'])))); $this->assign('url_review_selected_payments', banking_helper_buildURL('civicrm/banking/review', array($list_type => "__selected__"))); $this->assign('url_export_selected_payments', banking_helper_buildURL('civicrm/banking/export', array($list_type => "__selected__"))); $this->assign('can_delete', CRM_Core_Permission::check('administer CiviCRM')); // status filter button styles if (isset($_REQUEST['status_ids']) && strlen($_REQUEST['status_ids']) > 0) { if ($_REQUEST['status_ids'] == $payment_states['new']['id']) { $this->assign('button_style_new', "color:green"); } else { if ($_REQUEST['status_ids'] == $payment_states['suggestions']['id']) { $this->assign('button_style_analysed', "color:green"); } else { if ($_REQUEST['status_ids'] == $payment_states['processed']['id'] . "," . $payment_states['ignored']['id']) { $this->assign('button_style_completed', "color:green"); } else { $this->assign('button_style_custom', "color:green"); } } } } parent::run(); }
/** * Analyses the given bank transactions * used as AJAX call * * @param list list of bank_tx ids to process * @param s_list list of bank_tx_batch ids to process * * @return array api result array * @access public */ function civicrm_api3_banking_transaction_analyselist($params) { // calculate a timeout, so we wouldn't get killed off $now = strtotime('now'); $max_execution_time = ini_get('max_execution_time'); if (empty($max_execution_time)) { $max_execution_time = 10 * 60; // 10 minutes } else { $max_execution_time = min(10 * 60, (int) $max_execution_time * 0.9); } $timeout = strtotime("+{$max_execution_time} seconds"); // extract payment IDs from parameters $tx_ids = _civicrm_api3_banking_transaction_getTxIDs($params); if (empty($tx_ids)) { return civicrm_api3_create_error("Something's wrong with your parameters. No payments found."); } // no funny business... $list_string = implode(',', $tx_ids); // filter for non-closed statements $payment_states = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_tx_status'); $state_ignored = (int) $payment_states['ignored']['id']; $state_processed = (int) $payment_states['processed']['id']; $filter_query = "SELECT `id` \n FROM `civicrm_bank_tx` \n WHERE `status_id` NOT IN ({$state_ignored},{$state_processed})\n AND `id` IN ({$list_string});"; $filter_result = CRM_Core_DAO::executeQuery($filter_query); $filtered_list = array(); while ($filter_result->fetch()) { $filtered_list[] = $filter_result->id; } // now run the matchers $engine = CRM_Banking_Matcher_Engine::getInstance(); $timed_out = 0; $processed_count = 0; foreach ($filtered_list as $pid) { $engine->match($pid); $processed_count += 1; if (strtotime("now") > $timeout) { $timed_out = 1; break; } } // done. create a result. $after_exec = strtotime('now'); $payment_count = count(explode(',', $list_string)); $result = array('payment_count' => $payment_count, 'processed_count' => $processed_count, 'skipped_count' => $payment_count - count($filtered_list), 'time' => $after_exec - $now, 'timed_out' => $timed_out); return civicrm_api3_create_success($result); }
/** * will check if the given tx_status_id is closed, * i.e. marked as 'processed' or 'ignored' * * @return TRUE if closed, FALSE otherwise */ function banking_helper_tx_status_closed($tx_status_id) { $status = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_tx_status'); return $status[$tx_status_id]['name'] == 'processed' || $status[$tx_status_id]['name'] == 'ignored'; }
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(); }
function __construct($config_name) { parent::__construct($config_name); $this->_ba_ref_types = banking_helper_optiongroup_id_name_mapping('civicrm_banking.bank_account_reference_type'); }
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 %%', $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(); }