GnuCash  4.12-558-g06612b8434
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  RowInfo
 
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_PREF_MATCH_DATE_THRESHOLD   "match-date-threshold"
 
#define GNC_PREF_MATCH_DATE_NOT_THRESHOLD   "match-date-not-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_DESCRIPTION_ORIGINAL, DOWNLOADED_COL_DESCRIPTION_STYLE,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_MEMO_ORIGINAL, DOWNLOADED_COL_MEMO_STYLE, DOWNLOADED_COL_NOTES_ORIGINAL,
  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  { COMPLETION_LIST_ORIGINAL, COMPLETION_LIST_NORMALIZED_FOLDED, NUM_COMPLETION_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_DESCRIPTION_ORIGINAL, DOWNLOADED_COL_DESCRIPTION_STYLE,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_MEMO_ORIGINAL, DOWNLOADED_COL_MEMO_STYLE, DOWNLOADED_COL_NOTES_ORIGINAL,
  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...
 
GtkWidget * gnc_gen_trans_list_append_text_widget (GNCImportMainMatcher *info)
 Returns the append_text 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, gint date_threshold, gint date_not_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_set_append_text (GNCImportTransInfo *info, gboolean append_text)
 Set the append_text 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.
 
gint gnc_import_Settings_get_date_threshold (GNCImportSettings *settings)
 
gint gnc_import_Settings_get_date_not_threshold (GNCImportSettings *settings)
 
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.

gchar * gnc_import_get_acc_online_id (Account *account)
 
void gnc_import_set_acc_online_id (Account *account, const gchar *id)
 
gchar * gnc_import_get_trans_online_id (Transaction *transaction)
 
void gnc_import_set_trans_online_id (Transaction *transaction, const gchar *id)
 
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 299 of file import-backend.c.

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

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

1369 {
1370  extern int ofx_PARSER_msg;
1371  extern int ofx_DEBUG_msg;
1372  extern int ofx_WARNING_msg;
1373  extern int ofx_ERROR_msg;
1374  extern int ofx_INFO_msg;
1375  extern int ofx_STATUS_msg;
1376  GSList* selected_filenames = NULL;
1377  char *default_dir;
1378  GList *filters = NULL;
1379  GSList* iter = NULL;
1380  ofx_info* info = NULL;
1381  GtkFileFilter* filter = gtk_file_filter_new ();
1382 
1383 
1384  ofx_PARSER_msg = false;
1385  ofx_DEBUG_msg = false;
1386  ofx_WARNING_msg = true;
1387  ofx_ERROR_msg = true;
1388  ofx_INFO_msg = true;
1389  ofx_STATUS_msg = false;
1390 
1391  DEBUG("gnc_file_ofx_import(): Begin...\n");
1392 
1393  default_dir = gnc_get_default_directory(GNC_PREFS_GROUP);
1394  gtk_file_filter_set_name (filter, _("Open/Quicken Financial Exchange file (*.ofx, *.qfx)"));
1395  gtk_file_filter_add_pattern (filter, "*.[oqOQ][fF][xX]");
1396  filters = g_list_prepend( filters, filter );
1397 
1398  selected_filenames = gnc_file_dialog_multi (parent,
1399  _("Select one or multiple OFX/QFX file(s) to process"),
1400  filters,
1401  default_dir,
1402  GNC_FILE_DIALOG_IMPORT);
1403  g_free(default_dir);
1404 
1405  if (selected_filenames)
1406  {
1407  /* Remember the directory as the default. */
1408  default_dir = g_path_get_dirname(selected_filenames->data);
1409  gnc_set_default_directory(GNC_PREFS_GROUP, default_dir);
1410  g_free(default_dir);
1411 
1412  /* Look up the needed preferences */
1413  auto_create_commodity =
1414  gnc_prefs_get_bool (GNC_PREFS_GROUP_IMPORT, GNC_PREF_AUTO_COMMODITY);
1415 
1416  DEBUG("Opening selected file(s)");
1417  // Create the structure that holds the list of files to process and the statement info.
1418  info = g_new(ofx_info,1);
1419  info->num_trans_processed = 0;
1420  info->statement = NULL;
1421  info->last_investment_account = NULL;
1422  info->last_import_account = NULL;
1423  info->last_income_account = NULL;
1424  info->parent = parent;
1425  info->run_reconcile = FALSE;
1426  info->file_list = selected_filenames;
1427  info->trans_list = NULL;
1428  info->response = 0;
1429  // Call the aux import function.
1430  gnc_file_ofx_import_process_file (info);
1431  }
1432 }
#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 1749 of file import-main-matcher.c.

1754 {
1755  GNCImportMainMatcher *info;
1756  GtkBuilder *builder;
1757  GtkWidget *box;
1758 
1759  info = g_new0 (GNCImportMainMatcher, 1);
1760  info->main_widget = GTK_WIDGET(parent);
1761 
1762  /* load the interface */
1763  builder = gtk_builder_new ();
1764  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
1765 
1766  /* Pack content into Assistant page widget */
1767  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
1768  g_assert (box != NULL);
1769  gtk_box_pack_start (GTK_BOX(assistant_page), box, TRUE, TRUE, 6);
1770 
1771  /* setup the common parts */
1772  gnc_gen_trans_common_setup (info, parent, builder, heading,
1773  all_from_same_account, match_date_hardlimit);
1774 
1775  return info;
1776 }

◆ 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 the GNCImportMainMatcher structure

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

1780 {
1781  on_matcher_ok_clicked (NULL, info);
1782 }

◆ 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 1789 of file import-main-matcher.c.

1792 {
1793  info->user_data = user_data;
1794  info->transaction_processed_cb = trans_processed_cb;
1795 }

◆ 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 2193 of file import-main-matcher.c.

2194 {
2195  Account* acc = NULL;
2196  Split* split = NULL;
2197  int i=0;
2198 
2199  split = xaccTransGetSplit (trans, 0);
2200  acc = xaccSplitGetAccount (split);
2201  defer_bal_computation (gui, acc);
2202 
2204  return;
2205 }/* 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.
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 2223 of file import-main-matcher.c.

2224 {
2225  GNCImportTransInfo * transaction_info = NULL;
2226  GtkTreeModel *model;
2227  GtkTreeIter iter;
2228  g_assert (gui);
2229  g_assert (trans);
2230 
2231  if (gnc_import_exists_online_id (trans, gui->acct_id_hash))
2232  return;
2233  else
2234  {
2235  transaction_info = gnc_import_TransInfo_new (trans, NULL);
2236  gnc_import_TransInfo_set_ref_id (transaction_info, ref_id);
2237  // It's much faster to gather the imported transactions into a GSList than directly into the
2238  // treeview.
2239  gui->temp_trans_list = g_slist_prepend (gui->temp_trans_list, transaction_info);
2240  }
2241  return;
2242 }
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_append_text_widget()

GtkWidget * gnc_gen_trans_list_append_text_widget ( GNCImportMainMatcher *  info)

Returns the append_text widget of this dialog.

Parameters
infoA pointer to the GNCImportMainMatcher structure.
Returns
A GtkWidget pointer to the append_text widget.

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

2412 {
2413  g_assert (info);
2414  return info->append_text;
2415 }

◆ gnc_gen_trans_list_delete()

void gnc_gen_trans_list_delete ( GNCImportMainMatcher *  info)

Deletes the given object.

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

191 {
192  GtkTreeModel *model;
193  GtkTreeIter iter;
194  GNCImportTransInfo *trans_info;
195 
196  if (info == NULL)
197  return;
198 
199  model = gtk_tree_view_get_model (info->view);
200  if (gtk_tree_model_get_iter_first (model, &iter))
201  {
202  do
203  {
204  gtk_tree_model_get (model, &iter,
205  DOWNLOADED_COL_DATA, &trans_info,
206  -1);
207 
208  if (info->transaction_processed_cb)
209  {
210  info->transaction_processed_cb (trans_info, FALSE,
211  info->user_data);
212  }
213  }
214  while (gtk_tree_model_iter_next (model, &iter));
215  }
216 
217  if (GTK_IS_DIALOG(info->main_widget))
218  {
219  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->main_widget));
220  gnc_import_Settings_delete (info->user_settings);
221  gnc_unregister_gui_component (info->id);
222  gtk_widget_destroy (GTK_WIDGET(info->main_widget));
223  }
224  else
225  gnc_import_Settings_delete (info->user_settings);
226 
227  g_slist_free_full (info->temp_trans_list, (GDestroyNotify) gnc_import_TransInfo_delete);
228  info->temp_trans_list = NULL;
229 
230  // We've deferred balance computations on many accounts. Let's do it now that we're done.
231  update_all_balances (info);
232 
233  gnc_import_PendingMatches_delete (info->pending_matches);
234  g_hash_table_destroy (info->acct_id_hash);
235  g_hash_table_destroy (info->desc_hash);
236  g_hash_table_destroy (info->notes_hash);
237  g_hash_table_destroy (info->memo_hash);
238 
239  g_list_free_full (info->new_strings, (GDestroyNotify)g_free);
240 
241  g_free (info);
242 }
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 the GNCImportMainMatcher structure.
Returns
A boolean indicating whether the transaction list is empty.

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

246 {
247  GtkTreeModel *model;
248  GtkTreeIter iter;
249  GNCImportTransInfo *trans_info;
250  g_assert (info);
251  model = gtk_tree_view_get_model (info->view);
252  // Check that both the tree model and the temporary list are empty.
253  return !gtk_tree_model_get_iter_first (model, &iter) && !info->temp_trans_list;
254 }

◆ 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 the GNCImportMainMatcher structure.
Returns
The check button.

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

2218 {
2219  return info->reconcile_after_close;
2220 }

◆ 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 1696 of file import-main-matcher.c.

1701 {
1702  GNCImportMainMatcher *info;
1703  GtkBuilder *builder;
1704  GtkWidget *box, *pbox;
1705 
1706  info = g_new0 (GNCImportMainMatcher, 1);
1707 
1708  /* Initialize the GtkDialog. */
1709  builder = gtk_builder_new ();
1710  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_dialog");
1711  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
1712 
1713  info->main_widget = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_dialog"));
1714  g_assert (info->main_widget != NULL);
1715 
1716  /* Pack the content into the dialog vbox */
1717  pbox = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_vbox"));
1718  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
1719  gtk_box_pack_start (GTK_BOX(pbox), box, TRUE, TRUE, 0);
1720 
1721  /* setup the common parts */
1722  gnc_gen_trans_common_setup (info, parent, builder, heading,
1723  all_from_same_account, match_date_hardlimit);
1724 
1725  if (parent)
1726  gtk_window_set_transient_for (GTK_WINDOW(info->main_widget), GTK_WINDOW(parent));
1727 
1728  gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->main_widget), GTK_WINDOW(parent));
1729 
1730  if (show_all)
1731  gtk_widget_show_all (GTK_WIDGET(info->main_widget));
1732 
1733  // Register this UI, it needs to be closed when the session is closed.
1734  info->id = gnc_register_gui_component (IMPORT_MAIN_MATCHER_CM_CLASS,
1735  NULL, /* no refresh handler */
1736  (GNCComponentCloseHandler)gnc_gen_trans_list_delete,
1737  info);
1738  // This ensure this dialog is closed when the session is closed.
1739  gnc_gui_component_set_session (info->id, gnc_get_current_session());
1740 
1741  return info;
1742 }
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 the GNCImportMainMatcher structure.
Returns
The boolean return value of the dialog run.

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

