2002-12-6 Benoit Gr�goire <bock@step.polymtl.ca>

Huge patch, this is the new generic import
	architecture/transaction matcher.  Many old
	files were renamed, split or deleted.

	* src/engine/Transaction.c,h:
	- Add a DxaccSplitSetAmount function,
	- Fix a bug in xaccSplitsComputeValue (Split values were
	sometimes being summed, which is illogical) that caused
	xaccTransGetImbalance to sometimes return incorrect values.
	Somebody please review this.  Playing in the engine during
	freeze isn't ideal.

	* src/import-export/import-backend.c,h: There is now a
	real backend, completely independent of the GUI.

	* src/import-export/gnc-gen-transaction.c: This is Christian's
	old matcher, I tried to maintain compatibility, but couldn't
	really test.  Please note that there is some code
	simplification that could be done there now that there is a
	clean backend, and that some values passed between the functions
	might no longuer have any effect.

	* src/import-export/ofx/gnc-ofx-import.c:  Update for new
	matcher.  Use the currency reported by libofx and
	xaccSpiltSetBaseValue when adding a banking/credit card
	transaction.

	* src/import-export/import-account-matcher.c,h: This is a
	very generic and flexible account matcher/picker.

	* src/import-export/import-commodity-matcher.c,h: This is
	a generic commodity matcher/picker.

	* src/import-export/import-main-matcher.c,h: This is the
	main transaction matcher GUI. It's mostly feature complete
	and should be fairly stable, but probably leaks memory.

	* src/import-export/import-match-map.c,h: Derek Atkin's
	generic string/account matching infrastructure.

	* src/import-export/import-match-picker.c,h:  This is the
	interface to pick a matching transaction.  It has been
	completely ripped from the backend.

	* src/import-export/import-settings.c,h:  All user
	settings (or compiled-in settings) are now abstracted in
	an opaque structure with getter functions.

	* src/import-export/import-utilities.c:	These are utility
	functions to help import module writers.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7632 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Benoit Grégoire 2002-12-07 00:34:28 +00:00
parent 06e6ad6483
commit b6092223f6
27 changed files with 2916 additions and 2122 deletions

View File

@ -1,3 +1,56 @@
2002-12-6 Benoit Grégoire <bock@step.polymtl.ca>
Huge patch, this is the new generic import
architecture/transaction matcher. Many old
files were renamed, split or deleted.
* src/engine/Transaction.c,h:
- Add a DxaccSplitSetAmount function,
- Fix a bug in xaccSplitsComputeValue (Split values were
sometimes being summed, which is illogical) that caused
xaccTransGetImbalance to sometimes return incorrect values.
Somebody please review this. Playing in the engine during
freeze isn't ideal.
* src/import-export/import-backend.c,h: There is now a
real backend, completely independent of the GUI.
* src/import-export/gnc-gen-transaction.c: This is Christian's
old matcher, I tried to maintain compatibility, but couldn't
really test. Please note that there is some code
simplification that could be done there now that there is a
clean backend, and that some values passed between the functions
might no longuer have any effect.
* src/import-export/ofx/gnc-ofx-import.c: Update for new
matcher. Use the currency reported by libofx and
xaccSpiltSetBaseValue when adding a banking/credit card
transaction.
* src/import-export/import-account-matcher.c,h: This is a
very generic and flexible account matcher/picker.
* src/import-export/import-commodity-matcher.c,h: This is
a generic commodity matcher/picker.
* src/import-export/import-main-matcher.c,h: This is the
main transaction matcher GUI. It's mostly feature complete
and should be fairly stable, but probably leaks memory.
* src/import-export/import-match-map.c,h: Derek Atkin's
generic string/account matching infrastructure.
* src/import-export/import-match-picker.c,h: This is the
interface to pick a matching transaction. It has been
completely ripped from the backend.
* src/import-export/import-settings.c,h: All user
settings (or compiled-in settings) are now abstracted in
an opaque structure with getter functions.
* src/import-export/import-utilities.c: These are utility
functions to help import module writers.
2002-12-06 Christian Stimming <stimming@tuhh.de>
* po/nl.po, po/uk.po: Updated translations by Hendrik-Jan Heins

View File

