GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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-settings.h
 Import preference handling. User preference interface for transaction matching (for both the gui and the backend)
 
file  import-utilities.h
 Utility functions for writing import modules.
 

Data Structures

struct  AccountPickerDialog
 
struct  _transactioninfo
 
struct  _matchinfo
 
struct  _main_matcher_info
 
struct  _transpickerdialog
 
struct  _genimportsettings
 
struct  _split_record
 

Macros

#define STATE_SECTION   "dialogs/import/generic_matcher/account_matcher"
 
#define GNCIMPORT_DESC   "desc"
 
#define GNCIMPORT_MEMO   "memo"
 
#define GNCIMPORT_PAYEE   "payee"
 
#define GNC_PREFS_GROUP   "dialogs.import.generic.transaction-list"
 
#define COLOR_RED   "brown1"
 
#define COLOR_YELLOW   "gold"
 
#define COLOR_GREEN   "DarkSeaGreen1"
 
#define GNC_PREFS_GROUP   "dialogs.import.generic.match-picker"
 
#define GNC_PREFS_GROUP_IMPORT   "dialogs.import.generic"
 
#define GNC_PREF_ENABLE_SKIP   "enable-skip"
 
#define GNC_PREF_ENABLE_UPDATE   "enable-update"
 
#define GNC_PREF_USE_BAYES   "use-bayes"
 
#define GNC_PREF_ATM_FEE_THRESHOLD   "atm-fee-threshold"
 
#define GNC_PREF_AUTO_CLEAR_THRESHOLD   "auto-clear-threshold"
 
#define GNC_PREF_AUTO_ADD_THRESHOLD   "auto-add-threshold"
 
#define GNC_PREF_MATCH_THRESHOLD   "match-threshold"
 
#define GNC_PREFS_GROUP   "dialogs.log-replay"
 
#define STRING_FIELD_SIZE   256
 
#define GNC_PREFS_GROUP   "dialogs.import.ofx"
 
#define GNC_PREF_AUTO_COMMODITY   "auto-create-commodity"
 

Typedefs

typedef struct _transactioninfo GNCImportTransInfo
 
typedef struct _matchinfo GNCImportMatchInfo
 
typedef struct _GncImportMatchMap GncImportMatchMap
 
typedef enum _action GNCImportAction
 
typedef struct _main_matcher_info GNCImportMainMatcher
 
typedef void(* GNCTransactionProcessedCB )(GNCImportTransInfo *trans_info, gboolean imported, gpointer user_data)
 
typedef struct _transpickerdialog GNCImportMatchPicker
 
typedef struct _genimportsettings GNCImportSettings
 
typedef struct _split_record split_record
 

Enumerations

enum  _action {
  GNCImport_SKIP, GNCImport_ADD, GNCImport_CLEAR, GNCImport_UPDATE,
  GNCImport_LAST_ACTION, GNCImport_INVALID_ACTION
}
 
enum  downloaded_cols {
  DOWNLOADED_COL_DATE = 0, DOWNLOADED_COL_ACCOUNT, DOWNLOADED_COL_AMOUNT, DOWNLOADED_COL_DESCRIPTION,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_ACTION_ADD, DOWNLOADED_COL_ACTION_CLEAR, DOWNLOADED_COL_ACTION_UPDATE,
  DOWNLOADED_COL_ACTION_INFO, DOWNLOADED_COL_ACTION_PIXBUF, DOWNLOADED_COL_DATA, DOWNLOADED_COL_COLOR,
  NUM_DOWNLOADED_COLS, DOWNLOADED_COL_ACCOUNT = 0, DOWNLOADED_COL_DATE, DOWNLOADED_COL_AMOUNT,
  DOWNLOADED_COL_DESCRIPTION, DOWNLOADED_COL_MEMO, DOWNLOADED_COL_BALANCED, DOWNLOADED_COL_INFO_PTR,
  NUM_DOWNLOADED_COLS
}
 
enum  downloaded_cols {
  DOWNLOADED_COL_DATE = 0, DOWNLOADED_COL_ACCOUNT, DOWNLOADED_COL_AMOUNT, DOWNLOADED_COL_DESCRIPTION,
  DOWNLOADED_COL_MEMO, DOWNLOADED_COL_ACTION_ADD, DOWNLOADED_COL_ACTION_CLEAR, DOWNLOADED_COL_ACTION_UPDATE,
  DOWNLOADED_COL_ACTION_INFO, DOWNLOADED_COL_ACTION_PIXBUF, DOWNLOADED_COL_DATA, DOWNLOADED_COL_COLOR,
  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_INFO_PTR, NUM_MATCHER_COLS
}
 

Functions

char * libgncmod_csv_export_gnc_module_path (void)
 
char * libgncmod_csv_export_gnc_module_description (void)
 
int libgncmod_csv_export_gnc_module_init (int refcount)
 
int libgncmod_csv_export_gnc_module_end (int refcount)
 
char * libgncmod_csv_import_gnc_module_path (void)
 
char * libgncmod_csv_import_gnc_module_description (void)
 
int libgncmod_csv_import_gnc_module_init (int refcount)
 
int libgncmod_csv_import_gnc_module_end (int refcount)
 
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)
 
AccountPickerDialoggnc_import_account_assist_setup (GtkWidget *parent)
 
Accountgnc_import_account_assist_update (AccountPickerDialog *picker)
 
GncImportMatchMapgnc_account_create_imap (Account *acc)
 
Accountgnc_imap_find_account (GncImportMatchMap *imap, const char *category, const char *key)
 
void gnc_imap_add_account (GncImportMatchMap *imap, const char *category, const char *key, Account *acc)
 
Accountgnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens)
 
void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList *tokens, Account *acc)
 
gnc_commoditygnc_import_select_commodity (const char *cusip, gboolean ask_on_unknown, const char *default_fullname, const char *default_mnemonic)
 
void on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info)
 
void on_matcher_cancel_clicked (GtkButton *button, gpointer user_data)
 
void on_matcher_help_clicked (GtkButton *button, gpointer user_data)
 
void on_matcher_help_close_clicked (GtkButton *button, gpointer user_data)
 
void gnc_gen_trans_list_delete (GNCImportMainMatcher *info)
 
GNCImportMainMatchergnc_gen_trans_list_new (GtkWidget *parent, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit)
 
GNCImportMainMatchergnc_gen_trans_assist_new (GtkWidget *parent, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit)
 
void gnc_gen_trans_assist_start (GNCImportMainMatcher *info)
 
void gnc_gen_trans_list_add_tp_cb (GNCImportMainMatcher *info, GNCTransactionProcessedCB trans_processed_cb, gpointer user_data)
 
gboolean gnc_gen_trans_list_run (GNCImportMainMatcher *info)
 
void gnc_gen_trans_list_add_trans (GNCImportMainMatcher *gui, Transaction *trans)
 
void gnc_gen_trans_list_add_trans_with_ref_id (GNCImportMainMatcher *gui, Transaction *trans, guint32 ref_id)
 
GtkWidget * gnc_gen_trans_list_widget (GNCImportMainMatcher *info)
 
void gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info)
 
GNCImportSettingsgnc_import_Settings_new (void)
 
void gnc_import_Settings_delete (GNCImportSettings *settings)
 
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)
 
void gnc_file_log_replay (void)
 
char * libgncmod_log_replay_gnc_module_path (void)
 
char * libgncmod_log_replay_gnc_module_description (void)
 
int libgncmod_log_replay_gnc_module_init (int refcount)
 
int libgncmod_log_replay_gnc_module_end (int refcount)
 
int ofx_proc_security_cb (const struct OfxSecurityData data, void *security_user_data)
 
int ofx_proc_transaction_cb (struct OfxTransactionData data, void *transaction_user_data)
 
int ofx_proc_account_cb (struct OfxAccountData data, void *account_user_data)
 
void gnc_file_ofx_import (void)
 
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

int libgncmod_csv_export_gnc_module_system_interface = 0
 
int libgncmod_csv_export_gnc_module_current = 0
 
int libgncmod_csv_export_gnc_module_revision = 0
 
int libgncmod_csv_export_gnc_module_age = 0
 
int libgncmod_csv_import_gnc_module_system_interface = 0
 
int libgncmod_csv_import_gnc_module_current = 0
 
int libgncmod_csv_import_gnc_module_revision = 0
 
int libgncmod_csv_import_gnc_module_age = 0
 
int libgncmod_log_replay_gnc_module_system_interface = 0
 
int libgncmod_log_replay_gnc_module_current = 0
 
int libgncmod_log_replay_gnc_module_revision = 0
 
int libgncmod_log_replay_gnc_module_age = 0
 
GNCImportMainMatchergnc_ofx_importer_gui = NULL
 
GList * ofx_created_commodites = NULL
 
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_original, GNCImportSettings *settings, GtkWidget *widget)
 
void gnc_import_find_split_matches (GNCImportTransInfo *trans_info, gint process_threshold, double fuzzy_amount_difference, gint match_date_hardlimit)
 
gboolean gnc_import_process_trans_item (GncImportMatchMap *matchmap, GNCImportTransInfo *trans_info)
 
gboolean gnc_import_exists_online_id (Transaction *trans)
 
void gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info, GNCImportSettings *settings)
 

Getters/Setters for GNCImportTransInfo

GList * gnc_import_TransInfo_get_match_list (const GNCImportTransInfo *info)
 
Transactiongnc_import_TransInfo_get_trans (const GNCImportTransInfo *info)
 
gboolean gnc_import_TransInfo_is_balanced (const GNCImportTransInfo *info)
 
Splitgnc_import_TransInfo_get_fsplit (const GNCImportTransInfo *info)
 
GNCImportMatchInfognc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info)
 
void gnc_import_TransInfo_set_selected_match (GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
 
gboolean gnc_import_TransInfo_get_match_selected_manually (const GNCImportTransInfo *info)
 
GNCImportAction gnc_import_TransInfo_get_action (const GNCImportTransInfo *info)
 
void gnc_import_TransInfo_set_action (GNCImportTransInfo *info, GNCImportAction action)
 
Accountgnc_import_TransInfo_get_destacc (const GNCImportTransInfo *info)
 
void gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info, Account *acc, gboolean selected_manually)
 