1799 {
1800  gboolean result;
1801 
1802  /* DEBUG("Begin"); */
1803  result = gtk_dialog_run (GTK_DIALOG (info->main_widget));
1804  /* DEBUG("Result was %d", result); */
1805 
1806  /* No destroying here since the dialog was already destroyed through
1807  the ok_clicked handlers. */
1808 
1809  return result;
1810 }

◆ gnc_gen_trans_list_show_all()

void gnc_gen_trans_list_show_all ( GNCImportMainMatcher *  info)

Shows widgets.

Parameters
infoA pointer to the GNCImportMainMatcher structure.

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

505 {
506  GNCImportTransInfo* trans_info;
507  Account* account;
508  Split* first_split;
509  GSList* temp_trans_list;
510 
511  g_assert (info);
512 
513  // Set initial state of Append checkbox to same as last import for this account.
514  // Get the import account from the first split in first transaction.
515  temp_trans_list = info->temp_trans_list;
516  if (!temp_trans_list)
517  {
518  gnc_info_dialog (GTK_WINDOW (info->main_widget), _("No new transactions were found in this import."));
519  return;
520  }
521  trans_info = temp_trans_list->data;
522  first_split = gnc_import_TransInfo_get_fsplit (trans_info);
523  account = xaccSplitGetAccount(first_split);
524  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (info->append_text),
525  xaccAccountGetAppendText(account));
526 
527  gnc_gen_trans_list_create_matches (info);
528  load_hash_tables (info);
529  resolve_conflicts (info);
530  gtk_widget_show_all (GTK_WIDGET(info->main_widget));
531  gnc_gen_trans_list_show_accounts_column (info);
532 }
gboolean xaccAccountGetAppendText(const Account *acc)
Get the "import-append-text" flag for an account.
Definition: Account.cpp:4253
Split * gnc_import_TransInfo_get_fsplit(const GNCImportTransInfo *info)
Returns the first split of the transaction of this TransInfo.
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_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 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 2208 of file import-main-matcher.c.

