GnuCash  4.4-227-gc6421d67d+
Modules | Files | Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
Import_Export

Modules

 AqBanking
 

Files

 
file  import-backend.h
 Generic importer backend interface.
 
file  import-commodity-matcher.h
 A Generic commodity matcher/picker.
 
file  import-main-matcher.h
 Transaction matcher main window.
 
file  import-match-picker.h
 The transaction match picker dialog interface.
 
file  import-pending-matches.h
 Tracking container for pending match status.
 
file  import-settings.h
 Import preference handling.
 
file  import-utilities.h
 Utility functions for writing import modules.
 

Data Structures

struct  AccountOnlineMatch
 
struct  AccountPickerDialog
 
struct  GNCImportSelectedMatchInfo
 
struct  GNCImportTransInfo
 
struct  GNCImportMatchInfo
 
struct  GNCImportMainMatcher
 
struct  match_struct
 
struct  GNCImportMatchPicker
 
struct  GNCPendingMatches
 
struct  GNCImportSettings
 
struct  split_record
 
struct  ofx_info
 

Macros

#define STATE_SECTION   "dialogs/import/generic_matcher/account_matcher"
 
#define GNC_PREFS_GROUP   "dialogs.import.generic.account-picker"
 
#define GNCIMPORT_DESC   "desc"
 
#define GNCIMPORT_MEMO   "memo"
 
#define GNCIMPORT_PAYEE   "payee"
 
#define GNC_PREFS_GROUP   "dialogs.import.generic.transaction-list"
 
#define IMPORT_MAIN_MATCHER_CM_CLASS   "transaction-matcher-dialog"
 
#define CSS_INT_REQUIRED_CLASS   "gnc-class-intervention-required"
 
#define CSS_INT_PROB_REQUIRED_CLASS   "gnc-class-intervention-probably-required"
 
#define CSS_INT_NOT_REQUIRED_CLASS   "gnc-class-intervention-not-required"
 
#define G_MOD_IMPORT_MATCHER   "gnc.import.main-matcher"
 
#define GNC_PREFS_GROUP   "dialogs.import.generic.match-picker"
 
#define GNC_PREF_DISPLAY_RECONCILED   "display-reconciled"
 
#define GNC_PREFS_GROUP_IMPORT   "dialogs.import.generic"
 The preferences used by the importer.
 
#define GNC_PREF_ENABLE_SKIP   "enable-skip"
 
#define GNC_PREF_ENABLE_UPDATE   "enable-update"
 
#define GNC_PREF_USE_BAYES   "use-bayes"
 
#define GNC_PREF_ATM_FEE_THRESHOLD   "atm-fee-threshold"
 
#define GNC_PREF_AUTO_CLEAR_THRESHOLD   "auto-clear-threshold"
 
#define GNC_PREF_AUTO_ADD_THRESHOLD   "auto-add-threshold"
 
#define GNC_PREF_MATCH_THRESHOLD   "match-threshold"
 
#define GNC_PREFS_GROUP   "dialogs.log-replay"
 
#define STRING_FIELD_SIZE   256
 
#define GNC_PREFS_GROUP   "dialogs.import.ofx"
 
#define GNC_PREF_AUTO_COMMODITY   "auto-create-commodity"
 

Typedefs

typedef void(* GNCTransactionProcessedCB) (GNCImportTransInfo *trans_info, gboolean imported, gpointer user_data)
 
typedef GHashTable GNCImportPendingMatches
 

Enumerations

enum  GNCImportAction {
  GNCImport_SKIP, GNCImport_ADD, GNCImport_CLEAR, GNCImport_UPDATE,
  GNCImport_LAST_ACTION, GNCImport_INVALID_ACTION
}
 
enum  downloaded_cols {
  DOWNLOADED_COL_DATE_TXT = 0, DOWNLOADED_COL_DATE_INT64, DOWNLOADED_COL_ACCOUNT, DOWNLOADED_COL_AMOUNT,
  DOWNLOADED_COL_AMOUNT_DOUBLE, DOWNLOADED_COL_DESCRIPTION, DOWNLOADED_COL_MEMO, DOWNLOADED_COL_ACTION_ADD,
  DOWNLOADED_COL_ACTION_CLEAR, DOWNLOADED_COL_ACTION_UPDATE, DOWNLOADED_COL_ACTION_INFO, DOWNLOADED_COL_ACTION_PIXBUF,
  DOWNLOADED_COL_DATA, DOWNLOADED_COL_COLOR, DOWNLOADED_COL_ENABLE, NUM_DOWNLOADED_COLS,
  DOWNLOADED_COL_ACCOUNT = 0, DOWNLOADED_COL_DATE, DOWNLOADED_COL_AMOUNT, DOWNLOADED_COL_DESCRIPTION,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_BALANCED, DOWNLOADED_COL_INFO_PTR, NUM_DOWNLOADED_COLS
}
 
enum  downloaded_cols {
  DOWNLOADED_COL_DATE_TXT = 0, DOWNLOADED_COL_DATE_INT64, DOWNLOADED_COL_ACCOUNT, DOWNLOADED_COL_AMOUNT,
  DOWNLOADED_COL_AMOUNT_DOUBLE, DOWNLOADED_COL_DESCRIPTION, DOWNLOADED_COL_MEMO, DOWNLOADED_COL_ACTION_ADD,
  DOWNLOADED_COL_ACTION_CLEAR, DOWNLOADED_COL_ACTION_UPDATE, DOWNLOADED_COL_ACTION_INFO, DOWNLOADED_COL_ACTION_PIXBUF,
  DOWNLOADED_COL_DATA, DOWNLOADED_COL_COLOR, DOWNLOADED_COL_ENABLE, NUM_DOWNLOADED_COLS,
  DOWNLOADED_COL_ACCOUNT = 0, DOWNLOADED_COL_DATE, DOWNLOADED_COL_AMOUNT, DOWNLOADED_COL_DESCRIPTION,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_BALANCED, DOWNLOADED_COL_INFO_PTR, NUM_DOWNLOADED_COLS
}
 
enum  matcher_cols {
  MATCHER_COL_CONFIDENCE = 0, MATCHER_COL_CONFIDENCE_PIXBUF, MATCHER_COL_DATE, MATCHER_COL_AMOUNT,
  MATCHER_COL_DESCRIPTION, MATCHER_COL_MEMO, MATCHER_COL_RECONCILED, MATCHER_COL_PENDING,
  MATCHER_COL_INFO_PTR, NUM_MATCHER_COLS
}
 
enum  GNCImportPendingMatchType { GNCImportPending_NONE, GNCImportPending_AUTO, GNCImportPending_MANUAL }
 

Functions

Accountgnc_import_select_account (GtkWidget *parent, const gchar *account_online_id_value, gboolean auto_create, const gchar *account_human_description, const gnc_commodity *new_account_default_commodity, GNCAccountType new_account_default_type, Account *default_selection, gboolean *ok_pressed)
 Must be called with a string containing a unique identifier for the account. More...
 
gnc_commodity * gnc_import_select_commodity (const char *cusip, gboolean ask_on_unknown, const char *default_fullname, const char *default_mnemonic)
 Must be called with a string containing a unique identifier for the commodity. More...
 
void on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info)
 
void on_matcher_cancel_clicked (GtkButton *button, gpointer user_data)
 
gboolean on_matcher_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
 
void on_matcher_help_clicked (GtkButton *button, gpointer user_data)
 This allows for the transaction help dialog to be started from the assistant button callback. More...
 
void on_matcher_help_close_clicked (GtkButton *button, gpointer user_data)
 
void gnc_gen_trans_list_delete (GNCImportMainMatcher *info)
 Deletes the given object. More...
 
gboolean gnc_gen_trans_list_empty (GNCImportMainMatcher *info)
 Checks whether there are no transactions to match. More...
 
void gnc_gen_trans_list_show_all (GNCImportMainMatcher *info)
 Shows widgets. More...
 
GNCImportMainMatcher * gnc_gen_trans_list_new (GtkWidget *parent, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit, gboolean show_all)
 Create a new generic transaction dialog window and return it. More...
 
GNCImportMainMatcher * gnc_gen_trans_assist_new (GtkWidget *parent, GtkWidget *assistant_page, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit)
 Add the Transaction matcher to an existing page of an assistant. More...
 
void gnc_gen_trans_assist_start (GNCImportMainMatcher *info)
 This starts the import process for transaction from an assistant. More...
 
void gnc_gen_trans_list_add_tp_cb (GNCImportMainMatcher *info, GNCTransactionProcessedCB trans_processed_cb, gpointer user_data)
 Add transaction processed callback to the transaction importer. More...
 
gboolean gnc_gen_trans_list_run (GNCImportMainMatcher *info)
 Run this dialog and return only after the user pressed Ok, Cancel, or closed the window. More...
 
void gnc_gen_trans_list_add_trans (GNCImportMainMatcher *gui, Transaction *trans)
 Add a newly imported Transaction to the Transaction Importer. More...
 
void gnc_gen_trans_list_show_reconcile_after_close_button (GNCImportMainMatcher *info, gboolean reconcile_after_close, gboolean active)
 Show and set the reconcile after close check button. More...
 
GtkWidget * gnc_gen_trans_list_get_reconcile_after_close_button (GNCImportMainMatcher *info)
 Returns the reconcile after close check button. More...
 
void gnc_gen_trans_list_add_trans_with_ref_id (GNCImportMainMatcher *gui, Transaction *trans, guint32 ref_id)
 Add a newly imported Transaction to the Transaction Importer and provide an external reference id for it. More...
 
GtkWidget * gnc_gen_trans_list_widget (GNCImportMainMatcher *info)
 Returns the widget of this dialog. More...
 
void gnc_import_match_picker_run_and_close (GtkWidget *parent, GNCImportTransInfo *transaction_info, GNCImportPendingMatches *pending_matches)
 Run a match_picker dialog so that the selected-MatchInfo in the given trans_info is updated accordingly. More...
 
GNCImportPendingMatches * gnc_import_PendingMatches_new (void)
 
void gnc_import_PendingMatches_delete (GNCImportPendingMatches *map)
 
void gnc_import_PendingMatches_add_match (GNCImportPendingMatches *map, GNCImportMatchInfo *match_info, gboolean selected_manually)
 
void gnc_import_PendingMatches_remove_match (GNCImportPendingMatches *map, GNCImportMatchInfo *match_info, gboolean selected_manually)
 
GNCImportPendingMatchType gnc_import_PendingMatches_get_match_type (GNCImportPendingMatches *map, GNCImportMatchInfo *match_info)
 
const char * gnc_import_PendingMatches_get_type_str (GNCImportPendingMatchType type)
 
GNCImportSettings * gnc_import_Settings_new (void)
 Allocates a new GNCImportSettings object, and initialize it with the appropriate user prefs.
 
void gnc_import_Settings_delete (GNCImportSettings *settings)
 Destructor.
 
gboolean gnc_import_trans_has_online_id (Transaction *transaction)
 
gboolean gnc_import_split_has_online_id (Split *split)
 
void qof_instance_set_guid (gpointer inst, const GncGUID *guid)
 Set the GncGUID of this instance.
 
void gnc_file_log_replay (GtkWindow *parent)
 The gnc_file_log_replay() routine will pop up a standard file selection dialogue asking the user to pick a log file to replay. More...
 
int ofx_proc_statement_cb (struct OfxStatementData data, void *statement_user_data)
 
int ofx_proc_security_cb (const struct OfxSecurityData data, void *security_user_data)
 
int ofx_proc_transaction_cb (struct OfxTransactionData data, void *user_data)
 
int ofx_proc_account_cb (struct OfxAccountData data, void *account_user_data)
 
void gnc_file_ofx_import (GtkWindow *parent)
 The gnc_file_ofx_import() routine will pop up a standard file selection dialogue asking the user to pick a OFX/QFX file. More...
 
char * libgncmod_ofx_gnc_module_path (void)
 
char * libgncmod_ofx_gnc_module_description (void)
 
int libgncmod_ofx_gnc_module_init (int refcount)
 
int libgncmod_ofx_gnc_module_end (int refcount)
 

Variables

gint GNCPendingMatches::num_manual_matches
 
gint GNCPendingMatches::num_auto_matches
 