gboolean gnc_import_TransInfo_get_destacc_selected_manually (const GNCImportTransInfo *info)
 
guint32 gnc_import_TransInfo_get_ref_id (const GNCImportTransInfo *info)
 
void gnc_import_TransInfo_set_ref_id (GNCImportTransInfo *info, guint32 ref_id)
 
void gnc_import_TransInfo_delete (GNCImportTransInfo *info)
 
GNCImportTransInfognc_import_TransInfo_new (Transaction *trans, GncImportMatchMap *matchmap)
 
gboolean gnc_import_TransInfo_refresh_destacc (GNCImportTransInfo *transaction_info, GncImportMatchMap *matchmap)
 

Getters/Setters for GNCImportMatchInfo

Splitgnc_import_MatchInfo_get_split (const GNCImportMatchInfo *info)
 
gint gnc_import_MatchInfo_get_probability (const GNCImportMatchInfo *info)
 

Getters/Setters for GNCImportSettings

double gnc_import_Settings_get_fuzzy_amount (GNCImportSettings *settings)
 
gboolean gnc_import_Settings_get_action_skip_enabled (GNCImportSettings *settings)
 
gboolean gnc_import_Settings_get_action_add_enabled (GNCImportSettings *settings)
 
gboolean gnc_import_Settings_get_action_update_enabled (GNCImportSettings *settings)
 
gboolean gnc_import_Settings_get_action_clear_enabled (GNCImportSettings *settings)
 
gint gnc_import_Settings_get_clear_threshold (GNCImportSettings *settings)
 
gint gnc_import_Settings_get_add_threshold (GNCImportSettings *settings)
 
gint gnc_import_Settings_get_display_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 *s)
 

Setter-getters

Setter and getter functions for the online_id kvp_frame for Splits.

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

Detailed Description

Macro Definition Documentation

#define GNC_PREFS_GROUP_IMPORT   "dialogs.import.generic"

The preferences used by the importer

Definition at line 30 of file import-utilities.h.

Function Documentation

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

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

Obtain an ImportMatchMap object from an Account

Definition at line 5035 of file Account.c.

5036 {
5037  GncImportMatchMap *imap;
5038  KvpFrame *frame;
5039 
5040  if (!acc) return NULL;
5041  frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5042  g_return_val_if_fail (frame != NULL, NULL);
5043  g_return_val_if_fail (frame != NULL, NULL);
5044 
5045  imap = g_new0(GncImportMatchMap, 1);
5046  imap->frame = frame;
5047 
5048  /* Cache the book for easy lookups; store the account/book for
5049  * marking dirtiness
5050  */
5051  imap->acc = acc;
5052  imap->book = gnc_account_get_book (acc);
5053 
5054  return imap;
5055 }
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
void gnc_file_log_replay ( void  )

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 the .log file is opened and read. It's contents are then silently merged in the current log file.

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

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

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 the OFX file is opened and read. It's contents are merged into the existing session (if any). The current session continues to remain open for editing.

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

951 {
952  extern int ofx_PARSER_msg;
953  extern int ofx_DEBUG_msg;
954  extern int ofx_WARNING_msg;
955  extern int ofx_ERROR_msg;
956  extern int ofx_INFO_msg;
957  extern int ofx_STATUS_msg;
958  char *selected_filename;
959  char *default_dir;
960  LibofxContextPtr libofx_context = libofx_get_new_context();
961 
962  ofx_PARSER_msg = false;
963  ofx_DEBUG_msg = false;
964  ofx_WARNING_msg = true;
965  ofx_ERROR_msg = true;
966  ofx_INFO_msg = true;
967  ofx_STATUS_msg = false;
968 
969  DEBUG("gnc_file_ofx_import(): Begin...\n");
970 
971  default_dir = gnc_get_default_directory(GNC_PREFS_GROUP);
972  selected_filename = gnc_file_dialog(_("Select an OFX/QFX file to process"),
973  NULL,
974  default_dir,
975  GNC_FILE_DIALOG_IMPORT);
976  g_free(default_dir);
977 
978  if (selected_filename != NULL)
979  {
980 #ifdef G_OS_WIN32
981  gchar *conv_name;
982 #endif
983 
984  /* Remember the directory as the default. */
985  default_dir = g_path_get_dirname(selected_filename);
986  gnc_set_default_directory(GNC_PREFS_GROUP, default_dir);
987  g_free(default_dir);
988 
989  /*strncpy(file,selected_filename, 255);*/
990  DEBUG("Filename found: %s", selected_filename);
991 
992  /* Create the Generic transaction importer GUI. */
993  gnc_ofx_importer_gui = gnc_gen_trans_list_new(NULL, NULL, FALSE, 42);
994 
995  /* Look up the needed preferences */
996  auto_create_commodity =
997  gnc_prefs_get_bool (GNC_PREFS_GROUP_IMPORT, GNC_PREF_AUTO_COMMODITY);
998 
999  /* Initialize libofx */
1000 
1001  /*ofx_set_statement_cb(libofx_context, ofx_proc_statement_cb, 0);*/
1002  ofx_set_account_cb(libofx_context, ofx_proc_account_cb, 0);
1003  ofx_set_transaction_cb(libofx_context, ofx_proc_transaction_cb, 0);
1004  ofx_set_security_cb(libofx_context, ofx_proc_security_cb, 0);
1005  /*ofx_set_status_cb(libofx_context, ofx_proc_status_cb, 0);*/
1006 
1007 #ifdef G_OS_WIN32
1008  conv_name = g_win32_locale_filename_from_utf8(selected_filename);
1009  g_free(selected_filename);
1010  selected_filename = conv_name;
1011 #endif
1012 
1013  DEBUG("Opening selected file");
1014  libofx_proc_file(libofx_context, selected_filename, AUTODETECT);
1015  g_free(selected_filename);
1016  }
1017 
1018  if (ofx_created_commodites)
1019  {
1020  /* FIXME: Present some result window about the newly created
1021  * commodities */
1022  g_warning("Created %d new commodities during import", g_list_length(ofx_created_commodites));
1023  g_list_free(ofx_created_commodites);
1024  ofx_created_commodites = NULL;
1025  }
1026  else
1027  {
1028  //g_warning("No new commodities created");
1029  }
1030 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
#define GNC_PREFS_GROUP_IMPORT
GNCImportMainMatcher * gnc_gen_trans_list_new(GtkWidget *parent, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
GNCImportMainMatcher * gnc_gen_trans_assist_new ( GtkWidget *  parent,
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. 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 593 of file import-main-matcher.c.

597 {
598  GNCImportMainMatcher *info;
599  GtkBuilder *builder;
600  GtkWidget *heading_label;
601  GtkWidget *box;
602  gboolean show_update;
603 
604  info = g_new0 (GNCImportMainMatcher, 1);
605 
606  /* Initialize user Settings. */
607  info->user_settings = gnc_import_Settings_new ();
608  gnc_import_Settings_set_match_date_hardlimit (info->user_settings, match_date_hardlimit);
609 
610  /* load the interface */
611  builder = gtk_builder_new();
612  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
613  if (builder == NULL)
614  {
615  PERR("Error opening the glade builder interface");
616  }
617  /* Pack content into Assistant page widget */
618  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
619  gtk_box_pack_start( GTK_BOX(parent), box, TRUE, TRUE, 6);
620 
621  /* Get the view */
622  info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view"));
623  g_assert (info->view != NULL);
624 
625  show_update = gnc_import_Settings_get_action_update_enabled(info->user_settings);
626  gnc_gen_trans_init_view(info, all_from_same_account, show_update);
627  heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label"));
628  g_assert (heading_label != NULL);
629 
630  /*Initialise the colors */
631  gdk_color_parse(COLOR_RED, &info->color_back_red);
632  gdk_color_parse(COLOR_YELLOW, &info->color_back_yellow);
633  gdk_color_parse(COLOR_GREEN, &info->color_back_green);
634 
635  if (heading)
636  gtk_label_set_text (GTK_LABEL (heading_label), heading);
637 
638  info->transaction_processed_cb = NULL;
639 
640  /* Connect the signals */
641  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, info);
642 
643  g_object_unref(G_OBJECT(builder));
644 
645  return info;
646 }
GNCImportSettings * gnc_import_Settings_new(void)
#define PERR(format, args...)
Definition: qoflog.h:237
void gnc_import_Settings_set_match_date_hardlimit(GNCImportSettings *s, gint m)
gboolean gnc_import_Settings_get_action_update_enabled(GNCImportSettings *settings)
void gnc_gen_trans_assist_start ( GNCImportMainMatcher info)

This starts the import process for transaction from an assistant. assistant button callback.

Parameters
info.A pointer to a the GNCImportMainMatcher structure.

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

649 {
650  on_matcher_ok_clicked (NULL, info);
651 }
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 657 of file import-main-matcher.c.

660 {
661  info->user_data = user_data;
662  info->transaction_processed_cb = trans_processed_cb;
663 }
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 commited. The Importer takes over ownership of the passed transaction.

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

893 {
895  return;
896 }/* end gnc_import_add_trans() */
void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transaction *trans, guint32 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 commited. The Importer takes over ownership of the passed transaction.
ref_idReference id which links an external object to the transaction.

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

899 {
900  GNCImportTransInfo * transaction_info = NULL;
901  GtkTreeModel *model;
902  GtkTreeIter iter;
903  g_assert (gui);
904  g_assert (trans);
905 
906 
907  if (gnc_import_exists_online_id (trans))
908  return;
909  else
910  {
911  transaction_info = gnc_import_TransInfo_new(trans, NULL);
912  gnc_import_TransInfo_set_ref_id(transaction_info, ref_id);
913 
914  gnc_import_TransInfo_init_matches(transaction_info,
915  gui->user_settings);
916 
917  model = gtk_tree_view_get_model(gui->view);
918  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
919  refresh_model_row (gui, model, &iter, transaction_info);
920  }
921  return;
922 }/* end gnc_import_add_trans_with_ref_id() */
GNCImportTransInfo * gnc_import_TransInfo_new(Transaction *trans, GncImportMatchMap *matchmap)
void gnc_import_TransInfo_set_ref_id(GNCImportTransInfo *info, guint32 ref_id)
void gnc_import_TransInfo_init_matches(GNCImportTransInfo *trans_info, GNCImportSettings *settings)
gboolean gnc_import_exists_online_id(Transaction *trans)
void gnc_gen_trans_list_delete ( GNCImportMainMatcher info)

Deletes the given object.

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

107 {
108  GtkTreeModel *model;
109  GtkTreeIter iter;
110  GNCImportTransInfo *trans_info;
111 
112  if (info == NULL)
113  return;
114 
115  model = gtk_tree_view_get_model(info->view);
116  if (gtk_tree_model_get_iter_first(model, &iter))
117  {
118  do
119  {
120  gtk_tree_model_get(model, &iter,
121  DOWNLOADED_COL_DATA, &trans_info,
122  -1);
123 
124  if (info->transaction_processed_cb)
125  {
126  info->transaction_processed_cb(trans_info,
127  FALSE,
128  info->user_data);
129  }
130 
131  gnc_import_TransInfo_delete(trans_info);
132  }
133  while (gtk_tree_model_iter_next (model, &iter));
134  }
135 
136 
137  if (!(info->dialog == NULL))
138  {
139  gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(info->dialog));
140  gnc_import_Settings_delete (info->user_settings);
141  gtk_widget_destroy (GTK_WIDGET (info->dialog));
142  }
143  else
144  gnc_import_Settings_delete (info->user_settings);
145  g_free (info);
146 }
void gnc_import_TransInfo_delete(GNCImportTransInfo *info)
void gnc_import_Settings_delete(GNCImportSettings *settings)
GNCImportMainMatcher * gnc_gen_trans_list_new ( GtkWidget *  parent,
const gchar *  heading,
gboolean  all_from_same_account,
gint  match_date_hardlimit 
)

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.
Returns
A pointer to the GNCImportMainMatcher which has been setup.

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

530 {
531  GNCImportMainMatcher *info;
532  GtkBuilder *builder;
533  GtkWidget *heading_label;
534  GtkWidget *box, *pbox;
535  gboolean show_update;
536 
537  info = g_new0 (GNCImportMainMatcher, 1);
538 
539  /* Initialize user Settings. */
540  info->user_settings = gnc_import_Settings_new ();
541  gnc_import_Settings_set_match_date_hardlimit (info->user_settings, match_date_hardlimit);
542 
543  /* Initialize the GtkDialog. */
544  builder = gtk_builder_new();
545  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher");
546  gnc_builder_add_from_file (builder, "dialog-import.glade", "transaction_matcher_content");
547  info->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher"));
548  g_assert (info->dialog != NULL);
549 
550  /* Pack the content into the dialog vbox */
551  pbox = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_vbox"));
552  box = GTK_WIDGET(gtk_builder_get_object (builder, "transaction_matcher_content"));
553  gtk_box_pack_start( GTK_BOX(pbox), box, TRUE, TRUE, 0);
554 
555  /* Get the view */
556  info->view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "downloaded_view"));
557  g_assert (info->view != NULL);
558 
559  show_update = gnc_import_Settings_get_action_update_enabled(info->user_settings);
560  gnc_gen_trans_init_view(info, all_from_same_account, show_update);
561  heading_label = GTK_WIDGET(gtk_builder_get_object (builder, "heading_label"));
562  g_assert (heading_label != NULL);
563 
564  /* if (parent)
565  gtk_window_set_transient_for (GTK_WINDOW (info->dialog),
566  GTK_WINDOW (parent));*/
567 
568  /*Initialise the colors */
569  gdk_color_parse(COLOR_RED, &info->color_back_red);
570  gdk_color_parse(COLOR_YELLOW, &info->color_back_yellow);
571  gdk_color_parse(COLOR_GREEN, &info->color_back_green);
572 
573  if (heading)
574  gtk_label_set_text (GTK_LABEL (heading_label), heading);
575 
576  gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(info->dialog));
577  gtk_widget_show_all (GTK_WIDGET (info->dialog));
578 
579  info->transaction_processed_cb = NULL;
580 
581  /* Connect the signals */
582  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, info);
583 
584  g_object_unref(G_OBJECT(builder));
585 
586  return info;
587 }
GNCImportSettings * gnc_import_Settings_new(void)
void gnc_import_Settings_set_match_date_hardlimit(GNCImportSettings *s, gint m)
gboolean gnc_import_Settings_get_action_update_enabled(GNCImportSettings *settings)
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.

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