2211 {
2212  gtk_widget_set_visible (info->reconcile_after_close, reconcile_after_close);
2213  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->reconcile_after_close), active);
2214 }

◆ gnc_gen_trans_list_widget()

GtkWidget * gnc_gen_trans_list_widget ( GNCImportMainMatcher *  info)

Returns the widget of this dialog.

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

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

2405 {
2406  g_assert (info);
2407  return info->main_widget;
2408 }

◆ 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 1192 of file import-backend.c.

1193 {
1194  gboolean online_id_exists = FALSE;
1195  Account *dest_acct;
1196  Split *source_split;
1197  char *source_online_id;
1198 
1199  /* Look for an online_id in the first split */
1200  source_split = xaccTransGetSplit(trans, 0);
1201  g_assert(source_split);
1202 
1203  source_online_id = gnc_import_get_split_online_id (source_split);
1204 
1205  // No online id, no point in continuing. We'd crash if we tried.
1206  if (!source_online_id)
1207  return FALSE;
1208 
1209  // Create a hash per account of a hash of all split IDs. Then the
1210  // test below will be fast if we have many transactions to import.
1211  dest_acct = xaccSplitGetAccount (source_split);
1212  if (!g_hash_table_contains (acct_id_hash, dest_acct))
1213  {
1214  GHashTable* new_hash = g_hash_table_new_full
1215  (g_str_hash, g_str_equal, g_free, NULL);
1216  g_hash_table_insert (acct_id_hash, dest_acct, new_hash);
1217  for (GList *n = xaccAccountGetSplitList (dest_acct) ; n; n=n->next)
1218  {
1219  if (gnc_import_split_has_online_id (n->data))
1220  {
1221  char *id = gnc_import_get_split_online_id (n->data);
1222  g_hash_table_insert (new_hash, (void*) id, GINT_TO_POINTER (1));
1223  }
1224  }
1225  }
1226  online_id_exists = g_hash_table_contains (g_hash_table_lookup (acct_id_hash, dest_acct),
1227  source_online_id);
1228 
1229  /* If it does, abort the process for this transaction, since it is
1230  already in the system. */
1231  if (online_id_exists == TRUE)
1232  {
1233  DEBUG("%s", "Transaction with same online ID exists, destroying current transaction");
1234  xaccTransDestroy(trans);
1235  xaccTransCommitEdit(trans);
1236  }
1237  g_free (source_online_id);
1238  return online_id_exists;
1239 }
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
SplitList * xaccAccountGetSplitList(const Account *acc)
The xaccAccountGetSplitList() routine returns a pointer to a GList of the splits in the account...
Definition: Account.cpp:4007
#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 263 of file import-backend.c.