int libgncmod_ofx_gnc_module_system_interface = 0
 
int libgncmod_ofx_gnc_module_current = 0
 
int libgncmod_ofx_gnc_module_revision = 0
 
int libgncmod_ofx_gnc_module_age = 0
 

Non-GUI Functions

GdkPixbuf * gen_probability_pixbuf (gint score, GNCImportSettings *settings, GtkWidget *widget)
 This function generates a new pixmap representing a match score. More...
 
void split_find_match (GNCImportTransInfo *trans_info, Split *split, gint display_threshold, double fuzzy_amount_difference)
 The transaction matching heuristics are here. More...
 
gboolean gnc_import_process_trans_item (GncImportMatchMap *matchmap, GNCImportTransInfo *trans_info)
 /brief – Processes one match according to its selected action. More...
 
gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable *acct_id_hash)
 Checks whether the given transaction's online_id already exists in its parent account. More...
 
void gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info, GNCImportSettings *settings)
 Iterates through all splits of the originating account of trans_info. More...
 

Getters/Setters for GNCImportTransInfo

GList * gnc_import_TransInfo_get_match_list (const GNCImportTransInfo *info)
 Returns the stored list of possible matches. More...
 
void gnc_import_TransInfo_set_match_list (GNCImportTransInfo *info, GList *match_list)
 Assigns the list of possible matches. More...
 
Transaction * gnc_import_TransInfo_get_trans (const GNCImportTransInfo *info)
 Returns the transaction of this TransInfo. More...
 
gboolean gnc_import_TransInfo_is_balanced (const GNCImportTransInfo *info)
 Returns if the transaction stored in the TransInfo is currently balanced. More...
 
Split * gnc_import_TransInfo_get_fsplit (const GNCImportTransInfo *info)
 Returns the first split of the transaction of this TransInfo. More...
 
GNCImportMatchInfognc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info)
 Returns the currently selected match in this TransInfo. More...
 
void gnc_import_TransInfo_set_selected_match_info (GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
 Sets the currently selected match in this TransInfo. More...
 
gboolean gnc_import_TransInfo_get_match_selected_manually (const GNCImportTransInfo *info)
 Returns if the currently selected match was selected by the user. More...
 
GNCImportAction gnc_import_TransInfo_get_action (const GNCImportTransInfo *info)
 Returns the currently selected action for this TransInfo. More...
 
void gnc_import_TransInfo_set_action (GNCImportTransInfo *info, GNCImportAction action)
 Set the action for this TransInfo. More...
 
Accountgnc_import_TransInfo_get_destacc (const GNCImportTransInfo *info)
 Returns the 'other account' of this transaction. More...
 
void gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info, Account *acc, gboolean selected_manually)
 Set the 'other account' of this transaction (used for auto-balance if needed). More...
 
gboolean gnc_import_TransInfo_get_destacc_selected_manually (const GNCImportTransInfo *info)
 Returns if the currently selected destination account for auto-matching was selected by the user. More...
 
guint32 gnc_import_TransInfo_get_ref_id (const GNCImportTransInfo *info)
 Returns the reference id for this TransInfo. More...
 
void gnc_import_TransInfo_set_ref_id (GNCImportTransInfo *info, guint32 ref_id)
 Set the reference id for this TransInfo. More...
 
void gnc_import_TransInfo_delete (GNCImportTransInfo *info)
 Destructor.
 
GNCImportTransInfo * gnc_import_TransInfo_new (Transaction *trans, GncImportMatchMap *matchmap)
 Create a new object of GNCImportTransInfo here. More...
 
gboolean gnc_import_TransInfo_refresh_destacc (GNCImportTransInfo *transaction_info, GncImportMatchMap *matchmap)
 Try to automatch a given transaction to a destination account.
 

Getters/Setters for GNCImportMatchInfo

Split * gnc_import_MatchInfo_get_split (const GNCImportMatchInfo *info)
 Get the split ('this-side split') of this MatchInfo. More...
 
gint gnc_import_MatchInfo_get_probability (const GNCImportMatchInfo *info)
 Get the probability (confidence level) of this MatchInfo. More...
 

Getters/Setters for GNCImportSettings

double gnc_import_Settings_get_fuzzy_amount (GNCImportSettings *settings)
 Return the allowed amount range for fuzzy amount matching. More...
 
gboolean gnc_import_Settings_get_action_skip_enabled (GNCImportSettings *settings)
 Return the selected action is enable state.
 
gboolean gnc_import_Settings_get_action_add_enabled (GNCImportSettings *settings)
 Return the selected action is enable state.
 
gboolean gnc_import_Settings_get_action_update_enabled (GNCImportSettings *settings)
 Return the selected action is enable state.
 
gboolean gnc_import_Settings_get_action_clear_enabled (GNCImportSettings *settings)
 Return the selected action is enable state.
 
gint gnc_import_Settings_get_clear_threshold (GNCImportSettings *settings)
 Return the selected threshold.
 
gint gnc_import_Settings_get_add_threshold (GNCImportSettings *settings)
 Return the selected threshold.
 
gint gnc_import_Settings_get_display_threshold (GNCImportSettings *settings)
 Return the selected threshold.
 
void gnc_import_Settings_set_match_date_hardlimit (GNCImportSettings *s, gint m)
 
gint gnc_import_Settings_get_match_date_hardlimit (const GNCImportSettings *settings)
 Returns the hard-limiting number of days that a matching split may differ. More...
 

Setter-getters

Setter and getter functions for the online_id field for Splits.

const gchar * gnc_import_get_acc_online_id (Account *account)
 
void gnc_import_set_acc_online_id (Account *account, const gchar *id)
 
const gchar * gnc_import_get_trans_online_id (Transaction *transaction)
 
void gnc_import_set_trans_online_id (Transaction *transaction, const gchar *id)
 
const gchar * gnc_import_get_split_online_id (Split *split)
 
void gnc_import_set_split_online_id (Split *split, const gchar *id)
 

Detailed Description

Function Documentation

◆ gen_probability_pixbuf()

GdkPixbuf * gen_probability_pixbuf ( gint  score,
GNCImportSettings *  settings,
GtkWidget *  widget 
)

This function generates a new pixmap representing a match score.

It is a series of vertical bars of different colors. -Below or at the add_threshold the bars are red -Above or at the clear_threshold the bars are green -Between the two threshold the bars are yellow

Parameters
scoreThe score for which to generate a pixmap.
settingsThe user settings from which to get the threshold
widgetThe parent widget in which the pixmap will eventually be added. Will be used to generate the colormap.

Definition at line 294 of file import-backend.c.

295 {
296  GdkPixbuf* retval = NULL;
297  gint i, j;
298  gint score;
299  const gint height = 15;
300  const gint width_each_bar = 7;
301  gchar * green_bar = ("bggggb ");
302  gchar * yellow_bar = ("byyyyb ");
303  gchar * red_bar = ("brrrrb ");
304  gchar * black_bar = ("bbbbbb ");
305  const gint width_first_bar = 1;
306  gchar * black_first_bar = ("b");
307  const gint num_colors = 5;
308  gchar * size_str;
309  gchar * none_color_str = g_strdup_printf(" c None");
310  gchar * green_color_str = g_strdup_printf("g c green");
311  gchar * yellow_color_str = g_strdup_printf("y c yellow");
312  gchar * red_color_str = g_strdup_printf("r c red");
313  gchar * black_color_str = g_strdup_printf("b c black");
314  gchar * xpm[2+num_colors+height];
315  gint add_threshold, clear_threshold;
316 
317  g_assert(settings);
318  g_assert(widget);
319  if (score_original < 0)
320  {
321  score = 0;
322  }
323  else
324  {
325  score = score_original;
326  }
327  size_str = g_strdup_printf("%d%s%d%s%d%s", (width_each_bar * score) + width_first_bar/*width*/, " ", height, " ", num_colors, " 1"/*characters per pixel*/);
328 
329  /*DEBUG("Begin");*/
330  xpm[0] = size_str;
331  xpm[1] = none_color_str;
332  xpm[2] = green_color_str;
333  xpm[3] = yellow_color_str;
334  xpm[4] = red_color_str;
335  xpm[5] = black_color_str;
336  add_threshold = gnc_import_Settings_get_add_threshold(settings);
337  clear_threshold = gnc_import_Settings_get_clear_threshold(settings);
338 
339  for (i = 0; i < height; i++)
340  {
341  xpm[num_colors+1+i] = g_new0(char, (width_each_bar * score) + width_first_bar + 1);
342  for (j = 0; j <= score; j++)
343  {
344  if (i == 0 || i == height - 1)
345  {
346  if (j == 0)
347  {
348  strcat(xpm[num_colors+1+i], black_first_bar);
349  }
350  else
351  {
352  strcat(xpm[num_colors+1+i], black_bar);
353  }
354  }
355  else
356  {
357  if (j == 0)
358  {
359  strcat(xpm[num_colors+1+i], black_first_bar);
360  }
361  else if (j <= add_threshold)
362  {
363  strcat(xpm[num_colors+1+i], red_bar);
364  }
365  else if (j >= clear_threshold)
366  {
367  strcat(xpm[num_colors+1+i], green_bar);
368  }
369  else
370  {
371  strcat(xpm[num_colors+1+i], yellow_bar);
372  }
373  }
374  }
375  }
376 
377  retval = gdk_pixbuf_new_from_xpm_data((const gchar **)xpm);
378  for (i = 0; i <= num_colors + height; i++)
379  {
380  /*DEBUG("free_loop i=%d%s%s",i,": ",xpm[i]);*/
381  g_free(xpm[i]);
382  }
383 
384  return retval;
385 }
gint gnc_import_Settings_get_clear_threshold(GNCImportSettings *settings)
Return the selected threshold.
gint gnc_import_Settings_get_add_threshold(GNCImportSettings *settings)
Return the selected threshold.

◆ gnc_file_log_replay()

void gnc_file_log_replay ( GtkWindow *  parent)

The gnc_file_log_replay() routine will pop up a standard file selection dialogue asking the user to pick a log file to replay.

If one is selected the .log file is opened and read. Its contents are then silently merged in the current log file.

Definition at line 549 of file gnc-log-replay.c.