@ -665,6 +665,21 @@ DxaccSplitSetShareAmount (Split *s, double damt)
gen_event (s);
}
void
DxaccSplitSetAmount (Split *s, double damt)
{
gnc_numeric amt = double_to_gnc_numeric(damt,
get_currency_denom(s),
GNC_RND_ROUND);
if (!s) return;
check_open (s->parent);
s->amount = gnc_numeric_convert(amt, get_commodity_denom(s), GNC_RND_ROUND);
mark_split (s);
gen_event (s);
}
void
xaccSplitSetAmount (Split *s, gnc_numeric amt)
{
@ -1322,7 +1337,7 @@ xaccSplitsComputeValue (GList *splits, Split * skip_me,
* doesn't mean the denominators are the same! */
if (base_currency &&
gnc_commodity_equiv(currency, base_currency)) {
value = gnc_numeric_add(value, s->value,
value = gnc_numeric_add(value, s->amount,
GNC_DENOM_AUTO, GNC_DENOM_LCD);
}
else if (base_currency &&

View File

@ -357,11 +357,17 @@ Timespec xaccSplitRetDateReconciledTS (Split *split);
* update the share price and the number of shares. This
* is a utility routine that is equivalent to a xaccSplitSetSharePrice()
* followed by and xaccSplitSetAmount(), except that it incurs the
* processing overhead of balancing only once, instead of twice. */
* processing overhead of balancing only once, instead of twice.
*
* WARNING: The xaccSplitSetValue and DxaccSplitSetValue do NOT have the same
* behavior. The later divides the value given by the current value and set's
* the result as the new split value. Is that a but or just strange undocumented
* feature? Benoit Grégoire 2002-6-12 */
void DxaccSplitSetSharePriceAndAmount (Split *split, double price,
double amount);
void DxaccSplitSetShareAmount (Split *split, double amount);
void DxaccSplitSetAmount (Split *s, double damt);
void DxaccSplitSetSharePrice (Split *split, double price);
void DxaccSplitSetValue (Split *split, double value);
void DxaccSplitSetBaseValue (Split *split, double value,

View File

@ -3,24 +3,30 @@ SUBDIRS = . binary-import qif-import ${OFX_DIR} ${HBCI_DIR} test
pkglib_LTLIBRARIES=libgncmod-generic-import.la
libgncmod_generic_import_la_SOURCES = \
Account-matcher.c \
Commodity-matcher.c \
Transaction-matcher.c \
gnc-gen-utilities.c \
gnc-import-match-map.c \
import-account-matcher.c \
import-commodity-matcher.c \
import-backend.c \
import-match-picker.c \
import-utilities.c \
import-settings.c \
import-match-map.c \
gnc-gen-transaction.c \
import-main-matcher.c \
gncmod-generic-import.c
gncincludedir = ${GNC_INCLUDE_DIR}
gncinclude_HEADERS = \
gnc-import-match-map.h
import-match-map.h
noinst_HEADERS = \
gnc-gen-transaction.h \
Transaction-matcher.h \
Account-matcher.h \
Commodity-matcher.h \
gnc-gen-utilities.h
import-main-matcher.h \
import-backend.h \
import-match-picker.h \
import-account-matcher.h \
import-commodity-matcher.h \
import-utilities.h \
import-settings.h
libgncmod_generic_import_la_LDFLAGS = -module

File diff suppressed because it is too large Load Diff

View File

@ -283,7 +283,9 @@
<class>GtkButton</class>
<name>matcher_ok</name>
<can_default>True</can_default>
<has_default>True</has_default>
<can_focus>True</can_focus>
<has_focus>True</has_focus>
<signal>
<name>clicked</name>
<handler>on_matcher_ok_clicked</handler>
@ -320,8 +322,8 @@
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox1</name>
<class>GtkVBox</class>
<name>vbox3</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
@ -331,165 +333,29 @@
</child>
<widget>
<class>GtkVBox</class>
<name>vbox3</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<class>GtkLabel</class>
<name>heading_label</name>
<label>List of downloaded transactions (source split shown):</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label847721</name>
<label>List of downloaded transactions (source split shown):</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow25</name>
<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkCList</class>
<name>downloaded_clist</name>
<can_focus>True</can_focus>
<signal>
<name>select_row</name>
<handler>downloaded_transaction_select_cb</handler>
<last_modification_time>Thu, 22 Aug 2002 01:37:44 GMT</last_modification_time>
</signal>
<signal>
<name>unselect_row</name>
<handler>downloaded_transaction_unselect_cb</handler>
<last_modification_time>Thu, 22 Aug 2002 02:05:02 GMT</last_modification_time>
</signal>
<columns>7</columns>
<column_widths>80,80,80,80,80,80,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847716</name>
<label>Action</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847717</name>
<label>Account</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847718</name>
<label>Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847719</name>
<label>Amount</label>
<justify>GTK_JUSTIFY_RIGHT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847720</name>
<label>Description</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847730</name>
<label>Memo</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847732</name>
<label>Imbalance</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox2</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<class>GtkScrolledWindow</class>
<name>scrolledwindow25</name>
<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
<expand>True</expand>
@ -497,119 +363,153 @@
</child>
<widget>
<class>GtkLabel</class>
<name>label847722</name>
<label>Potential splits matching the selected transaction: </label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow26</name>
<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<class>GtkCList</class>
<name>downloaded_clist</name>
<can_focus>True</can_focus>
<signal>
<name>select_row</name>
<handler>downloaded_transaction_select_cb</handler>
<last_modification_time>Thu, 22 Aug 2002 01:37:44 GMT</last_modification_time>
</signal>
<signal>
<name>unselect_row</name>
<handler>downloaded_transaction_unselect_cb</handler>
<last_modification_time>Thu, 22 Aug 2002 02:05:02 GMT</last_modification_time>
</signal>
<columns>10</columns>
<column_widths>67,133,49,127,80,58,32,29,34,33</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkCList</class>
<name>match_clist</name>
<can_focus>True</can_focus>
<signal>
<name>select_row</name>
<handler>match_transaction_select_cb</handler>
<last_modification_time>Fri, 23 Aug 2002 00:41:39 GMT</last_modification_time>
</signal>
<signal>
<name>unselect_row</name>
<handler>match_transaction_unselect_cb</handler>
<last_modification_time>Fri, 23 Aug 2002 00:41:59 GMT</last_modification_time>
</signal>
<columns>5</columns>
<column_widths>80,80,80,80,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847716</name>
<label>Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847723</name>
<label>Confidence</label>
<justify>GTK_JUSTIFY_RIGHT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847717</name>
<label>Account</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847724</name>
<label>Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847718</name>
<label>Amount</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847725</name>
<label>Amount</label>
<justify>GTK_JUSTIFY_RIGHT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847719</name>
<label>Description</label>
<justify>GTK_JUSTIFY_RIGHT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847726</name>
<label>Description</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847720</name>
<label>Memo</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847731</name>
<label>Memo</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847730</name>
<label>Imbalance</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847786</name>
<label>ADD</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847787</name>
<label>CLEAR</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847788</name>
<label>EDIT</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847789</name>
<label>Action that will be taken</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
@ -879,12 +779,12 @@ click &quot;Ok&quot;.</label>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<default_width>700</default_width>
<default_height>300</default_height>
<default_width>800</default_width>
<default_height>600</default_height>
<allow_shrink>True</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<auto_close>True</auto_close>
<auto_shrink>True</auto_shrink>
<auto_close>False</auto_close>
<hide_on_close>False</hide_on_close>
<widget>
@ -947,7 +847,7 @@ click &quot;Ok&quot;.</label>
<widget>
<class>GtkLabel</class>
<name>label847772</name>
<label>Imported transaction:</label>
<label>Imported transaction's first split:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -987,25 +887,12 @@ click &quot;Ok&quot;.</label>
<handler>downloaded_transaction_unselect_cb</handler>
<last_modification_time>Thu, 22 Aug 2002 02:05:02 GMT</last_modification_time>
</signal>
<columns>7</columns>
<column_widths>80,80,80,80,80,80,80</column_widths>
<columns>6</columns>
<column_widths>80,80,80,80,80,80</column_widths>
<selection_mode>GTK_SELECTION_BROWSE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847778</name>
<label>Action</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>

View File

@ -14,8 +14,8 @@
(gnc:register-configuration-option
(gnc:make-simple-boolean-option
(N_ "Transaction Matcher") (N_ "Enable REPLACE match action")
"b" (N_ "Enable the REPLACE action in the transaction matcher. If the REPLACE action is selected, the downloaded transaction's data will replace the selected match")
(N_ "Transaction Matcher") (N_ "Enable EDIT match action")
"b" (N_ "Enable the EDIT action in the transaction matcher. NOT YET SUPPORTED")
#f))
(gnc:register-configuration-option
@ -50,3 +50,14 @@
0.0 ;; number of decimals
1.0 ;; step size
))
(gnc:register-configuration-option
(gnc:make-number-range-option
(N_ "Transaction Matcher") (N_ "Commercial ATM fees threshold")
"g" (N_ "In some places commercial ATMs (not belonging to a financial institution) are installed in places like convienience store. These ATM add it's fee directly to the amount instead of showing up as a separate transaction or in your monthly banking fees. For example, you withdraw 100$, and you are charged 101,50$ plus Interac fees. If you manually entered that 100$, the amounts won't match. You should set this to whatever is the maximum such fee in your area (in units of your local currency), so the transaction will be recognised as a match.")
2.00 ;; default
0.0 ;; lower bound
1000.0 ;; upper bound
2.0 ;; number of decimals
0.01 ;; step size
))

View File

@ -1,8 +1,4 @@
/********************************************************************\
* gnc-gen-transaction.c -- window/dialog for generic transaction
* processing *
* Copyright (C) 2002 Christian Stimming *
* *
* 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 *
@ -20,8 +16,9 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Transaction matcher main window
/** @file
@brief Christian Stimming's matcher
@author Copyright (C) 2002 Christian Stimming
*/
#include "config.h"
@ -35,15 +32,18 @@
#include "gnc-ui-util.h"
#include "gnc-engine-util.h"
#include "gnc-import-match-map.h"
#include "Transaction-matcher.h"
#include "Account-matcher.h"
#include "import-match-map.h"
#include "import-match-picker.h"
#include "import-backend.h"
#include "import-account-matcher.h"
struct _generic_transaction_info
{
GtkWidget *dialog;
GtkWidget *clist;
GNCImportSettings *user_settings;
/* BG: This is all obsolete, you should rip clear_threshold & al from your data structures */
int clear_threshold;
int add_threshold;
int display_threshold;
@ -69,6 +69,7 @@ void gnc_gen_trans_delete (GNCGenTransaction *info)
{
if (info == NULL)
return;
gnc_import_Settings_delete (info->user_settings);
gtk_widget_destroy (GTK_WIDGET (info->dialog));
g_free (info);
}
@ -113,30 +114,26 @@ run_account_picker_dialog (GNCGenTransaction *info,
{
Account *old_acc, *new_acc;
old_acc = gnc_import_TransInfo_get_destacc (trans_info);
/* new_acc = gnc_account_picker_dialog(old_acc);*/
/* new_acc = gnc_account_picker_dialog(old_acc);*/
new_acc = gnc_import_select_account(NULL,
TRUE,
_("A destination split for the transaction you selected."),
xaccTransGetCurrency(gnc_import_TransInfo_get_trans(trans_info)),
NO_TYPE,
old_acc);
if (old_acc != new_acc) {
gnc_import_TransInfo_set_destacc (trans_info, new_acc);
gnc_import_TransInfo_set_destacc (trans_info,
new_acc,
TRUE);
refresh_clist_row (info, row, trans_info);
}
}
static void
run_match_dialog (GNCGenTransaction *info,
gint row, GNCImportTransInfo *trans_info)
{
GNCImportMatchInfo *old =
gnc_import_TransInfo_get_selected_match (trans_info);
gnc_import_match_picker_run_and_close (trans_info);
if (old != gnc_import_TransInfo_get_selected_match (trans_info))
refresh_clist_row (info, row, trans_info);
refresh_clist_row (info, row, trans_info);
}
static void
@ -219,16 +216,15 @@ GNCGenTransaction *gnc_gen_trans_new (GtkWidget *parent,
info = g_new0 (GNCGenTransaction, 1);
/* Initialize user Settings. */
info->user_settings = gnc_import_Settings_new ();
/* Initialize misc. data members */
info->clear_threshold =
gnc_lookup_number_option("Transaction Matcher","Auto-CLEAR threshold",
DEFAULT_CLEAR_THRESHOLD);
info->add_threshold =
gnc_lookup_number_option("Transaction Matcher","Auto-ADD threshold",
DEFAULT_ADD_THRESHOLD);
info->display_threshold =
gnc_lookup_number_option("Transaction Matcher","Match display threshold",
DEFAULT_DISPLAY_THRESHOLD);
/* BG: This is obsolete, you should rip clear_threshold & al from your data structure */
info->clear_threshold = gnc_import_Settings_get_clear_threshold (info->user_settings);
info->add_threshold = gnc_import_Settings_get_add_threshold (info->user_settings);
info->display_threshold = gnc_import_Settings_get_display_threshold (info->user_settings);
/* Initialize the GnomeDialog. */
xml = gnc_glade_xml_new ("generic-import.glade", "transaction_list_dialog");
@ -398,10 +394,7 @@ void gnc_gen_trans_add_trans(GNCGenTransaction *gui, Transaction *trans)
transaction_info = gnc_import_TransInfo_new(trans, NULL);
gnc_import_TransInfo_init_matches (transaction_info,
gui->add_threshold,
gui->add_threshold,
gui->display_threshold,
gnc_gen_trans_get_fuzzy_amount (gui));
gui->user_settings);
row_number = gtk_clist_append(GTK_CLIST (gui->clist),
text_for_transInfo (transaction_info));

View File

@ -1,50 +0,0 @@
/**@file
\brief Generic import mapper service, maps strings->accounts
*
An import mapper service that stores Account Maps for the
generic importer. This allows importers to map various
"strings" to Gnucash accounts in a generic manner.
\author Derek Atkins <derek@ihtfp.com>
*/
#ifndef GNC_IMPORT_MATCH_MAP_H
#define GNC_IMPORT_MATCH_MAP_H
typedef struct _GncImportMatchMap GncImportMatchMap;
#include "Account.h"
#include "gnc-book.h"
/* Obtain an ImportMatchMap object from an Account or a Book */
GncImportMatchMap * gnc_imap_create_from_account (Account *acc);
GncImportMatchMap * gnc_imap_create_from_book (GNCBook *book);
/* Destroy an import map. But all stored entries will still continue
* to exist in the underlying kvp frame of the account or book. */
void gnc_imap_destroy (GncImportMatchMap *imap);
/* Clear an import map -- this removes ALL entries in the map */
void gnc_imap_clear (GncImportMatchMap *imap);
/* Look up an Account in the map */
Account * gnc_imap_find_account (GncImportMatchMap *imap, const char *category,
const char *key);
/* 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. */
void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
const char *key, Account *acc);
/* some well-known categories
*
* NOTE: You DO NOT have to use these values in your importer -- these
* are just "well known" values, not "mandatory" values. You are free
* to use these if they apply, map your own fields to these labels, or
* create your own category strings.
*/
#define GNCIMPORT_DESC "desc"
#define GNCIMPORT_MEMO "memo"
#define GNCIMPORT_PAYEE "payee"
#endif /* GNC_IMPORT_MATCH_MAP_H */

View File

@ -1,10 +1,4 @@
/********************************************************************\
* generic-import.c -- Functions and utilities to help writing *
* import modules. See file generic-import-design.txt for *
* description *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -23,7 +17,8 @@
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Account matching and account picking functionnality
* \brief Account-matcher.h: A very generic and flexible account matcher/picker
\author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#define _GNU_SOURCE
@ -36,9 +31,8 @@
#include <glade/glade.h>
#include <stdlib.h>
#include "Account-matcher.h"
#include "gnc-gen-utilities.h"
#include "Account.h"
#include "import-account-matcher.h"
#include "import-utilities.h"
#include "dialog-utils.h"
#include "AccWindow.h"

View File

@ -1,10 +1,4 @@
/********************************************************************\
* Account-matcher.h -- Account selection and matching functions for*
* import modules. *
* *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -23,7 +17,8 @@
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Account matching and account picking functionnality
* \brief Account-matcher.h: A very generic and flexible account matcher/picker
\author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#ifndef ACCOUNT_MATCHER_H
#define ACCOUNT_MATCHER_H

View File

@ -0,0 +1,858 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief import-backend.c: Generic importer backend implementation (duplicate matching algorithm, action handling, etc.)
@author Copyright (C) 2002 Benoit Grégoire, Christian Stimming
*/
#define _GNU_SOURCE
#include "config.h"
#include <glib.h>
#include <stdlib.h>
#include <math.h>
#include "import-backend.h"
#include "import-utilities.h"
#include "Account.h"
#include "dialog-utils.h"
#include "global-options.h"
#include "gnc-engine-util.h"
#include "gnc-ui-util.h"
/********************************************************************\
* Constants *
\********************************************************************/
static short module = MOD_IMPORT;
/********************************************************************\
* Constants, should idealy be defined a user preference dialog *
\********************************************************************/
static const int MATCH_DATE_THRESHOLD=4; /*within 4 days*/
static const int MATCH_DATE_NOT_THRESHOLD = 16;
/**Transaction's who have an online_id kvp frame have been downloaded
online can probably be skipped in the match list, since it is very
unlikely that they would match a transaction downloaded at a later
date and yet not have the same online_id. This also increases
performance of the matcher. */
static const int SHOW_TRANSACTIONS_WITH_UNIQUE_ID = FALSE;
/********************************************************************\
* Structures passed between the functions *
\********************************************************************/
struct _transactioninfo
{
Transaction * trans;
Split * first_split;
/* GList of GNCImportMatchInfo's, one for each possible duplicate match. */
GList * match_list;
GNCImportMatchInfo * selected_match_info;
gboolean match_selected_manually;
GNCImportAction action;
GNCImportAction previous_action;
/* In case of a single destination account it is stored here. */
Account *dest_acc;
gboolean dest_acc_selected_manually;
};
struct _matchinfo
{
Transaction * trans;
Split * split;
//GNC_match_probability probability;
gint probability;
};
/* Some simple getters and setters for the above data types. */
GList *
gnc_import_TransInfo_get_match_list (const GNCImportTransInfo *info)
{
g_assert (info);
return info->match_list;
}
Transaction *
gnc_import_TransInfo_get_trans (const GNCImportTransInfo *info)
{
g_assert (info);
return info->trans;
}
gboolean
gnc_import_TransInfo_is_balanced (const GNCImportTransInfo *info)
{
g_assert (info);
if(gnc_numeric_equal(xaccTransGetImbalance(gnc_import_TransInfo_get_trans(info)),gnc_numeric_zero()))
{
return TRUE;
}
else
{
return FALSE;
}
}
Split *
gnc_import_TransInfo_get_fsplit (const GNCImportTransInfo *info)
{
g_assert (info);
return info->first_split;
}
GNCImportMatchInfo *
gnc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info)
{
g_assert (info);
return info->selected_match_info;
}
void
gnc_import_TransInfo_set_selected_match (GNCImportTransInfo *info,
GNCImportMatchInfo *match,
gboolean selected_manually)
{
g_assert (info);
info->selected_match_info = match;
info->match_selected_manually = selected_manually;
}
gboolean
gnc_import_TransInfo_get_match_selected_manually (const GNCImportTransInfo *info)
{
g_assert (info);
return info->match_selected_manually;
}
GNCImportAction
gnc_import_TransInfo_get_action (const GNCImportTransInfo *info)
{
g_assert (info);
return info->action;
}
void
gnc_import_TransInfo_set_action (GNCImportTransInfo *info,
GNCImportAction action)
{
g_assert (info);
if(action!=info->action)
{
info->previous_action = info->action;
info->action = action;
}
}
Account *
gnc_import_TransInfo_get_destacc (const GNCImportTransInfo *info)
{
g_assert (info);
return info->dest_acc;
}
void gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info,
Account *acc,
gboolean selected_manually)
{
g_assert (info);
info->dest_acc = acc;
info->dest_acc_selected_manually = selected_manually;
}
gboolean
gnc_import_TransInfo_get_destacc_selected_manually (const GNCImportTransInfo *info)
{
g_assert (info);
return info->dest_acc_selected_manually;
}
Split *
gnc_import_MatchInfo_get_split (const GNCImportMatchInfo * info)
{
g_assert (info);
return info->split;
}
gint
gnc_import_MatchInfo_get_probability (const GNCImportMatchInfo * info)
{
if(info)
{
g_assert (info);
return info->probability;
}
else
{
return 0;
}
}
void gnc_import_TransInfo_delete (GNCImportTransInfo *info)
{
if (info) {
g_list_free (info->match_list);
/*If the transaction is still open, it must be destroyed*/
if(xaccTransIsOpen(info->trans)==TRUE)
{
xaccTransDestroy(info->trans);
xaccTransCommitEdit(info->trans);
}
g_free(info);
}
}
GdkPixmap* gen_probability_pixmap(gint score, GNCImportSettings *settings, GtkWidget * widget)
{
GdkPixmap* retval = NULL;
gint i, j;
if (score < 0)
{
score = 0;
}
const gint height = 15;
const gint width_each_bar = 7;
gchar * green_bar = ("bggggb ");
gchar * yellow_bar = ("byyyyb ");
gchar * red_bar = ("brrrrb ");
gchar * black_bar = ("bbbbbb ");
const gint width_first_bar = 1;
gchar * black_first_bar = ("b");
const gint num_colors = 5;
gchar * 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*/);
gchar * none_color_str = g_strdup_printf(" c None");
gchar * green_color_str = g_strdup_printf("g c green");
gchar * yellow_color_str = g_strdup_printf("y c yellow");
gchar * red_color_str = g_strdup_printf("r c red");
gchar * black_color_str = g_strdup_printf("b c black");
gchar * xpm[2+num_colors+height];
g_assert(settings);
g_assert(widget);
/*DEBUG("Begin");*/
xpm[0]=size_str;
xpm[1]=none_color_str;
xpm[2]=green_color_str;
xpm[3]=yellow_color_str;
xpm[4]=red_color_str;
xpm[5]=black_color_str;
for(i=0;i<height;i++)
{
xpm[num_colors+1+i]= g_new0(char,(width_each_bar*score)+width_first_bar+1);
for(j=0;j<=score;j++)
{
if(i==0||i==height-1)
{
if (j==0)
{
strcat(xpm[num_colors+1+i],black_first_bar);
}
else
{
strcat(xpm[num_colors+1+i],black_bar);
}
}
else
{
if (j==0)
{
strcat(xpm[num_colors+1+i],black_first_bar);
}
else if (j<=gnc_import_Settings_get_add_threshold(settings))
{
strcat(xpm[num_colors+1+i],red_bar);
}
else if (j>=gnc_import_Settings_get_clear_threshold(settings))
{
strcat(xpm[num_colors+1+i],green_bar);
}
else
{
strcat(xpm[num_colors+1+i],yellow_bar);
}
}
}
}
retval = gdk_pixmap_colormap_create_from_xpm_d (NULL,
gtk_widget_get_colormap(widget),
NULL,
NULL,
xpm);
for(i=0;i<=num_colors+height;i++)
{
/*DEBUG("free_loop i=%d%s%s",i,": ",xpm[i]);*/
g_free(xpm[i]);
}
return retval;
}
/*************************************************************************
* MatchMap- related functions (storing and retrieving)
*/
static Account *
matchmap_find_destination (GncImportMatchMap *matchmap,
GNCImportTransInfo *info)
{
GncImportMatchMap *tmp_map;
Account *result;
g_assert (info);
tmp_map = ((matchmap != NULL) ? matchmap :
gnc_imap_create_from_account
(xaccSplitGetAccount
(gnc_import_TransInfo_get_fsplit (info))));
result = gnc_imap_find_account
(tmp_map, GNCIMPORT_DESC,
xaccTransGetDescription (gnc_import_TransInfo_get_trans (info)));
if (result == NULL)
result = gnc_imap_find_account
(tmp_map, GNCIMPORT_MEMO,
xaccSplitGetMemo (gnc_import_TransInfo_get_fsplit (info)));
if (matchmap == NULL)
gnc_imap_destroy (tmp_map);
return result;
}
/* Store the destination account from trans_info in the matchmap. If
'use_match' is true, the destination account of the selected
matching/duplicate transaction is used; otherwise, the stored
destination_acc pointer is used. */
static void
matchmap_store_destination (GncImportMatchMap *matchmap,
GNCImportTransInfo *trans_info,
gboolean use_match)
{
GncImportMatchMap *tmp_matchmap = NULL;
Account *dest;
g_assert (trans_info);
/* This will store the destination account of the selected match if
the recondile match selected has only two split. Good idea
Christian! */
dest = ((use_match) ?
xaccSplitGetAccount
(xaccSplitGetOtherSplit
(gnc_import_MatchInfo_get_split
(gnc_import_TransInfo_get_selected_match (trans_info)))) :
gnc_import_TransInfo_get_destacc (trans_info));
if (dest == NULL)
return;
tmp_matchmap = ((matchmap != NULL) ?
matchmap :
gnc_imap_create_from_account
(xaccSplitGetAccount
(gnc_import_TransInfo_get_fsplit (trans_info))));
gnc_imap_add_account (tmp_matchmap,
GNCIMPORT_DESC,
xaccTransGetDescription
(gnc_import_TransInfo_get_trans (trans_info)),
dest);
gnc_imap_add_account (tmp_matchmap,
GNCIMPORT_MEMO,
xaccSplitGetMemo
(gnc_import_TransInfo_get_fsplit (trans_info)),
dest);
if (matchmap == NULL)
gnc_imap_destroy (tmp_matchmap);
}
/** /brief The transaction matching heuristics are here.
*/
static void split_find_match (GNCImportTransInfo * trans_info,
Split * split,
gint display_threshold,
double fuzzy_amount_difference)
{
/* DEBUG("Begin"); */
/*Ignore the split if the transaction is open for edit, meaning it
was just downloaded. Ignore the split if the transaction has an
online ID , unless overriden in prefs (i.e. do not ignore the
split if the online_id kvp is NULL or if it has zero length). */
if ((xaccTransIsOpen(xaccSplitGetParent(split)) == FALSE) &&
((gnc_import_get_trans_online_id(xaccSplitGetParent(split))==NULL) ||
(strlen(gnc_import_get_trans_online_id(xaccSplitGetParent(split))) == 0) ||
SHOW_TRANSACTIONS_WITH_UNIQUE_ID==TRUE))
{
GNCImportMatchInfo * match_info;
gint prob = 0;
double downloaded_split_amount, match_split_amount;
time_t match_time, download_time;
int datediff_day;
/* Matching heuristics */
/* Amount heuristics */
downloaded_split_amount =
gnc_numeric_to_double
(xaccSplitGetAmount(gnc_import_TransInfo_get_fsplit (trans_info)));
/*DEBUG(" downloaded_split_amount=%f", downloaded_split_amount);*/
match_split_amount = gnc_numeric_to_double(xaccSplitGetAmount(split));
/*DEBUG(" match_split_amount=%f", match_split_amount);*/
if(gnc_numeric_equal(xaccSplitGetAmount
(gnc_import_TransInfo_get_fsplit (trans_info)),
xaccSplitGetAmount(split)))
{
prob = prob+3;
DEBUG("heuristics: probability + 3 (amount)");
}
else if (fabs (downloaded_split_amount - match_split_amount) <=
fuzzy_amount_difference)
{
/* ATM fees are sometimes added directly in the transaction.
So you withdraw 100$ and get charged 101,25$ in the same
transaction */
prob = prob+2;
DEBUG("heuristics: probability + 2 (amount)");
}
else
{
/* If a transaction's amount doesn't match within the
threshold, it's very unlikely to be the same transaction
so we give it an extra -1 penality */
prob = prob-1;
/* DEBUG("heuristics: probability - 1 (amount)"); */
}
/* Date heuristics */
match_time = xaccTransGetDate (xaccSplitGetParent (split));
download_time =
xaccTransGetDate (gnc_import_TransInfo_get_trans (trans_info));
datediff_day = abs(match_time - download_time)/86400;
/* Sorry, there are not really functions around at all that
provide for less hacky calculation of days of date
differences. Whatever. On the other hand, the difference
calculation itself will work regardless of month/year
turnarounds. */
/*DEBUG("diff day %d", datediff_day);*/
if (datediff_day == 0)
{
prob = prob+2;
DEBUG("heuristics: probability + 2 (date)");
}
else if (datediff_day <= MATCH_DATE_THRESHOLD)
{
prob = prob+1;
DEBUG("heuristics: probability + 1 (date)");
}
else if (datediff_day > MATCH_DATE_NOT_THRESHOLD)
{
/* Extra penalty if that split lies awfully far away
from the given one. */
prob = prob-1;
/* DEBUG("heuristics: probability - 1 (date)"); */
}
/* Memo heuristics */
if((strcmp(xaccSplitGetMemo(gnc_import_TransInfo_get_fsplit (trans_info)),
xaccSplitGetMemo(split))
==0))
{
/* An exact match of description gives a +2 */
prob = prob+2;
DEBUG("heuristics: probability + 2 (memo)");
}
else if((strncmp(xaccSplitGetMemo(gnc_import_TransInfo_get_fsplit (trans_info)),
xaccSplitGetMemo(split),
strlen(xaccSplitGetMemo(split))/2)
==0))
{
/* Very primitive fuzzy match worth +1. This matches the
first 50% of the strings to skip annoying transaction
number some banks seem to include in the memo but someone
should write something more sophisticated */
prob = prob+1;
DEBUG("heuristics: probability + 1 (memo)");
}
/* Description heuristics */
if((strcmp(xaccTransGetDescription
(gnc_import_TransInfo_get_trans (trans_info)),
xaccTransGetDescription(xaccSplitGetParent(split)))
==0))
{
/*An exact match of Description gives a +2 */
prob = prob+2;
DEBUG("heuristics: probability + 2 (description)");
}
else if((strncmp(xaccTransGetDescription
(gnc_import_TransInfo_get_trans (trans_info)),
xaccTransGetDescription(xaccSplitGetParent(split)),
strlen(xaccTransGetDescription
(gnc_import_TransInfo_get_trans (trans_info)))/2)
==0))
{
/* Very primitive fuzzy match worth +1. This matches the
first 50% of the strings to skip annoying transaction
number some banks seem to include in the memo but someone
should write something more sophisticated */
prob = prob+1;
DEBUG("heuristics: probability + 1 (description)");
}
if ((gnc_import_get_trans_online_id(xaccSplitGetParent(split))!=NULL) &&
(strlen(gnc_import_get_trans_online_id(xaccSplitGetParent(split)))>0))
{
/* If the pref is to show match even with online ID's,
reverse the confidence value to distinguish them */
prob = 0-prob;
}
/* Is the probability high enough? Otherwise do nothing and return. */
if(prob < display_threshold)
{
return;
}
/* The probability is high enough, so allocate an object
here. Allocating it only when it's actually being used is
probably quite some performance gain. */
match_info = g_new0(GNCImportMatchInfo,1);
match_info->probability = prob;
match_info->split = split;
match_info->trans = xaccSplitGetParent(split);
/* Append that to the list. */
trans_info->match_list =
g_list_append(trans_info->match_list,
match_info);
}
}/* end split_find_match */
/** /brief Iterate through all splits of the originating account of the given
transaction, and find all matching splits there. */
void gnc_import_find_split_matches(GNCImportTransInfo *trans_info,
gint process_threshold,
double fuzzy_amount_difference)
{
GList * list_element;
g_assert (trans_info);
/* Get list of splits of the originating account. */
list_element =
g_list_first
(xaccAccountGetSplitList
(xaccSplitGetAccount (gnc_import_TransInfo_get_fsplit (trans_info))));
/* Traverse that list, calling split_find_match on each one. Note
that xaccAccountForEachSplit is declared in Account.h but
implemented nowhere :-( */
while(list_element!=NULL)
{
split_find_match (trans_info, list_element->data,
process_threshold, fuzzy_amount_difference);
list_element = g_list_next (list_element);
}
}
/***********************************************************************
*/
/** /brief -- Processes every selected match
according to its selected action. */
void
gnc_import_process_trans_clist (GtkCList *clist,
GncImportMatchMap *matchmap)
{
GNCImportTransInfo * trans_info;
gint row_number = 0, i = 0;
g_assert (clist);
/* DEBUG("Begin"); */
gtk_clist_freeze (clist);
trans_info =
(GNCImportTransInfo *) gtk_clist_get_row_data(clist, 0);
for(i = 1; trans_info != NULL; i++)
{
g_assert (trans_info);
/*DEBUG("Iteration %d, action %d, split %s", i,
trans_info->action,
xaccTransGetDescription (gnc_import_TransInfo_get_trans
(trans_info)))*/
switch (gnc_import_TransInfo_get_action (trans_info))
{
case GNCImport_SKIP:
break;
case GNCImport_ADD:
/* Transaction gets imported. */
/* Is the transaction not balanced and there is a non-NULL destination account? */
if (gnc_import_TransInfo_is_balanced(trans_info) == TRUE
&& gnc_import_TransInfo_get_destacc(trans_info) != NULL) {
/* Create the 'other' split. */
Split *split =
xaccMallocSplit
(xaccAccountGetBook
(gnc_import_TransInfo_get_destacc (trans_info)));
xaccTransAppendSplit
(gnc_import_TransInfo_get_trans (trans_info), split);
xaccAccountInsertSplit
(gnc_import_TransInfo_get_destacc (trans_info), split);
xaccSplitSetValue
(split, gnc_numeric_neg(xaccSplitGetValue
(gnc_import_TransInfo_get_fsplit (trans_info))));
xaccSplitSetMemo (split, _("Auto-Balance split"));
/* Store the mapping to the other account in the MatchMap. */
matchmap_store_destination (matchmap, trans_info, FALSE);
}
xaccSplitSetReconcile(gnc_import_TransInfo_get_fsplit (trans_info), CREC);
/*Set reconcile date to today*/
xaccSplitSetDateReconciledSecs(gnc_import_TransInfo_get_fsplit (trans_info),
time(NULL));
/* Done editing. */
xaccTransCommitEdit
(gnc_import_TransInfo_get_trans (trans_info));
break;
case GNCImport_CLEAR:
/* Transaction gets not imported but the matching one gets
reconciled. */
if(gnc_import_MatchInfo_get_split
(gnc_import_TransInfo_get_selected_match (trans_info)) ==NULL)
{
PERR("The split I am trying to reconcile is NULL, shouldn't happen!")
}
else
{
/* Reconcile the matching transaction */
/*DEBUG("BeginEdit selected_match")*/
xaccTransBeginEdit(trans_info->selected_match_info->trans);
if (xaccSplitGetReconcile
(trans_info->selected_match_info->split) == NREC)
xaccSplitSetReconcile
(trans_info->selected_match_info->split, CREC);
/* Set reconcile date to today */
xaccSplitSetDateReconciledSecs
(trans_info->selected_match_info->split,time(NULL));
/* Copy the online id to the reconciled transaction, so
the match will be remembered */
if (gnc_import_get_trans_online_id(trans_info->trans)
!= NULL)
gnc_import_set_trans_online_id
(trans_info->selected_match_info->trans,
gnc_import_get_trans_online_id(trans_info->trans));
/* Done editing. */
/*DEBUG("CommitEdit selected_match")*/
xaccTransCommitEdit
(trans_info->selected_match_info->trans);
/* Store the mapping to the other account in the MatchMap. */
matchmap_store_destination (matchmap, trans_info, TRUE);
/* Erase the downloaded transaction */
xaccTransDestroy(trans_info->trans);
DEBUG("CommitEdit trans")
xaccTransCommitEdit(trans_info->trans);
}
break;
case GNCImport_EDIT:
PERR("EDIT action is UNSUPPORTED!")
break;
default:
DEBUG("Invalid GNCImportAction for this imported transaction.");
}
/* For all actions except SKIP delete this transaction now. */
if(trans_info->action != GNCImport_SKIP) {
row_number = gtk_clist_find_row_from_data(clist, trans_info);
gtk_clist_remove (clist, row_number);
/* decrement the iteration counter since we've just removed
one row. */
i--;
}
/* Get next trans_info, NULL if finished */
trans_info =
(GNCImportTransInfo *) gtk_clist_get_row_data(clist, i);
}
/*DEBUG("End");*/
gtk_clist_thaw (clist);
/*DEBUG("Thawed.")*/
}
/********************************************************************\
* check_trans_online_id() Callback function to be used by
* gnc_import_exists_online_id. Takes pointers to two transaction and
* returns TRUE if their online_id kvp_frame do NOT match, or if both
* pointers point to the same transaction.
* \********************************************************************/
static gboolean check_trans_online_id(Transaction *trans1, void *user_data)
{
Transaction *trans2 = user_data;
const gchar *online_id1 = gnc_import_get_trans_online_id(trans1);
const gchar *online_id2 = gnc_import_get_trans_online_id(trans2);
if ((trans1 == trans2) || (online_id1 == NULL) ||
(online_id2 == NULL) || (strcmp(online_id1, online_id2) != 0))
{
return TRUE;
}
else
{
//printf("test_trans_online_id(): Duplicate found\n");
return FALSE;
}
}
/** Checks whether the given transaction's online_id already exists in
its parent account. */
gboolean gnc_import_exists_online_id (Transaction *trans)
{
int i;
gboolean online_id_exists = FALSE;
Account *dest_acct;
Split *source_split;
/* For each split in the transaction, check whether the parent account
contains a transaction with the same online id. */
for (i=0;
((source_split = xaccTransGetSplit(trans, i)) != NULL) &&
(online_id_exists == FALSE);
i++)
{
/* DEBUG("%s%d%s","Checking split ",i," for duplicates"); */
dest_acct = xaccSplitGetAccount(source_split);
online_id_exists = !xaccAccountForEachTransaction(dest_acct,
check_trans_online_id,
trans);
}
/* If it does, abort the process for this transaction, since it is
already in the system. */
if (online_id_exists == TRUE)
{
DEBUG("%s","Transaction with same online ID exists, destroying current transaction");
xaccTransDestroy(trans);
xaccTransCommitEdit(trans);
}
return online_id_exists;
}
/* ******************************************************************
*/
/** Create a new object of GNCImportTransInfo here. */
GNCImportTransInfo *
gnc_import_TransInfo_new (Transaction *trans, GncImportMatchMap *matchmap)
{
GNCImportTransInfo *transaction_info;
g_assert (trans);
transaction_info = g_new0(GNCImportTransInfo,1);
transaction_info->trans=trans;
/* Only use first split, the source split */
transaction_info->first_split = xaccTransGetSplit(trans,0);
/* Try to find a previously selected destination account
string match for the ADD action */
gnc_import_TransInfo_set_destacc (transaction_info,
matchmap_find_destination (matchmap, transaction_info),
FALSE);
return transaction_info;
}
/** compare_probability() is used by g_list_sort to sort by probability */
static gint compare_probability (gconstpointer a,
gconstpointer b)
{
return(((GNCImportMatchInfo *)b)->probability -
((GNCImportMatchInfo *)a)->probability);
}
/** 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.
*/
void
gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info,
GNCImportSettings *settings)
{
GNCImportMatchInfo * best_match;
g_assert (trans_info);
/* Find all split matches in originating account. */
gnc_import_find_split_matches(trans_info,
gnc_import_Settings_get_display_threshold (settings),
gnc_import_Settings_get_fuzzy_amount (settings));
if (trans_info->match_list != NULL)
{
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,
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) )
{
trans_info->action=GNCImport_ADD;
}
else
{
trans_info->action=GNCImport_SKIP;
}
}
else
trans_info->action = GNCImport_ADD;
trans_info->previous_action=trans_info->action;
}

View File

@ -22,16 +22,18 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Transaction duplicate matching functionnality
*/
/** @file
@brief import-backend.h: Generic importer backend interface
@author Copyright (C) 2002 Benoit Grégoire, Christian Stimming
*/
#ifndef TRANSACTION_MATCHER_H
#define TRANSACTION_MATCHER_H
#include <gtk/gtk.h>
#include "Transaction.h"
#include "gnc-import-match-map.h"
#include "import-match-map.h"
#include "import-settings.h"
typedef struct _transactioninfo GNCImportTransInfo;
typedef struct _matchinfo GNCImportMatchInfo;
@ -40,59 +42,12 @@ typedef enum _action {
GNCImport_SKIP,
GNCImport_ADD,
GNCImport_CLEAR,
GNCImport_REPLACE,
GNCImport_EDIT,
GNCImport_LAST_ACTION,
GNCImport_INVALID_ACTION
} GNCImportAction;
/* Note: If you modify this, modify also get_next_action(). */
/************************************************************************
* GUI Functions
************************************************************************/
/** @name Benoitg's Transaction Matcher
*
* Original Transaction Matcher (by benoitg), where the actual GUI
* objects are not visible from the outside since they are kept in
* static data.
*/
/*@{*/
/** Your import module should create a new transaction in the current book,
add as many splits as it knows about, and associate each split with an
account. It should then call gnc_import_add_trans() with that transaction
if a transaction with the same online_id kvp_frame exists in any of the
transaction's split's accounts, the transaction will be destroyed.
Otherwise it will be added.
Not yet implemented: GUI to balance the transaction using heuristics
*/
void gnc_import_add_trans (Transaction *trans);
/*@}*/
/** @name Match_Picker Dialog
*
* A dialog where the user should pick the best match for *one* given
* transaction.
*/
/*@{*/
/**
* 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.
*
* 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.
*
* @param trans_info The TransInfo for which the user is supposed to
* pick a matching transaction. */
void
gnc_import_match_picker_run_and_close (GNCImportTransInfo *trans_info);
/*@}*/
/************************************************************************
* @name Non-GUI Functions
************************************************************************/
@ -149,10 +104,7 @@ void gnc_import_find_split_matches(GNCImportTransInfo *transaction_info,
* exact matches. */
void
gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info,
gint clear_threshold,
gint add_threshold,
gint process_threshold,
double fuzzy_amount_difference);
GNCImportSettings *settings);
/** This function is intended to be called when the importer dialog is
* finished. It iterates through the GtkCList of imported transaction
@ -172,6 +124,24 @@ gnc_import_TransInfo_init_matches (GNCImportTransInfo *trans_info,
void
gnc_import_process_trans_clist (GtkCList *clist,
GncImportMatchMap *matchmap);
/** 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
@param score The score for which to generate a pixmap.
@param settings The user settings from which to get the threshold
@param widget The parent widget in which the pixmap will eventually
be added. Will be used to generate the colormap.
*/
GdkPixmap* gen_probability_pixmap (gint score,
GNCImportSettings *settings,
GtkWidget * widget);
/*@}*/
@ -196,43 +166,63 @@ gnc_import_process_trans_clist (GtkCList *clist,
GNCImportTransInfo *
gnc_import_TransInfo_new (Transaction *trans, GncImportMatchMap *matchmap);
/* Destructor */
/** Destructor */
void gnc_import_TransInfo_delete (GNCImportTransInfo *info);
/* Returns the stored list of possible matches. */
/** Returns the stored list of possible matches. */
GList *gnc_import_TransInfo_get_match_list (const GNCImportTransInfo *info);
/* Returns the transaction of this TransInfo. */
/** Returns the transaction of this TransInfo. */
Transaction *gnc_import_TransInfo_get_trans (const GNCImportTransInfo *info);
/* Returns the first split of the transaction of this TransInfo. */
/** Returns if the transaction stored in the TransInfo is currently balanced. */
gboolean gnc_import_TransInfo_is_balanced (const GNCImportTransInfo *info);
/** Returns the first split of the transaction of this TransInfo. */
Split *gnc_import_TransInfo_get_fsplit (const GNCImportTransInfo *info);
/* Returns the currently selected match in this TransInfo. */
/** Returns the currently selected match in this TransInfo. */
GNCImportMatchInfo *
gnc_import_TransInfo_get_selected_match (const GNCImportTransInfo *info);
/* Sets the currently selected match in this TransInfo. */
/** Sets the currently selected match in this TransInfo.
@param selected_manually TRUE or FALSE; Was this match set as a result of a selection
by the user or by an algorithm?
*/
void
gnc_import_TransInfo_set_selected_match (GNCImportTransInfo *info,
GNCImportMatchInfo *match);
GNCImportMatchInfo *match,
gboolean selected_manually);
/* Returns the currently selected action for this TransInfo. */
/** Returns if the currently selected match was selected by the user. */
gboolean
gnc_import_TransInfo_get_match_selected_manually (const GNCImportTransInfo *info);
/** Returns the currently selected action for this TransInfo. */
GNCImportAction
gnc_import_TransInfo_get_action (const GNCImportTransInfo *info);
/* Set the action for this TransInfo. */
/** Set the action for this TransInfo. Also sets the previous action. */
void
gnc_import_TransInfo_set_action (GNCImportTransInfo *info,
GNCImportAction action);
/* Returns the 'other account' of this transaction. May return NULL. */
/** Returns the 'other account' of this transaction. May return NULL. */
Account *
gnc_import_TransInfo_get_destacc (const GNCImportTransInfo *info);
/* Set the 'other account' of this transaction. May be set to NULL. */
/** Set the 'other account' of this transaction (used for auto-balance if needed). May be set to NULL.
@param selected_manually TRUE or FALSE; Was this account set as a result of a selection
by the user or by an algorithm?
*/
void
gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info, Account *acc);
gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info,
Account *acc,
gboolean selected_manually);
/** Returns if the currently selected destination account for auto-matching was selected by the user. */
gboolean
gnc_import_TransInfo_get_destacc_selected_manually (const GNCImportTransInfo *info);
/*@}*/
@ -242,21 +232,12 @@ gnc_import_TransInfo_set_destacc (GNCImportTransInfo *info, Account *acc);
/* Get the split ('this-side split') of this MatchInfo. */
Split *
gnc_import_MatchInfo_get_split (const GNCImportMatchInfo * info);
/* Get the probability (confidence level) of this MatchInfo.
@param info Can be NULL, in which case the function returns 0*/
gint
gnc_import_MatchInfo_get_probability (const GNCImportMatchInfo * info);
/*@}*/
/* Transaction who's best match probability is equal or higher than
this will reconcile their best match by default */
#define DEFAULT_CLEAR_THRESHOLD 5
/* Transaction who's best match probability is below or equal to
this will be added as new by default */
#define DEFAULT_ADD_THRESHOLD 2
/* Transaction's match probability must be at least this much to be
displayed in the match list. Dont set this to 0 except for
debugging purposes, otherwise all transactions of every accounts
will be shown in the list */
#define DEFAULT_DISPLAY_THRESHOLD 1
#define MATCH_ATM_FEE_THRESHOLD 3.00
#endif