264 {
265  if (info)
266  {
267  return info->probability;
268  }
269  else
270  {
271  return 0;
272  }
273 }

◆ 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 256 of file import-backend.c.

257 {
258  g_assert (info);
259  return info->split;
260 }

◆ 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 932 of file import-backend.c.

934 {
935  Split * other_split;
936  gnc_numeric imbalance_value;
937  Transaction *trans;
938 
939  /* DEBUG("Begin"); */
940 
941  g_assert (trans_info);
942  /*DEBUG("Iteration %d, action %d, split %s", i,
943  trans_info->action,
944  xaccTransGetDescription (gnc_import_TransInfo_get_trans
945  (trans_info)))*/
946  switch (gnc_import_TransInfo_get_action (trans_info))
947  {
948  case GNCImport_SKIP:
949  return FALSE;
950  case GNCImport_ADD:
951  /* Transaction gets imported. */
952 
953  /* Is the transaction not balanced and there is a non-NULL destination account? */
954  if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE
955  && gnc_import_TransInfo_get_destacc(trans_info) != NULL)
956  {
957  /* Create the 'other' split. */
958  Split *split =
960  (gnc_account_get_book
961  (gnc_import_TransInfo_get_destacc (trans_info)));
963  (gnc_import_TransInfo_get_trans (trans_info), split);
965  (gnc_import_TransInfo_get_destacc (trans_info), split);
966  /*xaccSplitSetBaseValue
967  (split,
968  gnc_numeric_neg(xaccTransGetImbalance
969  (gnc_import_TransInfo_get_trans (trans_info))),
970  xaccTransGetCurrency
971  (gnc_import_TransInfo_get_trans (trans_info)));*/
972  {
973  /* This is a quick workaround for the bug described in
974  http://lists.gnucash.org/pipermail/gnucash-devel/2003-August/009982.html
975  Assume that importers won't create transactions involving two or more
976  currencies so we can use xaccTransGetImbalanceValue. */
977  imbalance_value =
979  (gnc_import_TransInfo_get_trans (trans_info)));
980  xaccSplitSetValue (split, imbalance_value);
981  xaccSplitSetAmount (split, imbalance_value);
982  }
983  /*xaccSplitSetMemo (split, _("Auto-Balance split"));
984  -- disabled due to popular request */
985  }
986 
988  /*Set reconcile date to today*/
990  gnc_time (NULL));
991  /* Done editing. */
992  trans = gnc_import_TransInfo_get_trans (trans_info);
993  xaccTransCommitEdit(trans);
994  xaccTransRecordPrice(trans, PRICE_SOURCE_SPLIT_IMPORT);
995  return TRUE;
996  case GNCImport_UPDATE:
997  {
998  GNCImportMatchInfo *selected_match =
1000 
1001  /* If there is no selection, ignore this transaction. */
1002  if (!selected_match)
1003  {
1004  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
1005  break;
1006  }
1007 
1008  /* Transaction gets not imported but the matching one gets
1009  updated and reconciled. */
1010  if (gnc_import_MatchInfo_get_split(selected_match) == NULL)
1011  {
1012  PERR("The split I am trying to update and reconcile is NULL, shouldn't happen!");
1013  }
1014  else
1015  {
1016  /* Update and reconcile the matching transaction */
1017  /*DEBUG("BeginEdit selected_match")*/
1018  xaccTransBeginEdit(selected_match->trans);
1019 
1020  xaccTransSetDatePostedSecsNormalized(selected_match->trans,
1022  gnc_import_TransInfo_get_fsplit(trans_info))));
1023 
1024  xaccSplitSetAmount(selected_match->split,
1026  gnc_import_TransInfo_get_fsplit(trans_info)));
1027  xaccSplitSetValue(selected_match->split,
1029  gnc_import_TransInfo_get_fsplit(trans_info)));
1030 
1031  imbalance_value = xaccTransGetImbalanceValue(
1032  gnc_import_TransInfo_get_trans(trans_info));
1033  other_split = xaccSplitGetOtherSplit(selected_match->split);
1034  if (!gnc_numeric_zero_p(imbalance_value) && other_split)
1035  {
1036  if (xaccSplitGetReconcile(other_split) == NREC)
1037  {
1038  imbalance_value = gnc_numeric_neg(imbalance_value);
1039  xaccSplitSetValue(other_split, imbalance_value);
1040  xaccSplitSetAmount(other_split, imbalance_value);
1041  }
1042  /* else GC will automatically insert a split to equity
1043  to balance the transaction */
1044  }
1045 
1046  update_desc_and_notes( trans_info);
1047 
1048  if (xaccSplitGetReconcile(selected_match->split) == NREC)
1049  {
1050  xaccSplitSetReconcile(selected_match->split, CREC);
1051  }
1052 
1053  /* Set reconcile date to today */
1054  xaccSplitSetDateReconciledSecs(selected_match->split, gnc_time (NULL));
1055 
1056  /* Copy the online id to the reconciled transaction, so
1057  the match will be remembered */
1058  if (gnc_import_split_has_online_id(trans_info->first_split))
1059  {
1060  char *online_id = gnc_import_get_split_online_id
1061  (trans_info->first_split);
1062  gnc_import_set_split_online_id(selected_match->split, online_id);
1063  g_free (online_id);
1064  }
1065 
1066  /* Done editing. */
1067  /*DEBUG("CommitEdit selected_match")*/
1068  xaccTransCommitEdit(selected_match->trans);
1069 
1070  /* Store the mapping to the other account in the MatchMap. */
1071  matchmap_store_destination(matchmap, trans_info, TRUE);
1072 
1073  /* Erase the downloaded transaction */
1074  xaccTransDestroy(trans_info->trans);
1075  /*DEBUG("CommitEdit trans")*/
1076  xaccTransCommitEdit(trans_info->trans);
1077  /* Very important: Make sure the freed transaction is not freed again! */
1078  trans_info->trans = NULL;
1079  }
1080  }
1081  return TRUE;
1082  case GNCImport_CLEAR:
1083  {
1084  GNCImportMatchInfo *selected_match =
1086 
1087  /* If there is no selection, ignore this transaction. */
1088  if (!selected_match)
1089  {
1090  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
1091  break;
1092  }
1093 
1094  /* Transaction gets not imported but the matching one gets
1095  reconciled. */
1096  if (gnc_import_MatchInfo_get_split (selected_match) == NULL)
1097  {
1098  PERR("The split I am trying to reconcile is NULL, shouldn't happen!");
1099  }
1100  else
1101  {
1102  /* Reconcile the matching transaction */
1103  /*DEBUG("BeginEdit selected_match")*/
1104  xaccTransBeginEdit(selected_match->trans);
1105 
1107  (selected_match->split) == NREC)
1109  (selected_match->split, CREC);
1110  /* Set reconcile date to today */
1112  (selected_match->split, gnc_time (NULL));
1113 
1114  /* Copy the online id to the reconciled transaction, so
1115  the match will be remembered */
1116  if (gnc_import_split_has_online_id(trans_info->first_split))
1117  {
1118  char *online_id = gnc_import_get_split_online_id
1119  (trans_info->first_split);
1120  gnc_import_set_split_online_id (selected_match->split, online_id);
1121  g_free (online_id);
1122  }
1123 
1124  /* Done editing. */
1125  /*DEBUG("CommitEdit selected_match")*/
1127  (selected_match->trans);
1128 
1129  /* Store the mapping to the other account in the MatchMap. */
1130  matchmap_store_destination (matchmap, trans_info, TRUE);
1131 
1132  /* Erase the downloaded transaction */
1133  xaccTransDestroy(trans_info->trans);
1134  /*DEBUG("CommitEdit trans")*/
1135  xaccTransCommitEdit(trans_info->trans);
1136  /* Very important: Make sure the freed transaction is not freed again! */
1137  trans_info->trans = NULL;
1138  }
1139  }
1140  return TRUE;
1141  default:
1142  DEBUG("Invalid GNCImportAction for this imported transaction.");
1143  break;
1144  }
1145  /*DEBUG("End");*/
1146  return FALSE;
1147 }
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:370
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...
#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.
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
Returns the transaction of this TransInfo.
void xaccTransRecordPrice(Transaction *trans, PriceSource source)
The xaccTransRecordPrice() method iterates through the splits and and record the non-currency equival...
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:244
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:250
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.
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:1044
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 403 of file import-account-matcher.c.

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