550 {
551  char *selected_filename;
552  char *default_dir;
553  char read_buf[256];
554  char *read_retval;
555  GtkFileFilter *filter;
556  FILE *log_file;
557  char * record_start_str = "===== START";
558  /* NOTE: This string must match src/engine/TransLog.c (sans newline) */
559  char * expected_header_orig = "mod\ttrans_guid\tsplit_guid\ttime_now\t"
560  "date_entered\tdate_posted\tacc_guid\tacc_name\tnum\tdescription\t"
561  "notes\tmemo\taction\treconciled\tamount\tvalue\tdate_reconciled";
562  static char *expected_header = NULL;
563 
564  /* Use g_strdup_printf so we don't get accidental tab -> space conversion */
565  if (!expected_header)
566  expected_header = g_strdup(expected_header_orig);
567 
568  qof_log_set_level(GNC_MOD_IMPORT, QOF_LOG_DEBUG);
569  ENTER(" ");
570 
571  /* Don't log the log replay. This would only result in redundant logs */
572  xaccLogDisable();
573 
574  default_dir = gnc_get_default_directory(GNC_PREFS_GROUP);
575 
576  filter = gtk_file_filter_new();
577  gtk_file_filter_set_name(filter, "*.log");
578  gtk_file_filter_add_pattern(filter, "*.[Ll][Oo][Gg]");
579  selected_filename = gnc_file_dialog(parent,
580  _("Select a .log file to replay"),
581  g_list_prepend(NULL, filter),
582  default_dir,
583  GNC_FILE_DIALOG_OPEN);
584  g_free(default_dir);
585 
586  if (selected_filename != NULL)
587  {
588  /* Remember the directory as the default. */
589  default_dir = g_path_get_dirname(selected_filename);
590  gnc_set_default_directory(GNC_PREFS_GROUP, default_dir);
591  g_free(default_dir);
592 
593  /*strncpy(file,selected_filename, 255);*/
594  DEBUG("Filename found: %s", selected_filename);
595  if (xaccFileIsCurrentLog(selected_filename))
596  {
597  g_warning("Cannot open the current log file: %s", selected_filename);
598  gnc_error_dialog(NULL,
599  /* Translators: %s is the file name. */
600  _("Cannot open the current log file: %s"),
601  selected_filename);
602  }
603  else
604  {
605  DEBUG("Opening selected file");
606  log_file = g_fopen(selected_filename, "r");
607  if (!log_file || ferror(log_file) != 0)
608  {
609  int err = errno;
610  perror("File open failed");
611  /* Translators: First argument is the filename,
612  * second argument is the error.
613  */
614  gnc_error_dialog(NULL,
615  _("Failed to open log file: %s: %s"),
616  selected_filename,
617  strerror(err));
618  }
619  else
620  {
621  if ((read_retval = fgets(read_buf, sizeof(read_buf), log_file)) == NULL)
622  {
623  DEBUG("Read error or EOF");
624  gnc_info_dialog(NULL, "%s",
625  _("The log file you selected was empty."));
626  }
627  else
628  {
629  if (strncmp(expected_header, read_buf, strlen(expected_header)) != 0)
630  {
631  PERR("File header not recognised:\n%s", read_buf);
632  PERR("Expected:\n%s", expected_header);
633  gnc_error_dialog(NULL, "%s",
634  _("The log file you selected cannot be read. "
635  "The file header was not recognized."));
636  }
637  else
638  {
639  do
640  {
641  read_retval = fgets(read_buf, sizeof(read_buf), log_file);
642  /*DEBUG("Chunk read: %s",read_retval);*/
643  if (read_retval && strncmp(record_start_str, read_buf, strlen(record_start_str)) == 0) /* If a record started */
644  {
645  process_trans_record(log_file);
646  }
647  }
648  while (feof(log_file) == 0);
649  }
650  }
651  fclose(log_file);
652  }
653  }
654  g_free(selected_filename);
655  }
656  /* Start logging again */
657  xaccLogEnable();
658 
659  LEAVE("");
660 }
void qof_log_set_level(QofLogModule log_module, QofLogLevel level)
Set the logging level of the given log_module.
Definition: qoflog.cpp:292
void xaccLogDisable(void)
document me
Definition: TransLog.c:95
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:246
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:270
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:280
gboolean xaccFileIsCurrentLog(const gchar *name)
Test a filename to see if it is the name of the current logfile.
Definition: TransLog.c:141
void xaccLogEnable(void)
document me
Definition: TransLog.c:99

◆ gnc_file_ofx_import()

void gnc_file_ofx_import ( GtkWindow *  parent)

The gnc_file_ofx_import() routine will pop up a standard file selection dialogue asking the user to pick a OFX/QFX file.

If one is selected the OFX file is opened and read. Its contents are merged into the existing session (if any). The current session continues to remain open for editing.

Definition at line 1216 of file gnc-ofx-import.c.

1217 {
1218  extern int ofx_PARSER_msg;
1219  extern int ofx_DEBUG_msg;
1220  extern int ofx_WARNING_msg;
1221  extern int ofx_ERROR_msg;
1222  extern int ofx_INFO_msg;
1223  extern int ofx_STATUS_msg;
1224  GSList* selected_filenames = NULL;
1225  char *default_dir;
1226  GList *filters = NULL;
1227  GSList* iter = NULL;
1228  ofx_info* info = NULL;
1229  GtkFileFilter* filter = gtk_file_filter_new ();
1230 
1231 
1232  ofx_PARSER_msg = false;
1233  ofx_DEBUG_msg = false;
1234  ofx_WARNING_msg = true;
1235  ofx_ERROR_msg = true;
1236  ofx_INFO_msg = true;
1237  ofx_STATUS_msg = false;
1238 
1239  DEBUG("gnc_file_ofx_import(): Begin...\n");
1240 
1241  default_dir = gnc_get_default_directory(GNC_PREFS_GROUP);
1242  gtk_file_filter_set_name (filter, _("Open/Quicken Financial Exchange file (*.ofx, *.qfx)"));
1243  gtk_file_filter_add_pattern (filter, "*.[oqOQ][fF][xX]");
1244  filters = g_list_prepend( filters, filter );
1245 
1246  selected_filenames = gnc_file_dialog_multi (parent,
1247  _("Select one or multiple OFX/QFX file(s) to process"),
1248  filters,
1249  default_dir,
1250  GNC_FILE_DIALOG_IMPORT);
1251  g_free(default_dir);
1252 
1253  if (selected_filenames)
1254  {
1255  /* Remember the directory as the default. */
1256  default_dir = g_path_get_dirname(selected_filenames->data);
1257  gnc_set_default_directory(GNC_PREFS_GROUP, default_dir);
1258  g_free(default_dir);
1259 
1260  /* Look up the needed preferences */
1261  auto_create_commodity =
1262  gnc_prefs_get_bool (GNC_PREFS_GROUP_IMPORT, GNC_PREF_AUTO_COMMODITY);
1263 
1264  DEBUG("Opening selected file(s)");
1265  // Create the structure that holds the list of files to process and the statement info.
1266  info = g_new(ofx_info,1);
1267  info->num_trans_processed = 0;
1268  info->statement = NULL;
1269  info->last_investment_account = NULL;
1270  info->last_import_account = NULL;
1271  info->last_income_account = NULL;
1272  info->parent = parent;
1273  info->run_reconcile = FALSE;
1274  info->file_list = selected_filenames;
1275  // Call the aux import function.
1276  gnc_file_ofx_import_process_file (info);
1277  }
1278 }
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
#define GNC_PREFS_GROUP_IMPORT
The preferences used by the importer.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.

◆ gnc_gen_trans_assist_new()

GNCImportMainMatcher * gnc_gen_trans_assist_new ( GtkWidget *  parent,
GtkWidget *  assistant_page,
const gchar *  heading,
gboolean  all_from_same_account,
gint  match_date_hardlimit 
)

Add the Transaction matcher to an existing page of an assistant.

Must be called with the parent widget, ie. a vbox that the transaction matcher will be packed into. The data structure GNCImportMainMatcher is returned.

Parameters
parentThe parent widget
assistant_pageThe parent widget. This is the place the transaction matcher will be packed into.
headingThe heading label in the Importer window. May be NULL.
all_from_same_accountSet this to TRUE if ALL the transaction that will be added with gnc_gen_trans_list_add_trans are from the same source account. This will cause the account column to be hidden.
match_date_hardlimitThe number of days that a matching split may differ from the given transaction before it is discarded immediately. In other words, any split that is more distant from the given transaction than this match_date_hardlimit days will be ignored altogether. For use cases without paper checks (e.g. HBCI), values like 14 (days) might be appropriate, whereas for use cases with paper checks (e.g. OFX, QIF), values like 42 (days) seem more appropriate.
Returns
A pointer to the GNCImportMainMatcher which has been setup.

Definition at line 1288 of file import-main-matcher.c.

1293 {
1294  GNCImportMainMatcher *info;
1295  GtkBuilder *builder;
1296  GtkWidget *box;
1297 
1298  info = g_new0 (GNCImportMainMatcher, 1);
1299  info->main_widget = GTK_WIDGET(parent);
1300 
1301  /* load the interface */
1302  builder = gtk_builder_new ();
1303  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
1304 
1305  /* Pack content into Assistant page widget */
1306  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
1307  g_assert (box != NULL);
1308  gtk_box_pack_start (GTK_BOX(assistant_page), box, TRUE, TRUE, 6);
1309 
1310  /* setup the common parts */
1311  gnc_gen_trans_common_setup (info, parent, builder, heading,
1312  all_from_same_account, match_date_hardlimit);
1313 
1314  return info;
1315 }

◆ gnc_gen_trans_assist_start()

void gnc_gen_trans_assist_start ( GNCImportMainMatcher *  info)

This starts the import process for transaction from an assistant.

assistant button callback.

Parameters
info.A pointer to a the GNCImportMainMatcher structure.

Definition at line 1318 of file import-main-matcher.c.

1319 {
1320  on_matcher_ok_clicked (NULL, info);
1321 }

◆ gnc_gen_trans_list_add_tp_cb()

void gnc_gen_trans_list_add_tp_cb ( GNCImportMainMatcher *  info,
GNCTransactionProcessedCB  trans_processed_cb,
gpointer  user_data 
)

Add transaction processed callback to the transaction importer.

Parameters
infoThe Transaction Importer to use.
trans_processed_cbThe callback function.

Definition at line 1328 of file import-main-matcher.c.

1331 {
1332  info->user_data = user_data;
1333  info->transaction_processed_cb = trans_processed_cb;
1334 }

◆ gnc_gen_trans_list_add_trans()

void gnc_gen_trans_list_add_trans ( GNCImportMainMatcher *  gui,
Transaction *  trans 
)

Add a newly imported Transaction to the Transaction Importer.

The Importer takes over ownership of the passed transaction.

Parameters
guiThe Transaction Importer to use.
transThe Transaction to add. The must contain at least one split, and this split must have been associated with an account Only the first split will be used for matching. The transaction must NOT be committed. The Importer takes over ownership of the passed transaction.

Definition at line 1677 of file import-main-matcher.c.

1678 {
1679  Account* acc = NULL;
1680  Split* split = NULL;
1681  int i=0;
1682 
1683  split = xaccTransGetSplit (trans, 0);
1684  acc = xaccSplitGetAccount (split);
1685  defer_bal_computation (gui, acc);
1686 
1688  return;
1689 }/* end gnc_import_add_trans() */
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
STRUCTS.
void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transaction *trans, guint32 ref_id)
Add a newly imported Transaction to the Transaction Importer and provide an external reference id for...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
Definition: gmock-Split.cpp:53

◆ gnc_gen_trans_list_add_trans_with_ref_id()

void gnc_gen_trans_list_add_trans_with_ref_id ( GNCImportMainMatcher *  gui,
Transaction *  trans,
guint32  ref_id 
)

Add a newly imported Transaction to the Transaction Importer and provide an external reference id for it.

The Importer takes over ownership of the passed transaction.

Parameters
guiThe Transaction Importer to use.
transThe Transaction to add. The must contain at least one split, and this split must have been associated with an account Only the first split will be used for matching. The transaction must NOT be committed. The Importer takes over ownership of the passed transaction.
ref_idReference id which links an external object to the transaction.

Definition at line 1707 of file import-main-matcher.c.

1708 {
1709  GNCImportTransInfo * transaction_info = NULL;
1710  GtkTreeModel *model;
1711  GtkTreeIter iter;
1712  g_assert (gui);
1713  g_assert (trans);
1714 
1715  if (gnc_import_exists_online_id (trans, gui->acct_id_hash))
1716  return;
1717  else
1718  {
1719  transaction_info = gnc_import_TransInfo_new (trans, NULL);
1720  gnc_import_TransInfo_set_ref_id (transaction_info, ref_id);
1721  // It's much faster to gather the imported transactions into a GSList than directly into the
1722  // treeview.
1723  gui->temp_trans_list = g_slist_prepend (gui->temp_trans_list, transaction_info);
1724  }
1725  return;
1726 }
GNCImportTransInfo * gnc_import_TransInfo_new(Transaction *trans, GncImportMatchMap *matchmap)
Create a new object of GNCImportTransInfo here.
void gnc_import_TransInfo_set_ref_id(GNCImportTransInfo *info, guint32 ref_id)
Set the reference id for this TransInfo.
gboolean gnc_import_exists_online_id(Transaction *trans, GHashTable *acct_id_hash)
Checks whether the given transaction&#39;s online_id already exists in its parent account.

◆ gnc_gen_trans_list_delete()

void gnc_gen_trans_list_delete ( GNCImportMainMatcher *  info)

Deletes the given object.

Definition at line 178 of file import-main-matcher.c.

