mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 739571 - Matching imported transactions doesn't indicate previously matched entries
Track pending matches from the current import and display this information in the match picker. Conflicts: src/import-export/gschemas/org.gnucash.dialogs.import.generic.gschema.xml.in.in src/import-export/import-match-picker.c https://bugzilla.gnome.org/show_bug.cgi?id=739571
This commit is contained in:
committed by
Geert Janssens
parent
082d0f305b
commit
9f3ad55104
@@ -28,6 +28,7 @@ SET (generic_import_SOURCES
|
||||
import-utilities.c
|
||||
import-settings.c
|
||||
import-main-matcher.c
|
||||
import-pending-matches.c
|
||||
gncmod-generic-import.c
|
||||
)
|
||||
|
||||
@@ -45,6 +46,7 @@ SET (generic_import_noinst_HEADERS
|
||||
import-commodity-matcher.h
|
||||
import-main-matcher.h
|
||||
import-match-picker.h
|
||||
import-pending-matches.h
|
||||
import-settings.h
|
||||
import-utilities.h
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ libgncmod_generic_import_la_SOURCES = \
|
||||
import-settings.c \
|
||||
import-match-map.c \
|
||||
import-main-matcher.c \
|
||||
import-pending-matches.c \
|
||||
gncmod-generic-import.c
|
||||
|
||||
gncincludedir = ${GNC_INCLUDE_DIR}
|
||||
@@ -35,6 +36,7 @@ noinst_HEADERS = \
|
||||
import-match-map.h \
|
||||
import-match-picker.h \
|
||||
import-settings.h \
|
||||
import-pending-matches.h \
|
||||
import-utilities.h
|
||||
|
||||
libgncmod_generic_import_la_LDFLAGS = -avoid-version
|
||||
|
||||
@@ -72,6 +72,12 @@ matchmap_store_destination (GncImportMatchMap *matchmap,
|
||||
* Structures passed between the functions *
|
||||
\********************************************************************/
|
||||
|
||||
struct _selected_match_info
|
||||
{
|
||||
GNCImportMatchInfo *selected_match;
|
||||
gboolean selected_manually;
|
||||
};
|
||||
|
||||
struct _transactioninfo
|
||||
{
|
||||
Transaction * trans;
|
||||
@@ -79,8 +85,7 @@ struct _transactioninfo
|
||||
|
||||
/* GList of GNCImportMatchInfo's, one for each possible duplicate match. */
|
||||
GList * match_list;
|
||||
GNCImportMatchInfo * selected_match_info;
|
||||
gboolean match_selected_manually;
|
||||
GNCImportSelectedMatchInfo selected_match_info;
|
||||
|
||||
GNCImportAction action;
|
||||
GNCImportAction previous_action;
|
||||
@@ -96,15 +101,6 @@ struct _transactioninfo
|
||||
guint32 ref_id;
|
||||
};
|
||||
|
||||
struct _matchinfo
|
||||
{
|
||||
Transaction * trans;
|
||||
Split * split;
|
||||
/*GNC_match_probability probability;*/
|
||||
gint probability;
|
||||
gboolean update_proposed;
|
||||
};
|
||||
|
||||
/* Some simple getters and setters for the above data types. */
|
||||
|
||||
GList *
|
||||
@@ -149,24 +145,24 @@ GNCImportMatchInfo *
|
||||
gnc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info)
|
||||
{
|
||||
g_assert (info);
|
||||
return info->selected_match_info;
|
||||
return info->selected_match_info.selected_match;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_import_TransInfo_set_selected_match (GNCImportTransInfo *info,
|
||||
gnc_import_TransInfo_set_selected_match_info (GNCImportTransInfo *info,
|
||||
GNCImportMatchInfo *match,
|
||||
gboolean selected_manually)
|
||||
{
|
||||
g_assert (info);
|
||||
info->selected_match_info = match;
|
||||
info->match_selected_manually = selected_manually;
|
||||
info->selected_match_info.selected_match = match;
|
||||
info->selected_match_info.selected_manually = selected_manually;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_import_TransInfo_get_match_selected_manually (const GNCImportTransInfo *info)
|
||||
{
|
||||
g_assert (info);
|
||||
return info->match_selected_manually;
|
||||
return info->selected_match_info.selected_manually;
|
||||
}
|
||||
|
||||
GNCImportAction
|
||||
@@ -1202,14 +1198,13 @@ gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info,
|
||||
trans_info->match_list = g_list_sort(trans_info->match_list,
|
||||
compare_probability);
|
||||
best_match = g_list_nth_data(trans_info->match_list, 0);
|
||||
gnc_import_TransInfo_set_selected_match (trans_info,
|
||||
gnc_import_TransInfo_set_selected_match_info (trans_info,
|
||||
best_match,
|
||||
FALSE);
|
||||
if (best_match != NULL &&
|
||||
best_match->probability >= gnc_import_Settings_get_clear_threshold(settings))
|
||||
{
|
||||
trans_info->action = GNCImport_CLEAR;
|
||||
trans_info->selected_match_info = best_match;
|
||||
}
|
||||
else if (best_match == NULL ||
|
||||
best_match->probability <= gnc_import_Settings_get_add_threshold(settings))
|
||||
|
||||
@@ -25,15 +25,23 @@
|
||||
@author Copyright (c) 2006 David Hampton <hampton@employees.org>
|
||||
*/
|
||||
|
||||
#ifndef TRANSACTION_MATCHER_H
|
||||
#define TRANSACTION_MATCHER_H
|
||||
#ifndef IMPORT_BACKEND_H
|
||||
#define IMPORT_BACKEND_H
|
||||
|
||||
#include "Transaction.h"
|
||||
#include "import-match-map.h"
|
||||
#include "import-settings.h"
|
||||
|
||||
typedef struct _transactioninfo GNCImportTransInfo;
|
||||
typedef struct _matchinfo GNCImportMatchInfo;
|
||||
typedef struct _selected_match_info GNCImportSelectedMatchInfo;
|
||||
typedef struct _matchinfo
|
||||
{
|
||||
Transaction * trans;
|
||||
Split * split;
|
||||
/*GNC_match_probability probability;*/
|
||||
gint probability;
|
||||
gboolean update_proposed;
|
||||
} GNCImportMatchInfo;
|
||||
|
||||
typedef enum _action
|
||||
{
|
||||
@@ -187,7 +195,7 @@ gnc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info);
|
||||
by the user or by an algorithm?
|
||||
*/
|
||||
void
|
||||
gnc_import_TransInfo_set_selected_match (GNCImportTransInfo *info,
|
||||
gnc_import_TransInfo_set_selected_match_info (GNCImportTransInfo *info,
|
||||
GNCImportMatchInfo *match,
|
||||
gboolean selected_manually);
|
||||
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
#include "import-match-picker.h"
|
||||
#include "import-backend.h"
|
||||
#include "import-account-matcher.h"
|
||||
#include "import-pending-matches.h"
|
||||
#include "app-utils/gnc-component-manager.h"
|
||||
#include "guid.h"
|
||||
|
||||
#define GNC_PREFS_GROUP "dialogs.import.generic.transaction-list"
|
||||
|
||||
@@ -64,6 +66,7 @@ struct _main_matcher_info
|
||||
int selected_row;
|
||||
GNCTransactionProcessedCB transaction_processed_cb;
|
||||
gpointer user_data;
|
||||
GNCImportPendingMatches *pending_matches;
|
||||
};
|
||||
|
||||
enum downloaded_cols
|
||||
@@ -260,7 +263,7 @@ static void
|
||||
run_match_dialog (GNCImportMainMatcher *info,
|
||||
GNCImportTransInfo *trans_info)
|
||||
{
|
||||
gnc_import_match_picker_run_and_close (trans_info);
|
||||
gnc_import_match_picker_run_and_close (trans_info, info->pending_matches);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -516,6 +519,7 @@ GNCImportMainMatcher *gnc_gen_trans_list_new (GtkWidget *parent,
|
||||
gboolean show_update;
|
||||
|
||||
info = g_new0 (GNCImportMainMatcher, 1);
|
||||
info->pending_matches = gnc_import_PendingMatches_new();
|
||||
|
||||
/* Initialize user Settings. */
|
||||
info->user_settings = gnc_import_Settings_new ();
|
||||
@@ -881,6 +885,9 @@ void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transac
|
||||
GNCImportTransInfo * transaction_info = NULL;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GNCImportMatchInfo *selected_match;
|
||||
GncGUID *pending_match_guid;
|
||||
gboolean match_selected_manually;
|
||||
g_assert (gui);
|
||||
g_assert (trans);
|
||||
|
||||
@@ -894,6 +901,15 @@ void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transac
|
||||
|
||||
gnc_import_TransInfo_init_matches(transaction_info,
|
||||
gui->user_settings);
|
||||
|
||||
selected_match =
|
||||
gnc_import_TransInfo_get_selected_match(transaction_info);
|
||||
match_selected_manually =
|
||||
gnc_import_TransInfo_get_match_selected_manually(transaction_info);
|
||||
|
||||
gnc_import_PendingMatches_add_match(gui->pending_matches,
|
||||
selected_match,
|
||||
match_selected_manually);
|
||||
|
||||
model = gtk_tree_view_get_model(gui->view);
|
||||
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
|
||||
|
||||
@@ -33,11 +33,13 @@
|
||||
|
||||
#include "import-backend.h"
|
||||
#include "import-match-picker.h"
|
||||
#include "import-pending-matches.h"
|
||||
|
||||
#include "qof.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "dialog-utils.h"
|
||||
#include "gnc-prefs.h"
|
||||
|
||||
/********************************************************************\
|
||||
* Constants *
|
||||
\********************************************************************/
|
||||
@@ -66,6 +68,7 @@ enum matcher_cols
|
||||
MATCHER_COL_DESCRIPTION,
|
||||
MATCHER_COL_MEMO,
|
||||
MATCHER_COL_RECONCILED,
|
||||
MATCHER_COL_PENDING,
|
||||
MATCHER_COL_INFO_PTR,
|
||||
NUM_MATCHER_COLS
|
||||
};
|
||||
@@ -92,6 +95,7 @@ struct _transpickerdialog
|
||||
GNCImportSettings * user_settings;
|
||||
struct _transactioninfo * selected_trans_info;
|
||||
GNCImportMatchInfo * selected_match_info;
|
||||
GNCImportPendingMatches * pending_matches;
|
||||
};
|
||||
|
||||
|
||||
@@ -186,9 +190,10 @@ match_update_match_model (GNCImportMatchPicker *matcher)
|
||||
GList * list_element;
|
||||
gchar *text;
|
||||
const gchar *ro_text;
|
||||
GNCImportPendingMatchType pending_match_type;
|
||||
|
||||
show_reconciled = gtk_toggle_button_get_active(
|
||||
GTK_TOGGLE_BUTTON(matcher->reconciled_chk));
|
||||
show_reconciled = gtk_toggle_button_get_active
|
||||
(GTK_TOGGLE_BUTTON(matcher->reconciled_chk));
|
||||
|
||||
/* Now rewrite the "match" model based on that trans. */
|
||||
match_store = GTK_LIST_STORE(gtk_tree_view_get_model(matcher->match_view));
|
||||
@@ -200,11 +205,11 @@ match_update_match_model (GNCImportMatchPicker *matcher)
|
||||
match_info = list_element->data;
|
||||
|
||||
/* Skip this match if reconciled and we're not showing those */
|
||||
reconciled = xaccSplitGetReconcile(
|
||||
gnc_import_MatchInfo_get_split(match_info));
|
||||
reconciled = xaccSplitGetReconcile
|
||||
(gnc_import_MatchInfo_get_split(match_info));
|
||||
if (show_reconciled == FALSE && reconciled != NREC)
|
||||
{
|
||||
list_element = g_list_next(list_element);
|
||||
list_element = g_list_next (list_element);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -243,9 +248,27 @@ match_update_match_model (GNCImportMatchPicker *matcher)
|
||||
gtk_list_store_set(match_store, &iter, MATCHER_COL_MEMO, ro_text, -1);
|
||||
|
||||
/*Reconciled*/
|
||||
ro_text = gnc_get_reconcile_str(reconciled);
|
||||
gtk_list_store_set(match_store, &iter, MATCHER_COL_RECONCILED, ro_text,
|
||||
-1);
|
||||
ro_text = gnc_get_reconcile_str (reconciled);
|
||||
gtk_list_store_set (match_store, &iter, MATCHER_COL_RECONCILED, ro_text,
|
||||
-1);
|
||||
|
||||
/*Pending Action*/
|
||||
pending_match_type = gnc_import_PendingMatches_get_match_type
|
||||
(matcher->pending_matches, match_info);
|
||||
|
||||
/* If it has a pending match mark it cleared, otherwise leave alone */
|
||||
if (pending_match_type == GNCImportPending_MANUAL ||
|
||||
pending_match_type == GNCImportPending_AUTO)
|
||||
{
|
||||
ro_text = gnc_get_reconcile_str (CREC);
|
||||
text = g_strdup_printf("%s (%s)",
|
||||
ro_text,
|
||||
gnc_import_PendingMatches_get_type_str
|
||||
(pending_match_type));
|
||||
|
||||
gtk_list_store_set (match_store, &iter, MATCHER_COL_PENDING, text, -1);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
gtk_list_store_set(match_store, &iter, MATCHER_COL_INFO_PTR, match_info, -1);
|
||||
if (gnc_import_MatchInfo_get_probability(match_info) != 0)
|
||||
@@ -391,7 +414,7 @@ gnc_import_match_picker_init_match_view (GNCImportMatchPicker * matcher)
|
||||
store = gtk_list_store_new(NUM_MATCHER_COLS,
|
||||
G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_POINTER);
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
|
||||
g_object_unref(store);
|
||||
|
||||
@@ -407,11 +430,12 @@ gnc_import_match_picker_init_match_view (GNCImportMatchPicker * matcher)
|
||||
NULL);
|
||||
gtk_tree_view_append_column(view, column);
|
||||
|
||||
add_column(view, _("Date"), MATCHER_COL_DATE);
|
||||
add_column(view, _("Amount"), MATCHER_COL_AMOUNT);
|
||||
add_column(view, _("Description"), MATCHER_COL_DESCRIPTION);
|
||||
add_column(view, _("Memo"), MATCHER_COL_MEMO);
|
||||
add_column(view, _("Reconciled"), MATCHER_COL_RECONCILED);
|
||||
add_column(view, _("Date"), MATCHER_COL_DATE);
|
||||
add_column(view, _("Amount"), MATCHER_COL_AMOUNT);
|
||||
add_column(view, _("Description"), MATCHER_COL_DESCRIPTION);
|
||||
add_column(view, _("Memo"), MATCHER_COL_MEMO);
|
||||
add_column(view, _("Reconciled"), MATCHER_COL_RECONCILED);
|
||||
add_column(view, _("Pending Action"), MATCHER_COL_PENDING);
|
||||
|
||||
selection = gtk_tree_view_get_selection(view);
|
||||
g_signal_connect(selection, "changed",
|
||||
@@ -463,6 +487,9 @@ init_match_picker_gui(GNCImportMatchPicker * matcher)
|
||||
gtk_signal_connect ((GtkObject *)matcher->reconciled_chk, "toggled",
|
||||
G_CALLBACK(match_show_reconciled_changed_cb), matcher);
|
||||
|
||||
/* now that we've bound the checkbox appropriately we can hook up the change callback */
|
||||
gtk_signal_connect((GtkObject *)matcher->reconciled_chk, "toggled", G_CALLBACK(match_show_reconciled_changed_cb), matcher);
|
||||
|
||||
gnc_restore_window_size(GNC_PREFS_GROUP,
|
||||
GTK_WINDOW (matcher->transaction_matcher));
|
||||
gtk_widget_show(matcher->transaction_matcher);
|
||||
@@ -477,28 +504,36 @@ init_match_picker_gui(GNCImportMatchPicker * matcher)
|
||||
* return after the user clicked Ok, Cancel, or Window-Close.
|
||||
*/
|
||||
void
|
||||
gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info)
|
||||
gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info,
|
||||
GNCImportPendingMatches *pending_matches)
|
||||
{
|
||||
GNCImportMatchPicker *matcher;
|
||||
gint response;
|
||||
GNCImportMatchInfo *old;
|
||||
gboolean old_selected_manually;
|
||||
g_assert (transaction_info);
|
||||
|
||||
/* Create a new match_picker, even though it's stored in a
|
||||
transmatcher struct :-) */
|
||||
matcher = g_new0(GNCImportMatchPicker, 1);
|
||||
|
||||
matcher->pending_matches = pending_matches;
|
||||
|
||||
/* DEBUG("Init match_picker"); */
|
||||
init_match_picker_gui(matcher);
|
||||
|
||||
/* Append this single transaction to the view and select it */
|
||||
downloaded_transaction_append(matcher, transaction_info);
|
||||
|
||||
old = gnc_import_TransInfo_get_selected_match(transaction_info);
|
||||
old = gnc_import_TransInfo_get_selected_match (transaction_info);
|
||||
old_selected_manually =
|
||||
gnc_import_TransInfo_get_match_selected_manually (transaction_info);
|
||||
|
||||
/* Let this dialog run and close. */
|
||||
/*DEBUG("Right before run and close");*/
|
||||
gtk_window_set_modal(GTK_WINDOW(matcher->transaction_matcher), TRUE);
|
||||
response = gtk_dialog_run (GTK_DIALOG (matcher->transaction_matcher));
|
||||
|
||||
gnc_save_window_size(GNC_PREFS_GROUP,
|
||||
GTK_WINDOW (matcher->transaction_matcher));
|
||||
gtk_widget_destroy (matcher->transaction_matcher);
|
||||
@@ -507,9 +542,16 @@ gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info)
|
||||
if (response == GTK_RESPONSE_OK && matcher->selected_match_info != old)
|
||||
{
|
||||
/* OK was pressed */
|
||||
gnc_import_TransInfo_set_selected_match (transaction_info,
|
||||
gnc_import_TransInfo_set_selected_match_info (transaction_info,
|
||||
matcher->selected_match_info,
|
||||
TRUE);
|
||||
|
||||
gnc_import_PendingMatches_remove_match (pending_matches,
|
||||
old,
|
||||
old_selected_manually);
|
||||
gnc_import_PendingMatches_add_match (pending_matches,
|
||||
matcher->selected_match_info,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define GNC_GEN_MATCH_PICKER_H
|
||||
|
||||
#include "import-backend.h"
|
||||
#include "import-pending-matches.h"
|
||||
|
||||
typedef struct _transpickerdialog GNCImportMatchPicker;
|
||||
|
||||
@@ -50,7 +51,8 @@ typedef struct _transpickerdialog GNCImportMatchPicker;
|
||||
* @param transaction_info The TransInfo for which the user is supposed to
|
||||
* pick a matching transaction. */
|
||||
void
|
||||
gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info);
|
||||
gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info,
|
||||
GNCImportPendingMatches *pending_matches);
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
||||
201
src/import-export/import-pending-matches.c
Normal file
201
src/import-export/import-pending-matches.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/********************************************************************\
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @internal
|
||||
@file import-pending-matches.c
|
||||
@brief The pending match container implementation to track import reconciles.
|
||||
@author Copyright (C) 2016 Jesse Olmer
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h> /* for references in import-backend.h */
|
||||
#include "guid.h"
|
||||
|
||||
#include "import-pending-matches.h"
|
||||
#include "import-backend.h"
|
||||
|
||||
typedef struct _pending_matches
|
||||
{
|
||||
gint num_manual_matches;
|
||||
gint num_auto_matches;
|
||||
} GNCPendingMatches;
|
||||
|
||||
GNCImportPendingMatches *gnc_import_PendingMatches_new (void)
|
||||
{
|
||||
/* Can't use guid_hash_table_new() here since we want values to be taken
|
||||
care of for us on destroy. */
|
||||
return g_hash_table_new_full (guid_hash_to_guint,
|
||||
guid_g_hash_table_equal,
|
||||
g_free,
|
||||
g_free
|
||||
);
|
||||
}
|
||||
|
||||
void gnc_import_PendingMatches_delete (GNCImportPendingMatches *map)
|
||||
{
|
||||
g_assert (map);
|
||||
|
||||
g_hash_table_destroy (map);
|
||||
}
|
||||
|
||||
static const GncGUID *
|
||||
gnc_import_PendingMatches_get_key (GNCImportMatchInfo *match_info)
|
||||
{
|
||||
Split *split;
|
||||
const GncGUID *match_guid;
|
||||
|
||||
g_assert (match_info);
|
||||
|
||||
split = gnc_import_MatchInfo_get_split (match_info);
|
||||
match_guid = qof_instance_get_guid (split);
|
||||
|
||||
return match_guid;
|
||||
}
|
||||
|
||||
static GNCPendingMatches *
|
||||
gnc_import_PendingMatches_get_value (GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info)
|
||||
{
|
||||
GNCPendingMatches *pending_matches;
|
||||
const GncGUID *match_guid;
|
||||
|
||||
g_assert (map);
|
||||
g_assert (match_info);
|
||||
|
||||
match_guid = gnc_import_PendingMatches_get_key (match_info);
|
||||
|
||||
pending_matches = g_hash_table_lookup (map, match_guid);
|
||||
|
||||
return pending_matches;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_import_PendingMatches_add_match (GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info,
|
||||
gboolean selected_manually)
|
||||
{
|
||||
GNCPendingMatches *pending_matches;
|
||||
const GncGUID *match_guid;
|
||||
GncGUID *key;
|
||||
|
||||
g_assert (map);
|
||||
g_assert (match_info);
|
||||
|
||||
|
||||
pending_matches = gnc_import_PendingMatches_get_value (map, match_info);
|
||||
match_guid = gnc_import_PendingMatches_get_key (match_info);
|
||||
|
||||
if (pending_matches == NULL)
|
||||
{
|
||||
pending_matches = g_new0 (GNCPendingMatches, 1);
|
||||
key = g_new (GncGUID, 1);
|
||||
*key = *match_guid;
|
||||
g_hash_table_insert (map, key, pending_matches);
|
||||
}
|
||||
|
||||
if (selected_manually)
|
||||
{
|
||||
pending_matches->num_manual_matches++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_matches->num_auto_matches++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gnc_import_PendingMatches_remove_match (GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info,
|
||||
gboolean selected_manually)
|
||||
{
|
||||
GNCPendingMatches *pending_matches;
|
||||
|
||||
g_assert (map);
|
||||
g_assert (match_info);
|
||||
|
||||
pending_matches = gnc_import_PendingMatches_get_value (map, match_info);
|
||||
|
||||
g_assert (pending_matches);
|
||||
|
||||
if (selected_manually)
|
||||
{
|
||||
pending_matches->num_manual_matches--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_matches->num_auto_matches--;
|
||||
}
|
||||
|
||||
if (pending_matches->num_auto_matches == 0 &&
|
||||
pending_matches->num_manual_matches == 0)
|
||||
{
|
||||
/* Key & Value are freed for us */
|
||||
g_hash_table_remove (map,
|
||||
gnc_import_PendingMatches_get_key (match_info));
|
||||
}
|
||||
}
|
||||
|
||||
GNCImportPendingMatchType
|
||||
gnc_import_PendingMatches_get_match_type (GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info)
|
||||
{
|
||||
GNCPendingMatches *pending_matches;
|
||||
|
||||
g_assert (map);
|
||||
g_assert (match_info);
|
||||
|
||||
pending_matches = gnc_import_PendingMatches_get_value (map, match_info);
|
||||
|
||||
if (pending_matches == NULL)
|
||||
{
|
||||
return GNCImportPending_NONE;
|
||||
}
|
||||
|
||||
if (pending_matches->num_manual_matches > 0)
|
||||
{
|
||||
return GNCImportPending_MANUAL;
|
||||
}
|
||||
|
||||
if (pending_matches->num_auto_matches > 0)
|
||||
{
|
||||
return GNCImportPending_AUTO;
|
||||
}
|
||||
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
const char *
|
||||
gnc_import_PendingMatches_get_type_str (GNCImportPendingMatchType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GNCImportPending_NONE:
|
||||
return _("None");
|
||||
case GNCImportPending_MANUAL:
|
||||
return _("Manual");
|
||||
case GNCImportPending_AUTO:
|
||||
return _("Auto");
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
62
src/import-export/import-pending-matches.h
Normal file
62
src/import-export/import-pending-matches.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/********************************************************************\
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\ *********************************************************************/
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @file import-pending-matches.h
|
||||
@brief Tracking container for pending match status.
|
||||
@author Copyright (C) 2016 Jesse Olmer
|
||||
*/
|
||||
|
||||
#ifndef IMPORT_PENDING_MATCHES_H
|
||||
#define IMPORT_PENDING_MATCHES_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "import-backend.h"
|
||||
|
||||
typedef GHashTable GNCImportPendingMatches;
|
||||
|
||||
typedef enum _import_match_type {
|
||||
GNCImportPending_NONE,
|
||||
GNCImportPending_AUTO,
|
||||
GNCImportPending_MANUAL
|
||||
} GNCImportPendingMatchType;
|
||||
|
||||
GNCImportPendingMatches * gnc_import_PendingMatches_new(void);
|
||||
|
||||
void gnc_import_PendingMatches_delete(GNCImportPendingMatches *map);
|
||||
|
||||
void
|
||||
gnc_import_PendingMatches_add_match(GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info,
|
||||
gboolean selected_manually);
|
||||
|
||||
void
|
||||
gnc_import_PendingMatches_remove_match(GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info,
|
||||
gboolean selected_manually);
|
||||
|
||||
GNCImportPendingMatchType
|
||||
gnc_import_PendingMatches_get_match_type(GNCImportPendingMatches *map,
|
||||
GNCImportMatchInfo *match_info);
|
||||
|
||||
const char *
|
||||
gnc_import_PendingMatches_get_type_str(GNCImportPendingMatchType type);
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
@@ -6,10 +6,12 @@ SET(GENERIC_IMPORT_TEST_INCLUDE_DIRS
|
||||
${CMAKE_SOURCE_DIR}/src/import-export
|
||||
${CMAKE_SOURCE_DIR}/src/libqof/qof
|
||||
${CMAKE_SOURCE_DIR}/src/test-core
|
||||
${CMAKE_SOURCE_DIR}/src/engine/test-core
|
||||
${GLIB2_INCLUDE_DIRS}
|
||||
${GUILE_INCLUDE_DIRS}
|
||||
)
|
||||
SET(GENERIC_IMPORT_TEST_LIBS gncmod-generic-import gnc-qof test-core)
|
||||
|
||||
SET(GENERIC_IMPORT_TEST_LIBS gncmod-generic-import gncmod-test-engine gnc-qof test-core)
|
||||
|
||||
GNC_ADD_TEST_WITH_GUILE(test-import-parse test-import-parse.c
|
||||
GENERIC_IMPORT_TEST_INCLUDE_DIRS GENERIC_IMPORT_TEST_LIBS
|
||||
@@ -17,3 +19,6 @@ GNC_ADD_TEST_WITH_GUILE(test-import-parse test-import-parse.c
|
||||
GNC_ADD_TEST(test-link-generic-import test-link.c
|
||||
GENERIC_IMPORT_TEST_INCLUDE_DIRS GENERIC_IMPORT_TEST_LIBS
|
||||
)
|
||||
GNC_ADD_TEST(test-import-pending-matches test-import-pending-matches.c
|
||||
GENERIC_IMPORT_TEST_INCLUDE_DIRS GENERIC_IMPORT_TEST_LIBS
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include $(top_srcdir)/test-templates/Makefile.decl
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/src \
|
||||
-I${top_srcdir}/src/gnc-module \
|
||||
@@ -6,6 +8,8 @@ AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/src/app-utils \
|
||||
-I${top_srcdir}/src/import-export \
|
||||
-I${top_srcdir}/src/libqof/qof \
|
||||
-I${top_srcdir}/src/engine/test-core \
|
||||
${GTK_CFLAGS} \
|
||||
${GUILE_CFLAGS} \
|
||||
${GLIB_CFLAGS}
|
||||
|
||||
@@ -53,3 +57,24 @@ TESTS_ENVIRONMENT = \
|
||||
check_PROGRAMS = \
|
||||
test-link \
|
||||
test-import-parse
|
||||
|
||||
TEST_PROGS += test-import-pending-matches
|
||||
|
||||
noinst_PROGRAMS = $(TEST_PROGS) $(check_PROGRAMS)
|
||||
|
||||
test_import_pending_matches_SOURCES = test-import-pending-matches.c
|
||||
|
||||
test_import_pending_matches_LDADD = \
|
||||
${top_builddir}/src/libqof/qof/libgnc-qof.la \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la \
|
||||
../libgncmod-generic-import.la \
|
||||
${top_builddir}/src/test-core/libtest-core.la \
|
||||
${top_builddir}/src/engine/test-core/libgncmod-test-engine.la \
|
||||
${GLIB_LIBS}
|
||||
|
||||
test_import_pending_matches_CFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
clean-local:
|
||||
rm -f translog.*
|
||||
|
||||
distclean-local: clean-local
|
||||
|
||||
131
src/import-export/test/test-import-pending-matches.c
Normal file
131
src/import-export/test/test-import-pending-matches.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <config.h>
|
||||
#include <unittest-support.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h> /* for references in import-backend.h */
|
||||
#include "import-backend.h"
|
||||
#include "import-pending-matches.h"
|
||||
#include "Split.h"
|
||||
#include "test-engine-stuff.h"
|
||||
|
||||
static const gchar *suitename = "/import-export/import-pending-matches";
|
||||
|
||||
typedef struct
|
||||
{
|
||||
QofBook *book;
|
||||
Account *account1;
|
||||
Account *account2;
|
||||
Transaction *txn;
|
||||
Split *split;
|
||||
GNCImportMatchInfo *match_info;
|
||||
} Fixture;
|
||||
|
||||
static void
|
||||
setup (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
fixture->book = qof_book_new();
|
||||
fixture->account1 = get_random_account (fixture->book);
|
||||
fixture->account2 = get_random_account (fixture->book);
|
||||
fixture->txn = get_random_transaction (fixture->book);
|
||||
fixture->split = get_random_split (fixture->book, fixture->account1,
|
||||
fixture->txn);
|
||||
fixture->match_info = g_new0 (GNCImportMatchInfo, 1);
|
||||
|
||||
fixture->match_info->split = fixture->split;
|
||||
}
|
||||
|
||||
static void
|
||||
teardown (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
g_free (fixture->match_info);
|
||||
xaccSplitDestroy (fixture->split);
|
||||
xaccTransDestroy (fixture->txn);
|
||||
xaccAccountBeginEdit (fixture->account1);
|
||||
xaccAccountDestroy (fixture->account1);
|
||||
xaccAccountBeginEdit (fixture->account2);
|
||||
xaccAccountDestroy (fixture->account2);
|
||||
qof_book_destroy (fixture->book);
|
||||
|
||||
test_clear_error_list();
|
||||
}
|
||||
|
||||
static void
|
||||
test_pending_matches_match_types (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GNCImportPendingMatches *matches = gnc_import_PendingMatches_new();
|
||||
GNCImportPendingMatchType match_types;
|
||||
|
||||
match_types = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
g_assert_true (match_types == GNCImportPending_NONE);
|
||||
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, FALSE);
|
||||
match_types = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
g_assert_true (match_types == GNCImportPending_AUTO);
|
||||
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, TRUE);
|
||||
match_types = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
g_assert_true (match_types == GNCImportPending_MANUAL);
|
||||
|
||||
gnc_import_PendingMatches_delete (matches);
|
||||
}
|
||||
|
||||
static void
|
||||
test_pending_matches_prefer_manual_match (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GNCImportPendingMatchType match_type;
|
||||
GNCImportPendingMatches *matches = gnc_import_PendingMatches_new();
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, TRUE);
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, FALSE);
|
||||
match_type = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
|
||||
g_assert_true (match_type == GNCImportPending_MANUAL);
|
||||
|
||||
gnc_import_PendingMatches_delete (matches);
|
||||
}
|
||||
|
||||
static void
|
||||
test_pending_matches_keeps_count (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GNCImportPendingMatchType auto_match;
|
||||
GNCImportPendingMatchType no_match;
|
||||
GNCImportPendingMatches *matches = gnc_import_PendingMatches_new();
|
||||
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, TRUE);
|
||||
gnc_import_PendingMatches_add_match (matches, fixture->match_info, TRUE);
|
||||
gnc_import_PendingMatches_remove_match (matches, fixture->match_info, TRUE);
|
||||
|
||||
auto_match = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
|
||||
gnc_import_PendingMatches_remove_match (matches, fixture->match_info, TRUE);
|
||||
|
||||
no_match = gnc_import_PendingMatches_get_match_type (matches,
|
||||
fixture->match_info);
|
||||
|
||||
g_assert_true (auto_match != no_match);
|
||||
g_assert_true (no_match == GNCImportPending_NONE);
|
||||
|
||||
gnc_import_PendingMatches_delete (matches);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int result;
|
||||
qof_init();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
GNC_TEST_ADD (suitename, "match_types", Fixture, NULL, setup,
|
||||
test_pending_matches_match_types, teardown);
|
||||
GNC_TEST_ADD (suitename, "prefer_manual_match", Fixture, NULL, setup,
|
||||
test_pending_matches_prefer_manual_match, teardown);
|
||||
GNC_TEST_ADD (suitename, "keeps_count", Fixture, NULL, setup,
|
||||
test_pending_matches_keeps_count, teardown);
|
||||
result = g_test_run();
|
||||
|
||||
qof_close();
|
||||
}
|
||||
Reference in New Issue
Block a user