666 {
667  gboolean result;
668 
669  /* DEBUG("Begin"); */
670  result = gtk_dialog_run (GTK_DIALOG (info->dialog));
671  /* DEBUG("Result was %d", result); */
672 
673  /* No destroying here since the dialog was already destroyed through
674  the ok_clicked handlers. */
675 
676  return result;
677 }
GtkWidget * gnc_gen_trans_list_widget ( GNCImportMainMatcher info)

Returns the widget of this dialog.

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

939 {
940  g_assert(info);
941  return info->dialog;
942 }
void gnc_imap_add_account_bayes ( GncImportMatchMap imap,
GList *  tokens,
Account acc 
)

Updates the imap for a given account using a list of tokens

Definition at line 5418 of file Account.c.

5421 {
5422  GList *current_token;
5423  KvpValue *value;
5424  gint64 token_count;
5425  char* account_fullname;
5426  KvpValue *new_value; /* the value that will be added back into
5427  * the kvp tree */
5428 
5429  ENTER(" ");
5430 
5431  /* if imap is null return */
5432  if (!imap)
5433  {
5434  LEAVE(" ");
5435  return;
5436  }
5437 
5438  g_return_if_fail (acc != NULL);
5439  account_fullname = gnc_account_get_full_name(acc);
5440  xaccAccountBeginEdit (imap->acc);
5441 
5442  PINFO("account name: '%s'\n", account_fullname);
5443 
5444  /* process each token in the list */
5445  for (current_token = g_list_first(tokens); current_token;
5446  current_token = current_token->next)
5447  {
5448  /* Jump to next iteration if the pointer is not valid or if the
5449  string is empty. In HBCI import we almost always get an empty
5450  string, which doesn't work in the kvp loopkup later. So we
5451  skip this case here. */
5452  if (!current_token->data || (*((char*)current_token->data) == '\0'))
5453  continue;
5454 
5455  /* start off with no tokens for this account */
5456  token_count = 0;
5457 
5458  PINFO("adding token '%s'\n", (char*)current_token->data);
5459 
5460  /* is this token/account_name already in the kvp tree? */
5461  value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
5462  (char*)current_token->data,
5463  account_fullname,
5464  NULL);
5465 
5466  /* if the token/account is already in the tree, read the current
5467  * value from the tree and use this for the basis of the value we
5468  * are putting back
5469  */
5470  if (value)
5471  {
5472  PINFO("found existing value of '%ld'\n",
5473  (long)kvp_value_get_gint64(value));
5474 
5475  /* convert this value back into an integer */
5476  token_count += kvp_value_get_gint64(value);
5477  }
5478 
5479  /* increment the token count */
5480  token_count++;
5481 
5482  /* create a new value */
5483  new_value = kvp_value_new_gint64(token_count);
5484 
5485  /* insert the value into the kvp tree at
5486  * /imap->frame/IMAP_FRAME/token_string/account_name_string
5487  */
5488  kvp_frame_set_slot_path(imap->frame, new_value,
5489  IMAP_FRAME_BAYES,
5490  (char*)current_token->data,
5491  account_fullname,
5492  NULL);
5493  /* kvp_frame_set_slot_path() copied the value so we
5494  * need to delete this one ;-) */
5495  kvp_value_delete(new_value);
5496  }
5497 
5498  /* free up the account fullname string */
5499  qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
5500  xaccAccountCommitEdit (imap->acc);
5501  g_free(account_fullname);
5502 
5503  LEAVE(" ");
5504 }
#define PINFO(format, args...)
Definition: qoflog.h:249
#define ENTER(format, args...)
Definition: qoflog.h:261
void kvp_frame_set_slot_path(KvpFrame *frame, KvpValue *value, const gchar *first_key,...)
gint64 kvp_value_get_gint64(const KvpValue *value)
gchar * gnc_account_get_full_name(const Account *account)
Definition: Account.c:3038
KvpValue * kvp_frame_get_slot_path(KvpFrame *frame, const gchar *first_key,...)
void xaccAccountBeginEdit(Account *acc)
Definition: Account.c:1280
#define LEAVE(format, args...)
Definition: qoflog.h:271
void kvp_value_delete(KvpValue *value)
void xaccAccountCommitEdit(Account *acc)
Definition: Account.c:1321
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
Account* gnc_imap_find_account_bayes ( GncImportMatchMap imap,
GList *  tokens 
)

Look up an Account in the map

< holds the accounts and total token count for a single token

< pointer to the current token from the input GList tokens

< pointer to the struct account_token_count

< an account name and the number of times a token has appeared for the account

< intermediate storage of values to compute the bayes probability of an account

Definition at line 5238 of file Account.c.