179 {
180  GtkTreeModel *model;
181  GtkTreeIter iter;
182  GNCImportTransInfo *trans_info;
183 
184  if (info == NULL)
185  return;
186 
187  model = gtk_tree_view_get_model (info->view);
188  if (gtk_tree_model_get_iter_first (model, &iter))
189  {
190  do
191  {
192  gtk_tree_model_get (model, &iter,
193  DOWNLOADED_COL_DATA, &trans_info,
194  -1);
195 
196  if (info->transaction_processed_cb)
197  {
198  info->transaction_processed_cb (trans_info, FALSE,
199  info->user_data);
200  }
201  }
202  while (gtk_tree_model_iter_next (model, &iter));
203  }
204 
205  if (GTK_IS_DIALOG(info->main_widget))
206  {
207  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->main_widget));
208  gnc_import_Settings_delete (info->user_settings);
209  gnc_unregister_gui_component (info->id);
210  gtk_widget_destroy (GTK_WIDGET(info->main_widget));
211  }
212  else
213  gnc_import_Settings_delete (info->user_settings);
214 
215  g_slist_free_full (info->temp_trans_list, (GDestroyNotify) gnc_import_TransInfo_delete);
216  info->temp_trans_list = NULL;
217 
218  // We've deferred balance computations on many accounts. Let's do it now that we're done.
219  update_all_balances (info);
220 
221  g_hash_table_foreach_remove (info->acct_id_hash, delete_hash, NULL);
222  info->acct_id_hash = NULL;
223  g_free (info);
224 }
void gnc_import_TransInfo_delete(GNCImportTransInfo *info)
Destructor.
void gnc_import_Settings_delete(GNCImportSettings *settings)
Destructor.

◆ gnc_gen_trans_list_empty()

gboolean gnc_gen_trans_list_empty ( GNCImportMainMatcher *  info)

Checks whether there are no transactions to match.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.
Returns
A boolean indicating whether the transaction list is empty.

Definition at line 227 of file import-main-matcher.c.

228 {
229  GtkTreeModel *model;
230  GtkTreeIter iter;
231  GNCImportTransInfo *trans_info;
232  g_assert (info);
233  model = gtk_tree_view_get_model (info->view);
234  // Check that both the tree model and the temporary list are empty.
235  return !gtk_tree_model_get_iter_first (model, &iter) && !info->temp_trans_list;
236 }

◆ gnc_gen_trans_list_get_reconcile_after_close_button()

GtkWidget * gnc_gen_trans_list_get_reconcile_after_close_button ( GNCImportMainMatcher *  info)

Returns the reconcile after close check button.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.
Returns
The check button.

Definition at line 1701 of file import-main-matcher.c.

1702 {
1703  return info->reconcile_after_close;
1704 }

◆ gnc_gen_trans_list_new()

GNCImportMainMatcher * gnc_gen_trans_list_new ( GtkWidget *  parent,
const gchar *  heading,
gboolean  all_from_same_account,
gint  match_date_hardlimit,
gboolean  show_all 
)

Create a new generic transaction dialog window and return it.

Parameters
parentThe parent GtkWidget. May be NULL.
headingThe heading label in the Importer window. May be NULL.
all_from_same_accountSet this to TRUE if ALL the transaction that will be added with gnc_gen_trans_list_add_trans are from the same source account. This will cause the account column to be hidden.
match_date_hardlimitThe number of days that a matching split may differ from the given transaction before it is discarded immediately. In other words, any split that is more distant from the given transaction than this match_date_hardlimit days will be ignored altogether. For use cases without paper checks (e.g. HBCI), values like 14 (days) might be appropriate, whereas for use cases with paper checks (e.g. OFX, QIF), values like 42 (days) seem more appropriate.
show_allif true, all widgets are shown
Returns
A pointer to the GNCImportMainMatcher which has been setup.

Definition at line 1236 of file import-main-matcher.c.

1241 {
1242  GNCImportMainMatcher *info;
1243  GtkBuilder *builder;
1244  GtkWidget *box, *pbox;
1245 
1246  info = g_new0 (GNCImportMainMatcher, 1);
1247 
1248  /* Initialize the GtkDialog. */
1249  builder = gtk_builder_new ();
1250  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_dialog");
1251  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
1252 
1253  info->main_widget = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_dialog"));
1254  g_assert (info->main_widget != NULL);
1255 
1256  /* Pack the content into the dialog vbox */
1257  pbox = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_vbox"));
1258  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
1259  gtk_box_pack_start (GTK_BOX(pbox), box, TRUE, TRUE, 0);
1260 
1261  /* setup the common parts */
1262  gnc_gen_trans_common_setup (info, parent, builder, heading,
1263  all_from_same_account, match_date_hardlimit);
1264 
1265  if (parent)
1266  gtk_window_set_transient_for (GTK_WINDOW(info->main_widget), GTK_WINDOW(parent));
1267 
1268  gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->main_widget), GTK_WINDOW(parent));
1269 
1270  if (show_all)
1271  gtk_widget_show_all (GTK_WIDGET(info->main_widget));
1272 
1273  // Register this UI, it needs to be closed when the session is closed.
1274  info->id = gnc_register_gui_component (IMPORT_MAIN_MATCHER_CM_CLASS,
1275  NULL, /* no refresh handler */
1276  (GNCComponentCloseHandler)gnc_gen_trans_list_delete,
1277  info);
1278  // This ensure this dialog is closed when the session is closed.
1279  gnc_gui_component_set_session (info->id, gnc_get_current_session());
1280  return info;
1281 }
void gnc_gen_trans_list_delete(GNCImportMainMatcher *info)
Deletes the given object.

◆ gnc_gen_trans_list_run()

gboolean gnc_gen_trans_list_run ( GNCImportMainMatcher *  info)

Run this dialog and return only after the user pressed Ok, Cancel, or closed the window.

This means that all actual importing will have been finished upon returning.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.
Returns
The boolean return value of the dialog run.

Definition at line 1337 of file import-main-matcher.c.

1338 {
1339  gboolean result;
1340 
1341  /* DEBUG("Begin"); */
1342  result = gtk_dialog_run (GTK_DIALOG (info->main_widget));
1343  /* DEBUG("Result was %d", result); */
1344 
1345  /* No destroying here since the dialog was already destroyed through
1346  the ok_clicked handlers. */
1347 
1348  return result;
1349 }

◆ gnc_gen_trans_list_show_all()

void gnc_gen_trans_list_show_all ( GNCImportMainMatcher *  info)

Shows widgets.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.

Definition at line 446 of file import-main-matcher.c.

447 {
448  g_assert (info);
449  gnc_gen_trans_list_create_matches (info);
450  resolve_conflicts (info);
451  gtk_widget_show_all (GTK_WIDGET(info->main_widget));
452  gnc_gen_trans_list_show_accounts_column (info);
453 }

◆ gnc_gen_trans_list_show_reconcile_after_close_button()

void gnc_gen_trans_list_show_reconcile_after_close_button ( GNCImportMainMatcher *  info,
gboolean  reconcile_after_close,
gboolean  active 
)

Show and set the reconcile after close check button.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.
reconcile_after_closeA gboolean that shows or hides the button.
activeA gboolean to set or clear the check button.

Definition at line 1692 of file import-main-matcher.c.

1695 {
1696  gtk_widget_set_visible (info->reconcile_after_close, reconcile_after_close);
1697  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->reconcile_after_close), active);
1698 }

◆ gnc_gen_trans_list_widget()

GtkWidget * gnc_gen_trans_list_widget ( GNCImportMainMatcher *  info)

Returns the widget of this dialog.

Parameters
infoA pointer to a the GNCImportMainMatcher structure.
Returns
A GtkWidget pointer to the dialog's widget.

Definition at line 1879 of file import-main-matcher.c.

1880 {
1881  g_assert (info);
1882  return info->main_widget;
1883 }

◆ gnc_import_exists_online_id()

gboolean gnc_import_exists_online_id ( Transaction *  trans,
GHashTable *  acct_id_hash 
)

Checks whether the given transaction's online_id already exists in its parent account.

The given transaction has to be open for editing. If a matching online_id exists, the transaction is destroyed (!) and TRUE is returned, otherwise FALSE is returned.

Parameters
transThe transaction for which to check for an existing online_id.

Definition at line 1116 of file import-backend.c.

1117 {
1118  gboolean online_id_exists = FALSE;
1119  Account *dest_acct;
1120  Split *source_split;
1121 
1122  /* Look for an online_id in the first split */
1123  source_split = xaccTransGetSplit(trans, 0);
1124  g_assert(source_split);
1125 
1126  // No online id, no point in continuing. We'd crash if we tried.
1127  if (!gnc_import_get_split_online_id (source_split))
1128  return FALSE;
1129  // Create a hash per account of a hash of all transactions IDs. Then the test below will be fast if
1130  // we have many transactions to import.
1131  dest_acct = xaccSplitGetAccount (source_split);
1132  if (!g_hash_table_contains (acct_id_hash, dest_acct))
1133  {
1134  GHashTable* new_hash = g_hash_table_new (g_str_hash, g_str_equal);
1135  g_hash_table_insert (acct_id_hash, dest_acct, new_hash);
1136  xaccAccountForEachTransaction (dest_acct, collect_trans_online_id, new_hash);
1137  }
1138  online_id_exists = g_hash_table_contains (g_hash_table_lookup (acct_id_hash, dest_acct),
1139  gnc_import_get_split_online_id (source_split));
1140 
1141  /* If it does, abort the process for this transaction, since it is
1142  already in the system. */
1143  if (online_id_exists == TRUE)
1144  {
1145  DEBUG("%s", "Transaction with same online ID exists, destroying current transaction");
1146  xaccTransDestroy(trans);
1147  xaccTransCommitEdit(trans);
1148  }
1149  return online_id_exists;
1150 }
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
The xaccAccountForEachTransaction() routine will traverse all of the transactions in account and call...
Definition: Account.cpp:5343
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
STRUCTS.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
Definition: gmock-Split.cpp:53

◆ gnc_import_match_picker_run_and_close()

void gnc_import_match_picker_run_and_close ( GtkWidget *  parent,
GNCImportTransInfo *  transaction_info,
GNCImportPendingMatches *  pending_matches 
)

Run a match_picker dialog so that the selected-MatchInfo in the given trans_info is updated accordingly.

Run a match_picker dialog where the user should pick the best match for 'one' given transaction, so that the selected-MatchInfo in the given trans_info is updated accordingly.

This functions will only return after the user clicked Ok, Cancel, or Window-Close.

This functions will only return after the user clicked Ok, Cancel, or Window-Close.

The dialog uses the same functionality as the one created through gnc_import_add_trans(), except that its two listviews are shown above one another, and the listview of downloaded transactions shows only one transaction, namely, the given trans_info.

This function is used from the gnc-gen-transaction code.

Parameters
parentThe parent widget
transaction_infoThe TransInfo for which the user is supposed to pick a matching transaction.
pending_matchesList of transactions

Definition at line 508 of file import-match-picker.c.