View File

@ -1,10 +1,4 @@
/********************************************************************\
* Commodity-matcher.c -- *
* See file generic-import-design.txt for *
* description *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -22,8 +16,9 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Generic Commodity matching functionnality
/** @file
@brief import-commodity-matcher.h: A Generic commodity matcher/picker
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#define _GNU_SOURCE
@ -37,7 +32,7 @@
#include <stdlib.h>
#include <math.h>
#include "Commodity-matcher.h"
#include "import-commodity-matcher.h"
#include "Account.h"
#include "Transaction.h"
#include "dialog-commodity.h"

View File

@ -1,10 +1,4 @@
/********************************************************************\
* Commodity-matcher.h -- Commodity selection and matching functions*
* for import modules. *
* *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -22,11 +16,12 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
* \brief Generic Commodity matching functionnality
/** @file
@brief import-commodity-matcher.h: A Generic commodity matcher/picker
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#ifndef COMMODITY_MATCHER_H
#define COMMODITY_MATCHER_H
#ifndef IMPORT_COMMODITY_MATCHER_H
#define IMPORT_COMMODITY_MATCHER_H
#include "gnc-commodity.h"

View File

@ -0,0 +1,786 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
@brief import-main-mathcer.c: Transaction matcher main window
@author Copyright (C) 2002 Benoit Grégoire, Christian Stimming
*/
#include "config.h"
#include <gnome.h>
#include "import-main-matcher.h"
#include "dialog-utils.h"
#include "gnc-ui.h"
#include "global-options.h"
#include "gnc-ui-util.h"
#include "gnc-engine-util.h"
#include "import-settings.h"
#include "import-match-map.h"
#include "import-match-picker.h"
#include "import-backend.h"
#include "import-account-matcher.h"
struct _generic_transaction_info
{
GtkWidget *dialog;
GtkWidget *clist;
GNCImportSettings *user_settings;
GdkPixmap* fleche_pixmap;
GdkPixmap* checkbox_checked_pixmap;
GdkPixmap* checkbox_unchecked_pixmap;
int selected_row;
};
#define NUM_COLUMNS_DOWNLOADED_CLIST 10
#define DOWNLOADED_CLIST_ACCOUNT 1
#define DOWNLOADED_CLIST_DATE 0
#define DOWNLOADED_CLIST_AMOUNT 2
#define DOWNLOADED_CLIST_DESCRIPTION 3
#define DOWNLOADED_CLIST_MEMO 4
#define DOWNLOADED_CLIST_IMBALANCE 5
#define DOWNLOADED_CLIST_ACTION_ADD 6
#define DOWNLOADED_CLIST_ACTION_CLEAR 7
#define DOWNLOADED_CLIST_ACTION_EDIT 8
#define DOWNLOADED_CLIST_ACTION_INFO 9
static short module = MOD_IMPORT;
/* XPM */
static char * fleche_xpm[] = {
"17 22 41 1",
" c None",
". c #FFFFFF",
"+ c #000000",
"@ c #FFFAFF",
"# c #F6FFF6",
"$ c #EEEEE6",
"% c #B4B29C",
"& c #F6F6F6",
"* c #F6F2F6",
"= c #EFF7EF",
"- c #EEF2EE",
"; c #EEEEEE",
"> c #F6EEF6",
", c #E6EEE6",
"' c #EEEAEE",
") c #E6EAE6",
"! c #EEE6EE",
"~ c #E6E6E6",
"{ c #DEE2DE",
"] c #E6E2E6",
"^ c #DEDEDE",
"/ c #E6DEE6",
"( c #DEDADE",
"_ c #D5DED5",
": c #D5DAD5",
"< c #DED6DE",
"[ c #D5D6D5",
"} c #D5D2D5",
"| c #CDD6CD",
"1 c #CDD2CD",
"2 c #CDCECD",
"3 c #D5CED5",
"4 c #CDCACD",
"5 c #C5CAC5",
"6 c #C5C6C5",
"7 c #CDC6CD",
"8 c #BDC6BD",
"9 c #C5C2C5",
"0 c #C5BEC5",
"a c #BDC2BD",
"b c #BDBEBD",
".+++++++++++++++.",
"+@.............#+",
"+.$$$$$$$$$$$$$%+",
"+.$&&*&&&&&=&&&%+",
"+.$*--*-**-*-*-%+",
"+.$;;;;>-;;;;;-%+",
"+.$,',';;';',';%+",
"+.$)!)!)!))))')%+",
"+.$~~~~~~~~~~~~%+",
"+.${]+++++++]]]%+",
"+.${^/+++++/{^{%+",
"+.$(^(_+++((_(^%+",
"+.$:<:(<+<::<(<%+",
"+.$[[<[[[[[<[[[%+",
"+.$}|}}}}|}}}}}%+",
"+.$111112131131%+",
"+.$242442422424%+",
"+.$454545444545%+",
"+.$676676656767%+",
"+.$689689696966%+",
"+0%%%%%%%%%%%%%a+",
"b+++++++++++++++b"};
/* XPM */
static char * checkbox_checked_xpm[] = {
"16 16 28 1",
" c None",
". c #20449C",
"+ c #000000",
"@ c #FFFFFF",
"# c #D5D2D5",
"$ c #EEEEEE",
"% c #B4B6B4",
"& c #20409C",
"* c #DEE2DE",
"= c #E6E6E6",
"- c #EEEAEE",
"; c #838183",
"> c #184094",
", c #CDCACD",
"' c #8B898B",
") c #949594",
"! c #9C999C",
"~ c #A4A5A4",
"{ c #C5C6C5",
"] c #949194",
"^ c #A4A1A4",
"/ c #BDBABD",
"( c #DEDADE",
"_ c #C5C2C5",
": c #BDBEBD",
"< c #DEDEDE",
"[ c #D5D6D5",
"} c #ACAAAC",
" .............. ",
"................",
"..++++++++++++..",
"..+@@@@@@@@@#+..",
"..+@$$$$$$$+%+..",
"..+@$$$$$$++++&.",
"..+@$+*=-+++;+>.",
"..+@+++,+++''+&.",
"..+@=+++++)!~+..",
"..+@-{+++]^//+..",
"..+@$(_+]^_#:+..",
"..+@<[#/}/#[:+..",
"..+#:::/%/:::+..",
"..++++++++++++..",
"................",
" .............. "};
/* XPM */
static char * checkbox_unchecked_xpm[] = {
"12 12 14 1",
" c None",
". c #000000",
"+ c #FFFFFF",
"@ c #A4A5A4",
"# c #DEE2DE",
"$ c #7B7D7B",
"% c #DEDEDE",
"& c #D5D6D5",
"* c #CDD2CD",
"= c #CDCACD",
"- c #C5C6C5",
"; c #C5C2C5",
"> c #BDBEBD",
", c #ACAEAC",
"............",
".+++++++++@.",
".+########$.",
".+%%%%%%%%$.",
".+&&&&&&&&$.",
".+********$.",
".+========$.",
".+--;---;-$.",
".+>>>>>>>>$.",
".+,,,,,,,,$.",
".@$$$$$$$$$.",
"............"};
static void
refresh_clist_row (GNCGenTransaction *gui,
int row_number, GNCImportTransInfo *info);
void gnc_gen_trans_list_delete (GNCGenTransaction *info)
{
if (info == NULL)
return;
gnc_import_Settings_delete (info->user_settings);
gtk_widget_destroy (GTK_WIDGET (info->dialog));
g_free (info);
}
static void
on_matcher_ok_clicked (GtkButton *button,
gpointer user_data)
{
GNCGenTransaction *info = user_data;
g_assert (info);
/* DEBUG ("Begin") */
gnc_import_process_trans_clist (GTK_CLIST (info->clist), NULL);
/* DEBUG ("Deleting") */
gnc_gen_trans_list_delete (info);
/* DEBUG ("End") */
}
static void
on_matcher_cancel_clicked (GtkButton *button,
gpointer user_data)
{
GNCGenTransaction *info = user_data;
gnc_gen_trans_list_delete (info);
}
static void
run_account_picker_dialog (GNCGenTransaction *info,
gint row, GNCImportTransInfo *trans_info)
{
Account *old_acc, *new_acc;
g_assert (trans_info);
old_acc = gnc_import_TransInfo_get_destacc (trans_info);
new_acc = gnc_import_select_account(NULL,
TRUE,
_("A destination split for the transaction you selected."),
xaccTransGetCurrency(gnc_import_TransInfo_get_trans(trans_info)),
NO_TYPE,
old_acc);
gnc_import_TransInfo_set_destacc (trans_info,
new_acc,
TRUE);
refresh_clist_row (info, row, trans_info);
}
static void
run_match_dialog (GNCGenTransaction *info,
gint row, GNCImportTransInfo *trans_info)
{
gnc_import_match_picker_run_and_close (trans_info);
refresh_clist_row (info, row, trans_info);
}
static void
clist_select_row_cb (GtkCList *clist,
gint row_number,
gint column,
GdkEventButton *event,
gpointer user_data)
{
GNCGenTransaction *gui = user_data;
GNCImportTransInfo *trans_info;
gboolean should_refresh = TRUE;
DEBUG("row_number: %d%s%d",row_number,", column: ",column);
trans_info = gtk_clist_get_row_data (clist, row_number);
if (trans_info == NULL)
return;
switch(column)
{
case DOWNLOADED_CLIST_ACTION_ADD:
if( gnc_import_TransInfo_get_action(trans_info)==GNCImport_ADD
&& gnc_import_Settings_get_action_skip_enabled (gui->user_settings)==TRUE)
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP);
}
else
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_ADD);
}
break;
case DOWNLOADED_CLIST_ACTION_CLEAR:
if( gnc_import_TransInfo_get_action(trans_info)==GNCImport_CLEAR
&& gnc_import_Settings_get_action_skip_enabled (gui->user_settings)==TRUE)
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP);
}
else
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_CLEAR);
}
break;
case DOWNLOADED_CLIST_ACTION_EDIT:
if( gnc_import_TransInfo_get_action(trans_info)==GNCImport_EDIT
&& gnc_import_Settings_get_action_skip_enabled (gui->user_settings)==TRUE)
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_SKIP);
}
else
{
gnc_import_TransInfo_set_action(trans_info, GNCImport_EDIT);
}
break;
case DOWNLOADED_CLIST_ACTION_INFO:
switch(gnc_import_TransInfo_get_action (trans_info))
{
case GNCImport_ADD:
if(gnc_import_TransInfo_is_balanced(trans_info)==FALSE)
{
run_account_picker_dialog (gui, row_number, trans_info);
}
break;
case GNCImport_CLEAR:
run_match_dialog (gui, row_number, trans_info);
break;
case GNCImport_SKIP:
/*The information displayed is only informative, until you select an action*/
break;
default:
PERR("I don't know what to do! (Yet...)");
}
break;
default:
/*Do nothing for other columns*/
should_refresh = FALSE;
}
if(should_refresh == TRUE)/*If there was a change, refresh the GUI for that row*/
{
refresh_clist_row (gui, row_number, trans_info);
}
gtk_clist_unselect_row (clist,
row_number,
column);
}
void gnc_gen_trans_list_freeze (GNCGenTransaction *gui)
{
g_assert (gui);
gtk_clist_freeze (GTK_CLIST (gui->clist));
}
void gnc_gen_trans_list_thaw (GNCGenTransaction *gui)
{
g_assert (gui);
gtk_clist_thaw (GTK_CLIST (gui->clist));
}
GNCGenTransaction *gnc_gen_trans_list_new (GtkWidget *parent,
const gchar* heading,
gboolean all_from_same_account)
{
GNCGenTransaction *info;
GladeXML *xml;
GtkWidget *heading_label;
gnc_should_log(MOD_IMPORT, GNC_LOG_TRACE);
info = g_new0 (GNCGenTransaction, 1);
/* Initialize user Settings. */
info->user_settings = gnc_import_Settings_new ();
/* Initialize the GnomeDialog. */
xml = gnc_glade_xml_new ("generic-import.glade", "transaction_matcher");
g_assert
(info->dialog = glade_xml_get_widget (xml, "transaction_matcher"));
g_assert
(info->clist = glade_xml_get_widget (xml, "downloaded_clist"));
g_assert
(heading_label = glade_xml_get_widget (xml, "heading_label"));
/*if (parent)
gnome_dialog_set_parent (GNOME_DIALOG (info->dialog),
GTK_WINDOW (parent));*/
/* Connect signals */
glade_xml_signal_connect_data(xml, "downloaded_transaction_select_cb",
GTK_SIGNAL_FUNC(clist_select_row_cb),
info);
glade_xml_signal_connect_data(xml, "on_matcher_ok_clicked",
GTK_SIGNAL_FUNC(on_matcher_ok_clicked),
info);
glade_xml_signal_connect_data(xml, "on_matcher_cancel_clicked",
GTK_SIGNAL_FUNC(on_matcher_cancel_clicked),
info);
/*Initialise pixmaps*/
info->fleche_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
gtk_widget_get_colormap(info->dialog),
NULL,
NULL,
fleche_xpm);
info->checkbox_checked_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
gtk_widget_get_colormap(info->dialog),
NULL,
NULL,
checkbox_checked_xpm);
info->checkbox_unchecked_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
gtk_widget_get_colormap(info->dialog),
NULL,
NULL,
checkbox_unchecked_xpm);
/*Ajust column size*/
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_DATE,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_AMOUNT,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_IMBALANCE,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACTION_ADD,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACTION_CLEAR,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACTION_EDIT,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACTION_INFO,
TRUE);
/*Set column visibility*/
if(all_from_same_account==TRUE)
{
gtk_clist_set_column_visibility (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACCOUNT,
FALSE);
}
if(gnc_import_Settings_get_action_edit_enabled (info->user_settings)==FALSE)
{
gtk_clist_set_column_visibility (GTK_CLIST (info->clist),
DOWNLOADED_CLIST_ACTION_EDIT,
FALSE);
}
if (heading)
gtk_label_set_text (GTK_LABEL (heading_label), heading);
/* Hide on close instead of destroy since we still need the values
from the boxes. */
/*gnome_dialog_close_hides (GNOME_DIALOG (info->dialog), TRUE);*/
gtk_widget_show_all (GTK_WIDGET (info->dialog));
return info;
}
gboolean gnc_gen_trans_list_run (GNCGenTransaction *info)
{
gboolean result;
/* DEBUG("Begin"); */
result = gnome_dialog_run_and_close (GNOME_DIALOG (info->dialog));
/* DEBUG("Result was %d", result); */
/* No destroying here since the dialog was already destroyed through
the ok_clicked handlers. */
return result;
}
/* For cleaning up dangling row data. */
static void
trans_clist_row_destroy_cb (gpointer data)
{
GNCImportTransInfo * transaction_info = data;
/*DEBUG("Begin");*/
gnc_import_TransInfo_delete (transaction_info);
}
static void free_clist_row_text (GNCGenTransaction *gui,
int row_number)
{
gchar *tmp;
gint i;
DEBUG("Begin");
g_assert (gui);
for (i = 0; i < NUM_COLUMNS_DOWNLOADED_CLIST; i++)
{
tmp=NULL;
if(gtk_clist_get_text (GTK_CLIST (gui->clist), row_number,
i,
&tmp)==1)
{
g_free(tmp);
}
}
}
static char ** gen_clist_row_text (GNCImportTransInfo *info)
{
static char *text[NUM_COLUMNS_DOWNLOADED_CLIST];
const char * AUTO_SELECTED_TEXT=_("Auto-Selected");
const char * MANUALY_SELECTED_TEXT=_("User-Selected");
gint i;
gchar *tmp;
const char *select_origin;
DEBUG("Begin");
g_assert (info);
for(i = 0; i < NUM_COLUMNS_DOWNLOADED_CLIST; i++)
{
text[i]=NULL;
}
/* row_number = gtk_clist_find_row_from_data(matcher->downloaded_clist,
transaction_info);*/
/* Note that ALL strings must be duplicated with g_strdup or equivalent, so that they can
be g_freed by free_clist_row_text*/
/*Account:*/
text[DOWNLOADED_CLIST_ACCOUNT] = g_strdup(xaccAccountGetName(xaccSplitGetAccount(gnc_import_TransInfo_get_fsplit (info))));
/*Date*/
text[DOWNLOADED_CLIST_DATE] = g_strdup( xaccPrintDateSecs ( xaccTransGetDate( gnc_import_TransInfo_get_trans(info) ) ));
/*Amount*/
text[DOWNLOADED_CLIST_AMOUNT] = g_strdup(xaccPrintAmount (xaccSplitGetAmount (gnc_import_TransInfo_get_fsplit(info) ),
gnc_split_amount_print_info(gnc_import_TransInfo_get_fsplit(info), TRUE)
) );
/*Description*/
text[DOWNLOADED_CLIST_DESCRIPTION] = g_strdup(xaccTransGetDescription(gnc_import_TransInfo_get_trans(info) ) );
/*Memo*/
text[DOWNLOADED_CLIST_MEMO] = g_strdup(xaccSplitGetMemo(gnc_import_TransInfo_get_fsplit(info) ) );
/*Imbalance*/
text[DOWNLOADED_CLIST_IMBALANCE]=g_strdup(xaccPrintAmount (xaccTransGetImbalance(gnc_import_TransInfo_get_trans(info) ),
gnc_default_print_info (TRUE) )
);
/*Actions*/
text[DOWNLOADED_CLIST_ACTION_ADD] = g_strdup("");
text[DOWNLOADED_CLIST_ACTION_CLEAR] = g_strdup("");
text[DOWNLOADED_CLIST_ACTION_EDIT] = g_strdup("");
switch(gnc_import_TransInfo_get_action(info))
{
case GNCImport_ADD:
if(gnc_import_TransInfo_is_balanced(info)==TRUE)
{
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup(_("Add the transaction (Already balanced)"));
}
else
{
if (gnc_import_TransInfo_get_destacc (info) != NULL) {
tmp = xaccAccountGetFullName
(gnc_import_TransInfo_get_destacc (info),
gnc_get_account_separator ());
if(gnc_import_TransInfo_get_destacc_selected_manually(info)==TRUE)
{
select_origin=MANUALY_SELECTED_TEXT;
}
else
{
select_origin=AUTO_SELECTED_TEXT;
}
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup_printf(_("Add with balancing split into (%s) account \"%s\""),select_origin,tmp);
free (tmp);
}
else
{
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup(_("Add UNBALANCED!"));
}
}
break;
case GNCImport_CLEAR:
if(gnc_import_TransInfo_get_selected_match(info))
{
if(gnc_import_TransInfo_get_match_selected_manually(info)==TRUE)
{
select_origin=MANUALY_SELECTED_TEXT;
}
else
{
select_origin=AUTO_SELECTED_TEXT;
}
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup_printf(_("Reconcile the (%s) match"),select_origin);
}
else
{
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup_printf(_("Please select other action or a transaction to reconcile"));
}
break;
case GNCImport_EDIT: text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup("NOT SUPPORTED YET!");
break;
case GNCImport_SKIP: text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup(_("Will NOT import: inconclusive match or SKIP selected"));
break;
default:
text[DOWNLOADED_CLIST_ACTION_INFO] = g_strdup("WRITEME, this is an unknown action");
}
return text;
}
static void
refresh_clist_row (GNCGenTransaction *gui,
int row_number, GNCImportTransInfo *info)
{
static char ** text;
gint i;
g_assert (gui);
g_assert (info);
gnc_gen_trans_list_freeze(gui);
/*What the hell, neither freeing the memory used by the previous values here or elsewhere seems to work, WHY?*/
/*free_clist_row_text (gui,
row_number);*/
text=gen_clist_row_text (info);
for (i = 0; i < NUM_COLUMNS_DOWNLOADED_CLIST; i++)
{
/*DEBUG("gtk_clist_set_text %d",i);*/
/*gtk_clist_get_text (GTK_CLIST (gui->clist), row_number,
i,
&tmp);*/
gtk_clist_set_text (GTK_CLIST (gui->clist), row_number,
i,
text[i]);
/*g_free(tmp);*/
}
if(gnc_import_TransInfo_get_action(info)==GNCImport_ADD)
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_ADD,
text[DOWNLOADED_CLIST_ACTION_ADD],
3,
gui->checkbox_checked_pixmap,
NULL);
if(gnc_import_TransInfo_is_balanced(info)==FALSE)
{
/*Show the arrow button*/
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_INFO,
text[DOWNLOADED_CLIST_ACTION_INFO],
3,
gui->fleche_pixmap,
NULL);
}
}
else
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_ADD,
text[DOWNLOADED_CLIST_ACTION_ADD],
3,
gui->checkbox_unchecked_pixmap,
NULL);
}
if(gnc_import_TransInfo_get_action(info)==GNCImport_SKIP)
{
/*Show the best match's confidence pixmap in the info column*/
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_INFO,
text[DOWNLOADED_CLIST_ACTION_INFO],
3,
gen_probability_pixmap( gnc_import_MatchInfo_get_probability
( gnc_import_TransInfo_get_selected_match (info)),
gui->user_settings,
GTK_WIDGET(gui->clist)),
NULL);
}
if(gnc_import_TransInfo_get_action(info)==GNCImport_CLEAR)
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_CLEAR,
text[DOWNLOADED_CLIST_ACTION_CLEAR],
3,
gui->checkbox_checked_pixmap,
NULL);
/*Show the best match's confidence pixmap in the info column*/
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_INFO,
text[DOWNLOADED_CLIST_ACTION_INFO],
3,
gen_probability_pixmap( gnc_import_MatchInfo_get_probability
( gnc_import_TransInfo_get_selected_match (info)),
gui->user_settings,
GTK_WIDGET(gui->clist)),
NULL);
}
else
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_CLEAR,
text[DOWNLOADED_CLIST_ACTION_CLEAR],
3,
gui->checkbox_unchecked_pixmap,
NULL);
}
if(gnc_import_TransInfo_get_action(info)==GNCImport_EDIT)
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_EDIT,
text[DOWNLOADED_CLIST_ACTION_EDIT],
3,
gui->checkbox_checked_pixmap,
NULL);
}
else
{
gtk_clist_set_pixtext (GTK_CLIST (gui->clist), row_number,
DOWNLOADED_CLIST_ACTION_EDIT,
text[DOWNLOADED_CLIST_ACTION_EDIT],
3,
gui->checkbox_unchecked_pixmap,
NULL);
}
gtk_clist_set_row_height (GTK_CLIST (gui->clist),
24);
gnc_gen_trans_list_thaw(gui);
}
void gnc_gen_trans_list_add_trans(GNCGenTransaction *gui, Transaction *trans)
{
GNCImportTransInfo * transaction_info = NULL;
gint row_number;
g_assert (gui);
g_assert (trans);
if (gnc_import_exists_online_id (trans))
return;
else
{
transaction_info = gnc_import_TransInfo_new(trans, NULL);
gnc_import_TransInfo_init_matches (transaction_info,
gui->user_settings);
row_number = gtk_clist_append(GTK_CLIST (gui->clist),
gen_clist_row_text (transaction_info));
gtk_clist_set_row_data_full(GTK_CLIST (gui->clist),
row_number,
transaction_info,
trans_clist_row_destroy_cb);
refresh_clist_row (gui,
row_number,
transaction_info);
}
return;
}/* end gnc_import_add_trans() */