◆ 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 122 of file import-settings.c.

123 {
124  g_assert (settings);
125  return settings->fuzzy_amount;
126 };

◆ 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 188 of file import-settings.c.

189 {
190  g_assert(s);
191  return s->match_date_hardlimit;
192 }

◆ 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 182 of file import-settings.c.

183 {
184  g_assert(s);
185  s->match_date_hardlimit = m;
186 }

◆ 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 184 of file import-backend.c.

185 {
186  g_assert (info);
187  return info->action;
188 }

◆ 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 203 of file import-backend.c.

204 {
205  g_assert (info);
206  return info->dest_acc;
207 }

◆ 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 224 of file import-backend.c.

225 {
226  g_assert (info);
227  return info->dest_acc_selected_manually;
228 }

◆ 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 153 of file import-backend.c.

154 {
155  g_assert (info);
156  return info->first_split;
157 }

◆ 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 106 of file import-backend.c.

107 {
108  g_assert (info);
109  return info->match_list;
110 }

◆ 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 177 of file import-backend.c.

178 {
179  g_assert (info);
180  return info->selected_match_info.selected_manually;
181 }

◆ 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 231 of file import-backend.c.

232 {
233  g_assert (info);
234  return info->ref_id;
235 }

◆ 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 160 of file import-backend.c.