5239 {
5240  struct token_accounts_info tokenInfo;
5242  GList *current_token;
5245  GList *current_account_token;
5247  struct account_token_count *account_c;
5250  struct account_probability *account_p;
5253  GHashTable *running_probabilities = g_hash_table_new(g_str_hash,
5254  g_str_equal);
5255  GHashTable *final_probabilities = g_hash_table_new(g_str_hash,
5256  g_str_equal);
5257  struct account_info account_i;
5258  KvpValue* value;
5259  KvpFrame* token_frame;
5260 
5261  ENTER(" ");
5262 
5263  /* check to see if the imap is NULL */
5264  if (!imap)
5265  {
5266  PINFO("imap is null, returning null");
5267  LEAVE(" ");
5268  return NULL;
5269  }
5270 
5271  /* find the probability for each account that contains any of the tokens
5272  * in the input tokens list
5273  */
5274  for (current_token = tokens; current_token;
5275  current_token = current_token->next)
5276  {
5277  /* zero out the token_accounts_info structure */
5278  memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
5279 
5280  PINFO("token: '%s'", (char*)current_token->data);
5281 
5282  /* find the slot for the given token off of the source account
5283  * for these tokens, search off of the IMAP_FRAME_BAYES path so
5284  * we aren't looking from the parent of the entire kvp tree
5285  */
5286  value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
5287  (char*)current_token->data, NULL);
5288 
5289  /* if value is null we should skip over this token */
5290  if (!value)
5291  continue;
5292 
5293  /* convert the slot(value) into a the frame that contains the
5294  * list of accounts
5295  */
5296  token_frame = kvp_value_get_frame(value);
5297 
5298  /* token_frame should NEVER be null */
5299  if (!token_frame)
5300  {
5301  PERR("token '%s' has no accounts", (char*)current_token->data);
5302  continue; /* skip over this token */
5303  }
5304 
5305  /* process the accounts for this token, adding the account if it
5306  * doesn't already exist or adding to the existing accounts token
5307  * count if it does
5308  */
5309  kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
5310 
5311  /* for each account we have just found, see if the account
5312  * already exists in the list of account probabilities, if not
5313  * add it
5314  */
5315  for (current_account_token = tokenInfo.accounts; current_account_token;
5316  current_account_token = current_account_token->next)
5317  {
5318  /* get the account name and corresponding token count */
5319  account_c = (struct account_token_count*)current_account_token->data;
5320 
5321  PINFO("account_c->account_name('%s'), "
5322  "account_c->token_count('%ld')/total_count('%ld')",
5323  account_c->account_name, (long)account_c->token_count,
5324  (long)tokenInfo.total_count);
5325 
5326  account_p = g_hash_table_lookup(running_probabilities,
5327  account_c->account_name);
5328 
5329  /* if the account exists in the list then continue
5330  * the running probablities
5331  */
5332  if (account_p)
5333  {
5334  account_p->product = (((double)account_c->token_count /
5335  (double)tokenInfo.total_count)
5336  * account_p->product);
5337  account_p->product_difference =
5338  ((double)1 - ((double)account_c->token_count /
5339  (double)tokenInfo.total_count))
5340  * account_p->product_difference;
5341  PINFO("product == %f, product_difference == %f",
5342  account_p->product, account_p->product_difference);
5343  }
5344  else
5345  {
5346  /* add a new entry */
5347  PINFO("adding a new entry for this account");
5348  account_p = (struct account_probability*)
5349  g_new0(struct account_probability, 1);
5350 
5351  /* set the product and product difference values */
5352  account_p->product = ((double)account_c->token_count /
5353  (double)tokenInfo.total_count);
5354  account_p->product_difference =
5355  (double)1 - ((double)account_c->token_count /
5356  (double)tokenInfo.total_count);
5357 
5358  PINFO("product == %f, product_difference == %f",
5359  account_p->product, account_p->product_difference);
5360 
5361  /* add the account name and (struct account_probability*)
5362  * to the hash table */
5363  g_hash_table_insert(running_probabilities,
5364  account_c->account_name, account_p);
5365  }
5366  } /* for all accounts in tokenInfo */
5367 
5368  /* free the data in tokenInfo */
5369  for (current_account_token = tokenInfo.accounts; current_account_token;
5370  current_account_token = current_account_token->next)
5371  {
5372  /* free up each struct account_token_count we allocated */
5373  g_free((struct account_token_count*)current_account_token->data);
5374  }
5375 
5376  g_list_free(tokenInfo.accounts); /* free the accounts GList */
5377  }
5378 
5379  /* build a hash table of account names and their final probabilities
5380  * from each entry in the running_probabilties hash table
5381  */
5382  g_hash_table_foreach(running_probabilities, buildProbabilities,
5383  final_probabilities);
5384 
5385  /* find the highest probabilty and the corresponding account */
5386  memset(&account_i, 0, sizeof(struct account_info));
5387  g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
5388 
5389  /* free each element of the running_probabilities hash */
5390  g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
5391 
5392  /* free the hash tables */
5393  g_hash_table_destroy(running_probabilities);
5394  g_hash_table_destroy(final_probabilities);
5395 
5396  PINFO("highest P('%s') = '%d'",
5397  account_i.account_name ? account_i.account_name : "(null)",
5398  account_i.probability);
5399 
5400  /* has this probability met our threshold? */
5401  if (account_i.probability >= threshold)
5402  {
5403  PINFO("found match");
5404  LEAVE(" ");
5405  return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
5406  account_i.account_name);
5407  }
5408 
5409  PINFO("no match");
5410  LEAVE(" ");
5411 
5412  return NULL; /* we didn't meet our threshold, return NULL for an account */
5413 }
#define PINFO(format, args...)
Definition: qoflog.h:249
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
Definition: Account.c:2915
KvpValue * kvp_frame_get_slot_path(KvpFrame *frame, const gchar *first_key,...)
void kvp_frame_for_each_slot(KvpFrame *f, void(*proc)(const gchar *key, KvpValue *value, gpointer data), gpointer data)
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
#define LEAVE(format, args...)
Definition: qoflog.h:271
KvpFrame * kvp_value_get_frame(const KvpValue *value)
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
AccountPickerDialog * gnc_import_account_assist_setup ( GtkWidget *  parent)

Must be called with the parent widget, ie. a vbox that the account picker dialog will be packed into. The data structure AccountPickerDialog is initialised and default values populated.

Parameters
parentThe parent widget. This is the place the account picker dialog will be packed into.
Returns
A pointer to the AccountPickerDialog which has been setup.

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

412 {
413  AccountPickerDialog * picker;
414  GtkBuilder *builder;
415  GtkWidget *button, *box, *h_box;
416 
417  /* Init the account picker structure */
418  picker = gnc_import_new_account_picker();
419 
420  /* load the interface */
421  builder = gtk_builder_new();
422  gnc_builder_add_from_file (builder, "dialog-import.glade", "account_picker_content");
423  /* connect the signals in the interface */
424  if (builder == NULL)
425  {
426  PERR("Error opening the glade builder interface");
427  }
428 
429  picker->assistant = gtk_widget_get_parent(parent);
430  /* Pack content into Assistant page widget */
431  box = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker_content"));
432  gtk_box_pack_start( GTK_BOX(parent), box, TRUE, TRUE, 6);
433 
434  picker->account_tree_sw = GTK_WIDGET(gtk_builder_get_object (builder, "account_tree_sw"));
435  picker->account_online_id_label = GTK_WIDGET(gtk_builder_get_object (builder, "online_id_label"));
436 
437  /* Add the New Account Button */
438  button = gtk_button_new_with_mnemonic ("_New Account");
439  h_box = gtk_hbox_new(TRUE, 0);
440  gtk_box_pack_start(GTK_BOX(h_box), button, FALSE, FALSE, 0);
441  gtk_box_pack_start( GTK_BOX(box), h_box, FALSE, FALSE, 6);
442  gtk_button_set_use_stock (GTK_BUTTON(button), TRUE);
443  gtk_widget_show (button);
444  g_signal_connect(button, "clicked",
445  G_CALLBACK(gnc_import_add_account), picker);
446 
447  build_acct_tree(picker);
448 
449  g_signal_connect(picker->account_tree, "row-activated",
450  G_CALLBACK(account_tree_row_activated_cb), picker);
451 
452  g_object_unref(G_OBJECT(builder));
453  return picker;
454 }
#define PERR(format, args...)
Definition: qoflog.h:237
Account * gnc_import_account_assist_update ( AccountPickerDialog picker)

Must be called with an AccountPickerDialog structure allready setup. If an account with a matching online_id kvp_frame is found, which is allready present in the dialog structure, the function returns with a pointer to that account or NULL if not found.

Parameters
Accountpicker Dialog structure, AccountPickerDialog
Returns
A pointer to the found account, or NULL if account not found.

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