View File

@ -0,0 +1,71 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
@brief import-main-mathcer.h: Transaction matcher main window
@author Copyright (C) 2002 Benoit Grégoire, Christian Stimming
*/
#ifndef GNC_GEN_TRANSACTION_H
#define GNC_GEN_TRANSACTION_H
#include <gnome.h>
#include "Transaction.h"
typedef struct _generic_transaction_info GNCGenTransaction;
/** Create a new generic transaction dialog window and return it.
@param parent The parent GtkWidget. May be NULL.
@param heading The heading label in the Importer window. May be NULL.
@param 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.
*/
GNCGenTransaction *gnc_gen_trans_list_new (GtkWidget *parent,
const gchar* heading,
gboolean all_from_same_account);
/** Deletes the given object. */
void gnc_gen_trans_list_delete (GNCGenTransaction *info);
/** Add a newly imported Transaction to the Transaction Importer.
@param gui The Transaction Importer to use.
@param 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.
*/
void gnc_gen_trans_list_add_trans(GNCGenTransaction *gui, Transaction *trans);
/** 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.
*/
gboolean gnc_gen_trans_list_run (GNCGenTransaction *info);
/** Freeze the underlying GtkCList. Do this before you add a lot of
* transactions. */
void gnc_gen_trans_list_freeze (GNCGenTransaction *gui);
/** Thaw the underlying GtkCList. Do this after you added a lot of
* transactions. */
void gnc_gen_trans_list_thaw (GNCGenTransaction *gui);
#endif