161 {
162  g_assert (info);
163  return info->selected_match_info.selected_match;
164 }

◆ gnc_import_TransInfo_get_trans()

Transaction * gnc_import_TransInfo_get_trans ( const GNCImportTransInfo *  info)

Returns the transaction of this TransInfo.

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

130 {
131  g_assert (info);
132  return info->trans;
133 }

◆ 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 1283 of file import-backend.c.

1285 {
1286  GNCImportMatchInfo * best_match = NULL;
1287  g_assert (trans_info);
1288 
1289  if (trans_info->match_list != NULL)
1290  {
1291  trans_info->match_list = g_list_sort(trans_info->match_list,
1292  compare_probability);
1293  best_match = g_list_nth_data(trans_info->match_list, 0);
1295  best_match,
1296  FALSE);
1297  if (best_match != NULL &&
1298  best_match->probability >= gnc_import_Settings_get_clear_threshold(settings))
1299  {
1300  trans_info->action = GNCImport_CLEAR;
1301  }
1302  else if (best_match == NULL ||
1303  best_match->probability <= gnc_import_Settings_get_add_threshold(settings))
1304  {
1305  trans_info->action = GNCImport_ADD;
1306  }
1308  {
1309  trans_info->action = GNCImport_SKIP;
1310  }
1312  {
1313  trans_info->action = GNCImport_UPDATE;
1314  }
1315  else
1316  {
1317  trans_info->action = GNCImport_ADD;
1318  }
1319  }
1320  else
1321  {
1322  trans_info->action = GNCImport_ADD;
1323  }
1324  if (best_match &&
1325  trans_info->action == GNCImport_CLEAR &&
1327  {
1328  if (best_match->update_proposed)
1329  {
1330  trans_info->action = GNCImport_UPDATE;
1331  }
1332  }
1333 
1334  trans_info->previous_action = trans_info->action;
1335 }
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 136 of file import-backend.c.