463 {
464 #define ACCOUNT_DESCRIPTION_MAX_SIZE 255
465 
466  const gchar *retval_name = NULL;
467  gchar account_description_text[ACCOUNT_DESCRIPTION_MAX_SIZE] = "";
468 
469  ENTER("Default commodity received: %s", gnc_commodity_get_fullname( picker->new_account_default_commodity));
470  DEBUG("Default account type received: %s", xaccAccountGetTypeStr( picker->new_account_default_type));
471 
472  /*DEBUG("Looking for account with online_id: %s", picker->account_online_id_value);*/
473  if (picker->account_online_id_value != NULL)
474  {
475  picker->retAccount =
476  gnc_account_foreach_descendant_until(gnc_get_current_root_account (),
477  test_acct_online_id_match,
478  /* This argument will only be used as a "const char*" */
479  (void*)picker->account_online_id_value);
480  }
481 
482  if (picker->account_human_description != NULL)
483  {
484  strncat(account_description_text, picker->account_human_description,
485  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
486  strncat(account_description_text, "\n",
487  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
488  }
489  if (picker->account_online_id_value != NULL)
490  {
491  strncat(account_description_text, _("(Full account ID: "),
492  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
493  strncat(account_description_text, picker->account_online_id_value,
494  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
495  strncat(account_description_text, ")",
496  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
497  }
498  gtk_label_set_text(GTK_LABEL( picker->account_online_id_label), account_description_text);
499 
500  if (picker->default_account == NULL)
501  gnc_tree_view_account_set_selected_account(picker->account_tree, picker->retAccount);
502  else
503  gnc_tree_view_account_set_selected_account(picker->account_tree, picker->default_account);
504 
505  /*FIXME: DEBUG("WRITEME: Here we should check if an account type is compatible, currency matches, etc.\n"); */
506 
507  /*DEBUG("Return value: %p%s%s%s",picker->retAccount,", account name:",xaccAccountGetName(picker->retAccount),"\n");*/
508  retval_name = picker->retAccount ? xaccAccountGetName(picker->retAccount) : NULL;
509  LEAVE("Selected account %p, %s", picker->retAccount, retval_name ? retval_name : "(null)");
510  return picker->retAccount;
511 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
Definition: Account.c:2979
#define ENTER(format, args...)
Definition: qoflog.h:261
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
void gnc_tree_view_account_set_selected_account(GncTreeViewAccount *view, Account *account)
#define LEAVE(format, args...)
Definition: qoflog.h:271
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
const char * xaccAccountGetTypeStr(GNCAccountType type)
Definition: Account.c:4137
gboolean gnc_import_exists_online_id ( Transaction trans)

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

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

1162 {
1163  gboolean online_id_exists = FALSE;
1164  Account *dest_acct;
1165  Split *source_split;
1166 
1167  /* Look for an online_id in the first split */
1168  source_split = xaccTransGetSplit(trans, 0);
1169  g_assert(source_split);
1170 
1171  /* DEBUG("%s%d%s","Checking split ",i," for duplicates"); */
1172  dest_acct = xaccSplitGetAccount(source_split);
1173  online_id_exists = xaccAccountForEachTransaction(dest_acct,
1174  check_trans_online_id,
1175  source_split);
1176 
1177  /* If it does, abort the process for this transaction, since it is
1178  already in the system. */
1179  if (online_id_exists == TRUE)
1180  {
1181  DEBUG("%s", "Transaction with same online ID exists, destroying current transaction");
1182  xaccTransDestroy(trans);
1183  xaccTransCommitEdit(trans);
1184  }
1185  return online_id_exists;
1186 }
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
Definition: Account.c:4996
Split * xaccTransGetSplit(const Transaction *trans, int i)
Definition: Transaction.c:2144
#define DEBUG(format, args...)
Definition: qoflog.h:255
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
void gnc_import_find_split_matches ( GNCImportTransInfo trans_info,
gint  process_threshold,
double  fuzzy_amount_difference,
gint  match_date_hardlimit 
)

/brief Iterate through all splits of the originating account of the given transaction, and find all matching splits there.

Iterate through all splits of the originating account of the given transaction, find all matching splits there, and store them in the GNCImportTransInfo structure.

Parameters
trans_infoThe TransInfo for which the corresponding matching existing transactions should be found.
process_thresholdEach match whose heuristics are smaller than this value is totally ignored.
fuzzy_amount_differenceFor fuzzy amount matching, a certain fuzzyness in the matching amount is allowed up to this value. May be e.g. 3.00 dollars for ATM fees, or 0.0 if you only want to allow exact matches.
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 842 of file import-backend.c.

846 {
847  GList * list_element;
848  Query *query = qof_query_create_for(GNC_ID_SPLIT);
849  g_assert (trans_info);
850 
851  /* Get list of splits of the originating account. */
852  {
853  /* We used to traverse *all* splits of the account by using
854  xaccAccountGetSplitList, which is a bad idea because 90% of these
855  splits are outside the date range that is interesting. We should
856  rather use a query according to the date region, which is
857  implemented here.
858  */
859  Account *importaccount =
861  time64 download_time = xaccTransGetDate (gnc_import_TransInfo_get_trans (trans_info));
862 
863  qof_query_set_book (query, gnc_get_current_book());
864  xaccQueryAddSingleAccountMatch (query, importaccount,
865  QOF_QUERY_AND);
866  xaccQueryAddDateMatchTT (query,
867  TRUE, download_time - match_date_hardlimit * 86400,
868  TRUE, download_time + match_date_hardlimit * 86400,
869  QOF_QUERY_AND);
870  list_element = qof_query_run (query);
871  /* Sigh. Doesnt help too much. We still create and run one query
872  for each imported transaction. Maybe it would improve
873  performance further if there is one single (master-)query at
874  the beginning, matching the full date range and all accounts in
875  question. However, this doesnt quite work because this function
876  here is called from each gnc_gen_trans_list_add_trans(), which
877  is called one at a time. Therefore the whole importer would
878  have to change its behaviour: Accept the imported txns via
879  gnc_gen_trans_list_add_trans(), and only when
880  gnc_gen_trans_list_run() is called, then calculate all the
881  different match candidates. That's too much work for now.
882  */
883  }
884 
885  /* Traverse that list, calling split_find_match on each one. Note
886  that xaccAccountForEachSplit is declared in Account.h but
887  implemented nowhere :-( */
888  while (list_element != NULL)
889  {
890  split_find_match (trans_info, list_element->data,
891  process_threshold, fuzzy_amount_difference);
892  list_element = g_list_next (list_element);
893  }
894 
895  qof_query_destroy (query);
896 }
time64 xaccTransGetDate(const Transaction *trans)
Definition: Transaction.c:2215
Split * gnc_import_TransInfo_get_fsplit(const GNCImportTransInfo *info)
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
void qof_query_destroy(QofQuery *q)
void qof_query_set_book(QofQuery *q, QofBook *book)
GList * qof_query_run(QofQuery *query)
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gint64 time64
Definition: gnc-date.h:83
void gnc_import_match_picker_run_and_close ( GNCImportTransInfo transaction_info)

Run a match_picker dialog 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.

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.

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
transaction_infoThe TransInfo for which the user is supposed to pick a matching transaction.

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

444 {
445  GNCImportMatchPicker *matcher;
446  gint response;
447  GNCImportMatchInfo *old;
448  g_assert (transaction_info);
449 
450  /* Create a new match_picker, even though it's stored in a
451  transmatcher struct :-) */
452  matcher = g_new0(GNCImportMatchPicker, 1);
453  /* DEBUG("Init match_picker"); */
454  init_match_picker_gui(matcher);
455 
456  /* Append this single transaction to the view and select it */
457  downloaded_transaction_append(matcher, transaction_info);
458 
459  old = gnc_import_TransInfo_get_selected_match(transaction_info);
460 
461  /* Let this dialog run and close. */
462  /*DEBUG("Right before run and close");*/
463  gtk_window_set_modal(GTK_WINDOW(matcher->transaction_matcher), TRUE);
464  response = gtk_dialog_run (GTK_DIALOG (matcher->transaction_matcher));
465  gnc_save_window_size(GNC_PREFS_GROUP,
466  GTK_WINDOW (matcher->transaction_matcher));
467  gtk_widget_destroy (matcher->transaction_matcher);
468  /*DEBUG("Right after run and close");*/
469  /* DEBUG("Response was %d.", response); */
470  if (response == GTK_RESPONSE_OK && matcher->selected_match_info != old)
471  {
472  /* OK was pressed */
473  gnc_import_TransInfo_set_selected_match (transaction_info,
474  matcher->selected_match_info,
475  TRUE);
476  }
477 }
void gnc_import_TransInfo_set_selected_match(GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match(const GNCImportTransInfo *info)
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 277 of file import-backend.c.

278 {
279  if (info)
280  {
281  return info->probability;
282  }
283  else
284  {
285  return 0;
286  }
287 }
Split * gnc_import_MatchInfo_get_split ( const GNCImportMatchInfo info)

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

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

271 {
272  g_assert (info);
273  return info->split;
274 }
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 succesful 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 905 of file import-backend.c.

907 {
908  Split * other_split;
909  gnc_numeric imbalance_value;
910 
911  /* DEBUG("Begin"); */
912 
913  g_assert (trans_info);
914  /*DEBUG("Iteration %d, action %d, split %s", i,
915  trans_info->action,
916  xaccTransGetDescription (gnc_import_TransInfo_get_trans
917  (trans_info)))*/
918  switch (gnc_import_TransInfo_get_action (trans_info))
919  {
920  case GNCImport_SKIP:
921  return FALSE;
922  case GNCImport_ADD:
923  /* Transaction gets imported. */
924 
925  /* Is the transaction not balanced and there is a non-NULL destination account? */
926  if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE
927  && gnc_import_TransInfo_get_destacc(trans_info) != NULL)
928  {
929  /* Create the 'other' split. */
930  Split *split =
932  (gnc_account_get_book
933  (gnc_import_TransInfo_get_destacc (trans_info)));
935  (gnc_import_TransInfo_get_trans (trans_info), split);
937  (gnc_import_TransInfo_get_destacc (trans_info), split);
938  /*xaccSplitSetBaseValue
939  (split,
940  gnc_numeric_neg(xaccTransGetImbalance
941  (gnc_import_TransInfo_get_trans (trans_info))),
942  xaccTransGetCurrency
943  (gnc_import_TransInfo_get_trans (trans_info)));*/
944  {
945  /* This is a quick workaround for the bug described in
946  http://gnucash.org/pipermail/gnucash-devel/2003-August/009982.html
947  Assume that importers won't create transactions involving two or more
948  currencies so we can use xaccTransGetImbalanceValue. */
949  imbalance_value =
951  (gnc_import_TransInfo_get_trans (trans_info)));
952  xaccSplitSetValue (split, imbalance_value);
953  xaccSplitSetAmount (split, imbalance_value);
954  }
955  /*xaccSplitSetMemo (split, _("Auto-Balance split"));
956  -- disabled due to popular request */
957  }
958 
960  /*Set reconcile date to today*/
962  gnc_time (NULL));
963  /* Done editing. */
965  return TRUE;
966  case GNCImport_UPDATE:
967  {
968  GNCImportMatchInfo *selected_match =
970 
971  /* If there is no selection, ignore this transaction. */
972  if (!selected_match)
973  {
974  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
975  break;
976  }
977 
978  /* Transaction gets not imported but the matching one gets
979  updated and reconciled. */
980  if (gnc_import_MatchInfo_get_split(selected_match) == NULL)
981  {
982  PERR("The split I am trying to update and reconcile is NULL, shouldn't happen!");
983  }
984  else
985  {
986  /* Update and reconcile the matching transaction */
987  /*DEBUG("BeginEdit selected_match")*/
988  xaccTransBeginEdit(selected_match->trans);
989 
990  xaccTransSetDatePostedSecsNormalized(selected_match->trans,
992  gnc_import_TransInfo_get_fsplit(trans_info))));
993 
994  xaccSplitSetAmount(selected_match->split,
996  gnc_import_TransInfo_get_fsplit(trans_info)));
997  xaccSplitSetValue(selected_match->split,
999  gnc_import_TransInfo_get_fsplit(trans_info)));
1000 
1001  imbalance_value = xaccTransGetImbalanceValue(
1002  gnc_import_TransInfo_get_trans(trans_info));
1003  other_split = xaccSplitGetOtherSplit(selected_match->split);
1004  if (!gnc_numeric_zero_p(imbalance_value) && other_split)
1005  {
1006  if (xaccSplitGetReconcile(other_split) == NREC)
1007  {
1008  imbalance_value = gnc_numeric_neg(imbalance_value);
1009  xaccSplitSetValue(other_split, imbalance_value);
1010  xaccSplitSetAmount(other_split, imbalance_value);
1011  }
1012  /* else GC will automatically insert a split to equity
1013  to balance the transaction */
1014  }
1015 
1016  xaccTransSetDescription(selected_match->trans,
1018  gnc_import_TransInfo_get_trans(trans_info)));
1019 
1020  if (xaccSplitGetReconcile(selected_match->split) == NREC)
1021  {
1022  xaccSplitSetReconcile(selected_match->split, CREC);
1023  }
1024 
1025  /* Set reconcile date to today */
1026  xaccSplitSetDateReconciledSecs(selected_match->split, gnc_time (NULL));
1027 
1028  /* Copy the online id to the reconciled transaction, so
1029  the match will be remembered */
1030  if (gnc_import_split_has_online_id(trans_info->first_split))
1031  {
1032  gnc_import_set_split_online_id(selected_match->split,
1033  gnc_import_get_split_online_id(trans_info->first_split));
1034  }
1035 
1036  /* Done editing. */
1037  /*DEBUG("CommitEdit selected_match")*/
1038  xaccTransCommitEdit(selected_match->trans);
1039 
1040  /* Store the mapping to the other account in the MatchMap. */
1041  matchmap_store_destination(matchmap, trans_info, TRUE);
1042 
1043  /* Erase the downloaded transaction */
1044  xaccTransDestroy(trans_info->trans);
1045  /*DEBUG("CommitEdit trans")*/
1046  xaccTransCommitEdit(trans_info->trans);
1047  /* Very important: Make sure the freed transaction is not freed again! */
1048  trans_info->trans = NULL;
1049  }
1050  }
1051  return TRUE;
1052  case GNCImport_CLEAR:
1053  {
1054  GNCImportMatchInfo *selected_match =
1056 
1057  /* If there is no selection, ignore this transaction. */
1058  if (!selected_match)
1059  {
1060  PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored.");
1061  break;
1062  }
1063 
1064  /* Transaction gets not imported but the matching one gets
1065  reconciled. */
1066  if (gnc_import_MatchInfo_get_split (selected_match) == NULL)
1067  {
1068  PERR("The split I am trying to reconcile is NULL, shouldn't happen!");
1069  }
1070  else
1071  {
1072  /* Reconcile the matching transaction */
1073  /*DEBUG("BeginEdit selected_match")*/
1074  xaccTransBeginEdit(selected_match->trans);
1075 
1077  (selected_match->split) == NREC)
1079  (selected_match->split, CREC);
1080  /* Set reconcile date to today */
1082  (selected_match->split, gnc_time (NULL));
1083 
1084  /* Copy the online id to the reconciled transaction, so
1085  the match will be remembered */
1086  if (gnc_import_split_has_online_id(trans_info->first_split))
1087  gnc_import_set_split_online_id
1088  (selected_match->split,
1089  gnc_import_get_split_online_id(trans_info->first_split));
1090 
1091  /* Done editing. */
1092  /*DEBUG("CommitEdit selected_match")*/
1094  (selected_match->trans);
1095 
1096  /* Store the mapping to the other account in the MatchMap. */
1097  matchmap_store_destination (matchmap, trans_info, TRUE);
1098 
1099  /* Erase the downloaded transaction */
1100  xaccTransDestroy(trans_info->trans);
1101  /*DEBUG("CommitEdit trans")*/
1102  xaccTransCommitEdit(trans_info->trans);
1103  /* Very important: Make sure the freed transaction is not freed again! */
1104  trans_info->trans = NULL;
1105  }
1106  }
1107  return TRUE;
1108  default:
1109  DEBUG("Invalid GNCImportAction for this imported transaction.");
1110  break;
1111  }
1112  /*DEBUG("End");*/
1113  return FALSE;
1114 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
#define xaccTransAppendSplit(t, s)
Definition: Transaction.h:357
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
Definition: Transaction.c:1920
time64 xaccTransGetDate(const Transaction *trans)
Definition: Transaction.c:2215
gnc_numeric gnc_numeric_neg(gnc_numeric a)
#define DEBUG(format, args...)
Definition: qoflog.h:255
char xaccSplitGetReconcile(const Split *split)
Definition: Split.c:1980
Split * gnc_import_TransInfo_get_fsplit(const GNCImportTransInfo *info)
void xaccTransSetDescription(Transaction *trans, const char *desc)
Definition: Transaction.c:2085
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
gboolean gnc_numeric_zero_p(gnc_numeric a)
void xaccSplitSetReconcile(Split *split, char recn)
Definition: Split.c:1826
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
#define PERR(format, args...)
Definition: qoflog.h:237
GNCImportAction gnc_import_TransInfo_get_action(const GNCImportTransInfo *info)
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
#define PWARN(format, args...)
Definition: qoflog.h:243
Split * gnc_import_MatchInfo_get_split(const GNCImportMatchInfo *info)
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
Definition: Split.c:1258
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
Definition: Transaction.c:1036
const char * xaccTransGetDescription(const Transaction *trans)
Definition: Transaction.c:2184
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define CREC
Definition: Split.h:67
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
void xaccSplitSetDateReconciledSecs(Split *split, time64 secs)
Definition: Split.c:1852
Definition: SplitP.h:71
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
#define xaccAccountInsertSplit(acc, s)
Definition: Account.h:972
Split * xaccSplitGetOtherSplit(const Split *split)
Definition: Split.c:2086
Account * gnc_import_TransInfo_get_destacc(const GNCImportTransInfo *info)
time64 gnc_time(time64 *tbuf)
get the current local time
GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match(const GNCImportTransInfo *info)
gboolean gnc_import_TransInfo_is_balanced(const GNCImportTransInfo *info)
#define NREC
Definition: Split.h:70
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
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 kvp_frame 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's kvp_frame, 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 kvp_frame 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 224 of file import-account-matcher.c.