View File

@ -1,12 +1,30 @@
/**@file
* \brief Generic import mapper service, maps strings->accounts
*
An import mapper service that stores Account Maps for the
generic importer. This allows importers to map various
"strings" to Gnucash accounts in a generic manner.
\author Derek Atkins <derek@ihtfp.com>
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief Generic import mapper service, maps strings->accounts
*
import-match-map.c: An import mapper service that stores Account Maps for the
generic importer. This allows importers to map various
"strings" to Gnucash accounts in a generic manner.
@author Copyright (C) 2002 Derek Atkins <derek@ihtfp.com>
*/
#include "gnc-import-match-map.h"
#include "import-match-map.h"
#include "kvp_frame.h"
struct _GncImportMatchMap {

View File

@ -0,0 +1,68 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief Generic import mapper service, maps strings->accounts
*
import-match-map.h: An import mapper service that stores Account Maps for the
generic importer. This allows importers to map various
"strings" to Gnucash accounts in a generic manner.
@author Copyright (C) 2002 Derek Atkins <derek@ihtfp.com>
*/
#ifndef GNC_IMPORT_MATCH_MAP_H
#define GNC_IMPORT_MATCH_MAP_H
typedef struct _GncImportMatchMap GncImportMatchMap;
#include "Account.h"
#include "gnc-book.h"
/* Obtain an ImportMatchMap object from an Account or a Book */
GncImportMatchMap * gnc_imap_create_from_account (Account *acc);
GncImportMatchMap * gnc_imap_create_from_book (GNCBook *book);
/* Destroy an import map. But all stored entries will still continue
* to exist in the underlying kvp frame of the account or book. */
void gnc_imap_destroy (GncImportMatchMap *imap);
/* Clear an import map -- this removes ALL entries in the map */
void gnc_imap_clear (GncImportMatchMap *imap);
/* Look up an Account in the map */
Account * gnc_imap_find_account (GncImportMatchMap *imap, const char *category,
const char *key);
/* 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. */
void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
const char *key, Account *acc);
/* some well-known categories
*
* NOTE: You DO NOT have to use these values in your importer -- these
* are just "well known" values, not "mandatory" values. You are free
* to use these if they apply, map your own fields to these labels, or
* create your own category strings.
*/
#define GNCIMPORT_DESC "desc"
#define GNCIMPORT_MEMO "memo"
#define GNCIMPORT_PAYEE "payee"
#endif /* GNC_IMPORT_MATCH_MAP_H */