137 {
138  g_assert (info);
139  /* Assume that the importer won't create a transaction that involves two or more
140  currencies and no non-currency commodity. In that case can use the simpler
141  value imbalance check. */
143  {
144  return TRUE;
145  }
146  else
147  {
148  return FALSE;
149  }
150 }
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 1247 of file import-backend.c.

1248 {
1249  GNCImportTransInfo *transaction_info;
1250  Split *split;
1251  g_assert (trans);
1252 
1253  transaction_info = g_new0(GNCImportTransInfo, 1);
1254 
1255  transaction_info->trans = trans;
1256  /* Only use first split, the source split */
1257  split = xaccTransGetSplit(trans, 0);
1258  g_assert(split);
1259  transaction_info->first_split = split;
1260 
1261  /* Try to find a previously selected destination account
1262  string match for the ADD action */
1263  gnc_import_TransInfo_set_destacc (transaction_info,
1264  matchmap_find_destination (matchmap, transaction_info),
1265  FALSE);
1266  return transaction_info;
1267 }
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 191 of file import-backend.c.

193 {
194  g_assert (info);
195  if (action != info->action)
196  {
197  info->previous_action = info->action;
198  info->action = action;
199  }
200 }

◆ gnc_import_TransInfo_set_append_text()

void gnc_import_TransInfo_set_append_text ( GNCImportTransInfo *  info,
gboolean  append_text 
)