510 {
511  GNCImportMatchPicker *matcher;
512  gint response;
513  GNCImportMatchInfo *old;
514  gboolean old_selected_manually;
515  g_assert (transaction_info);
516 
517  /* Create a new match_picker, even though it's stored in a
518  transmatcher struct :-) */
519  matcher = g_new0(GNCImportMatchPicker, 1);
520 
521  matcher->pending_matches = pending_matches;
522 
523  /* DEBUG("Init match_picker"); */
524  init_match_picker_gui(parent, matcher);
525 
526  /* Append this single transaction to the view and select it */
527  downloaded_transaction_append(matcher, transaction_info);
528 
529  old = gnc_import_TransInfo_get_selected_match (transaction_info);
530  old_selected_manually =
532 
533  /* Let this dialog run and close. */
534  /*DEBUG("Right before run and close");*/
535  gtk_window_set_modal(GTK_WINDOW(matcher->transaction_matcher), TRUE);
536  response = gtk_dialog_run (GTK_DIALOG (matcher->transaction_matcher));
537 
538  gnc_save_window_size(GNC_PREFS_GROUP,
539  GTK_WINDOW (matcher->transaction_matcher));
540  gtk_widget_destroy (matcher->transaction_matcher);
541  /*DEBUG("Right after run and close");*/
542  /* DEBUG("Response was %d.", response); */
543  if (response == GTK_RESPONSE_OK && matcher->selected_match_info != old)
544  {
545  /* OK was pressed */
547  matcher->selected_match_info,
548  TRUE);
549 
550  gnc_import_PendingMatches_remove_match (pending_matches,
551  old,
552  old_selected_manually);
553  gnc_import_PendingMatches_add_match (pending_matches,
554  matcher->selected_match_info,
555  TRUE);
556  }
557 }
void gnc_import_TransInfo_set_selected_match_info(GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
Sets the currently selected match in this TransInfo.
gboolean gnc_import_TransInfo_get_match_selected_manually(const GNCImportTransInfo *info)
Returns if the currently selected match was selected by the user.
GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match(const GNCImportTransInfo *info)
Returns the currently selected match in this TransInfo.

◆ gnc_import_MatchInfo_get_probability()

gint gnc_import_MatchInfo_get_probability ( const GNCImportMatchInfo info)

Get the probability (confidence level) of this MatchInfo.

Parameters
infoCan be NULL, in which case the function returns 0

Definition at line 258 of file import-backend.c.

259 {
260  if (info)
261  {
262  return info->probability;
263  }
264  else
265  {
266  return 0;
267  }
268 }

◆ gnc_import_MatchInfo_get_split()

Split * gnc_import_MatchInfo_get_split ( const GNCImportMatchInfo info)

Get the split ('this-side split') of this MatchInfo.

Definition at line 251 of file import-backend.c.

252 {
253  g_assert (info);
254  return info->split;
255 }

◆ gnc_import_process_trans_item()

gboolean gnc_import_process_trans_item ( GncImportMatchMap matchmap,
GNCImportTransInfo *  trans_info 
)

/brief – Processes one match according to its selected action.

This function is intended to be called when the importer dialog is finished.

It should be called once for each imported transaction and processes each ImportTransInfo according to its selected action: For GNCImport_ADD, the transaction is added etc. etc.

Each successful match is also stored in the given ImportMatchMap, or, if that argument is NULL, in the ImportMatchMap of each originating account.

Parameters
matchmapThe ImportMatchMap where each match should be stored. May be NULL, in which case the ImportMatchMap of each account will be used.
trans_infoThe ImportTransInfo item to process.
Returns
TRUE if the item has been processed.

Definition at line 838 of file import-backend.c.

840 {
841  Split * other_split;
842  gnc_numeric imbalance_value;
843 
844  /* DEBUG("Begin"); */
845 
846  g_assert (trans_info);
847  /*DEBUG("Iteration %d, action %d, split %s", i,
848  trans_info->action,
849  xaccTransGetDescription (gnc_import_TransInfo_get_trans
850  (trans_info)))*/
851  switch (gnc_import_TransInfo_get_action (trans_info))
852  {
853  case GNCImport_SKIP:
854  return FALSE;
855  case GNCImport_ADD:
856  /* Transaction gets imported. */
857 
858  /* Is the transaction not balanced and there is a non-NULL destination account? */
859  if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE
860  && gnc_import_TransInfo_get_destacc(trans_info) != NULL)
861  {
862  /* Create the 'other' split. */
863  Split *split =
865  (gnc_account_get_book
866  (gnc_import_TransInfo_get_destacc (trans_info)));
868  (gnc_import_TransInfo_get_trans (trans_info), split);
870  (gnc_import_TransInfo_get_destacc (trans_info), split);
871  /*xaccSplitSetBaseValue
872  (split,
873  gnc_numeric_neg(xaccTransGetImbalance
874  (gnc_import_TransInfo_get_trans (trans_info))),
875  xaccTransGetCurrency
876  (gnc_import_TransInfo_get_trans (trans_info)));*/
877  {
878  /* This is a quick workaround for the bug described in
879  http://lists.gnucash.org/pipermail/gnucash-devel/2003-August/009982.html
880  Assume that importers won't create transactions involving two or more
881  currencies so we can use xaccTransGetImbalanceValue. */
882  imbalance_value =
884  (gnc_import_TransInfo_get_trans (trans_info)));
885  xaccSplitSetValue (split, imbalance_value);
886  xaccSplitSetAmount (split, imbalance_value);
887  }
888  /*xaccSplitSetMemo (split, _("Auto-Balance split"));
889  -- disabled due to popular request */
890  }
891 
893  /*Set reconcile date to today*/
895  gnc_time (NULL));
896  /* Done editing. */
898  return TRUE;
899  case GNCImport_UPDATE:
900  {
901  GNCImportMatchInfo *selected_match =
903 
904  /* If there is no selection, ignore this transaction. */
905  if (!selected_match)
906  {
907  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
908  break;
909  }
910 
911  /* Transaction gets not imported but the matching one gets
912  updated and reconciled. */
913  if (gnc_import_MatchInfo_get_split(selected_match) == NULL)
914  {
915  PERR("The split I am trying to update and reconcile is NULL, shouldn't happen!");
916  }
917  else
918  {
919  /* Update and reconcile the matching transaction */
920  /*DEBUG("BeginEdit selected_match")*/
921  xaccTransBeginEdit(selected_match->trans);
922 
923  xaccTransSetDatePostedSecsNormalized(selected_match->trans,
925  gnc_import_TransInfo_get_fsplit(trans_info))));
926 
927  xaccSplitSetAmount(selected_match->split,
929  gnc_import_TransInfo_get_fsplit(trans_info)));
930  xaccSplitSetValue(selected_match->split,
932  gnc_import_TransInfo_get_fsplit(trans_info)));
933 
934  imbalance_value = xaccTransGetImbalanceValue(
935  gnc_import_TransInfo_get_trans(trans_info));
936  other_split = xaccSplitGetOtherSplit(selected_match->split);
937  if (!gnc_numeric_zero_p(imbalance_value) && other_split)
938  {
939  if (xaccSplitGetReconcile(other_split) == NREC)
940  {
941  imbalance_value = gnc_numeric_neg(imbalance_value);
942  xaccSplitSetValue(other_split, imbalance_value);
943  xaccSplitSetAmount(other_split, imbalance_value);
944  }
945  /* else GC will automatically insert a split to equity
946  to balance the transaction */
947  }
948 
949  xaccTransSetDescription(selected_match->trans,
951  gnc_import_TransInfo_get_trans(trans_info)));
952 
953  xaccTransSetNotes(selected_match->trans,
955  gnc_import_TransInfo_get_trans(trans_info)));
956 
957  if (xaccSplitGetReconcile(selected_match->split) == NREC)
958  {
959  xaccSplitSetReconcile(selected_match->split, CREC);
960  }
961 
962  /* Set reconcile date to today */
963  xaccSplitSetDateReconciledSecs(selected_match->split, gnc_time (NULL));
964 
965  /* Copy the online id to the reconciled transaction, so
966  the match will be remembered */
967  if (gnc_import_split_has_online_id(trans_info->first_split))
968  {
969  gnc_import_set_split_online_id(selected_match->split,
970  gnc_import_get_split_online_id(trans_info->first_split));
971  }
972 
973  /* Done editing. */
974  /*DEBUG("CommitEdit selected_match")*/
975  xaccTransCommitEdit(selected_match->trans);
976 
977  /* Store the mapping to the other account in the MatchMap. */
978  matchmap_store_destination(matchmap, trans_info, TRUE);
979 
980  /* Erase the downloaded transaction */
981  xaccTransDestroy(trans_info->trans);
982  /*DEBUG("CommitEdit trans")*/
983  xaccTransCommitEdit(trans_info->trans);
984  /* Very important: Make sure the freed transaction is not freed again! */
985  trans_info->trans = NULL;
986  }
987  }
988  return TRUE;
989  case GNCImport_CLEAR:
990  {
991  GNCImportMatchInfo *selected_match =
993 
994  /* If there is no selection, ignore this transaction. */
995  if (!selected_match)
996  {
997  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
998  break;
999  }
1000 
1001  /* Transaction gets not imported but the matching one gets
1002  reconciled. */
1003  if (gnc_import_MatchInfo_get_split (selected_match) == NULL)
1004  {
1005  PERR("The split I am trying to reconcile is NULL, shouldn't happen!");
1006  }
1007  else
1008  {
1009  /* Reconcile the matching transaction */
1010  /*DEBUG("BeginEdit selected_match")*/
1011  xaccTransBeginEdit(selected_match->trans);
1012 
1014  (selected_match->split) == NREC)
1016  (selected_match->split, CREC);
1017  /* Set reconcile date to today */
1019  (selected_match->split, gnc_time (NULL));
1020 
1021  /* Copy the online id to the reconciled transaction, so
1022  the match will be remembered */
1023  if (gnc_import_split_has_online_id(trans_info->first_split))
1024  gnc_import_set_split_online_id
1025  (selected_match->split,
1026  gnc_import_get_split_online_id(trans_info->first_split));
1027 
1028  /* Done editing. */
1029  /*DEBUG("CommitEdit selected_match")*/
1031  (selected_match->trans);
1032 
1033  /* Store the mapping to the other account in the MatchMap. */
1034  matchmap_store_destination (matchmap, trans_info, TRUE);
1035 
1036  /* Erase the downloaded transaction */
1037  xaccTransDestroy(trans_info->trans);
1038  /*DEBUG("CommitEdit trans")*/
1039  xaccTransCommitEdit(trans_info->trans);
1040  /* Very important: Make sure the freed transaction is not freed again! */
1041  trans_info->trans = NULL;
1042  }
1043  }
1044  return TRUE;
1045  default:
1046  DEBUG("Invalid GNCImportAction for this imported transaction.");
1047  break;
1048  }
1049  /*DEBUG("End");*/
1050  return FALSE;
1051 }
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:92
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Definition: Transaction.h:361
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
Split * gnc_import_TransInfo_get_fsplit(const GNCImportTransInfo *info)
Returns the first split of the transaction of this TransInfo.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
Returns the transaction of this TransInfo.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:246
GNCImportAction gnc_import_TransInfo_get_action(const GNCImportTransInfo *info)
Returns the currently selected action for this TransInfo.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:252
const char * xaccTransGetNotes(const Transaction *trans)
Gets the transaction Notes.
Split * gnc_import_MatchInfo_get_split(const GNCImportMatchInfo *info)
Get the split (&#39;this-side split&#39;) of this MatchInfo.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account&#39;s commodity that the split should have...
Definition: gmock-Split.cpp:77
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
The xaccTransGetImbalanceValue() method returns the total value of the transaction.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
#define CREC
The Split has been cleared.
Definition: Split.h:71
Split * xaccMallocSplit(QofBook *book)
Constructor.
Definition: gmock-Split.cpp:37
void xaccSplitSetDateReconciledSecs(Split *split, time64 secs)
Set the date on which this split was reconciled by specifying the time as time64. ...
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:84
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
Definition: Account.h:1038
Split * xaccSplitGetOtherSplit(const Split *split)
The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits...
Account * gnc_import_TransInfo_get_destacc(const GNCImportTransInfo *info)
Returns the &#39;other account&#39; of this transaction.
time64 gnc_time(time64 *tbuf)
get the current local time
Definition: gnc-date.cpp:273
GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match(const GNCImportTransInfo *info)
Returns the currently selected match in this TransInfo.
gboolean gnc_import_TransInfo_is_balanced(const GNCImportTransInfo *info)
Returns if the transaction stored in the TransInfo is currently balanced.
#define NREC
not reconciled or cleared
Definition: Split.h:74
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account&#39;s commodity.
Definition: gmock-Split.cpp:69

◆ gnc_import_select_account()

Account * gnc_import_select_account ( GtkWidget *  parent,
const gchar *  account_online_id_value,
gboolean  auto_create,
const gchar *  account_human_description,
const gnc_commodity *  new_account_default_commodity,
GNCAccountType  new_account_default_type,
Account default_selection,
gboolean *  ok_pressed 
)

Must be called with a string containing a unique identifier for the account.

If an account with a matching online_id is found, the function immediately returns with a pointer to that account. Otherwise, the user is prompted to select a GnuCash account or create a new one (in both cases, the unique identifier is written to the account, so the user won't be prompted again). If the user refuses to select or create an account, NULL is returned.

Parameters
parentThe parent widget. Can be NULL.
account_online_id_valueThe string containing your unique account_id coming from some string of your module. This is the normal mode of operation. Can be NULL.

If account_online_id_value==NULL, you basically end up with an account selector that allows you to select an account whose GncGUID will be remembered elsewhere. You would fill account_human_description to tell the user what he is looking for. In this mode, the online_id field of the found account will not be touched. To use this mode, auto_create must NOT be set to 0.

Parameters
account_human_descriptionA human-readable description of the account. Can be NULL. If it is not NULL, it will be shown before the id in the account matching dialog. It will also be used as the default account name if a new account is created.
new_account_default_commodityDefault commodity of the new account. Can be NULL. If not NULL, it will be the account's commodity if a new account is created. Also, if not NULL, the function will also warn the user if the found or created account's commodity doesn't match.
new_account_default_typeDefault account type of a new account. Can be NULL. If not ACCT_TYPE_NONE, it will be the account's type if a new account is created. If not ACCT_TYPE_NONE, the function will also warn the user if the found or created account's commodity doesn't match.
auto_createOnly active if no account with the account_online_id_value could be found in gnucash, or if online-id was NULL. In that case, if auto_create is TRUE (nonzero), the user will be asked to create a new account. If auto_create is FALSE (zero), this function will simply return NULL but will neither select nor create any account.
default_selectionIf not NULL, that account will be pre-selected by default.
ok_pressedA pointer to gboolean. If non-NULL, whether or not the picker dialog was closed by the user pressing ok will be stored in the parameter. If no dialog was created by the gnc_import_select_account() call, TRUE is always returned.
Returns
A pointer to the found or created Account, or NULL if no account was found or created.

Definition at line 391 of file import-account-matcher.c.

399 {
400 #define ACCOUNT_DESCRIPTION_MAX_SIZE 255
401  AccountPickerDialog * picker;
402  gint response;
403  Account * retval = NULL;
404  const gchar *retval_name = NULL;
405  GtkBuilder *builder;
406  GtkTreeSelection *selection;
407  GtkWidget * online_id_label;
408  gchar account_description_text[ACCOUNT_DESCRIPTION_MAX_SIZE + 1] = "";
409  gboolean ok_pressed_retval = FALSE;
410 
411  ENTER("Default commodity received: %s", gnc_commodity_get_fullname( new_account_default_commodity));
412  DEBUG("Default account type received: %s", xaccAccountGetTypeStr( new_account_default_type));
413  picker = g_new0(AccountPickerDialog, 1);
414 
415  picker->account_online_id_value = account_online_id_value;
416  picker->account_human_description = account_human_description;
417  picker->new_account_default_commodity = new_account_default_commodity;
418  picker->new_account_default_type = new_account_default_type;
419 
420  /*DEBUG("Looking for account with online_id: \"%s\"", account_online_id_value);*/
421  if (account_online_id_value != NULL)
422  {
423  AccountOnlineMatch match = {NULL, 0, account_online_id_value};
424  retval =
425  gnc_account_foreach_descendant_until(gnc_get_current_root_account (),
426  test_acct_online_id_match,
427  (void*)&match);
428  if (!retval && match.count == 1 &&
429  new_account_default_type == ACCT_TYPE_NONE)
430  retval = match.partial_match;
431  }
432  if (retval == NULL && auto_create != 0)
433  {
434  /* load the interface */
435  builder = gtk_builder_new();
436  gnc_builder_add_from_file (builder, "dialog-import.glade", "account_new_icon");
437  gnc_builder_add_from_file (builder, "dialog-import.glade", "account_picker_dialog");
438  /* connect the signals in the interface */
439  if (builder == NULL)
440  {
441  PERR("Error opening the glade builder interface");
442  }
443  picker->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker_dialog"));
444  picker->whbox = GTK_WIDGET(gtk_builder_get_object (builder, "warning_hbox"));
445  picker->warning = GTK_WIDGET(gtk_builder_get_object (builder, "warning_label"));
446  picker->ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "okbutton"));
447 
448  if (parent)
449  gtk_window_set_transient_for (GTK_WINDOW (picker->dialog),
450  GTK_WINDOW (parent));
451 
452  gnc_restore_window_size (GNC_PREFS_GROUP,
453  GTK_WINDOW(picker->dialog), GTK_WINDOW (parent));
454 
455  picker->account_tree_sw = GTK_WIDGET(gtk_builder_get_object (builder, "account_tree_sw"));
456  online_id_label = GTK_WIDGET(gtk_builder_get_object (builder, "online_id_label"));
457 
458  //printf("gnc_import_select_account(): Fin get widget\n");
459 
460  if (account_human_description != NULL)
461  {
462  strncat(account_description_text, account_human_description,
463  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
464  strncat(account_description_text, "\n",
465  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
466  }
467  if (account_online_id_value != NULL)
468  {
469  strncat(account_description_text, _("(Full account ID: "),
470  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
471  strncat(account_description_text, account_online_id_value,
472  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
473  strncat(account_description_text, ")",
474  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
475  }
476  gtk_label_set_text((GtkLabel*)online_id_label, account_description_text);
477  build_acct_tree(picker);
478  gtk_window_set_modal(GTK_WINDOW(picker->dialog), TRUE);
479  g_signal_connect(picker->account_tree, "row-activated",
480  G_CALLBACK(account_tree_row_activated_cb), picker);
481 
482  /* Connect key press event so we can expand the tree when the user starts typing, allowing
483  * any subaccount to match */
484  g_signal_connect (picker->account_tree, "key-press-event", G_CALLBACK (account_tree_key_press_cb), picker->account_tree);
485 
486  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(picker->account_tree));
487  g_signal_connect(selection, "changed",
488  G_CALLBACK(account_tree_row_changed_cb), picker);
489 
490  gnc_tree_view_account_set_selected_account(picker->account_tree, default_selection);
491 
492  do
493  {
494  response = gtk_dialog_run(GTK_DIALOG(picker->dialog));
495  switch (response)
496  {
497  case GNC_RESPONSE_NEW:
498  gnc_import_add_account(NULL, picker);
499  response = GTK_RESPONSE_OK;
500  /* no break */
501 
502  case GTK_RESPONSE_OK:
503  retval = gnc_tree_view_account_get_selected_account(picker->account_tree);
504  if (retval == NULL)
505  {
506  response = GNC_RESPONSE_NEW;
507  break;
508  }
509  if (retval)
510  retval_name = xaccAccountGetName(retval);
511  if (!retval_name)
512  retval_name = "(null)";
513  DEBUG("Selected account %p, %s", retval, retval_name);
514 
515  /* See if the selected account is a placeholder. */
516  if (retval && xaccAccountGetPlaceholder (retval))
517  {
518  show_placeholder_warning (picker, retval_name);
519  response = GNC_RESPONSE_NEW;
520  break;
521  }
522  else if (picker->new_account_default_commodity &&
524  picker->new_account_default_commodity))) // check commodity
525  {
526  show_commodity_warning (picker, retval_name);
527  response = GNC_RESPONSE_NEW;
528  break;
529  }
530 
531  if ( account_online_id_value != NULL)
532  {
533  gnc_import_set_acc_online_id(retval, account_online_id_value);
534  }
535  ok_pressed_retval = TRUE;
536  break;
537 
538  default:
539  ok_pressed_retval = FALSE;
540  break;
541  }
542  }
543  while (response == GNC_RESPONSE_NEW);
544 
545  g_object_unref(G_OBJECT(builder));
546  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(picker->dialog));
547  gtk_widget_destroy(picker->dialog);
548  }
549  else
550  {
551  retval_name = retval ? xaccAccountGetName(retval) : NULL;
552  ok_pressed_retval = TRUE; /* There was no dialog involved, so the computer "pressed" ok */
553  }
554  /*FIXME: DEBUG("WRITEME: gnc_import_select_account() Here we should check if account type is compatible, currency matches, etc.\n"); */
555  g_free(picker);
556  /*DEBUG("Return value: %p%s%s%s",retval,", account name:",xaccAccountGetName(retval),"\n");*/
557  if (ok_pressed != NULL)
558  {
559  *ok_pressed = ok_pressed_retval;
560  }
561  LEAVE("Selected account %p, %s", retval, retval_name ? retval_name : "(null)");
562  return retval;
563 }
STRUCTS.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
This method will traverse all children of this accounts and their descendants, calling &#39;func&#39; on each...
Definition: Account.cpp:3185
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:246
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:270
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
void gnc_tree_view_account_set_selected_account(GncTreeViewAccount *view, Account *account)
This function selects an account in the account tree view.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account&#39;s commodity.
Definition: Account.cpp:3360
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
Definition: Account.cpp:4177
Account * gnc_tree_view_account_get_selected_account(GncTreeViewAccount *view)
This function returns the account associated with the selected item in the account tree view...
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:280
const char * xaccAccountGetName(const Account *acc)
Get the account&#39;s name.
Definition: Account.cpp:3237
const char * xaccAccountGetTypeStr(GNCAccountType type)
The xaccAccountGetTypeStr() routine returns a string suitable for use in the GUI/Interface.
Definition: Account.cpp:4411
Not a type.
Definition: Account.h:108

◆ gnc_import_select_commodity()

gnc_commodity * gnc_import_select_commodity ( const char *  cusip,
gboolean  ask_on_unknown,
const char *  default_fullname,
const char *  default_mnemonic 
)

Must be called with a string containing a unique identifier for the commodity.

If an commodity with a matching cusip is found, the function immediately returns with a pointer to that commodity. Otherwise, the user may be prompted to select a GnuCash commodity or create a new one (in both cases, the cusip is written to the commodity's cusip field, overwriting anything that was there before.

Parameters
cusipThe string containing the code for which you want a matching commodity. A CUISP code or similar UNIQUE code. The stock ticker is NOT appropriate, unless you have no other option. Must be non-NULL.
ask_on_unknownIf the cusip value is unknown and this parameter is false (zero), the function returns NULL. Otherwise the user will be asked to select an existing or create a new commodity.
default_fullnameA human-readable description of the commodity, such as the stock name. Can be NULL. If it is not NULL, it will be shown to the user when selecting a commodity. It will also be used as the default if a new commodity is created.
default_mnemonicUsually the stock ticker or similar. Can be NULL. If it is not NULL, it will be shown to the user when selecting a commodity. It will also be used as the default if a new commodity is created.
Returns
A pointer to the found or created commodity, or NULL if no commodity was found or created.

Definition at line 53 of file import-commodity-matcher.c.

57 {
58  const gnc_commodity_table * commodity_table = gnc_get_current_commodities ();
59  gnc_commodity * retval = NULL;
60  gnc_commodity * tmp_commodity = NULL;
61  char * tmp_namespace = NULL;
62  GList * commodity_list = NULL;
63  GList * namespace_list = NULL;
64  DEBUG("Default fullname received: %s",
65  default_fullname ? default_fullname : "(null)");
66  DEBUG("Default mnemonic received: %s",
67  default_mnemonic ? default_mnemonic : "(null)");
68 
69  g_return_val_if_fail(cusip, NULL);
70  DEBUG("Looking for commodity with exchange_code: %s", cusip);
71 
72  g_assert(commodity_table);
73  namespace_list = gnc_commodity_table_get_namespaces(commodity_table);
74 
75 
76  namespace_list = g_list_first(namespace_list);
77  while ( namespace_list != NULL && retval == NULL)
78  {
79  tmp_namespace = namespace_list->data;
80  DEBUG("Looking at namespace %s", tmp_namespace);
81  commodity_list = gnc_commodity_table_get_commodities(commodity_table,
82  tmp_namespace);
83  commodity_list = g_list_first(commodity_list);
84  while ( commodity_list != NULL && retval == NULL)
85  {
86  const char* tmp_cusip = NULL;
87  tmp_commodity = commodity_list->data;
88  DEBUG("Looking at commodity %s",
89  gnc_commodity_get_fullname(tmp_commodity));
90  tmp_cusip = gnc_commodity_get_cusip(tmp_commodity);
91  if (tmp_cusip != NULL && cusip != NULL)
92  {
93  int len = strlen(cusip) > strlen(tmp_cusip) ? strlen(cusip) :
94  strlen(tmp_cusip);
95  if (strncmp(tmp_cusip, cusip, len) == 0)
96  {
97  retval = tmp_commodity;
98  DEBUG("Commodity %s%s",
99  gnc_commodity_get_fullname(retval), " matches.");
100  }
101  }
102  commodity_list = g_list_next(commodity_list);
103  }
104  namespace_list = g_list_next(namespace_list);
105  }
106 
107  g_list_free(commodity_list);
108  g_list_free(namespace_list);
109 
110  if (retval == NULL && ask_on_unknown != 0)
111  {
112  const gchar *message =
113  _("Please select a commodity to match the following exchange "
114  "specific code. Please note that the exchange code of the "
115  "commodity you select will be overwritten.");
117  NULL,
119  message,
120  cusip,
121  default_fullname,
122  default_mnemonic);
123 
124  }
125  /* There seems to be a problem here - if the matched commodity does not
126  have a cusip defined (gnc_commodity_get_cusip returns NULL) then
127  it does not get overwritten - which is not consistent with the
128  message - so Im adding it to do this. Looks like this is all
129  that was needed to fix the cash value used as stock units problem
130  for pre-defined commodities which didn't have the cusip defined! */
131  if (retval != NULL &&
132  gnc_commodity_get_cusip(retval) != NULL &&
133  cusip != NULL &&
134  (strncmp(gnc_commodity_get_cusip(retval), cusip, strlen(cusip)) != 0))
135  {
136  gnc_commodity_set_cusip(retval, cusip);
137  }
138  else if (gnc_commodity_get_cusip(retval) == NULL && cusip != NULL)
139  {
140  gnc_commodity_set_cusip(retval, cusip);
141  }
142  return retval;
143 };
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
Retrieve the &#39;exchange code&#39; for the specified commodity.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
Dialog box should allow selection of anything.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
Set the &#39;exchange code&#39; for the specified commodity.
gnc_commodity * gnc_ui_select_commodity_modal_full(gnc_commodity *orig_sel, GtkWidget *parent, dialog_commodity_mode mode, const char *user_message, const char *cusip, const char *fullname, const char *mnemonic)
Ask the user to select a commodity from the existing set of commodities.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
Return a list of all commodities in the commodity table that are in the given namespace.

◆ gnc_import_Settings_get_fuzzy_amount()

double gnc_import_Settings_get_fuzzy_amount ( GNCImportSettings *  settings)

Return the allowed amount range for fuzzy amount matching.

Returns
The allowed amount range for fuzzy amount matching, in the users default commodity.

Definition at line 115 of file import-settings.c.

116 {
117  g_assert (settings);
118  return settings->fuzzy_amount;
119 };

◆ gnc_import_Settings_get_match_date_hardlimit()

gint gnc_import_Settings_get_match_date_hardlimit ( const GNCImportSettings *  settings)

Returns the hard-limiting number of days that a matching split may differ.

Definition at line 168 of file import-settings.c.

169 {
170  g_assert(s);
171  return s->match_date_hardlimit;
172 }

◆ gnc_import_Settings_set_match_date_hardlimit()

void gnc_import_Settings_set_match_date_hardlimit ( GNCImportSettings *  settings,
gint  match_date_hardlimit 
)
Parameters
match_date_hardlimitThe number of days that a matching split may differ from the given transaction before it is discarded immediately. In other words, any split that is more distant from the given transaction than this match_date_hardlimit days will be ignored altogether. For use cases without paper checks (e.g. HBCI), values like 14 (days) might be appropriate, whereas for use cases with paper checks (e.g. OFX, QIF), values like 42 (days) seem more appropriate.

Definition at line 163 of file import-settings.c.

164 {
165  g_assert(s);
166  s->match_date_hardlimit = m;
167 }

◆ gnc_import_TransInfo_get_action()

GNCImportAction gnc_import_TransInfo_get_action ( const GNCImportTransInfo *  info)

Returns the currently selected action for this TransInfo.

Definition at line 188 of file import-backend.c.

189 {
190  g_assert (info);
191  return info->action;
192 }

◆ gnc_import_TransInfo_get_destacc()

Account * gnc_import_TransInfo_get_destacc ( const GNCImportTransInfo *  info)

Returns the 'other account' of this transaction.

May return NULL.

Definition at line 207 of file import-backend.c.

208 {
209  g_assert (info);
210  return info->dest_acc;
211 }

◆ gnc_import_TransInfo_get_destacc_selected_manually()

gboolean gnc_import_TransInfo_get_destacc_selected_manually ( const GNCImportTransInfo *  info)

Returns if the currently selected destination account for auto-matching was selected by the user.

Definition at line 228 of file import-backend.c.

229 {
230  g_assert (info);
231  return info->dest_acc_selected_manually;
232 }

◆ gnc_import_TransInfo_get_fsplit()

Split * gnc_import_TransInfo_get_fsplit ( const GNCImportTransInfo *  info)

Returns the first split of the transaction of this TransInfo.

Definition at line 157 of file import-backend.c.

158 {
159  g_assert (info);
160  return info->first_split;
161 }

◆ gnc_import_TransInfo_get_match_list()

GList * gnc_import_TransInfo_get_match_list ( const GNCImportTransInfo *  info)

Returns the stored list of possible matches.

Definition at line 110 of file import-backend.c.

111 {
112  g_assert (info);
113  return info->match_list;
114 }

◆ gnc_import_TransInfo_get_match_selected_manually()

gboolean gnc_import_TransInfo_get_match_selected_manually ( const GNCImportTransInfo *  info)

Returns if the currently selected match was selected by the user.

Definition at line 181 of file import-backend.c.

182 {
183  g_assert (info);
184  return info->selected_match_info.selected_manually;
185 }

◆ gnc_import_TransInfo_get_ref_id()

guint32 gnc_import_TransInfo_get_ref_id ( const GNCImportTransInfo *  info)

Returns the reference id for this TransInfo.

Definition at line 235 of file import-backend.c.

236 {
237  g_assert (info);
238  return info->ref_id;
239 }

◆ gnc_import_TransInfo_get_selected_match()

GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match ( const GNCImportTransInfo *  info)

Returns the currently selected match in this TransInfo.

Definition at line 164 of file import-backend.c.

165 {
166  g_assert (info);
167  return info->selected_match_info.selected_match;
168 }

◆ gnc_import_TransInfo_get_trans()

Transaction * gnc_import_TransInfo_get_trans ( const GNCImportTransInfo *  info)

Returns the transaction of this TransInfo.

Definition at line 133 of file import-backend.c.

134 {
135  g_assert (info);
136  return info->trans;
137 }

◆ gnc_import_TransInfo_init_matches()

void gnc_import_TransInfo_init_matches ( GNCImportTransInfo *  trans_info,
GNCImportSettings *  settings 
)

Iterates through all splits of the originating account of trans_info.

Sorts the resulting list and sets the selected_match and action fields in the trans_info.

Sorts the resulting list and sets the selected_match and action fields in the trans_info.

Parameters
trans_infoThe TransInfo for which the matches should be found, sorted, and selected.
settingsThe structure that holds all the user preferences.

Definition at line 1194 of file import-backend.c.

1196 {
1197  GNCImportMatchInfo * best_match = NULL;
1198  g_assert (trans_info);
1199 
1200  if (trans_info->match_list != NULL)
1201  {
1202  trans_info->match_list = g_list_sort(trans_info->match_list,
1203  compare_probability);
1204  best_match = g_list_nth_data(trans_info->match_list, 0);
1206  best_match,
1207  FALSE);
1208  if (best_match != NULL &&
1209  best_match->probability >= gnc_import_Settings_get_clear_threshold(settings))
1210  {
1211  trans_info->action = GNCImport_CLEAR;
1212  }
1213  else if (best_match == NULL ||
1214  best_match->probability <= gnc_import_Settings_get_add_threshold(settings))
1215  {
1216  trans_info->action = GNCImport_ADD;
1217  }
1219  {
1220  trans_info->action = GNCImport_SKIP;
1221  }
1223  {
1224  trans_info->action = GNCImport_UPDATE;
1225  }
1226  else
1227  {
1228  trans_info->action = GNCImport_ADD;
1229  }
1230  }
1231  else
1232  {
1233  trans_info->action = GNCImport_ADD;
1234  }
1235  if (best_match &&
1236  trans_info->action == GNCImport_CLEAR &&
1238  {
1239  if (best_match->update_proposed)
1240  {
1241  trans_info->action = GNCImport_UPDATE;
1242  }
1243  }
1244 
1245  trans_info->previous_action = trans_info->action;
1246 }
gint gnc_import_Settings_get_clear_threshold(GNCImportSettings *settings)
Return the selected threshold.
void gnc_import_TransInfo_set_selected_match_info(GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
Sets the currently selected match in this TransInfo.
gboolean gnc_import_Settings_get_action_update_enabled(GNCImportSettings *settings)
Return the selected action is enable state.
gboolean gnc_import_Settings_get_action_skip_enabled(GNCImportSettings *settings)
Return the selected action is enable state.
gint gnc_import_Settings_get_add_threshold(GNCImportSettings *settings)
Return the selected threshold.

◆ gnc_import_TransInfo_is_balanced()

gboolean gnc_import_TransInfo_is_balanced ( const GNCImportTransInfo *  info)

Returns if the transaction stored in the TransInfo is currently balanced.

Definition at line 140 of file import-backend.c.

141 {
142  g_assert (info);
143  /* Assume that the importer won't create a transaction that involves two or more
144  currencies and no non-currency commodity. In that case can use the simpler
145  value imbalance check. */
147  {
148  return TRUE;
149  }
150  else
151  {
152  return FALSE;
153  }
154 }
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
Returns the transaction of this TransInfo.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
The xaccTransGetImbalanceValue() method returns the total value of the transaction.

◆ gnc_import_TransInfo_new()

GNCImportTransInfo * gnc_import_TransInfo_new ( Transaction *  trans,
GncImportMatchMap matchmap 
)

Create a new object of GNCImportTransInfo here.

Allocates a new TransInfo object, with the Transaction 'trans' already stored in there.

Also, this already checks the ImportMatchMap for automated destination account matching. The given MatchMap may be NULL, in which case the ImportMatchMap of the originating account will be used.

Parameters
transThe transaction that this TransInfo should work with.
matchmapMatchMap used for automated destination account choosing. This may be NULL, in which case the MatchMap of the originating account will be used.

Definition at line 1158 of file import-backend.c.

1159 {
1160  GNCImportTransInfo *transaction_info;
1161  Split *split;
1162  g_assert (trans);
1163 
1164  transaction_info = g_new0(GNCImportTransInfo, 1);
1165 
1166  transaction_info->trans = trans;
1167  /* Only use first split, the source split */
1168  split = xaccTransGetSplit(trans, 0);
1169  g_assert(split);
1170  transaction_info->first_split = split;
1171 
1172  /* Try to find a previously selected destination account
1173  string match for the ADD action */
1174  gnc_import_TransInfo_set_destacc (transaction_info,
1175  matchmap_find_destination (matchmap, transaction_info),
1176  FALSE);
1177  return transaction_info;
1178 }
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
void gnc_import_TransInfo_set_destacc(GNCImportTransInfo *info, Account *acc, gboolean selected_manually)
Set the &#39;other account&#39; of this transaction (used for auto-balance if needed).

◆ gnc_import_TransInfo_set_action()

void gnc_import_TransInfo_set_action ( GNCImportTransInfo *  info,
GNCImportAction  action 
)

Set the action for this TransInfo.

Also sets the previous action.

Definition at line 195 of file import-backend.c.

197 {
198  g_assert (info);
199  if (action != info->action)
200  {
201  info->previous_action = info->action;
202  info->action = action;
203  }
204 }

◆ gnc_import_TransInfo_set_destacc()

void gnc_import_TransInfo_set_destacc ( GNCImportTransInfo *  info,
Account acc,
gboolean  selected_manually 
)

Set the 'other account' of this transaction (used for auto-balance if needed).

May be set to NULL.

Parameters
selected_manuallyTRUE or FALSE; Was this account set as a result of a selection by the user or by an algorithm?

Definition at line 212 of file import-backend.c.

215 {
216  g_assert (info);
217  info->dest_acc = acc;
218  info->dest_acc_selected_manually = selected_manually;
219 
220  /* Store the mapping to the other account in the MatchMap. */
221  if (selected_manually)
222  {
223  matchmap_store_destination (NULL, info, FALSE);
224  }
225 }

◆ gnc_import_TransInfo_set_match_list()

void gnc_import_TransInfo_set_match_list ( GNCImportTransInfo *  info,
GList *  match_list 
)

Assigns the list of possible matches.

Definition at line 117 of file import-backend.c.

118 {
119  g_assert (info);
120  info->match_list = match_list;
121  if (match_list)
122  {
123  info->selected_match_info.selected_match = match_list->data;
124  }
125  else
126  {
127  info->selected_match_info.selected_match = NULL;
128  gnc_import_TransInfo_set_action (info, GNCImport_ADD);
129  }
130 }
void gnc_import_TransInfo_set_action(GNCImportTransInfo *info, GNCImportAction action)
Set the action for this TransInfo.

◆ gnc_import_TransInfo_set_ref_id()

void gnc_import_TransInfo_set_ref_id ( GNCImportTransInfo *  info,
guint32  ref_id 
)

Set the reference id for this TransInfo.

Definition at line 242 of file import-backend.c.

244 {
245  g_assert (info);
246  info->ref_id = ref_id;
247 }

◆ gnc_import_TransInfo_set_selected_match_info()

void gnc_import_TransInfo_set_selected_match_info ( GNCImportTransInfo *  info,
GNCImportMatchInfo match,
gboolean  selected_manually 
)

Sets the currently selected match in this TransInfo.

Parameters
selected_manuallyTRUE or FALSE; Was this match set as a result of a selection by the user or by an algorithm?

Definition at line 171 of file import-backend.c.

174 {
175  g_assert (info);
176  info->selected_match_info.selected_match = match;
177  info->selected_match_info.selected_manually = selected_manually;
178 }

◆ on_matcher_help_clicked()

void on_matcher_help_clicked ( GtkButton *  button,
gpointer  user_data 
)

This allows for the transaction help dialog to be started from the assistant button callback.

Parameters
button.The button widget clicked on in the call back.
user_data.A pointer to a structure.

Definition at line 529 of file import-main-matcher.c.

530 {
531  GNCImportMainMatcher *info = user_data;
532  GtkBuilder *builder;
533  GtkWidget *help_dialog, *box;
534  gchar *int_required_class, *int_prob_required_class, *int_not_required_class;
535  gchar *class_extension = NULL;
536 
537  builder = gtk_builder_new ();
538  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer2");
539  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer3");
540  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer4");
541  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer5");
542  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer1");
543  gnc_builder_add_from_file (builder, "dialog-import.glade", "matcher_help_dialog");
544 
545  if (info->dark_theme == TRUE)
546  class_extension = "-dark";
547 
548  int_required_class = g_strconcat (CSS_INT_REQUIRED_CLASS, class_extension, NULL);
549  int_prob_required_class = g_strconcat (CSS_INT_PROB_REQUIRED_CLASS, class_extension, NULL);
550  int_not_required_class = g_strconcat (CSS_INT_NOT_REQUIRED_CLASS, class_extension, NULL);
551 
552  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_required_box"));
553  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_required_class);
554 
555  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_probably_required_box"));
556  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_prob_required_class);
557 
558  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_not_required_box"));
559  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_not_required_class);
560 
561  help_dialog = GTK_WIDGET(gtk_builder_get_object (builder, "matcher_help_dialog"));
562  gtk_window_set_transient_for (GTK_WINDOW(help_dialog), GTK_WINDOW(info->main_widget));
563 
564  /* Connect the signals */
565  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, help_dialog);
566 
567  g_object_unref (G_OBJECT(builder));
568 
569  g_free (int_required_class);
570  g_free (int_prob_required_class);
571  g_free (int_not_required_class);
572 
573  gtk_widget_show (help_dialog);
574 }