View File

@ -0,0 +1,370 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief import-match-picker.c: The transaction match picker dialog
implementation
@author Copyright (C) 2002 Benoit Grégoire
*/
#define _GNU_SOURCE
#include "config.h"
#include <glib.h>
#include "import-backend.h"
#include "import-match-picker.h"
#include "gnc-engine-util.h"
#include "gnc-ui-util.h"
#include <glade/glade.h>
#include "dialog-utils.h"
/********************************************************************\
* Constants *
\********************************************************************/
#define NUM_COLUMNS_DOWNLOADED_CLIST 6
static const int DOWNLOADED_CLIST_ACCOUNT = 0;
static const int DOWNLOADED_CLIST_DATE = 1;
static const int DOWNLOADED_CLIST_AMOUNT = 2;
static const int DOWNLOADED_CLIST_DESCRIPTION = 3;
static const int DOWNLOADED_CLIST_MEMO = 4;
static const int DOWNLOADED_CLIST_BALANCED = 5;
#define NUM_COLUMNS_MATCHER_CLIST 5
static const int MATCHER_CLIST_CONFIDENCE = 0;
static const int MATCHER_CLIST_DATE = 1;
static const int MATCHER_CLIST_AMOUNT = 2;
static const int MATCHER_CLIST_DESCRIPTION = 3;
static const int MATCHER_CLIST_MEMO = 4;
static short module = MOD_IMPORT;
/********************************************************************\
* Constants, should idealy be defined a user preference dialog *
\********************************************************************/
static const int SHOW_NUMERIC_SCORE = FALSE;
/********************************************************************\
* Structures passed between the functions *
\********************************************************************/
struct _transpickerdialog {
GtkWidget * transaction_matcher;
GtkCList * downloaded_clist;
GtkCList * match_clist;
GNCImportSettings * user_settings;
struct _transactioninfo * selected_trans_info;
GNCImportMatchInfo * selected_match_info;
};
static gint
downloaded_transaction_append(GNCImportMatchPicker * matcher,
GNCImportTransInfo * transaction_info)
{
gint row_number;
const char * clist_text[NUM_COLUMNS_DOWNLOADED_CLIST];
g_assert(matcher);
g_assert(transaction_info);
DEBUG("Begin");
row_number = gtk_clist_find_row_from_data(matcher->downloaded_clist,
transaction_info);
/*Account*/
clist_text[DOWNLOADED_CLIST_ACCOUNT] =
g_strdup ( xaccAccountGetName
( xaccSplitGetAccount
( gnc_import_TransInfo_get_fsplit (transaction_info))));
/*Date*/
clist_text[DOWNLOADED_CLIST_DATE] =
g_strdup ( xaccPrintDateSecs
( xaccTransGetDate
( gnc_import_TransInfo_get_trans(transaction_info) ) ));
/*Amount*/
clist_text[DOWNLOADED_CLIST_AMOUNT] =
g_strdup( xaccPrintAmount( xaccSplitGetAmount ( gnc_import_TransInfo_get_fsplit(transaction_info) ),
gnc_split_amount_print_info( gnc_import_TransInfo_get_fsplit(transaction_info), TRUE)
) );
/*Description*/
clist_text[DOWNLOADED_CLIST_DESCRIPTION] = g_strdup(xaccTransGetDescription(gnc_import_TransInfo_get_trans(transaction_info) ) );
/*Memo*/
clist_text[DOWNLOADED_CLIST_MEMO] =
g_strdup(xaccSplitGetMemo(gnc_import_TransInfo_get_fsplit(transaction_info) ) );
/*Imbalance*/
clist_text[DOWNLOADED_CLIST_BALANCED] =
g_strdup (xaccPrintAmount (xaccTransGetImbalance(gnc_import_TransInfo_get_trans(transaction_info) ),
gnc_default_print_info (TRUE) )
);
row_number = gtk_clist_append(matcher->downloaded_clist,
(char **)(clist_text));
gtk_clist_set_row_data(matcher->downloaded_clist,
row_number,
transaction_info);
return row_number;
}
/********************************************************************\
* *
* GUI callbacks *
* *
\********************************************************************/
static void
downloaded_transaction_select_cb (GtkCList *clist,
gint row,
gint column,
GdkEventButton *event,
gpointer user_data) {
GNCImportMatchPicker * matcher = user_data;
GNCImportMatchInfo * match_info;
GList * list_element;
gint row_number;
const char * clist_text[NUM_COLUMNS_MATCHER_CLIST];
DEBUG("row: %d%s%d",row,", column: ",column);
matcher->selected_trans_info = gtk_clist_get_row_data(clist, row);
gtk_clist_clear(matcher->match_clist);
list_element = g_list_first (gnc_import_TransInfo_get_match_list
(matcher->selected_trans_info));
while(list_element!=NULL)
{
match_info = list_element->data;
/* Print fields. */
/* Probability */
clist_text[MATCHER_CLIST_CONFIDENCE] =
g_strdup_printf("%d", gnc_import_MatchInfo_get_probability (match_info));
/* Date */
clist_text[MATCHER_CLIST_DATE]=
g_strdup( xaccPrintDateSecs
( xaccTransGetDate
( xaccSplitGetParent
( gnc_import_MatchInfo_get_split(match_info) ) )));
/* Amount */
clist_text[MATCHER_CLIST_AMOUNT]=
g_strdup(xaccPrintAmount( xaccSplitGetAmount ( gnc_import_MatchInfo_get_split(match_info) ),
gnc_split_amount_print_info(gnc_import_MatchInfo_get_split(match_info), TRUE)
) );
/*Description*/
clist_text[MATCHER_CLIST_DESCRIPTION] =
g_strdup( xaccTransGetDescription
( xaccSplitGetParent( gnc_import_MatchInfo_get_split(match_info)) ));
/*Split memo*/
clist_text[MATCHER_CLIST_MEMO]=
g_strdup(xaccSplitGetMemo(gnc_import_MatchInfo_get_split(match_info) ) );
row_number = gtk_clist_append(matcher->match_clist,
(char **)(clist_text));
gtk_clist_set_row_data (matcher->match_clist,
row_number,
match_info);
if(gnc_import_MatchInfo_get_probability(match_info) != 0)
{
if(SHOW_NUMERIC_SCORE==TRUE)
{
gtk_clist_set_pixtext (matcher->match_clist,
row_number,
MATCHER_CLIST_CONFIDENCE,
clist_text[MATCHER_CLIST_CONFIDENCE],
3,
gen_probability_pixmap(gnc_import_MatchInfo_get_probability(match_info),
matcher->user_settings,
GTK_WIDGET(matcher->match_clist)),
NULL);
}
else
{
gtk_clist_set_pixmap (matcher->match_clist,
row_number,
MATCHER_CLIST_CONFIDENCE,
gen_probability_pixmap(gnc_import_MatchInfo_get_probability(match_info),
matcher->user_settings,
GTK_WIDGET(matcher->match_clist)),
NULL);
}
}
gtk_clist_set_row_height (matcher->match_clist,
0);
if(match_info ==
gnc_import_TransInfo_get_selected_match (matcher->selected_trans_info))
{
gtk_clist_select_row (matcher->match_clist,
row_number,
0);
}
list_element=g_list_next(list_element);
}
}
static void
match_transaction_select_cb (GtkCList *clist,
gint row,
gint column,
GdkEventButton *event,
gpointer user_data) {
GNCImportMatchPicker * matcher = user_data;
DEBUG("row: %d%s%d",row,", column: ",column);
matcher->selected_match_info =
gtk_clist_get_row_data(clist, row);
}
static void
match_transaction_unselect_cb(GtkCList *clist,
gint row,
gint column,
GdkEventButton *event,
gpointer user_data) {
GNCImportMatchPicker * matcher = user_data;
DEBUG("row: %d%s%d",row,", column: ",column);
matcher->selected_match_info=NULL;
}
/********************************************************************\
* init_match_picker_gui()
* -- GUI initialization for the Match_Picker Dialog
\********************************************************************/
static void
init_match_picker_gui(GNCImportMatchPicker * matcher)
{
GladeXML *xml;
/* DEBUG("Begin..."); */
/* Initialize user Settings. */
matcher->user_settings = gnc_import_Settings_new ();
/* load the interface */
g_assert
(xml = gnc_glade_xml_new ("generic-import.glade", "match_picker"));
/* connect the signals in the interface */
glade_xml_signal_connect_data(xml,
"match_transaction_select_cb",
GTK_SIGNAL_FUNC(match_transaction_select_cb),
matcher);
glade_xml_signal_connect_data(xml,
"match_transaction_unselect_cb",
GTK_SIGNAL_FUNC(match_transaction_unselect_cb),
matcher);
matcher->transaction_matcher = glade_xml_get_widget (xml, "match_picker");
matcher->downloaded_clist = (GtkCList *)glade_xml_get_widget (xml, "downloaded_clist");
matcher->match_clist = (GtkCList *)glade_xml_get_widget (xml, "matched_clist");
/*Ajust column size*/
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->downloaded_clist),
DOWNLOADED_CLIST_DATE,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->downloaded_clist),
DOWNLOADED_CLIST_AMOUNT,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->downloaded_clist),
DOWNLOADED_CLIST_BALANCED,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->match_clist),
MATCHER_CLIST_CONFIDENCE,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->match_clist),
MATCHER_CLIST_DATE,
TRUE);
gtk_clist_set_column_auto_resize (GTK_CLIST (matcher->match_clist),
MATCHER_CLIST_AMOUNT,
TRUE);
/* DEBUG("User prefs:%s%d%s%d%s%d%s%d%s%d",
" action_replace_enabled:",matcher->action_replace_enabled,
", action_skip_enabled:",matcher->action_skip_enabled,
", clear_threshold:",matcher->clear_threshold,
", add_threshold:",matcher->add_threshold,
", display_threshold:",matcher->display_threshold); */
gtk_widget_show(matcher->transaction_matcher);
}/* end init_match_picker_gui */
/**
* 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.
*/
void
gnc_import_match_picker_run_and_close (GNCImportTransInfo *transaction_info)
{
GNCImportMatchPicker *matcher;
gint row_number, result;
GNCImportMatchInfo *old;
g_assert (transaction_info);
/* Create a new match_picker, even though it's stored in a
transmatcher struct :-) */
matcher = g_new0(GNCImportMatchPicker, 1);
/* DEBUG("Init match_picker"); */
init_match_picker_gui(matcher);
/* Append this single transaction to the downloaded_clist */
row_number = downloaded_transaction_append(matcher,
transaction_info);
/* Now fake a selection of that transaction. */
downloaded_transaction_select_cb (matcher->downloaded_clist,
row_number,
2,
NULL,
matcher);
gtk_widget_set_sensitive (GTK_WIDGET (matcher->downloaded_clist), FALSE);
old = gnc_import_TransInfo_get_selected_match(transaction_info);
/* Let this dialog run and close. */
DEBUG("Right before run and close");
result =
gnome_dialog_run_and_close (GNOME_DIALOG (matcher->transaction_matcher));
DEBUG("Right after run and close");
/* DEBUG("Result was %d.", result); */
if (result == 0 && matcher->selected_match_info != old)
{ /* OK was pressed */
gnc_import_TransInfo_set_selected_match (transaction_info,
matcher->selected_match_info,
TRUE);
}
}