Set the append_text for this TransInfo.

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

249 {
250  g_assert (info);
251  info->append_text = append_text;
252 }

◆ 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 208 of file import-backend.c.

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

◆ 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 113 of file import-backend.c.

114 {
115  g_assert (info);
116  info->match_list = match_list;
117  if (match_list)
118  {
119  info->selected_match_info.selected_match = match_list->data;
120  }
121  else
122  {
123  info->selected_match_info.selected_match = NULL;
124  gnc_import_TransInfo_set_action (info, GNCImport_ADD);
125  }
126 }
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 238 of file import-backend.c.

240 {
241  g_assert (info);
242  info->ref_id = ref_id;
243 }

◆ 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 167 of file import-backend.c.

170 {
171  g_assert (info);
172  info->selected_match_info.selected_match = match;
173  info->selected_match_info.selected_manually = selected_manually;
174 }

◆ 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 625 of file import-main-matcher.c.

626 {
627  GNCImportMainMatcher *info = user_data;
628  GtkBuilder *builder;
629  GtkWidget *help_dialog, *box;
630  gchar *int_required_class, *int_prob_required_class, *int_not_required_class;
631  gchar *class_extension = NULL;
632 
633  builder = gtk_builder_new ();
634  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer2");
635  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer3");
636  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer4");
637  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer5");
638  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer1");
639  gnc_builder_add_from_file (builder, "dialog-import.glade", "matcher_help_dialog");
640 
641  if (info->dark_theme == TRUE)
642  class_extension = "-dark";
643 
644  int_required_class = g_strconcat (CSS_INT_REQUIRED_CLASS, class_extension, NULL);
645  int_prob_required_class = g_strconcat (CSS_INT_PROB_REQUIRED_CLASS, class_extension, NULL);
646  int_not_required_class = g_strconcat (CSS_INT_NOT_REQUIRED_CLASS, class_extension, NULL);
647 
648  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_required_box"));
649  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_required_class);
650 
651  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_probably_required_box"));
652  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_prob_required_class);
653 
654  box = GTK_WIDGET(gtk_builder_get_object (builder, "intervention_not_required_box"));
655  gnc_widget_style_context_add_class (GTK_WIDGET(box), int_not_required_class);
656 
657  help_dialog = GTK_WIDGET(gtk_builder_get_object (builder, "matcher_help_dialog"));
658  gtk_window_set_transient_for (GTK_WINDOW(help_dialog), GTK_WINDOW(info->main_widget));
659 
660  /* Connect the signals */
661  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, help_dialog);
662 
663  g_object_unref (G_OBJECT(builder));
664 
665  g_free (int_required_class);
666  g_free (int_prob_required_class);
667  g_free (int_not_required_class);
668 
669  gtk_widget_show (help_dialog);
670 }

◆ split_find_match()

void split_find_match ( GNCImportTransInfo *  trans_info,
Split *  split,
gint  display_threshold,
gint  date_threshold,
gint  date_not_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.
date_thresholdMaximum number of days a match considered likely.
date_not_thresholdMinimum number of days a match is considered unlikely.
fuzzy_amount_differenceMaximum amount difference to consider the match good.

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

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