232 {
233 #define ACCOUNT_DESCRIPTION_MAX_SIZE 255
234  AccountPickerDialog * picker;
235  gint response;
236  Account * retval = NULL;
237  const gchar *retval_name = NULL;
238  GtkBuilder *builder;
239  GtkWidget * online_id_label, *button, *box, *pbox;
240  gchar account_description_text[ACCOUNT_DESCRIPTION_MAX_SIZE] = "";
241  gboolean ok_pressed_retval = FALSE;
242 
243  ENTER("Default commodity received: %s", gnc_commodity_get_fullname( new_account_default_commodity));
244  DEBUG("Default account type received: %s", xaccAccountGetTypeStr( new_account_default_type));
245  picker = g_new0(AccountPickerDialog, 1);
246 
247  picker->account_online_id_value = account_online_id_value;
248  picker->account_human_description = account_human_description;
249  picker->new_account_default_commodity = new_account_default_commodity;
250  picker->new_account_default_type = new_account_default_type;
251 
252  /*DEBUG("Looking for account with online_id: \"%s\"", account_online_id_value);*/
253  if (account_online_id_value != NULL)
254  {
255  retval =
256  gnc_account_foreach_descendant_until(gnc_get_current_root_account (),
257  test_acct_online_id_match,
258  /* This argument will only be used as a "const char*" */
259  (void*)account_online_id_value);
260 
261  /* BEGIN: try again without extra space at the end */
262  /*
263  * libofx, used for file import, generates online_id as
264  * ACCTID + space + ACCTKEY which differs from the online_id
265  * generated by aqbanking for online ofx transfer as ACCTID.
266  *
267  * If a gnucash account has been associated with an online_id
268  * via aqbanking data, it is not possible to construct an OFX
269  * file for gnucash import that matches the same online_id
270  * because even with no ACCTKEY in the file, there will be a
271  * trailing space.
272  *
273  * This is a hack to overcome that problem.
274  */
275  if ((retval == NULL) && g_str_has_suffix(account_online_id_value, " "))
276  {
277  gchar *trimmed = g_strndup(account_online_id_value, strlen(account_online_id_value) - 1);
278  if (trimmed)
279  {
281  gnc_get_current_root_account (),
282  test_acct_online_id_match,
283  (void *)trimmed);
284  }
285  g_free(trimmed);
286  }
287  /* END: try again without extra space at the end */
288  }
289  if (retval == NULL && auto_create != 0)
290  {
291  /* load the interface */
292  builder = gtk_builder_new();
293  gnc_builder_add_from_file (builder, "dialog-import.glade", "account_picker");
294  gnc_builder_add_from_file (builder, "dialog-import.glade", "account_picker_content");
295  /* connect the signals in the interface */
296  if (builder == NULL)
297  {
298  PERR("Error opening the glade builder interface");
299  }
300  picker->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker"));
301  if (parent)
302  gtk_window_set_transient_for (GTK_WINDOW (picker->dialog),
303  GTK_WINDOW (parent));
304 
305  /* Pack the content into the dialog vbox */
306  pbox = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker_vbox"));
307  box = GTK_WIDGET(gtk_builder_get_object (builder, "account_picker_content"));
308  gtk_box_pack_start( GTK_BOX(pbox), box, TRUE, TRUE, 0);
309 
310  picker->account_tree_sw = GTK_WIDGET(gtk_builder_get_object (builder, "account_tree_sw"));
311  online_id_label = GTK_WIDGET(gtk_builder_get_object (builder, "online_id_label"));
312  button = GTK_WIDGET(gtk_builder_get_object (builder, "newbutton"));
313  gtk_button_set_use_stock (GTK_BUTTON(button), TRUE);
314 
315  //printf("gnc_import_select_account(): Fin get widget\n");
316 
317  if (account_human_description != NULL)
318  {
319  strncat(account_description_text, account_human_description,
320  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
321  strncat(account_description_text, "\n",
322  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
323  }
324  if (account_online_id_value != NULL)
325  {
326  strncat(account_description_text, _("(Full account ID: "),
327  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
328  strncat(account_description_text, account_online_id_value,
329  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
330  strncat(account_description_text, ")",
331  ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text));
332  }
333  gtk_label_set_text((GtkLabel*)online_id_label, account_description_text);
334  build_acct_tree(picker);
335  gnc_tree_view_account_set_selected_account(picker->account_tree, default_selection);
336 
337  gtk_window_set_modal(GTK_WINDOW(picker->dialog), TRUE);
338  g_signal_connect(picker->account_tree, "row-activated",
339  G_CALLBACK(account_tree_row_activated_cb), picker);
340  do
341  {
342  response = gtk_dialog_run(GTK_DIALOG(picker->dialog));
343  switch (response)
344  {
345  case GTK_RESPONSE_OK:
346  retval = gnc_tree_view_account_get_selected_account(picker->account_tree);
347  if (retval)
348  retval_name = xaccAccountGetName(retval);
349  if (!retval_name)
350  retval_name = "(null)";
351  DEBUG("Selected account %p, %s", retval, retval_name);
352 
353  /* See if the selected account is a placeholder. */
354  if (retval && xaccAccountGetPlaceholder (retval))
355  {
356  gnc_error_dialog
357  (picker->dialog,
358  _("The account %s is a placeholder account and does not allow "
359  "transactions. Please choose a different account."),
360  retval_name);
361  response = GNC_RESPONSE_NEW;
362  break;
363  }
364 
365  if ( account_online_id_value != NULL)
366  {
367  gnc_import_set_acc_online_id(retval, account_online_id_value);
368  }
369  ok_pressed_retval = TRUE;
370  break;
371  case GNC_RESPONSE_NEW:
372  gnc_import_add_account(NULL, picker);
373  ok_pressed_retval = TRUE;
374  break;
375  default:
376  ok_pressed_retval = FALSE;
377  break;
378  }
379  }
380  while (response == GNC_RESPONSE_NEW);
381 
382  g_object_unref(G_OBJECT(builder));
383  gtk_widget_destroy(picker->dialog);
384  }
385  else
386  {
387  retval_name = retval ? xaccAccountGetName(retval) : NULL;
388  ok_pressed_retval = TRUE; /* There was no dialog involved, so the computer "pressed" ok */
389  }
390  /*FIXME: DEBUG("WRITEME: gnc_import_select_account() Here we should check if account type is compatible, currency matches, etc.\n"); */
391  g_free(picker);
392  /*DEBUG("Return value: %p%s%s%s",retval,", account name:",xaccAccountGetName(retval),"\n");*/
393  if (ok_pressed != NULL)
394  {
395  *ok_pressed = ok_pressed_retval;
396  }
397  LEAVE("Selected account %p, %s", retval, retval_name ? retval_name : "(null)");
398  return retval;
399 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
Definition: Account.c:2979
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
void gnc_tree_view_account_set_selected_account(GncTreeViewAccount *view, Account *account)
gboolean xaccAccountGetPlaceholder(const Account *acc)
Definition: Account.c:3912
Account * gnc_tree_view_account_get_selected_account(GncTreeViewAccount *view)
#define LEAVE(format, args...)
Definition: qoflog.h:271
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
const char * xaccAccountGetTypeStr(GNCAccountType type)
Definition: Account.c:4137
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 
82 
83  /*Nested loop*/
84  commodity_list = gnc_commodity_table_get_commodities(commodity_table,
85  tmp_namespace);
86  commodity_list = g_list_first(commodity_list);
87  while ( commodity_list != NULL && retval == NULL)
88  {
89  tmp_commodity = commodity_list->data;
90  DEBUG("Looking at commodity %s", gnc_commodity_get_fullname(tmp_commodity));
91 
92  if (gnc_commodity_get_cusip(tmp_commodity) != NULL &&
93  cusip != NULL &&
94  strncmp(gnc_commodity_get_cusip(tmp_commodity), cusip, strlen(cusip)) == 0)
95  {
96  retval = tmp_commodity;
97  DEBUG("Commodity %s%s", gnc_commodity_get_fullname(retval), " matches.");
98  }
99  commodity_list = g_list_next(commodity_list);
100  }
101  /*End nested loop*/
102 
103  namespace_list = g_list_next(namespace_list);
104  }
105 
106 
107 
108 
109  g_list_free(commodity_list);
110  g_list_free(namespace_list);
111 
112  if (retval == NULL && ask_on_unknown != 0)
113  {
114  const gchar *message =
115  _("Please select a commodity to match the following exchange "
116  "specific code. Please note that the exchange code of the "
117  "commodity you select will be overwritten.");
119  NULL,
121  message,
122  cusip,
123  default_fullname,
124  default_mnemonic);
125 
126  }
127  /* There seems to be a problem here - if the matched commodity does not
128  have a cusip defined (gnc_commodity_get_cusip returns NULL) then
129  it does not get overwritten - which is not consistent with the
130  message - so Im adding it to do this. Looks like this is all
131  that was needed to fix the cash value used as stock units problem
132  for pre-defined commodities which didnt have the cusip defined! */
133  if (retval != NULL &&
134  gnc_commodity_get_cusip(retval) != NULL &&
135  cusip != NULL &&
136  (strncmp(gnc_commodity_get_cusip(retval), cusip, strlen(cusip)) != 0))
137  {
138  gnc_commodity_set_cusip(retval, cusip);
139  }
140  else if (gnc_commodity_get_cusip(retval) == NULL && cusip != NULL)
141  {
142  gnc_commodity_set_cusip(retval, cusip);
143  }
144  return retval;
145 };
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
#define DEBUG(format, args...)
Definition: qoflog.h:255
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
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)
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
void gnc_import_Settings_delete ( GNCImportSettings settings)