View File

@ -0,0 +1,61 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief import-match-picker.h -- THe transaction match picker dialog interface
@author Copyright (C) 2002 Benoit Grégoire
*/
#ifndef GNC_GEN_MATCH_PICKER_H
#define GNC_GEN_MATCH_PICKER_H
#include "import-backend.h"
typedef struct _transpickerdialog GNCImportMatchPicker;
/************************************************************************
* GUI Functions
************************************************************************/
/** @name Match_Picker Dialog
*
* A dialog where the user should pick the best match for *one* given
* transaction.
*/
/*@{*/
/**
* 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.
*
* 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.
*
* @param trans_info The TransInfo for which the user is supposed to
* pick a matching transaction. */
void
gnc_import_match_picker_run_and_close (GNCImportTransInfo *trans_info);
/*@}*/
#endif

View File

@ -0,0 +1,179 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
@brief import-settings.c: User preference handling for
transaction matching (for both the gui and the backend)
@author Copyright (C) 2002 Benoit Grégoire
*/
#define _GNU_SOURCE
#include "config.h"
#include <glib.h>
#include "global-options.h"
#include "import-settings.h"
/********************************************************************\
* Default values for user prefs (or values for unimplemented prefs.*
* If you modify the value of any of these, you must do the same in *
* generic-import.scm *
\********************************************************************/
/** Transaction who's best match probability is equal or higher than
this will reconcile their best match by default */
#define DEFAULT_CLEAR_THRESHOLD 5
/** Transaction who's best match probability is below or equal to
this will be added as new by default */
#define DEFAULT_ADD_THRESHOLD 2
/** Transaction's match probability must be at least this much to be
displayed in the match list. Dont set this to 0 except for
debugging purposes, otherwise all transactions of every accounts
will be shown in the list */
#define DEFAULT_DISPLAY_THRESHOLD 1
#define DEFAULT_ATM_FEE_THRESHOLD 2.00
static const int DEFAULT_ACTION_SKIP_ENABLED = TRUE;
static const int DEFAULT_ACTION_EDIT_ENABLED = FALSE;
static const int DEFAULT_ACTION_ADD_ENABLED = TRUE;
static const int DEFAULT_ACTION_CLEAR_ENABLED = TRUE;
/********************************************************************\
* Structures passed between the functions *
\********************************************************************/
struct _genimportsettings {
gboolean action_skip_enabled;
gboolean action_edit_enabled;
gboolean action_add_enabled;
gboolean action_clear_enabled;
/**Transaction who's best match probability is equal or higher than
this will reconcile their best match by default */
int clear_threshold;
/**Transaction who's best match probability is below or equal to
this will be added as new by default */
int add_threshold;
/**Transaction's match probability must be at least this much to be
displayed in the match list. Dont set this to 0 except for
debugging purposes, otherwise all transactions of every accounts
will be shown in the list */
int display_threshold;
/** The allowed amount range for fuzzy amount matching,
in the users default commodity.*/
double fuzzy_amount;
};
/************************************************************************
* Getter/Setter Functions for the Data Types.
************************************************************************/
/* Constructor */
GNCImportSettings *
gnc_import_Settings_new (void)
{
GNCImportSettings * settings;
settings = g_new0 ( GNCImportSettings, 1);
settings->action_skip_enabled =
gnc_lookup_boolean_option("Transaction Matcher",
"Enable SKIP transaction action",
DEFAULT_ACTION_SKIP_ENABLED);
settings->action_edit_enabled =
gnc_lookup_boolean_option("Transaction Matcher",
"Enable EDIT match action",
DEFAULT_ACTION_EDIT_ENABLED);
settings->action_add_enabled=DEFAULT_ACTION_ADD_ENABLED;
settings->action_clear_enabled=DEFAULT_ACTION_CLEAR_ENABLED;
settings->clear_threshold=gnc_lookup_number_option("Transaction Matcher",
"Auto-CLEAR threshold",
DEFAULT_CLEAR_THRESHOLD);
settings->add_threshold=gnc_lookup_number_option("Transaction Matcher",
"Auto-ADD threshold",
DEFAULT_ADD_THRESHOLD);
settings->display_threshold =
gnc_lookup_number_option("Transaction Matcher","Match display threshold",
DEFAULT_DISPLAY_THRESHOLD);
settings->fuzzy_amount =
gnc_lookup_number_option("Transaction Matcher","Commercial ATM fees threshold",
DEFAULT_ATM_FEE_THRESHOLD);
return settings;
}
/* Destructor */
void gnc_import_Settings_delete (GNCImportSettings *settings)
{
if (settings) {
g_free(settings);
}
}
double
gnc_import_Settings_get_fuzzy_amount (GNCImportSettings *settings)
{
g_assert (settings);
return settings->fuzzy_amount;
};
gboolean gnc_import_Settings_get_action_skip_enabled (GNCImportSettings *settings)
{
g_assert (settings);
return settings->action_skip_enabled;
};
gboolean gnc_import_Settings_get_action_add_enabled (GNCImportSettings *settings)
{
g_assert (settings);
return settings->action_add_enabled;
};
gboolean gnc_import_Settings_get_action_edit_enabled (GNCImportSettings *settings)
{
g_assert (settings);
return settings->action_edit_enabled;
};
gboolean gnc_import_Settings_get_action_clear_enabled (GNCImportSettings *settings)
{
g_assert (settings);
return settings->action_clear_enabled;
};
gint gnc_import_Settings_get_clear_threshold (GNCImportSettings *settings)
{
g_assert (settings);
return settings->clear_threshold;
};
gint gnc_import_Settings_get_add_threshold (GNCImportSettings *settings)
{
g_assert (settings);
return settings->add_threshold;
};
gint gnc_import_Settings_get_display_threshold (GNCImportSettings *settings)
{
g_assert (settings);
return settings->display_threshold;
};