◆ split_find_match()

void split_find_match ( GNCImportTransInfo *  trans_info,
Split *  split,
gint  display_threshold,
double  fuzzy_amount_difference 
)

The transaction matching heuristics are here.

Evaluates the match between trans_info and split using the provided parameters.

Parameters
trans_infoThe TransInfo for the imported transaction
splitThe register split that should be evaluated for a match.
display_thresholdMinimum match score to include split in the list of matches.
fuzzy_amount_differenceMaximum amount difference to consider the match good.

Definition at line 622 of file import-backend.c.

626 {
627  /* DEBUG("Begin"); */
628 
629  /*Ignore the split if the transaction is open for edit, meaning it
630  was just downloaded. */
631  if (xaccTransIsOpen(xaccSplitGetParent(split)) == FALSE)
632  {
633  GNCImportMatchInfo * match_info;
634  gint prob = 0;
635  gboolean update_proposed;
636  double downloaded_split_amount, match_split_amount;
637  time64 match_time, download_time;
638  int datediff_day;
639  Transaction *new_trans = gnc_import_TransInfo_get_trans (trans_info);
640  Split *new_trans_fsplit = gnc_import_TransInfo_get_fsplit (trans_info);
641 
642  /* Matching heuristics */
643 
644  /* Amount heuristics */
645  downloaded_split_amount =
646  gnc_numeric_to_double (xaccSplitGetAmount(new_trans_fsplit));
647  /*DEBUG(" downloaded_split_amount=%f", downloaded_split_amount);*/
648  match_split_amount = gnc_numeric_to_double(xaccSplitGetAmount(split));
649  /*DEBUG(" match_split_amount=%f", match_split_amount);*/
650  if (fabs(downloaded_split_amount - match_split_amount) < 1e-6)
651  /* bug#347791: Double type shouldn't be compared for exact
652  equality, so we're using fabs() instead. */
653  /*if (gnc_numeric_equal(xaccSplitGetAmount
654  (new_trans_fsplit),
655  xaccSplitGetAmount(split)))
656  -- gnc_numeric_equal is an expensive function call */
657  {
658  prob = prob + 3;
659  /*DEBUG("heuristics: probability + 3 (amount)");*/
660  }
661  else if (fabs (downloaded_split_amount - match_split_amount) <=
662  fuzzy_amount_difference)
663  {
664  /* ATM fees are sometimes added directly in the transaction.
665  So you withdraw 100$ and get charged 101,25$ in the same
666  transaction */
667  prob = prob + 2;
668  /*DEBUG("heuristics: probability + 2 (amount)");*/
669  }
670  else
671  {
672  /* If a transaction's amount doesn't match within the
673  threshold, it's very unlikely to be the same transaction
674  so we give it an extra -5 penalty */
675  prob = prob - 5;
676  /* DEBUG("heuristics: probability - 1 (amount)"); */
677  }
678 
679  /* Date heuristics */
680  match_time = xaccTransGetDate (xaccSplitGetParent (split));
681  download_time = xaccTransGetDate (new_trans);
682  datediff_day = llabs(match_time - download_time) / 86400;
683  /* Sorry, there are not really functions around at all that
684  provide for less hacky calculation of days of date
685  differences. Whatever. On the other hand, the difference
686  calculation itself will work regardless of month/year
687  turnarounds. */
688  /*DEBUG("diff day %d", datediff_day);*/
689  if (datediff_day == 0)
690  {
691  prob = prob + 3;
692  /*DEBUG("heuristics: probability + 3 (date)");*/
693  }
694  else if (datediff_day <= MATCH_DATE_THRESHOLD)
695  {
696  prob = prob + 2;
697  /*DEBUG("heuristics: probability + 2 (date)");*/
698  }
699  else if (datediff_day > MATCH_DATE_NOT_THRESHOLD)
700  {
701  /* Extra penalty if that split lies awfully far away from
702  the given one. */
703  prob = prob - 5;
704  /*DEBUG("heuristics: probability - 5 (date)"); */
705  /* Changed 2005-02-21: Revert the hard-limiting behaviour
706  back to the previous large penalty. (Changed 2004-11-27:
707  The penalty is so high that we can forget about this
708  split anyway and skip the rest of the tests.) */
709  }
710 
711  /* Check if date and amount are identical */
712  update_proposed = (prob < 6);
713 
714  /* Check number heuristics */
715  {
716  const char *new_trans_str = gnc_get_num_action(new_trans, new_trans_fsplit);
717  if (new_trans_str && strlen(new_trans_str) != 0)
718  {
719  long new_trans_number, split_number;
720  const gchar *split_str;
721  char *endptr;
722  gboolean conversion_ok = TRUE;
723 
724  /* To distinguish success/failure after strtol call */
725  errno = 0;
726  new_trans_number = strtol(new_trans_str, &endptr, 10);
727  /* Possible addressed problems: over/underflow, only non
728  numbers on string and string empty */
729  if (errno || endptr == new_trans_str)
730  conversion_ok = FALSE;
731 
732  split_str = gnc_get_num_action (xaccSplitGetParent (split), split);
733  errno = 0;
734  split_number = strtol(split_str, &endptr, 10);
735  if (errno || endptr == split_str)
736  conversion_ok = FALSE;
737 
738  if ( (conversion_ok && (split_number == new_trans_number)) ||
739  (g_strcmp0(new_trans_str, split_str) == 0) )
740  {
741  /* An exact match of the Check number gives a +4 */
742  prob += 4;
743  /*DEBUG("heuristics: probability + 4 (Check number)");*/
744  }
745  else if (strlen(new_trans_str) > 0 && strlen(split_str) > 0)
746  {
747  /* If both number are not empty yet do not match, add a
748  little extra penalty */
749  prob -= 2;
750  }
751  }
752  }
753 
754  /* Memo heuristics */
755  {
756  const char *memo = xaccSplitGetMemo(new_trans_fsplit);
757  if (memo && strlen(memo) != 0)
758  {
759  if (safe_strcasecmp(memo, xaccSplitGetMemo(split)) == 0)
760  {
761  /* An exact match of memo gives a +2 */
762  prob = prob + 2;
763  /* DEBUG("heuristics: probability + 2 (memo)"); */
764  }
765  else if ((strncasecmp(memo, xaccSplitGetMemo(split),
766  strlen(xaccSplitGetMemo(split)) / 2)
767  == 0))
768  {
769  /* Very primitive fuzzy match worth +1. This matches the
770  first 50% of the strings to skip annoying transaction
771  number some banks seem to include in the memo but someone
772  should write something more sophisticated */
773  prob = prob + 1;
774  /*DEBUG("heuristics: probability + 1 (memo)"); */
775  }
776  }
777  }
778 
779  /* Description heuristics */
780  {
781  const char *descr = xaccTransGetDescription(new_trans);
782  if (descr && strlen(descr) != 0)
783  {
784  if (safe_strcasecmp(descr,
786  == 0)
787  {
788  /*An exact match of Description gives a +2 */
789  prob = prob + 2;
790  /*DEBUG("heuristics: probability + 2 (description)");*/
791  }
792  else if ((strncasecmp(descr,
794  strlen(xaccTransGetDescription (new_trans)) / 2)
795  == 0))
796  {
797  /* Very primitive fuzzy match worth +1. This matches the
798  first 50% of the strings to skip annoying transaction
799  number some banks seem to include in the memo but someone
800  should write something more sophisticated */
801  prob = prob + 1;
802  /*DEBUG("heuristics: probability + 1 (description)"); */
803  }
804  }
805  }
806 
807  /* Is the probability high enough? Otherwise do nothing and return. */
808  if (prob < display_threshold)
809  {
810  return;
811  }
812 
813  /* The probability is high enough, so allocate an object
814  here. Allocating it only when it's actually being used is
815  probably quite some performance gain. */
816  match_info = g_new0(GNCImportMatchInfo, 1);
817 
818  match_info->probability = prob;
819  match_info->update_proposed = update_proposed;
820  match_info->split = split;
821  match_info->trans = xaccSplitGetParent(split);
822 
823 
824  /* Append that to the list. Do not use g_list_append because
825  it is slow. The list is sorted afterwards anyway. */
826  trans_info->match_list =
827  g_list_prepend(trans_info->match_list,
828  match_info);
829  }
830 }/* end split_find_match */
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
gint safe_strcasecmp(const gchar *da, const gchar *db)
case sensitive comparison of strings da and db - either may be NULL.
Definition: qofutil.cpp:100
Split * gnc_import_TransInfo_get_fsplit(const GNCImportTransInfo *info)
Returns the first split of the transaction of this TransInfo.
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
Returns the transaction of this TransInfo.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
double gnc_numeric_to_double(gnc_numeric in)
Convert numeric to floating-point value.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
Definition: gmock-Split.cpp:99
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
Definition: gnc-date.h:93
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account&#39;s commodity.
Definition: gmock-Split.cpp:69