Destructor

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

107 {
108  if (settings)
109  {
110  g_free(settings);
111  }
112 }
gboolean gnc_import_Settings_get_action_add_enabled ( GNCImportSettings settings)

Return the selected action is enable state.

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

128 {
129  g_assert (settings);
130  return settings->action_add_enabled;
131 };
gboolean gnc_import_Settings_get_action_clear_enabled ( GNCImportSettings settings)

Return the selected action is enable state.

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

140 {
141  g_assert (settings);
142  return settings->action_clear_enabled;
143 };
gboolean gnc_import_Settings_get_action_skip_enabled ( GNCImportSettings settings)

Return the selected action is enable state.

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

122 {
123  g_assert (settings);
124  return settings->action_skip_enabled;
125 };
gboolean gnc_import_Settings_get_action_update_enabled ( GNCImportSettings settings)

Return the selected action is enable state.

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

134 {
135  g_assert (settings);
136  return settings->action_update_enabled;
137 };
gint gnc_import_Settings_get_add_threshold ( GNCImportSettings settings)

Return the selected threshold.

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

152 {
153  g_assert (settings);
154  return settings->add_threshold;
155 };
gint gnc_import_Settings_get_clear_threshold ( GNCImportSettings settings)

Return the selected threshold.

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

146 {
147  g_assert (settings);
148  return settings->clear_threshold;
149 };
gint gnc_import_Settings_get_display_threshold ( GNCImportSettings settings)

Return the selected threshold.

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

158 {
159  g_assert (settings);
160  return settings->display_threshold;
161 };
double gnc_import_Settings_get_fuzzy_amount ( GNCImportSettings settings)

Return the allowed amount range for fuzzy amount matching.

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

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

116 {
117  g_assert (settings);
118  return settings->fuzzy_amount;
119 };
gint gnc_import_Settings_get_match_date_hardlimit ( const GNCImportSettings settings)

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

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

169 {
170  g_assert(s);
171  return s->match_date_hardlimit;
172 }
GNCImportSettings * gnc_import_Settings_new ( void  )

Allocates a new GNCImportSettings object, and initialize it with the appropriate user prefs.

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

79 {
80  GNCImportSettings * settings;
81 
82  settings = g_new0 ( GNCImportSettings, 1);
83 
84 
85  settings->action_skip_enabled =
86  gnc_prefs_get_bool (GNC_PREFS_GROUP_IMPORT, GNC_PREF_ENABLE_SKIP);
87  settings->action_update_enabled =
88  gnc_prefs_get_bool (GNC_PREFS_GROUP_IMPORT, GNC_PREF_ENABLE_UPDATE);
89  settings->action_add_enabled = DEFAULT_ACTION_ADD_ENABLED;
90  settings->action_clear_enabled = DEFAULT_ACTION_CLEAR_ENABLED;
91  settings->clear_threshold =
92  (int)gnc_prefs_get_float (GNC_PREFS_GROUP_IMPORT, GNC_PREF_AUTO_CLEAR_THRESHOLD);
93  settings->add_threshold =
94  (int)gnc_prefs_get_float (GNC_PREFS_GROUP_IMPORT, GNC_PREF_AUTO_ADD_THRESHOLD);
95  settings->display_threshold =
96  (int)gnc_prefs_get_float (GNC_PREFS_GROUP_IMPORT, GNC_PREF_MATCH_THRESHOLD);
97 
98  settings->fuzzy_amount =
99  gnc_prefs_get_float (GNC_PREFS_GROUP_IMPORT, GNC_PREF_ATM_FEE_THRESHOLD);
100 
101  settings->match_date_hardlimit = 42; /* 6 weeks */
102  return settings;
103 }
#define GNC_PREFS_GROUP_IMPORT
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:227
void gnc_import_Settings_set_match_date_hardlimit ( GNCImportSettings settings,
gint  match_date_hardlimit 
)
Parameters
match_date_hardlimitThe number of days that a matching split may differ from the given transaction before it is discarded immediately. In other words, any split that is more distant from the given transaction than this match_date_hardlimit days will be ignored altogether. For use cases without paper checks (e.g. HBCI), values like 14 (days) might be appropriate, whereas for use cases with paper checks (e.g. OFX, QIF), values like 42 (days) seem more appropriate.

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

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

Destructor

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