View File

@ -0,0 +1,85 @@
/********************************************************************\
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
\brief import-settings.h: User preference interface for
transaction matching (for both the gui and the backend)
\author Copyright (C) 2002 Benoit Grégoire
*/
#ifndef GNC_GEN_SETTINGS_H
#define GNC_GEN_SETTINGS_H
typedef struct _genimportsettings GNCImportSettings;
/************************************************************************
* Getter/Setter Functions for the Data Types.
************************************************************************/
/** @name Getters/Setters for GNCImportSettings */
/*@{*/
/** Allocates a new GNCImportSettings object, and initialize it with the
appropriate user prefs.
*/
GNCImportSettings *
gnc_import_Settings_new (void);
/** Destructor */
void gnc_import_Settings_delete (GNCImportSettings *settings);
/** Return the allowed amount range for fuzzy amount matching.
@return The allowed amount range for fuzzy amount matching,
in the users default commodity.
*/
double
gnc_import_Settings_get_fuzzy_amount (GNCImportSettings *settings);
/** Return the selected action is enable state.
*/
gboolean gnc_import_Settings_get_action_skip_enabled (GNCImportSettings *settings);
/** Return the selected action is enable state.
*/
gboolean gnc_import_Settings_get_action_add_enabled (GNCImportSettings *settings);
/** Return the selected action is enable state.
*/
gboolean gnc_import_Settings_get_action_edit_enabled (GNCImportSettings *settings);
/** Return the selected action is enable state.
*/
gboolean gnc_import_Settings_get_action_clear_enabled (GNCImportSettings *settings);
/** Return the selected threshold.
*/
gint gnc_import_Settings_get_clear_threshold (GNCImportSettings *settings);
/** Return the selected threshold.
*/
gint gnc_import_Settings_get_add_threshold (GNCImportSettings *settings);
/** Return the selected threshold.
*/
gint gnc_import_Settings_get_display_threshold (GNCImportSettings *settings);
/*@}*/
#endif

View File

@ -1,10 +1,4 @@
/********************************************************************\
* generic-import.c -- Functions and utilities to help writing *
* import modules. See file generic-import-design.txt for *
* description *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -22,7 +16,10 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/** @file
@brief import-utilities.h: Utility functions for writing import modules.
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#define _GNU_SOURCE
#include "config.h"
@ -31,7 +28,7 @@
#include <glib.h>
#include <stdlib.h>
#include "gnc-gen-utilities.h"
#include "import-utilities.h"
#include "Account.h"
#include "Transaction.h"

View File

@ -1,10 +1,4 @@
/********************************************************************\
* generic-import.h -- Functions and utilities to help writing *
* import modules. See file generic-import-design.txt for *
* description *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -22,9 +16,12 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
#ifndef GENERIC_IMPORT_UTILITIES_H
#define GENERIC_IMPORT_UTILITIES_H
/** @file
@brief import-utilities.h: Utility functions for writing import modules.
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#ifndef IMPORT_UTILITIES_H
#define IMPORT_UTILITIES_H
#include "Account.h"

View File

@ -1,8 +1,4 @@
/********************************************************************\
* ofx-import.c -- OFX files import *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -20,9 +16,11 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
\brief Ofx import module code
\author Copyright (c) 2002 Benoit Grégoire bock@step.polymtl.ca
/** @file
@brief Ofx import module code
*
gnc-ofx-import.c
@author Copyright (c) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#define _GNU_SOURCE
@ -37,10 +35,10 @@
#include <gmodule.h>
#include "libofx/libofx.h"
#include "Transaction-matcher.h"
#include "Account-matcher.h"
#include "Commodity-matcher.h"
#include "gnc-gen-utilities.h"
#include "import-account-matcher.h"
#include "import-commodity-matcher.h"
#include "import-utilities.h"
#include "import-main-matcher.h"
#include "Account.h"
#include "Transaction.h"
@ -50,7 +48,7 @@
#include "gnc-engine-util.h"
#include "gnc-book.h"
#include "gnc-ui-util.h"
#include "gnc-gen-transaction.h"
#include "dialog-utils.h"
@ -106,11 +104,9 @@ void gnc_file_ofx_import (void)
/* filenames[1]=file;*/
filenames[2]=NULL;
/* CS: Create the Generic transaction importer GUI. */
gnc_ofx_importer_gui = gnc_gen_trans_new(NULL, NULL);
/* Set the allowed fuzzy amount difference to something higher than zero. */
gnc_gen_trans_set_fuzzy_amount (gnc_ofx_importer_gui,
MATCH_ATM_FEE_THRESHOLD);
/* Create the Generic transaction importer GUI. */
gnc_ofx_importer_gui = gnc_gen_trans_list_new(NULL, NULL, FALSE);
DEBUG("Opening selected file");
ofx_proc_file(2, filenames);
}
@ -166,6 +162,8 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data)
Split *split;
gchar *notes, *tmp;
g_assert(gnc_ofx_importer_gui);
if(data.account_id_valid==true){
account = gnc_import_select_account(data.account_id, 0, NULL, NULL, NO_TYPE, NULL);
if(account!=NULL)
@ -366,8 +364,9 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data)
xaccTransAppendSplit(transaction,split);
xaccAccountInsertSplit(account,split);
/*gnc_amount = double_to_gnc_numeric(data.amount,xaccAccountGetCommoditySCU(account),GNC_RND_ROUND);*/
DxaccSplitSetBaseValue(split, data.amount,xaccAccountGetCommodity(account));
DxaccSplitSetBaseValue(split, data.amount, currency);
/* Also put the ofx transaction's memo in the split's memo field */
if(data.memo_valid==true){
xaccSplitSetMemo(split, data.memo);
@ -509,11 +508,9 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data)
}
}
//gnc_import_add_trans(transaction);
/* Previous importer GUI: gnc_import_add_trans(transaction); */
/* CS: Use new importer GUI. */
if (gnc_ofx_importer_gui)
gnc_gen_trans_add_trans (gnc_ofx_importer_gui, transaction);
/* Use new importer GUI. */
DEBUG("%d splits sent to the importer gui",xaccTransCountSplits(transaction));
gnc_gen_trans_list_add_trans (gnc_ofx_importer_gui, transaction);
}
else
{

View File

@ -1,8 +1,4 @@
/********************************************************************\
* gnc-ofx-import.h -- OFX file import *
* (GnuCash) *
* Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> *
* *
* 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 *
@ -20,9 +16,11 @@
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
/**@file
\brief Ofx import module
\author Copyright (c) 2002 Benoit Grégoire bock@step.polymtl.ca
/** @file
@brief Ofx import module interface
*
gnc-ofx-import.h
@author Copyright (c) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#ifndef OFX_IMPORT_H
#define OFX_IMPORT_H