Data Structures | |
| struct | _accountpickerdialog |
| struct | _transactioninfo |
| struct | _matchinfo |
| struct | _main_matcher_info |
| struct | _GncImportMatchMap |
| struct | account_token_count |
| struct | token_accounts_info |
| struct | account_probability |
| struct | account_info |
| struct | _transpickerdialog |
| struct | _genimportsettings |
| struct | _split_record |
Modules | |
| Export a chart of accounts. | |
| AqBanking | |
Files | |
| file | import-account-matcher.h |
| Generic and very flexible account matcher/picker. | |
| 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-map.h |
| Generic import mapper service, maps strings->accounts. | |
| 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. | |
Defines | |
| #define | GCONF_SECTION "dialogs/import/generic_matcher/account_matcher" |
| #define | GCONF_SECTION "dialogs/import/generic_matcher" |
| #define | BAYES_OPTION "use_bayes" |
| #define | GCONF_SECTION "dialogs/import/generic_matcher/transaction_list" |
| #define | COLOR_RED "brown1" |
| #define | COLOR_YELLOW "gold" |
| #define | COLOR_GREEN "DarkSeaGreen1" |
| #define | IMAP_FRAME "import-map" |
| #define | IMAP_FRAME_BAYES "import-map-bayes" |
| #define | PROBABILITY_FACTOR 100000 |
| #define | threshold (.90 * PROBABILITY_FACTOR) |
| #define | GCONF_SECTION "dialogs/import/generic_matcher/match_picker" |
| #define | GCONF_SECTION "dialogs/import/generic_matcher" |
| #define | GCONF_SECTION "dialogs/log_replay" |
| #define | STRING_FIELD_SIZE 256 |
| #define | GCONF_SECTION "dialogs/import/ofx" |
Typedefs | |
| typedef struct _transactioninfo | GNCImportTransInfo |
| typedef struct _matchinfo | GNCImportMatchInfo |
| typedef enum _action | GNCImportAction |
| typedef struct _main_matcher_info | GNCImportMainMatcher |
| typedef struct _GncImportMatchMap | GncImportMatchMap |
| typedef struct _transpickerdialog | GNCImportMatchPicker |
| typedef struct _genimportsettings | GNCImportSettings |
| typedef struct _split_record | split_record |
Enumerations | |
| enum | _action { GNCImport_SKIP, GNCImport_ADD, GNCImport_CLEAR, GNCImport_EDIT, 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_EDIT, 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_EDIT, 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_gnc_module_path (void) |
| char * | libgncmod_csv_gnc_module_description (void) |
| int | libgncmod_csv_gnc_module_init (int refcount) |
| int | libgncmod_csv_gnc_module_end (int refcount) |
| void | gnc_file_aqbanking_import (const gchar *aqbanking_importername, const gchar *aqbanking_profilename, gboolean execute_transactions) |
| Account * | gnc_import_select_account (gncUIWidget parent, const gchar *account_online_id_value, gboolean auto_create, const gchar *account_human_description, gnc_commodity *new_account_default_commodity, GNCAccountType new_account_default_type, Account *default_selection, gboolean *ok_pressed) |
| gnc_commodity * | gnc_import_select_commodity (char *cusip, char auto_create, char *default_fullname, char *default_mnemonic) |
| void | gnc_gen_trans_list_delete (GNCImportMainMatcher *info) |
| GNCImportMainMatcher * | gnc_gen_trans_list_new (GtkWidget *parent, const gchar *heading, gboolean all_from_same_account, gint match_date_hardlimit) |
| gboolean | gnc_gen_trans_list_run (GNCImportMainMatcher *info) |
| void | gnc_gen_trans_list_add_trans (GNCImportMainMatcher *gui, Transaction *trans) |
| void | gnc_imap_destroy (GncImportMatchMap *imap) |
| void | gnc_imap_clear (GncImportMatchMap *imap) |
| Account * | gnc_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) |
| Account * | gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) |
| void | gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList *tokens, Account *acc) |
| void | gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info) |
| GNCImportSettings * | gnc_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 | 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) |
| double | ofx_get_investment_amount (struct OfxTransactionData 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_gnc_module_system_interface = 0 |
| int | libgncmod_csv_gnc_module_current = 0 |
| int | libgncmod_csv_gnc_module_revision = 0 |
| int | libgncmod_csv_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 |
| GNCImportMainMatcher * | gnc_ofx_importer_gui = 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 |
| #define PROBABILITY_FACTOR 100000 |
convert a hash table of account names and (struct account_probability*) into a hash table of 100000x the percentage match value, ie. 10% would be 0.10 * 100000 = 10000
Definition at line 226 of file import-match-map.c.
| 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
| score | The score for which to generate a pixmap. | |
| settings | The user settings from which to get the threshold | |
| widget | The parent widget in which the pixmap will eventually be added. Will be used to generate the colormap. |
Definition at line 260 of file import-backend.c.
00261 { 00262 GdkPixbuf* retval = NULL; 00263 gint i, j; 00264 gint score; 00265 const gint height = 15; 00266 const gint width_each_bar = 7; 00267 gchar * green_bar = ("bggggb "); 00268 gchar * yellow_bar = ("byyyyb "); 00269 gchar * red_bar = ("brrrrb "); 00270 gchar * black_bar = ("bbbbbb "); 00271 const gint width_first_bar = 1; 00272 gchar * black_first_bar = ("b"); 00273 const gint num_colors = 5; 00274 gchar * size_str; 00275 gchar * none_color_str = g_strdup_printf(" c None"); 00276 gchar * green_color_str = g_strdup_printf("g c green"); 00277 gchar * yellow_color_str = g_strdup_printf("y c yellow"); 00278 gchar * red_color_str = g_strdup_printf("r c red"); 00279 gchar * black_color_str = g_strdup_printf("b c black"); 00280 gchar * xpm[2+num_colors+height]; 00281 gint add_threshold, clear_threshold; 00282 00283 g_assert(settings); 00284 g_assert(widget); 00285 if (score_original < 0) 00286 { 00287 score = 0; 00288 } 00289 else 00290 { 00291 score = score_original; 00292 } 00293 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*/); 00294 00295 /*DEBUG("Begin");*/ 00296 xpm[0] = size_str; 00297 xpm[1] = none_color_str; 00298 xpm[2] = green_color_str; 00299 xpm[3] = yellow_color_str; 00300 xpm[4] = red_color_str; 00301 xpm[5] = black_color_str; 00302 add_threshold = gnc_import_Settings_get_add_threshold(settings); 00303 clear_threshold = gnc_import_Settings_get_clear_threshold(settings); 00304 00305 for (i = 0; i < height; i++) 00306 { 00307 xpm[num_colors+1+i] = g_new0(char, (width_each_bar * score) + width_first_bar + 1); 00308 for (j = 0; j <= score; j++) 00309 { 00310 if (i == 0 || i == height - 1) 00311 { 00312 if (j == 0) 00313 { 00314 strcat(xpm[num_colors+1+i], black_first_bar); 00315 } 00316 else 00317 { 00318 strcat(xpm[num_colors+1+i], black_bar); 00319 } 00320 } 00321 else 00322 { 00323 if (j == 0) 00324 { 00325 strcat(xpm[num_colors+1+i], black_first_bar); 00326 } 00327 else if (j <= add_threshold) 00328 { 00329 strcat(xpm[num_colors+1+i], red_bar); 00330 } 00331 else if (j >= clear_threshold) 00332 { 00333 strcat(xpm[num_colors+1+i], green_bar); 00334 } 00335 else 00336 { 00337 strcat(xpm[num_colors+1+i], yellow_bar); 00338 } 00339 } 00340 } 00341 } 00342 00343 retval = gdk_pixbuf_new_from_xpm_data((const gchar **)xpm); 00344 for (i = 0; i <= num_colors + height; i++) 00345 { 00346 /*DEBUG("free_loop i=%d%s%s",i,": ",xpm[i]);*/ 00347 g_free(xpm[i]); 00348 } 00349 00350 return retval; 00351 }
| void gnc_file_aqbanking_import | ( | const gchar * | aqbanking_importername, | |
| const gchar * | aqbanking_formatname, | |||
| gboolean | exec_as_aqbanking_jobs | |||
| ) |
This routine will pop up a standard file selection dialog asking the user to pick a file to import. This file will be opened and read. Its contents will be imported into the current book, using the import matcher from import-main-matcher.h.
| aqbanking_importername | The aqbanking importer module that should be used. Possible values: "dtaus", "csv", "swift", or more. | |
| aqbanking_formatname | In aqbanking, each importer has one or more data formats available which define the actual data fields that should be used. In aqbanking, such a different format is called a "profile". Possible values for swift: "swift-mt940" or "swift-mt942", but for all others: "default", or more precisely: Look into $datadir/aqbanking/imexporters and look into the "name" field of the foo.conf files. | |
| exec_as_aqbanking_jobs | If TRUE, additionally queue the imported transactions as online jobs over aqbanking/HBCI. If FALSE, just import the transactions and that's it. |
Definition at line 65 of file hbci/gnc-file-aqb-import.c.
00068 { 00069 char *selected_filename; 00070 char *default_dir; 00071 int dtaus_fd; 00072 00073 DEBUG("gnc_file_dtaus_import(): Begin...\n"); 00074 00075 default_dir = gnc_get_default_directory(GCONF_SECTION); 00076 selected_filename = gnc_file_dialog(_("Select a file to import"), 00077 NULL, 00078 default_dir, 00079 GNC_FILE_DIALOG_IMPORT); 00080 g_free(default_dir); 00081 00082 if (selected_filename != NULL) 00083 { 00084 /* Remember the directory as the default. */ 00085 default_dir = g_path_get_dirname(selected_filename); 00086 gnc_set_default_directory(GCONF_SECTION, default_dir); 00087 g_free(default_dir); 00088 00089 /*strncpy(file,selected_filename, 255);*/ 00090 DEBUG("Filename found: %s", selected_filename); 00091 00092 DEBUG("Opening selected file"); 00093 dtaus_fd = g_open(selected_filename, O_RDONLY, 0); 00094 if (dtaus_fd == -1) 00095 { 00096 DEBUG("Could not open file %s", selected_filename); 00097 return; 00098 } 00099 g_free(selected_filename); 00100 00101 { 00102 int result; 00103 AB_BANKING *ab; 00104 AB_IMEXPORTER *importer; 00105 AB_IMEXPORTER_CONTEXT *ctx = 0; 00106 GWEN_BUFFEREDIO *buffio; 00107 GWEN_DB_NODE *dbProfiles; 00108 GWEN_DB_NODE *dbProfile; 00109 GNCInteractor *interactor = NULL; 00110 const char *importerName = aqbanking_importername; 00111 const char *profileName = aqbanking_profilename; 00112 00113 /* Get API */ 00114 ab = gnc_AB_BANKING_new_currentbook (NULL, &interactor); 00115 if (ab == NULL) 00116 { 00117 g_message("gnc_file_dtaus_import: Couldn't get HBCI API. Nothing will happen.\n"); 00118 return; 00119 } 00120 g_assert (interactor); 00121 00122 /* get import module */ 00123 importer = AB_Banking_GetImExporter(ab, importerName); 00124 if (!importer) 00125 { 00126 DEBUG("Import module %s not found", importerName); 00127 gnc_error_dialog(NULL, "%s", ("Import module for DTAUS import not found.")); 00128 return; 00129 } 00130 g_assert(importer); 00131 00132 /* load the import profile */ 00133 dbProfiles = AB_Banking_GetImExporterProfiles(ab, importerName); 00134 00135 /* select profile */ 00136 dbProfile = GWEN_DB_GetFirstGroup(dbProfiles); 00137 while (dbProfile) 00138 { 00139 const char *name; 00140 00141 name = GWEN_DB_GetCharValue(dbProfile, "name", 0, 0); 00142 g_assert(name); 00143 if (strcasecmp(name, profileName) == 0) 00144 break; 00145 dbProfile = GWEN_DB_GetNextGroup(dbProfile); 00146 } 00147 if (!dbProfile) 00148 { 00149 g_warning("Profile \"%s\" for importer \"%s\" not found\n", 00150 profileName, importerName); 00151 /* For debugging: Print those available names that have been found. */ 00152 dbProfile = GWEN_DB_GetFirstGroup(dbProfiles); 00153 while (dbProfile) 00154 { 00155 const char *name; 00156 name = GWEN_DB_GetCharValue(dbProfile, "name", 0, 0); 00157 g_assert(name); 00158 g_warning("Only found profile \"%s\"\n", name); 00159 dbProfile = GWEN_DB_GetNextGroup(dbProfile); 00160 } 00161 return; 00162 } 00163 g_assert(dbProfile); 00164 00165 /* import new context */ 00166 ctx = AB_ImExporterContext_new(); 00167 g_assert(ctx); 00168 00169 /* Wrap file in gwen_bufferedio */ 00170 buffio = GWEN_BufferedIO_File_new(dtaus_fd); 00171 g_assert(buffio); 00172 GWEN_BufferedIO_SetReadBuffer(buffio, 0, 1024); 00173 00174 result = AB_ImExporter_Import(importer, 00175 ctx, 00176 buffio, 00177 dbProfile); 00178 00179 DEBUG("Parsing result: %d\n", result); 00180 00181 GWEN_BufferedIO_Close(buffio); 00182 GWEN_BufferedIO_free(buffio); 00183 GWEN_DB_Group_free(dbProfiles); 00184 00185 { 00186 /* Now get all accountinfos */ 00187 GNCImportMainMatcher *importer_generic_gui; 00188 GtkWidget *parent = NULL; 00189 gboolean successful = FALSE; 00190 GList *ab_job_list; 00191 00192 /* Create importer GUI */ 00193 importer_generic_gui = gnc_gen_trans_list_new(parent, NULL, TRUE, 14); 00194 00195 /* Import the transactions from the ctx into gnucash. */ 00196 ab_job_list = gnc_hbci_import_ctx(ab, ctx, importer_generic_gui, 00197 execute_transactions); 00198 /* Finished importing. */ 00199 00200 /* We clean up here. */ 00201 AB_ImExporterContext_free(ctx); 00202 00203 if (execute_transactions) 00204 { 00205 /* Wait for the gnucash importer to be finished (it is being 00206 run anyway). */ 00207 result = gnc_gen_trans_list_run (importer_generic_gui); 00208 00209 if (result) 00210 /* Execute these jobs now. This function already delete()s the 00211 job. */ 00212 /* no parent so far; otherwise add this: GNCInteractor_reparent (interactor, parent); */ 00213 successful = gnc_hbci_multijob_execute (parent, ab, ab_job_list, interactor); 00214 /* else */ 00215 00216 /* Delete all jobs from queue in any case. */ 00217 gnc_hbci_clearqueue (ab, ab_job_list); 00218 } 00219 else 00220 { 00221 successful = TRUE; 00222 } 00223 00224 if (successful) 00225 { 00226 /* If execution was not successful, leave the log window 00227 still intact and open. */ 00228 gnc_AB_BANKING_fini (ab); 00229 gnc_AB_BANKING_delete (ab); 00230 } 00231 } 00232 } 00233 } 00234 }
| 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 506 of file gnc-log-replay.c.
00507 { 00508 char *selected_filename; 00509 char *default_dir; 00510 char read_buf[256]; 00511 char *read_retval; 00512 GtkFileFilter *filter; 00513 FILE *log_file; 00514 char * record_start_str = "===== START"; 00515 /* NOTE: This string must match src/engine/TransLog.c (sans newline) */ 00516 char * expected_header_orig = "mod\ttrans_guid\tsplit_guid\ttime_now\t" 00517 "date_entered\tdate_posted\tacc_guid\tacc_name\tnum\tdescription\t" 00518 "notes\tmemo\taction\treconciled\tamount\tvalue\tdate_reconciled"; 00519 static char *expected_header = NULL; 00520 00521 /* Use g_strdup_printf so we don't get accidental tab -> space conversion */ 00522 if (!expected_header) 00523 expected_header = g_strdup(expected_header_orig); 00524 00525 qof_log_set_level(GNC_MOD_IMPORT, QOF_LOG_DEBUG); 00526 ENTER(" "); 00527 00528 default_dir = gnc_get_default_directory(GCONF_SECTION); 00529 00530 filter = gtk_file_filter_new(); 00531 gtk_file_filter_set_name(filter, "*.log"); 00532 gtk_file_filter_add_pattern(filter, "*.[Ll][Oo][Gg]"); 00533 selected_filename = gnc_file_dialog(_("Select a .log file to replay"), 00534 g_list_prepend(NULL, filter), 00535 default_dir, 00536 GNC_FILE_DIALOG_OPEN); 00537 g_free(default_dir); 00538 00539 if (selected_filename != NULL) 00540 { 00541 /* Remember the directory as the default. */ 00542 default_dir = g_path_get_dirname(selected_filename); 00543 gnc_set_default_directory(GCONF_SECTION, default_dir); 00544 g_free(default_dir); 00545 00546 /*strncpy(file,selected_filename, 255);*/ 00547 DEBUG("Filename found: %s", selected_filename); 00548 if (xaccFileIsCurrentLog(selected_filename)) 00549 { 00550 g_warning("Cannot open the current log file: %s", selected_filename); 00551 gnc_error_dialog(NULL, 00552 /* Translators: %s is the file name. */ 00553 _("Cannot open the current log file: %s"), 00554 selected_filename); 00555 } 00556 else 00557 { 00558 DEBUG("Opening selected file"); 00559 log_file = g_fopen(selected_filename, "r"); 00560 if (!log_file || ferror(log_file) != 0) 00561 { 00562 int err = errno; 00563 perror("File open failed"); 00564 gnc_error_dialog(NULL, 00565 /* Translation note: 00566 * First argument is the filename, 00567 * second argument is the error. 00568 */ 00569 _("Failed to open log file: %s: %s"), 00570 selected_filename, 00571 strerror(err)); 00572 } 00573 else 00574 { 00575 if ((read_retval = fgets(read_buf, sizeof(read_buf), log_file)) == NULL) 00576 { 00577 DEBUG("Read error or EOF"); 00578 gnc_info_dialog(NULL, "%s", 00579 _("The log file you selected was empty.")); 00580 } 00581 else 00582 { 00583 if (strncmp(expected_header, read_buf, strlen(expected_header)) != 0) 00584 { 00585 PERR("File header not recognised:\n%s", read_buf); 00586 PERR("Expected:\n%s", expected_header); 00587 gnc_error_dialog(NULL, "%s", 00588 _("The log file you selected cannot be read. " 00589 "The file header was not recognized.")); 00590 } 00591 else 00592 { 00593 do 00594 { 00595 read_retval = fgets(read_buf, sizeof(read_buf), log_file); 00596 /*DEBUG("Chunk read: %s",read_retval);*/ 00597 if (strncmp(record_start_str, read_buf, strlen(record_start_str)) == 0) /* If a record started */ 00598 { 00599 process_trans_record(log_file); 00600 } 00601 } 00602 while (feof(log_file) == 0); 00603 } 00604 } 00605 fclose(log_file); 00606 } 00607 } 00608 g_free(selected_filename); 00609 } 00610 LEAVE(""); 00611 }
| 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 725 of file gnc-ofx-import.c.
00726 { 00727 extern int ofx_PARSER_msg; 00728 extern int ofx_DEBUG_msg; 00729 extern int ofx_WARNING_msg; 00730 extern int ofx_ERROR_msg; 00731 extern int ofx_INFO_msg; 00732 extern int ofx_STATUS_msg; 00733 char *selected_filename; 00734 char *default_dir; 00735 LibofxContextPtr libofx_context = libofx_get_new_context(); 00736 00737 ofx_PARSER_msg = false; 00738 ofx_DEBUG_msg = false; 00739 ofx_WARNING_msg = true; 00740 ofx_ERROR_msg = true; 00741 ofx_INFO_msg = true; 00742 ofx_STATUS_msg = false; 00743 00744 DEBUG("gnc_file_ofx_import(): Begin...\n"); 00745 00746 default_dir = gnc_get_default_directory(GCONF_SECTION); 00747 selected_filename = gnc_file_dialog(_("Select an OFX/QFX file to process"), 00748 NULL, 00749 default_dir, 00750 GNC_FILE_DIALOG_IMPORT); 00751 g_free(default_dir); 00752 00753 if (selected_filename != NULL) 00754 { 00755 #ifdef G_OS_WIN32 00756 gchar *conv_name; 00757 #endif 00758 00759 /* Remember the directory as the default. */ 00760 default_dir = g_path_get_dirname(selected_filename); 00761 gnc_set_default_directory(GCONF_SECTION, default_dir); 00762 g_free(default_dir); 00763 00764 /*strncpy(file,selected_filename, 255);*/ 00765 DEBUG("Filename found: %s", selected_filename); 00766 00767 /* Create the Generic transaction importer GUI. */ 00768 gnc_ofx_importer_gui = gnc_gen_trans_list_new(NULL, NULL, FALSE, 42); 00769 00770 /* Initialize libofx */ 00771 00772 /*ofx_set_statement_cb(libofx_context, ofx_proc_statement_cb, 0);*/ 00773 ofx_set_account_cb(libofx_context, ofx_proc_account_cb, 0); 00774 ofx_set_transaction_cb(libofx_context, ofx_proc_transaction_cb, 0); 00775 ofx_set_security_cb(libofx_context, ofx_proc_security_cb, 0); 00776 /*ofx_set_status_cb(libofx_context, ofx_proc_status_cb, 0);*/ 00777 00778 #ifdef G_OS_WIN32 00779 conv_name = g_win32_locale_filename_from_utf8(selected_filename); 00780 g_free(selected_filename); 00781 selected_filename = conv_name; 00782 #endif 00783 00784 DEBUG("Opening selected file"); 00785 libofx_proc_file(libofx_context, selected_filename, AUTODETECT); 00786 g_free(selected_filename); 00787 } 00788 00789 }
| 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.
| gui | The Transaction Importer to use. | |
| trans | The 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 753 of file import-main-matcher.c.
00754 { 00755 GNCImportTransInfo * transaction_info = NULL; 00756 GtkTreeModel *model; 00757 GtkTreeIter iter; 00758 g_assert (gui); 00759 g_assert (trans); 00760 00761 00762 if (gnc_import_exists_online_id (trans)) 00763 return; 00764 else 00765 { 00766 transaction_info = gnc_import_TransInfo_new(trans, NULL); 00767 00768 gnc_import_TransInfo_init_matches (transaction_info, 00769 gui->user_settings); 00770 00771 model = gtk_tree_view_get_model(gui->view); 00772 gtk_list_store_append(GTK_LIST_STORE(model), &iter); 00773 refresh_model_row (gui, model, &iter, transaction_info); 00774 } 00775 return; 00776 }/* end gnc_import_add_trans() */
| void gnc_gen_trans_list_delete | ( | GNCImportMainMatcher * | info | ) |
Deletes the given object.
Definition at line 91 of file import-main-matcher.c.
00092 { 00093 GtkTreeModel *model; 00094 GtkTreeIter iter; 00095 GNCImportTransInfo *trans_info; 00096 00097 if (info == NULL) 00098 return; 00099 00100 model = gtk_tree_view_get_model(info->view); 00101 if (gtk_tree_model_get_iter_first(model, &iter)) 00102 { 00103 do 00104 { 00105 gtk_tree_model_get(model, &iter, 00106 DOWNLOADED_COL_DATA, &trans_info, 00107 -1); 00108 gnc_import_TransInfo_delete(trans_info); 00109 } 00110 while (gtk_tree_model_iter_next (model, &iter)); 00111 } 00112 00113 gnc_save_window_size(GCONF_SECTION, GTK_WINDOW(info->dialog)); 00114 gnc_import_Settings_delete (info->user_settings); 00115 gtk_widget_destroy (GTK_WIDGET (info->dialog)); 00116 g_free (info); 00117 }
| 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.
| parent | The parent GtkWidget. May be NULL. | |
| heading | The heading label in the Importer window. May be NULL. | |
| all_from_same_account | Set 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_hardlimit | The 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 493 of file import-main-matcher.c.
00497 { 00498 GNCImportMainMatcher *info; 00499 GladeXML *xml; 00500 GtkWidget *heading_label; 00501 gboolean show_edit; 00502 00503 info = g_new0 (GNCImportMainMatcher, 1); 00504 00505 /* Initialize user Settings. */ 00506 info->user_settings = gnc_import_Settings_new (); 00507 gnc_import_Settings_set_match_date_hardlimit (info->user_settings, match_date_hardlimit); 00508 00509 /* Initialize the GtkDialog. */ 00510 xml = gnc_glade_xml_new ("generic-import.glade", "transaction_matcher"); 00511 00512 info->dialog = glade_xml_get_widget (xml, "transaction_matcher"); 00513 g_assert (info->dialog != NULL); 00514 info->view = GTK_TREE_VIEW(glade_xml_get_widget (xml, "downloaded_view")); 00515 g_assert (info->view != NULL); 00516 00517 show_edit = gnc_import_Settings_get_action_edit_enabled (info->user_settings); 00518 gnc_gen_trans_init_view(info, all_from_same_account, show_edit); 00519 heading_label = glade_xml_get_widget (xml, "heading_label"); 00520 g_assert (heading_label != NULL); 00521 00522 /* if (parent) 00523 gtk_window_set_transient_for (GTK_WINDOW (info->dialog), 00524 GTK_WINDOW (parent));*/ 00525 00526 /* Connect signals */ 00527 glade_xml_signal_connect_data(xml, "on_matcher_ok_clicked", 00528 G_CALLBACK(on_matcher_ok_clicked), 00529 info); 00530 glade_xml_signal_connect_data(xml, "on_matcher_cancel_clicked", 00531 G_CALLBACK(on_matcher_cancel_clicked), 00532 info); 00533 glade_xml_signal_connect_data(xml, "on_matcher_help_clicked", 00534 G_CALLBACK(on_matcher_help_clicked), 00535 info); 00536 00537 /*Initialise the colors */ 00538 gdk_color_parse(COLOR_RED, &info->color_back_red); 00539 gdk_color_parse(COLOR_YELLOW, &info->color_back_yellow); 00540 gdk_color_parse(COLOR_GREEN, &info->color_back_green); 00541 00542 if (heading) 00543 gtk_label_set_text (GTK_LABEL (heading_label), heading); 00544 00545 gnc_restore_window_size(GCONF_SECTION, GTK_WINDOW(info->dialog)); 00546 gtk_widget_show_all (GTK_WIDGET (info->dialog)); 00547 return info; 00548 }
| 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 550 of file import-main-matcher.c.
00551 { 00552 gboolean result; 00553 00554 /* DEBUG("Begin"); */ 00555 00556 result = gtk_dialog_run (GTK_DIALOG (info->dialog)); 00557 00558 /* DEBUG("Result was %d", result); */ 00559 00560 /* No destroying here since the dialog was already destroyed through 00561 the ok_clicked handlers. */ 00562 return result; 00563 }
| void gnc_imap_add_account | ( | GncImportMatchMap * | imap, | |
| const char * | category, | |||
| const char * | key, | |||
| Account * | acc | |||
| ) |
Store an Account in the map
Store an Account in the map. This mapping is immediatly stored in the underlying kvp frame, regardless of whether the MatchMap is destroyed later or not.
Definition at line 142 of file import-match-map.c.
00144 { 00145 kvp_value *value; 00146 00147 if (!imap || !key || !acc || (strlen (key) == 0)) return; 00148 if (!category) 00149 { 00150 category = key; 00151 key = NULL; 00152 } 00153 00154 value = kvp_value_new_guid (xaccAccountGetGUID (acc)); 00155 g_return_if_fail (value != NULL); 00156 00157 kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL); 00158 kvp_value_delete (value); 00159 00160 /* XXX Mark the account (or book) as dirty! */ 00161 }
| void gnc_imap_add_account_bayes | ( | GncImportMatchMap * | imap, | |
| GList * | tokens, | |||
| Account * | acc | |||
| ) |
Updates the imap for a given account using a list of tokens
Store an Account in the map. This mapping is immediatly stored in the underlying kvp frame, regardless of whether the MatchMap is destroyed later or not.
Definition at line 461 of file import-match-map.c.
00462 { 00463 GList *current_token; 00464 kvp_value *value; 00465 gint64 token_count; 00466 char* account_fullname; 00467 kvp_value *new_value; /* the value that will be added back into the kvp tree */ 00468 00469 ENTER(" "); 00470 00471 /* if imap is null return */ 00472 if (!imap) 00473 { 00474 LEAVE(" "); 00475 return; 00476 } 00477 00478 account_fullname = gnc_account_get_full_name(acc); 00479 00480 PINFO("account name: '%s'\n", account_fullname); 00481 00482 /* process each token in the list */ 00483 for (current_token = g_list_first(tokens); current_token; 00484 current_token = current_token->next) 00485 { 00486 /* Jump to next iteration if the pointer is not valid or if the 00487 string is empty. In HBCI import we almost always get an empty 00488 string, which doesn't work in the kvp loopkup later. So we 00489 skip this case here. */ 00490 if (!current_token->data || (*((char*)current_token->data) == '\0')) 00491 continue; 00492 00493 /* start off with no tokens for this account */ 00494 token_count = 0; 00495 00496 PINFO("adding token '%s'\n", (char*)current_token->data); 00497 00498 /* is this token/account_name already in the kvp tree? */ 00499 value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES, 00500 (char*)current_token->data, account_fullname, 00501 NULL); 00502 00503 /* if the token/account is already in the tree, read the current 00504 * value from the tree and use this for the basis of the value we 00505 * are putting back 00506 */ 00507 if (value) 00508 { 00509 PINFO("found existing value of '%ld'\n", 00510 (long)kvp_value_get_gint64(value)); 00511 00512 /* convert this value back into an integer */ 00513 token_count += kvp_value_get_gint64(value); 00514 } 00515 00516 /* increment the token count */ 00517 token_count++; 00518 00519 /* create a new value */ 00520 new_value = kvp_value_new_gint64(token_count); 00521 00522 /* insert the value into the kvp tree at 00523 * /imap->frame/IMAP_FRAME/token_string/account_name_string 00524 */ 00525 kvp_frame_set_slot_path(imap->frame, new_value, IMAP_FRAME_BAYES, 00526 (char*)current_token->data, account_fullname, NULL); 00527 00528 /* kvp_frame_set_slot_path() copied the value so we 00529 * need to delete this one ;-) */ 00530 kvp_value_delete(new_value); 00531 } 00532 00533 /* free up the account fullname string */ 00534 g_free(account_fullname); 00535 00536 LEAVE(" "); 00537 }
| void gnc_imap_clear | ( | GncImportMatchMap * | imap | ) |
Clear an import map -- this removes ALL entries in the map
Definition at line 107 of file import-match-map.c.
00108 { 00109 if (!imap) return; 00110 00111 /* Clear the IMAP_FRAME kvp */ 00112 kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME); 00113 00114 /* Clear the bayes kvp, IMAP_FRAME_BAYES */ 00115 kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME_BAYES); 00116 00117 /* XXX: mark the account (or book) as dirty! */ 00118 }
| GncImportMatchMap * gnc_imap_create_from_account | ( | Account * | acc | ) |
Obtain an ImportMatchMap object from an Account or a Book
Obtain an ImportMatchMap object from an Account or a Book
Definition at line 77 of file import-match-map.c.
00078 { 00079 kvp_frame * frame; 00080 00081 if (!acc) return NULL; 00082 frame = xaccAccountGetSlots (acc); 00083 g_return_val_if_fail (frame != NULL, NULL); 00084 00085 return gnc_imap_create_from_frame (frame, acc, NULL); 00086 }
| void gnc_imap_destroy | ( | GncImportMatchMap * | imap | ) |
Destroy an import map
Destroy an import map. But all stored entries will still continue to exist in the underlying kvp frame of the account or book.
Definition at line 100 of file import-match-map.c.
| Account * gnc_imap_find_account | ( | GncImportMatchMap * | imap, | |
| const char * | category, | |||
| const char * | key | |||
| ) |
Look up an Account in the map
Definition at line 121 of file import-match-map.c.
00123 { 00124 kvp_value *value; 00125 GUID * guid; 00126 00127 if (!imap || !key) return NULL; 00128 if (!category) 00129 { 00130 category = key; 00131 key = NULL; 00132 } 00133 00134 value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME, category, key, NULL); 00135 if (!value) return NULL; 00136 00137 guid = kvp_value_get_guid (value); 00138 return xaccAccountLookup (guid, imap->book); 00139 }
| Account * gnc_imap_find_account_bayes | ( | GncImportMatchMap * | imap, | |
| GList * | tokens | |||
| ) |
Look up an Account in the map
Look up an Account in the map from a GList* of pointers to strings(tokens) from the current transaction
Definition at line 287 of file import-match-map.c.
00288 { 00289 struct token_accounts_info tokenInfo; 00291 GList *current_token; 00293 GList *current_account_token; 00295 struct account_token_count *account_c; 00298 struct account_probability *account_p; 00301 GHashTable *running_probabilities = g_hash_table_new(g_str_hash, g_str_equal); 00302 GHashTable *final_probabilities = g_hash_table_new(g_str_hash, g_str_equal); 00303 struct account_info account_i; 00304 kvp_value* value; 00305 kvp_frame* token_frame; 00306 00307 ENTER(" "); 00308 00309 /* check to see if the imap is NULL */ 00310 if (!imap) 00311 { 00312 PINFO("imap is null, returning null"); 00313 LEAVE(" "); 00314 return NULL; 00315 } 00316 00317 /* find the probability for each account that contains any of the tokens 00318 * in the input tokens list 00319 */ 00320 for (current_token = tokens; current_token; current_token = current_token->next) 00321 { 00322 /* zero out the token_accounts_info structure */ 00323 memset(&tokenInfo, 0, sizeof(struct token_accounts_info)); 00324 00325 PINFO("token: '%s'", (char*)current_token->data); 00326 00327 /* find the slot for the given token off of the source account 00328 * for these tokens, search off of the IMAP_FRAME_BAYES path so 00329 * we aren't looking from the parent of the entire kvp tree 00330 */ 00331 value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES, 00332 (char*)current_token->data, NULL); 00333 00334 /* if value is null we should skip over this token */ 00335 if (!value) 00336 continue; 00337 00338 /* convert the slot(value) into a the frame that contains the 00339 * list of accounts 00340 */ 00341 token_frame = kvp_value_get_frame(value); 00342 00343 /* token_frame should NEVER be null */ 00344 if (!token_frame) 00345 { 00346 PERR("token '%s' has no accounts", (char*)current_token->data); 00347 continue; /* skip over this token */ 00348 } 00349 00350 /* process the accounts for this token, adding the account if it 00351 * doesn't already exist or adding to the existing accounts token 00352 * count if it does 00353 */ 00354 kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo); 00355 00356 /* for each account we have just found, see if the account already exists 00357 * in the list of account probabilities, if not add it 00358 */ 00359 for (current_account_token = tokenInfo.accounts; current_account_token; 00360 current_account_token = current_account_token->next) 00361 { 00362 /* get the account name and corresponding token count */ 00363 account_c = (struct account_token_count*)current_account_token->data; 00364 00365 PINFO("account_c->account_name('%s'), " 00366 "account_c->token_count('%ld')/total_count('%ld')", 00367 account_c->account_name, (long)account_c->token_count, 00368 (long)tokenInfo.total_count); 00369 00370 account_p = g_hash_table_lookup(running_probabilities, 00371 account_c->account_name); 00372 00373 /* if the account exists in the list then continue 00374 * the running probablities 00375 */ 00376 if (account_p) 00377 { 00378 account_p->product = 00379 ((double)account_c->token_count / (double)tokenInfo.total_count) 00380 * account_p->product; 00381 account_p->product_difference = 00382 ((double)1 - ((double)account_c->token_count / 00383 (double)tokenInfo.total_count)) 00384 * account_p->product_difference; 00385 PINFO("product == %f, product_difference == %f", 00386 account_p->product, account_p->product_difference); 00387 } 00388 else 00389 { 00390 /* add a new entry */ 00391 PINFO("adding a new entry for this account"); 00392 account_p = (struct account_probability*) 00393 g_new0(struct account_probability, 1); 00394 00395 /* set the product and product difference values */ 00396 account_p->product = ((double)account_c->token_count / 00397 (double)tokenInfo.total_count); 00398 account_p->product_difference = 00399 (double)1 - ((double)account_c->token_count / 00400 (double)tokenInfo.total_count); 00401 00402 PINFO("product == %f, product_difference == %f", 00403 account_p->product, account_p->product_difference); 00404 00405 /* add the account name and (struct account_probability*) 00406 * to the hash table */ 00407 g_hash_table_insert(running_probabilities, 00408 account_c->account_name, account_p); 00409 } 00410 } /* for all accounts in tokenInfo */ 00411 00412 /* free the data in tokenInfo */ 00413 for (current_account_token = tokenInfo.accounts; current_account_token; 00414 current_account_token = current_account_token->next) 00415 { 00416 /* free up each struct account_token_count we allocated */ 00417 g_free((struct account_token_count*)current_account_token->data); 00418 } 00419 00420 g_list_free(tokenInfo.accounts); /* free the accounts GList */ 00421 } 00422 00423 /* build a hash table of account names and their final probabilities 00424 * from each entry in the running_probabilties hash table 00425 */ 00426 g_hash_table_foreach(running_probabilities, buildProbabilities, 00427 final_probabilities); 00428 00429 /* find the highest probabilty and the corresponding account */ 00430 memset(&account_i, 0, sizeof(struct account_info)); 00431 g_hash_table_foreach(final_probabilities, highestProbability, &account_i); 00432 00433 /* free each element of the running_probabilities hash */ 00434 g_hash_table_foreach(running_probabilities, freeProbabilities, NULL); 00435 00436 /* free the hash tables */ 00437 g_hash_table_destroy(running_probabilities); 00438 g_hash_table_destroy(final_probabilities); 00439 00440 PINFO("highest P('%s') = '%d'", 00441 account_i.account_name ? account_i.account_name : "(null)", 00442 account_i.probability); 00443 00444 /* has this probability met our threshold? */ 00445 if (account_i.probability >= threshold) 00446 { 00447 PINFO("found match"); 00448 LEAVE(" "); 00449 return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book), 00450 account_i.account_name); 00451 } 00452 00453 PINFO("no match"); 00454 LEAVE(" "); 00455 00456 return NULL; /* we didn't meet our threshold, return NULL for an account */ 00457 }
| 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.
| trans | The transaction for which to check for an existing online_id. |
Definition at line 1008 of file import-backend.c.
01009 { 01010 int i; 01011 gboolean online_id_exists = FALSE; 01012 Account *dest_acct; 01013 Split *source_split; 01014 01015 /* Look for an online_id in the first split */ 01016 source_split = xaccTransGetSplit(trans, 0); 01017 01018 /* DEBUG("%s%d%s","Checking split ",i," for duplicates"); */ 01019 dest_acct = xaccSplitGetAccount(source_split); 01020 online_id_exists = xaccAccountForEachTransaction(dest_acct, 01021 check_trans_online_id, 01022 source_split); 01023 01024 /* If it does, abort the process for this transaction, since it is 01025 already in the system. */ 01026 if (online_id_exists == TRUE) 01027 { 01028 DEBUG("%s", "Transaction with same online ID exists, destroying current transaction"); 01029 xaccTransDestroy(trans); 01030 xaccTransCommitEdit(trans); 01031 } 01032 return online_id_exists; 01033 }
| 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.
| trans_info | The TransInfo for which the corresponding matching existing transactions should be found. | |
| process_threshold | Each match whose heuristics are smaller than this value is totally ignored. | |
| fuzzy_amount_difference | For 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_hardlimit | The 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 775 of file import-backend.c.
00779 { 00780 GList * list_element; 00781 Query *query = xaccMallocQuery(); 00782 g_assert (trans_info); 00783 00784 /* Get list of splits of the originating account. */ 00785 { 00786 /* We used to traverse *all* splits of the account by using 00787 xaccAccountGetSplitList, which is a bad idea because 90% of these 00788 splits are outside the date range that is interesting. We should 00789 rather use a query according to the date region, which is 00790 implemented here. 00791 */ 00792 Account *importaccount = 00793 xaccSplitGetAccount (gnc_import_TransInfo_get_fsplit (trans_info)); 00794 time_t download_time = xaccTransGetDate (gnc_import_TransInfo_get_trans (trans_info)); 00795 00796 xaccQuerySetBook (query, gnc_get_current_book()); 00797 xaccQueryAddSingleAccountMatch (query, importaccount, 00798 QOF_QUERY_AND); 00799 xaccQueryAddDateMatchTT (query, 00800 TRUE, download_time - match_date_hardlimit * 86400, 00801 TRUE, download_time + match_date_hardlimit * 86400, 00802 QOF_QUERY_AND); 00803 list_element = xaccQueryGetSplits (query); 00804 /* Sigh. Doesnt help too much. We still create and run one query 00805 for each imported transaction. Maybe it would improve 00806 performance further if there is one single (master-)query at 00807 the beginning, matching the full date range and all accounts in 00808 question. However, this doesnt quite work because this function 00809 here is called from each gnc_gen_trans_list_add_trans(), which 00810 is called one at a time. Therefore the whole importer would 00811 have to change its behaviour: Accept the imported txns via 00812 gnc_gen_trans_list_add_trans(), and only when 00813 gnc_gen_trans_list_run() is called, then calculate all the 00814 different match candidates. That's too much work for now. 00815 */ 00816 } 00817 00818 /* Traverse that list, calling split_find_match on each one. Note 00819 that xaccAccountForEachSplit is declared in Account.h but 00820 implemented nowhere :-( */ 00821 while (list_element != NULL) 00822 { 00823 split_find_match (trans_info, list_element->data, 00824 process_threshold, fuzzy_amount_difference); 00825 list_element = g_list_next (list_element); 00826 } 00827 00828 xaccFreeQuery (query); 00829 }
| 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.
| transaction_info | The TransInfo for which the user is supposed to pick a matching transaction. |
Definition at line 441 of file import-match-picker.c.
00442 { 00443 GNCImportMatchPicker *matcher; 00444 gint response; 00445 GNCImportMatchInfo *old; 00446 g_assert (transaction_info); 00447 00448 /* Create a new match_picker, even though it's stored in a 00449 transmatcher struct :-) */ 00450 matcher = g_new0(GNCImportMatchPicker, 1); 00451 /* DEBUG("Init match_picker"); */ 00452 init_match_picker_gui(matcher); 00453 00454 /* Append this single transaction to the view and select it */ 00455 downloaded_transaction_append(matcher, transaction_info); 00456 00457 old = gnc_import_TransInfo_get_selected_match(transaction_info); 00458 00459 /* Let this dialog run and close. */ 00460 /*DEBUG("Right before run and close");*/ 00461 gtk_window_set_modal(GTK_WINDOW(matcher->transaction_matcher), TRUE); 00462 response = gtk_dialog_run (GTK_DIALOG (matcher->transaction_matcher)); 00463 gnc_save_window_size(GCONF_SECTION, 00464 GTK_WINDOW (matcher->transaction_matcher)); 00465 gtk_widget_destroy (matcher->transaction_matcher); 00466 /*DEBUG("Right after run and close");*/ 00467 /* DEBUG("Response was %d.", response); */ 00468 if (response == GTK_RESPONSE_OK && matcher->selected_match_info != old) 00469 { 00470 /* OK was pressed */ 00471 gnc_import_TransInfo_set_selected_match (transaction_info, 00472 matcher->selected_match_info, 00473 TRUE); 00474 } 00475 }
| gint gnc_import_MatchInfo_get_probability | ( | const GNCImportMatchInfo * | info | ) |
Get the probability (confidence level) of this MatchInfo.
| info | Can be NULL, in which case the function returns 0 |
Definition at line 224 of file import-backend.c.
00225 { 00226 if (info) 00227 { 00228 return info->probability; 00229 } 00230 else 00231 { 00232 return 0; 00233 } 00234 }
| Split * gnc_import_MatchInfo_get_split | ( | const GNCImportMatchInfo * | info | ) |
Get the split ('this-side split') of this MatchInfo.
Definition at line 217 of file import-backend.c.
| 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.
| matchmap | The ImportMatchMap where each match should be stored. May be NULL, in which case the ImportMatchMap of each account will be used. | |
| trans_info | The ImportTransInfo item to process. |
Definition at line 838 of file import-backend.c.
00840 { 00841 /* DEBUG("Begin"); */ 00842 00843 g_assert (trans_info); 00844 /*DEBUG("Iteration %d, action %d, split %s", i, 00845 trans_info->action, 00846 xaccTransGetDescription (gnc_import_TransInfo_get_trans 00847 (trans_info)))*/ 00848 switch (gnc_import_TransInfo_get_action (trans_info)) 00849 { 00850 case GNCImport_SKIP: 00851 return FALSE; 00852 case GNCImport_ADD: 00853 /* Transaction gets imported. */ 00854 00855 /* Is the transaction not balanced and there is a non-NULL destination account? */ 00856 if (gnc_import_TransInfo_is_balanced(trans_info) == FALSE 00857 && gnc_import_TransInfo_get_destacc(trans_info) != NULL) 00858 { 00859 /* Create the 'other' split. */ 00860 Split *split = 00861 xaccMallocSplit 00862 (gnc_account_get_book 00863 (gnc_import_TransInfo_get_destacc (trans_info))); 00864 xaccTransAppendSplit 00865 (gnc_import_TransInfo_get_trans (trans_info), split); 00866 xaccAccountInsertSplit 00867 (gnc_import_TransInfo_get_destacc (trans_info), split); 00868 /*xaccSplitSetBaseValue 00869 (split, 00870 gnc_numeric_neg(xaccTransGetImbalance 00871 (gnc_import_TransInfo_get_trans (trans_info))), 00872 xaccTransGetCurrency 00873 (gnc_import_TransInfo_get_trans (trans_info)));*/ 00874 { 00875 /* This is a quick workaround for the bug described in 00876 http://gnucash.org/pipermail/gnucash-devel/2003-August/009982.html 00877 Assume that importers won't create transactions involving two or more 00878 currencies so we can use xaccTransGetImbalanceValue. */ 00879 gnc_numeric v = 00880 gnc_numeric_neg (xaccTransGetImbalanceValue 00881 (gnc_import_TransInfo_get_trans (trans_info))); 00882 xaccSplitSetValue (split, v); 00883 xaccSplitSetAmount (split, v); 00884 } 00885 /*xaccSplitSetMemo (split, _("Auto-Balance split")); 00886 -- disabled due to popular request */ 00887 } 00888 00889 xaccSplitSetReconcile(gnc_import_TransInfo_get_fsplit (trans_info), CREC); 00890 /*Set reconcile date to today*/ 00891 xaccSplitSetDateReconciledSecs(gnc_import_TransInfo_get_fsplit (trans_info), 00892 time(NULL)); 00893 /* Done editing. */ 00894 xaccTransCommitEdit 00895 (gnc_import_TransInfo_get_trans (trans_info)); 00896 return TRUE; 00897 case GNCImport_CLEAR: 00898 { 00899 GNCImportMatchInfo *selected_match = 00900 gnc_import_TransInfo_get_selected_match (trans_info); 00901 00902 /* If there is no selection, ignore this transaction. */ 00903 if (!selected_match) 00904 { 00905 PWARN("No matching translaction to be cleared was chosen. Imported transaction will be ignored."); 00906 break; 00907 } 00908 00909 /* Transaction gets not imported but the matching one gets 00910 reconciled. */ 00911 if (gnc_import_MatchInfo_get_split (selected_match) == NULL) 00912 { 00913 PERR("The split I am trying to reconcile is NULL, shouldn't happen!"); 00914 } 00915 else 00916 { 00917 /* Reconcile the matching transaction */ 00918 /*DEBUG("BeginEdit selected_match")*/ 00919 xaccTransBeginEdit(selected_match->trans); 00920 00921 if (xaccSplitGetReconcile 00922 (selected_match->split) == NREC) 00923 xaccSplitSetReconcile 00924 (selected_match->split, CREC); 00925 /* Set reconcile date to today */ 00926 xaccSplitSetDateReconciledSecs 00927 (selected_match->split, time(NULL)); 00928 00929 /* Copy the online id to the reconciled transaction, so 00930 the match will be remembered */ 00931 if (gnc_import_split_has_online_id(trans_info->first_split)) 00932 gnc_import_set_split_online_id 00933 (selected_match->split, 00934 gnc_import_get_split_online_id(trans_info->first_split)); 00935 00936 /* Done editing. */ 00937 /*DEBUG("CommitEdit selected_match")*/ 00938 xaccTransCommitEdit 00939 (selected_match->trans); 00940 00941 /* Store the mapping to the other account in the MatchMap. */ 00942 matchmap_store_destination (matchmap, trans_info, TRUE); 00943 00944 /* Erase the downloaded transaction */ 00945 xaccTransDestroy(trans_info->trans); 00946 /*DEBUG("CommitEdit trans")*/ 00947 xaccTransCommitEdit(trans_info->trans); 00948 /* Very important: Make sure the freed transaction is not freed again! */ 00949 trans_info->trans = NULL; 00950 } 00951 } 00952 return TRUE; 00953 case GNCImport_EDIT: 00954 PERR("EDIT action is UNSUPPORTED!"); 00955 break; 00956 default: 00957 DEBUG("Invalid GNCImportAction for this imported transaction."); 00958 } 00959 /*DEBUG("End");*/ 00960 return FALSE; 00961 }
| Account * gnc_import_select_account | ( | gncUIWidget | parent, | |
| const gchar * | account_online_id_value, | |||
| gboolean | auto_create, | |||
| const gchar * | account_human_description, | |||
| 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.
| parent | The parent widget. Can be NULL. | |
| account_online_id_value | The string containing your unique account_id coming from some string of your module. This is the normal mode of operation. Can be NULL. |
| account_human_description | A 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_commodity | Default 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_type | Default 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_create | Only 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_selection | If not NULL, that account will be pre-selected by default. | |
| ok_pressed | A 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. |
Definition at line 145 of file import-account-matcher.c.
00153 { 00154 #define ACCOUNT_DESCRIPTION_MAX_SIZE 255 00155 struct _accountpickerdialog * picker; 00156 gint response; 00157 Account * retval = NULL; 00158 const gchar *retval_name = NULL; 00159 GladeXML *xml; 00160 GtkWidget * online_id_label, *button; 00161 gchar account_description_text[ACCOUNT_DESCRIPTION_MAX_SIZE] = ""; 00162 gboolean ok_pressed_retval = FALSE; 00163 00164 ENTER("Default commodity received: %s", gnc_commodity_get_fullname( new_account_default_commodity)); 00165 DEBUG("Default account type received: %s", xaccAccountGetTypeStr( new_account_default_type)); 00166 picker = g_new0(struct _accountpickerdialog, 1); 00167 00168 picker->account_online_id_value = account_online_id_value; 00169 picker->account_human_description = account_human_description; 00170 picker->new_account_default_commodity = new_account_default_commodity; 00171 picker->new_account_default_type = new_account_default_type; 00172 00173 /*DEBUG("Looking for account with online_id: %s", account_online_id_value);*/ 00174 if (account_online_id_value != NULL) 00175 { 00176 retval = 00177 gnc_account_foreach_descendant_until(gnc_get_current_root_account (), 00178 test_acct_online_id_match, 00179 /* This argument will only be 00180 used as a "const char*" */ 00181 (void*)account_online_id_value); 00182 } 00183 if (retval == NULL && auto_create != 0) 00184 { 00185 /* load the interface */ 00186 xml = gnc_glade_xml_new ("generic-import.glade", "Generic Import Account Picker"); 00187 /* connect the signals in the interface */ 00188 if (xml == NULL) 00189 { 00190 PERR("Error opening the glade interface"); 00191 } 00192 00193 picker->dialog = glade_xml_get_widget (xml, "Generic Import Account Picker"); 00194 if (parent) 00195 gtk_window_set_transient_for (GTK_WINDOW (picker->dialog), 00196 GTK_WINDOW (parent)); 00197 picker->account_tree_sw = glade_xml_get_widget (xml, "account_tree_sw"); 00198 online_id_label = glade_xml_get_widget (xml, "online_id_label"); 00199 button = glade_xml_get_widget (xml, "newbutton"); 00200 gtk_button_set_use_stock (GTK_BUTTON(button), TRUE); 00201 00202 //printf("gnc_import_select_account(): Fin get widget\n"); 00203 00204 if (account_human_description != NULL) 00205 { 00206 strncat(account_description_text, account_human_description, 00207 ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text)); 00208 strncat(account_description_text, "\n", 00209 ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text)); 00210 } 00211 if (account_online_id_value != NULL) 00212 { 00213 strncat(account_description_text, _("(Full account ID: "), 00214 ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text)); 00215 strncat(account_description_text, account_online_id_value, 00216 ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text)); 00217 strncat(account_description_text, ")", 00218 ACCOUNT_DESCRIPTION_MAX_SIZE - strlen(account_description_text)); 00219 } 00220 gtk_label_set_text((GtkLabel*)online_id_label, account_description_text); 00221 build_acct_tree(picker); 00222 gnc_tree_view_account_set_selected_account(picker->account_tree, default_selection); 00223 00224 gtk_window_set_modal(GTK_WINDOW(picker->dialog), TRUE); 00225 g_signal_connect(picker->account_tree, "row-activated", 00226 G_CALLBACK(account_tree_row_activated_cb), picker); 00227 do 00228 { 00229 response = gtk_dialog_run(GTK_DIALOG(picker->dialog)); 00230 switch (response) 00231 { 00232 case GTK_RESPONSE_OK: 00233 retval = gnc_tree_view_account_get_selected_account(picker->account_tree); 00234 if (retval) 00235 retval_name = xaccAccountGetName(retval); 00236 if (!retval_name) 00237 retval_name = "(null)"; 00238 DEBUG("Selected account %p, %s", retval, retval_name); 00239 00240 /* See if the selected account is a placeholder. */ 00241 if (retval && xaccAccountGetPlaceholder (retval)) 00242 { 00243 gnc_error_dialog 00244 (picker->dialog, 00245 _("The account %s is a placeholder account and does not allow " 00246 "transactions. Please choose a different account."), 00247 retval_name); 00248 response = GNC_RESPONSE_NEW; 00249 break; 00250 } 00251 00252 if ( account_online_id_value != NULL) 00253 { 00254 gnc_import_set_acc_online_id(retval, account_online_id_value); 00255 } 00256 ok_pressed_retval = TRUE; 00257 break; 00258 case GNC_RESPONSE_NEW: 00259 gnc_import_add_account(picker); 00260 break; 00261 default: 00262 ok_pressed_retval = FALSE; 00263 break; 00264 } 00265 } 00266 while (response == GNC_RESPONSE_NEW); 00267 gtk_widget_destroy(picker->dialog); 00268 } 00269 else 00270 { 00271 retval_name = xaccAccountGetName(retval); 00272 ok_pressed_retval = TRUE; /* There was no dialog involved, so the computer "pressed" ok */ 00273 } 00274 /*FIXME: DEBUG("WRITEME: gnc_import_select_account() Here we should check if account type is compatible, currency matches, etc.\n"); */ 00275 g_free(picker); 00276 /*DEBUG("Return value: %p%s%s%s",retval,", account name:",xaccAccountGetName(retval),"\n");*/ 00277 if (ok_pressed != NULL) 00278 { 00279 *ok_pressed = ok_pressed_retval; 00280 } 00281 LEAVE("Selected account %p, %s", retval, retval_name ? retval_name : "(null)"); 00282 return retval; 00283 }
| gnc_commodity * gnc_import_select_commodity | ( | char * | cusip, | |
| char | auto_create, | |||
| char * | default_fullname, | |||
| 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 account or create a new one (in both cases, the cusip is written to the commodity's cusip field, overwriting anything that was there before.
| cusip | The 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. | |
| auto_create | If 0, if the cusip value in unknown, the function returns NULL, otherwise, the user will be asked to create a new account. | |
| default_fullname | A 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_mnemonic | Usually 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. |
Definition at line 54 of file import-commodity-matcher.c.
00058 { 00059 gnc_commodity_table * commodity_table = gnc_get_current_commodities (); 00060 gnc_commodity * retval = NULL; 00061 gnc_commodity * tmp_commodity = NULL; 00062 char * tmp_namespace = NULL; 00063 GList * commodity_list = NULL; 00064 GList * namespace_list = NULL; 00065 DEBUG("Default fullname received: %s", 00066 default_fullname ? default_fullname : "(null)"); 00067 DEBUG("Default mnemonic received: %s", 00068 default_mnemonic ? default_mnemonic : "(null)"); 00069 00070 DEBUG("Looking for commodity with exchange_code: %s", cusip); 00071 00072 namespace_list = gnc_commodity_table_get_namespaces(commodity_table); 00073 00074 00075 namespace_list = g_list_first(namespace_list); 00076 while ( namespace_list != NULL && retval == NULL) 00077 { 00078 tmp_namespace = namespace_list->data; 00079 DEBUG("Looking at namespace %s", tmp_namespace); 00080 00081 00082 /*Nested loop*/ 00083 commodity_list = gnc_commodity_table_get_commodities(commodity_table, 00084 tmp_namespace); 00085 commodity_list = g_list_first(commodity_list); 00086 while ( commodity_list != NULL && retval == NULL) 00087 { 00088 tmp_commodity = commodity_list->data; 00089 DEBUG("Looking at commodity %s", gnc_commodity_get_fullname(tmp_commodity)); 00090 00091 if (gnc_commodity_get_cusip(tmp_commodity) != NULL && 00092 cusip != NULL && 00093 strncmp(gnc_commodity_get_cusip(tmp_commodity), cusip, strlen(cusip)) == 0) 00094 { 00095 retval = tmp_commodity; 00096 DEBUG("Commodity %s%s", gnc_commodity_get_fullname(retval), " matches."); 00097 } 00098 commodity_list = g_list_next(commodity_list); 00099 } 00100 /*End nested loop*/ 00101 00102 namespace_list = g_list_next(namespace_list); 00103 } 00104 00105 00106 00107 00108 g_list_free(commodity_list); 00109 g_list_free(namespace_list); 00110 00111 if (retval == NULL && auto_create != 0) 00112 { 00113 const gchar *message = 00114 _("Please select a commodity to match the following exchange " 00115 "specific code. Please note that the exchange code of the " 00116 "commodity you select will be overwritten."); 00117 retval = gnc_ui_select_commodity_modal_full(NULL, 00118 NULL, 00119 DIAG_COMM_ALL, 00120 message, 00121 cusip, 00122 default_fullname, 00123 default_mnemonic); 00124 00125 } 00126 /* There seems to be a problem here - if the matched commodity does not 00127 have a cusip defined (gnc_commodity_get_cusip returns NULL) then 00128 it does not get overwritten - which is not consistent with the 00129 message - so Im adding it to do this. Looks like this is all 00130 that was needed to fix the cash value used as stock units problem 00131 for pre-defined commodities which didnt have the cusip defined! */ 00132 if (retval != NULL && 00133 gnc_commodity_get_cusip(retval) != NULL && 00134 cusip != NULL && 00135 (strncmp(gnc_commodity_get_cusip(retval), cusip, strlen(cusip)) != 0)) 00136 { 00137 gnc_commodity_set_cusip(retval, cusip); 00138 } 00139 else if (gnc_commodity_get_cusip(retval) == NULL && cusip != NULL) 00140 { 00141 gnc_commodity_set_cusip(retval, cusip); 00142 } 00143 return retval; 00144 };
| void gnc_import_Settings_delete | ( | GNCImportSettings * | settings | ) |
| gboolean gnc_import_Settings_get_action_add_enabled | ( | GNCImportSettings * | settings | ) |
| gboolean gnc_import_Settings_get_action_clear_enabled | ( | GNCImportSettings * | settings | ) |
| gboolean gnc_import_Settings_get_action_edit_enabled | ( | GNCImportSettings * | settings | ) |
| gboolean gnc_import_Settings_get_action_skip_enabled | ( | GNCImportSettings * | settings | ) |
| gint gnc_import_Settings_get_add_threshold | ( | GNCImportSettings * | settings | ) |
| gint gnc_import_Settings_get_clear_threshold | ( | GNCImportSettings * | settings | ) |
| gint gnc_import_Settings_get_display_threshold | ( | GNCImportSettings * | settings | ) |
| double gnc_import_Settings_get_fuzzy_amount | ( | GNCImportSettings * | settings | ) |
Return the allowed amount range for fuzzy amount matching.
Definition at line 116 of file import-settings.c.
| 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 169 of file import-settings.c.
| GNCImportSettings * gnc_import_Settings_new | ( | void | ) |
Allocates a new GNCImportSettings object, and initialize it with the appropriate user prefs.
Definition at line 79 of file import-settings.c.
00080 { 00081 GNCImportSettings * settings; 00082 00083 settings = g_new0 ( GNCImportSettings, 1); 00084 00085 00086 settings->action_skip_enabled = 00087 gnc_gconf_get_bool(GCONF_SECTION, "enable_skip", NULL); 00088 settings->action_edit_enabled = 00089 gnc_gconf_get_bool(GCONF_SECTION, "enable_edit", NULL); 00090 settings->action_add_enabled = DEFAULT_ACTION_ADD_ENABLED; 00091 settings->action_clear_enabled = DEFAULT_ACTION_CLEAR_ENABLED; 00092 settings->clear_threshold = 00093 gnc_gconf_get_float(GCONF_SECTION, "auto_clear_threshold", NULL); 00094 settings->add_threshold = 00095 gnc_gconf_get_float(GCONF_SECTION, "auto_add_threshold", NULL); 00096 settings->display_threshold = 00097 gnc_gconf_get_float(GCONF_SECTION, "match_threshold", NULL); 00098 00099 settings->fuzzy_amount = 00100 gnc_gconf_get_float(GCONF_SECTION, "atm_fee_threshold", NULL); 00101 00102 settings->match_date_hardlimit = 42; /* 6 weeks */ 00103 return settings; 00104 }
| void gnc_import_Settings_set_match_date_hardlimit | ( | GNCImportSettings * | settings, | |
| gint | match_date_hardlimit | |||
| ) |
| match_date_hardlimit | The 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 164 of file import-settings.c.
| void gnc_import_TransInfo_delete | ( | GNCImportTransInfo * | info | ) |
Destructor
Definition at line 236 of file import-backend.c.
00237 { 00238 if (info) 00239 { 00240 g_list_free (info->match_list); 00241 /*If the transaction exists and is still open, it must be destroyed*/ 00242 if (info->trans && xaccTransIsOpen(info->trans)) 00243 { 00244 xaccTransDestroy(info->trans); 00245 xaccTransCommitEdit(info->trans); 00246 } 00247 if (info->match_tokens) 00248 { 00249 GList *node; 00250 00251 for (node = info->match_tokens; node; node = node->next) 00252 g_free (node->data); 00253 00254 g_list_free (info->match_tokens); 00255 } 00256 g_free(info); 00257 } 00258 }
| GNCImportAction gnc_import_TransInfo_get_action | ( | const GNCImportTransInfo * | info | ) |
Returns the currently selected action for this TransInfo.
Definition at line 170 of file import-backend.c.
| Account * gnc_import_TransInfo_get_destacc | ( | const GNCImportTransInfo * | info | ) |
Returns the 'other account' of this transaction. May return NULL.
Definition at line 189 of file import-backend.c.
| 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 210 of file import-backend.c.
| Split * gnc_import_TransInfo_get_fsplit | ( | const GNCImportTransInfo * | info | ) |
Returns the first split of the transaction of this TransInfo.
Definition at line 139 of file import-backend.c.
| GList * gnc_import_TransInfo_get_match_list | ( | const GNCImportTransInfo * | info | ) |
| 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 163 of file import-backend.c.
| GNCImportMatchInfo * gnc_import_TransInfo_get_selected_match | ( | const GNCImportTransInfo * | info | ) |
Returns the currently selected match in this TransInfo.
Definition at line 146 of file import-backend.c.
| Transaction * gnc_import_TransInfo_get_trans | ( | const GNCImportTransInfo * | info | ) |
| 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.
| trans_info | The TransInfo for which the matches should be found, sorted, and selected. | |
| settings | The structure that holds all the user preferences. |
Definition at line 1074 of file import-backend.c.
01076 { 01077 GNCImportMatchInfo * best_match; 01078 g_assert (trans_info); 01079 01080 01081 /* Find all split matches in originating account. */ 01082 gnc_import_find_split_matches(trans_info, 01083 gnc_import_Settings_get_display_threshold (settings), 01084 gnc_import_Settings_get_fuzzy_amount (settings), 01085 gnc_import_Settings_get_match_date_hardlimit (settings)); 01086 01087 if (trans_info->match_list != NULL) 01088 { 01089 trans_info->match_list = g_list_sort(trans_info->match_list, 01090 compare_probability); 01091 best_match = g_list_nth_data(trans_info->match_list, 0); 01092 gnc_import_TransInfo_set_selected_match (trans_info, 01093 best_match, 01094 FALSE); 01095 if (best_match != NULL && 01096 best_match->probability >= gnc_import_Settings_get_clear_threshold(settings)) 01097 { 01098 trans_info->action = GNCImport_CLEAR; 01099 trans_info->selected_match_info = best_match; 01100 } 01101 else if (best_match == NULL || 01102 best_match->probability <= gnc_import_Settings_get_add_threshold(settings) ) 01103 { 01104 trans_info->action = GNCImport_ADD; 01105 } 01106 else 01107 { 01108 trans_info->action = GNCImport_SKIP; 01109 } 01110 } 01111 else 01112 trans_info->action = GNCImport_ADD; 01113 01114 trans_info->previous_action = trans_info->action; 01115 }
| gboolean gnc_import_TransInfo_is_balanced | ( | const GNCImportTransInfo * | info | ) |
Returns if the transaction stored in the TransInfo is currently balanced.
Definition at line 122 of file import-backend.c.
00123 { 00124 g_assert (info); 00125 /* Assume that the importer won't create a transaction that involves two or more 00126 currencies and no non-currency commodity. In that case can use the simpler 00127 value imbalance check. */ 00128 if (gnc_numeric_zero_p(xaccTransGetImbalanceValue(gnc_import_TransInfo_get_trans(info)))) 00129 { 00130 return TRUE; 00131 } 00132 else 00133 { 00134 return FALSE; 00135 } 00136 }
| 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.
| trans | The transaction that this TransInfo should work with. | |
| matchmap | MatchMap 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 1041 of file import-backend.c.
01042 { 01043 GNCImportTransInfo *transaction_info; 01044 g_assert (trans); 01045 01046 transaction_info = g_new0(GNCImportTransInfo, 1); 01047 01048 transaction_info->trans = trans; 01049 /* Only use first split, the source split */ 01050 transaction_info->first_split = xaccTransGetSplit(trans, 0); 01051 01052 /* Try to find a previously selected destination account 01053 string match for the ADD action */ 01054 gnc_import_TransInfo_set_destacc (transaction_info, 01055 matchmap_find_destination (matchmap, transaction_info), 01056 FALSE); 01057 return transaction_info; 01058 }
| gboolean gnc_import_TransInfo_refresh_destacc | ( | GNCImportTransInfo * | transaction_info, | |
| GncImportMatchMap * | matchmap | |||
| ) |
Try to automatch a given transaction to a destination account
Definition at line 1121 of file import-backend.c.
01123 { 01124 Account *orig_destacc; 01125 Account *new_destacc = NULL; 01126 g_assert(transaction_info); 01127 01128 orig_destacc = gnc_import_TransInfo_get_destacc(transaction_info); 01129 01130 /* if we haven't manually selected a destination account for this transaction */ 01131 if (gnc_import_TransInfo_get_destacc_selected_manually(transaction_info) == FALSE) 01132 { 01133 /* Try to find the destination account for this transaction based on prior ones */ 01134 new_destacc = matchmap_find_destination(matchmap, transaction_info); 01135 gnc_import_TransInfo_set_destacc(transaction_info, new_destacc, FALSE); 01136 } 01137 else 01138 { 01139 new_destacc = orig_destacc; 01140 } 01141 01142 /* account has changed */ 01143 if (new_destacc != orig_destacc) 01144 { 01145 return TRUE; 01146 } 01147 else /* account is the same */ 01148 { 01149 return FALSE; 01150 } 01151 }
| void gnc_import_TransInfo_set_action | ( | GNCImportTransInfo * | info, | |
| GNCImportAction | action | |||
| ) |
Set the action for this TransInfo. Also sets the previous action.
Definition at line 177 of file import-backend.c.
00179 { 00180 g_assert (info); 00181 if (action != info->action) 00182 { 00183 info->previous_action = info->action; 00184 info->action = action; 00185 } 00186 }
| 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.
| selected_manually | TRUE or FALSE; Was this account set as a result of a selection by the user or by an algorithm? |
Definition at line 194 of file import-backend.c.
00197 { 00198 g_assert (info); 00199 info->dest_acc = acc; 00200 info->dest_acc_selected_manually = selected_manually; 00201 00202 /* Store the mapping to the other account in the MatchMap. */ 00203 if (selected_manually) 00204 { 00205 matchmap_store_destination (NULL, info, FALSE); 00206 } 00207 }
| void gnc_import_TransInfo_set_selected_match | ( | GNCImportTransInfo * | info, | |
| GNCImportMatchInfo * | match, | |||
| gboolean | selected_manually | |||
| ) |
Sets the currently selected match in this TransInfo.
| selected_manually | TRUE or FALSE; Was this match set as a result of a selection by the user or by an algorithm? |
Definition at line 153 of file import-backend.c.
00156 { 00157 g_assert (info); 00158 info->selected_match_info = match; 00159 info->match_selected_manually = selected_manually; 00160 }
1.5.7.1