290 {
291  if (info)
292  {
293  g_list_free (info->match_list);
294  /*If the transaction exists and is still open, it must be destroyed*/
295  if (info->trans && xaccTransIsOpen(info->trans))
296  {
297  xaccTransDestroy(info->trans);
298  xaccTransCommitEdit(info->trans);
299  }
300  if (info->match_tokens)
301  {
302  GList *node;
303 
304  for (node = info->match_tokens; node; node = node->next)
305  g_free (node->data);
306 
307  g_list_free (info->match_tokens);
308  }
309  g_free(info);
310  }
311 }
gboolean xaccTransIsOpen(const Transaction *trans)
Definition: Transaction.c:1819
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
GNCImportAction gnc_import_TransInfo_get_action ( const GNCImportTransInfo info)

Returns the currently selected action for this TransInfo.

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

208 {
209  g_assert (info);
210  return info->action;
211 }
Account * gnc_import_TransInfo_get_destacc ( const GNCImportTransInfo info)

Returns the 'other account' of this transaction. May return NULL.

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

227 {
228  g_assert (info);
229  return info->dest_acc;
230 }
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 247 of file import-backend.c.

248 {
249  g_assert (info);
250  return info->dest_acc_selected_manually;
251 }
Split * gnc_import_TransInfo_get_fsplit ( const GNCImportTransInfo info)

Returns the first split of the transaction of this TransInfo.

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

177 {
178  g_assert (info);
179  return info->first_split;
180 }
GList * gnc_import_TransInfo_get_match_list ( const GNCImportTransInfo info)

Returns the stored list of possible matches.

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

146 {
147  g_assert (info);
148  return info->match_list;
149 }
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 200 of file import-backend.c.

201 {
202  g_assert (info);
203  return info->match_selected_manually;
204 }
guint32 gnc_import_TransInfo_get_ref_id ( const GNCImportTransInfo info)

Returns the reference id for this TransInfo.

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

255 {
256  g_assert (info);
257  return info->ref_id;
258 }
GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match ( const GNCImportTransInfo info)

Returns the currently selected match in this TransInfo.

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

184 {
185  g_assert (info);
186  return info->selected_match_info;
187 }
Transaction * gnc_import_TransInfo_get_trans ( const GNCImportTransInfo info)

Returns the transaction of this TransInfo.

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

153 {
154  g_assert (info);
155  return info->trans;
156 }
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.

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.

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

1232 {
1233  GNCImportMatchInfo * best_match = NULL;
1234  g_assert (trans_info);
1235 
1236 
1237  /* Find all split matches in originating account. */
1238  gnc_import_find_split_matches(trans_info,
1242 
1243  if (trans_info->match_list != NULL)
1244  {
1245  trans_info->match_list = g_list_sort(trans_info->match_list,
1246  compare_probability);
1247  best_match = g_list_nth_data(trans_info->match_list, 0);
1249  best_match,
1250  FALSE);
1251  if (best_match != NULL &&
1252  best_match->probability >= gnc_import_Settings_get_clear_threshold(settings))
1253  {
1254  trans_info->action = GNCImport_CLEAR;
1255  trans_info->selected_match_info = best_match;
1256  }
1257  else if (best_match == NULL ||
1258  best_match->probability <= gnc_import_Settings_get_add_threshold(settings))
1259  {
1260  trans_info->action = GNCImport_ADD;
1261  }
1263  {
1264  trans_info->action = GNCImport_SKIP;
1265  }
1267  {
1268  trans_info->action = GNCImport_UPDATE;
1269  }
1270  else
1271  {
1272  trans_info->action = GNCImport_ADD;
1273  }
1274  }
1275  else
1276  {
1277  trans_info->action = GNCImport_ADD;
1278  }
1279  if (best_match &&
1280  trans_info->action == GNCImport_CLEAR &&
1282  {
1283  if (best_match->update_proposed)
1284  {
1285  trans_info->action = GNCImport_UPDATE;
1286  }
1287  }
1288 
1289  trans_info->previous_action = trans_info->action;
1290 }
gint gnc_import_Settings_get_match_date_hardlimit(const GNCImportSettings *s)
gint gnc_import_Settings_get_clear_threshold(GNCImportSettings *settings)
gint gnc_import_Settings_get_display_threshold(GNCImportSettings *settings)
void gnc_import_TransInfo_set_selected_match(GNCImportTransInfo *info, GNCImportMatchInfo *match, gboolean selected_manually)
double gnc_import_Settings_get_fuzzy_amount(GNCImportSettings *settings)
void gnc_import_find_split_matches(GNCImportTransInfo *trans_info, gint process_threshold, double fuzzy_amount_difference, gint match_date_hardlimit)
gboolean gnc_import_Settings_get_action_update_enabled(GNCImportSettings *settings)
gboolean gnc_import_Settings_get_action_skip_enabled(GNCImportSettings *settings)
gint gnc_import_Settings_get_add_threshold(GNCImportSettings *settings)
gboolean gnc_import_TransInfo_is_balanced ( const GNCImportTransInfo info)

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

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

160 {
161  g_assert (info);
162  /* Assume that the importer won't create a transaction that involves two or more
163  currencies and no non-currency commodity. In that case can use the simpler
164  value imbalance check. */
166  {
167  return TRUE;
168  }
169  else
170  {
171  return FALSE;
172  }
173 }
Transaction * gnc_import_TransInfo_get_trans(const GNCImportTransInfo *info)
gboolean gnc_numeric_zero_p(gnc_numeric a)
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
Definition: Transaction.c:1036
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 1194 of file import-backend.c.

1195 {
1196  GNCImportTransInfo *transaction_info;
1197  Split *split;
1198  g_assert (trans);
1199 
1200  transaction_info = g_new0(GNCImportTransInfo, 1);
1201 
1202  transaction_info->trans = trans;
1203  /* Only use first split, the source split */
1204  split = xaccTransGetSplit(trans, 0);
1205  g_assert(split);
1206  transaction_info->first_split = split;
1207 
1208  /* Try to find a previously selected destination account
1209  string match for the ADD action */
1210  gnc_import_TransInfo_set_destacc (transaction_info,
1211  matchmap_find_destination (matchmap, transaction_info),
1212  FALSE);
1213  return transaction_info;
1214 }
Split * xaccTransGetSplit(const Transaction *trans, int i)
Definition: Transaction.c:2144
void gnc_import_TransInfo_set_destacc(GNCImportTransInfo *info, Account *acc, gboolean selected_manually)
Definition: SplitP.h:71
gboolean gnc_import_TransInfo_refresh_destacc ( GNCImportTransInfo transaction_info,
GncImportMatchMap matchmap 
)

Try to automatch a given transaction to a destination account

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

1298 {
1299  Account *orig_destacc;
1300  Account *new_destacc = NULL;
1301  g_assert(transaction_info);
1302 
1303  orig_destacc = gnc_import_TransInfo_get_destacc(transaction_info);
1304 
1305  /* if we haven't manually selected a destination account for this transaction */
1306  if (gnc_import_TransInfo_get_destacc_selected_manually(transaction_info) == FALSE)
1307  {
1308  /* Try to find the destination account for this transaction based on prior ones */
1309  new_destacc = matchmap_find_destination(matchmap, transaction_info);
1310  gnc_import_TransInfo_set_destacc(transaction_info, new_destacc, FALSE);
1311  }
1312  else
1313  {
1314  new_destacc = orig_destacc;
1315  }
1316 
1317  /* account has changed */
1318  if (new_destacc != orig_destacc)
1319  {
1320  return TRUE;
1321  }
1322  else /* account is the same */
1323  {
1324  return FALSE;
1325  }
1326 }
void gnc_import_TransInfo_set_destacc(GNCImportTransInfo *info, Account *acc, gboolean selected_manually)
Account * gnc_import_TransInfo_get_destacc(const GNCImportTransInfo *info)
gboolean gnc_import_TransInfo_get_destacc_selected_manually(const GNCImportTransInfo *info)
void gnc_import_TransInfo_set_action ( GNCImportTransInfo info,
GNCImportAction  action 
)

Set the action for this TransInfo. Also sets the previous action.

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

216 {
217  g_assert (info);
218  if (action != info->action)
219  {
220  info->previous_action = info->action;
221  info->action = action;
222  }
223 }
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 231 of file import-backend.c.

234 {
235  g_assert (info);
236  info->dest_acc = acc;
237  info->dest_acc_selected_manually = selected_manually;
238 
239  /* Store the mapping to the other account in the MatchMap. */
240  if (selected_manually)
241  {
242  matchmap_store_destination (NULL, info, FALSE);
243  }
244 }
void gnc_import_TransInfo_set_ref_id ( GNCImportTransInfo info,
guint32  ref_id 
)

Set the reference id for this TransInfo.

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

263 {
264  g_assert (info);
265  info->ref_id = ref_id;
266 }
void gnc_import_TransInfo_set_selected_match ( 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 190 of file import-backend.c.

193 {
194  g_assert (info);
195  info->selected_match_info = match;
196  info->match_selected_manually = selected_manually;
197 }
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 217 of file import-main-matcher.c.

218 {
219  GNCImportMainMatcher *info = user_data;
220  GtkBuilder *builder;
221  GtkWidget *help_dialog, *box;
222 
223  builder = gtk_builder_new();
224  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer2");
225  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer3");
226  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer4");
227  gnc_builder_add_from_file (builder, "dialog-import.glade", "textbuffer5");
228  gnc_builder_add_from_file (builder, "dialog-import.glade", "matcher_help");
229 
230  box = GTK_WIDGET(gtk_builder_get_object (builder, "red"));
231  gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_red);
232  box = GTK_WIDGET(gtk_builder_get_object (builder, "yellow"));
233  gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_yellow);
234  box = GTK_WIDGET(gtk_builder_get_object (builder, "green"));
235  gtk_widget_modify_bg(box, GTK_STATE_NORMAL, &info->color_back_green);
236 
237  help_dialog = GTK_WIDGET(gtk_builder_get_object (builder, "matcher_help"));
238  gtk_window_set_transient_for(GTK_WINDOW(help_dialog),
239  GTK_WINDOW(info->dialog));
240 
241  /* Connect the signals */
242  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, help_dialog);
243 
244  g_object_unref(G_OBJECT(builder));
245 
246  gtk_widget_show(help_dialog);
247 }