From 0ad94ddcc01ea11282b0875d4edb1f77c6db5644 Mon Sep 17 00:00:00 2001 From: Ueli Niederer Date: Tue, 28 Mar 2017 22:16:30 +0200 Subject: [PATCH 1/6] Including the transaction text into the purpose text Some banks include additional purpose information for a transaction in non-swift-section 17 (aka transaction text). If available, this transaction text is put in front of the other purpose texts to provide full transaction information. While the final solution is still under discussion. This change is a first low-impact implementation backported and distilled from the work discussed in gnucash/gnucash#139. --- src/import-export/aqb/gnc-ab-utils.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/import-export/aqb/gnc-ab-utils.c b/src/import-export/aqb/gnc-ab-utils.c index b0b2ffb5de..0c80948a5b 100644 --- a/src/import-export/aqb/gnc-ab-utils.c +++ b/src/import-export/aqb/gnc-ab-utils.c @@ -364,10 +364,18 @@ gchar * gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans) { const GWEN_STRINGLIST *ab_purpose; + const char *ab_transactionText = NULL; gchar *gnc_description = NULL; g_return_val_if_fail(ab_trans, g_strdup("")); + /* According to AqBanking, some of the non-swift lines have a special + * meaning. Some banks place valuable text into the transaction text, + * hence we put this text in front of the purpose. */ + ab_transactionText = AB_Transaction_GetTransactionText(ab_trans); + if (ab_transactionText) + gnc_description = g_strdup(ab_transactionText); + ab_purpose = AB_Transaction_GetPurpose(ab_trans); if (ab_purpose) GWEN_StringList_ForEach(ab_purpose, join_ab_strings_cb, From 448d97553ff1765b8ac753220af19374fe95f09f Mon Sep 17 00:00:00 2001 From: Ueli Niederer Date: Thu, 30 Mar 2017 20:17:44 +0200 Subject: [PATCH 2/6] Added a preference to control import behaivour of transaction text In order to allow to revert the newly introduced behaviour of putting transaction text in front of the extracted purpose, the feature can now be disabled through the preferences dialog. --- src/import-export/aqb/dialog-ab.glade | 23 +++++++++++++++++-- src/import-export/aqb/gnc-ab-utils.c | 14 ++++++----- src/import-export/aqb/gnc-ab-utils.h | 11 +++++---- ...cash.dialogs.import.hbci.gschema.xml.in.in | 5 ++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/import-export/aqb/dialog-ab.glade b/src/import-export/aqb/dialog-ab.glade index 543e06dba1..b5c4ee3b82 100644 --- a/src/import-export/aqb/dialog-ab.glade +++ b/src/import-export/aqb/dialog-ab.glade @@ -852,6 +852,25 @@ 12 + + + Use Non-SWIFT _transaction text + True + True + True + False + True + True + + + 4 + 3 + 4 + GTK_FILL + + 12 + + _Verbose debug messages @@ -864,8 +883,8 @@ 4 - 3 - 4 + 4 + 5 GTK_FILL 12 diff --git a/src/import-export/aqb/gnc-ab-utils.c b/src/import-export/aqb/gnc-ab-utils.c index 0c80948a5b..b3db650219 100644 --- a/src/import-export/aqb/gnc-ab-utils.c +++ b/src/import-export/aqb/gnc-ab-utils.c @@ -369,12 +369,14 @@ gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans) g_return_val_if_fail(ab_trans, g_strdup("")); - /* According to AqBanking, some of the non-swift lines have a special - * meaning. Some banks place valuable text into the transaction text, - * hence we put this text in front of the purpose. */ - ab_transactionText = AB_Transaction_GetTransactionText(ab_trans); - if (ab_transactionText) - gnc_description = g_strdup(ab_transactionText); + if (gnc_prefs_get_bool(GNC_PREFS_GROUP_AQBANKING, GNC_PREF_USE_TRANSACTION_TXT)) { + /* According to AqBanking, some of the non-swift lines have a special + * meaning. Some banks place valuable text into the transaction text, + * hence we put this text in front of the purpose. */ + ab_transactionText = AB_Transaction_GetTransactionText(ab_trans); + if (ab_transactionText) + gnc_description = g_strdup(ab_transactionText); + } ab_purpose = AB_Transaction_GetPurpose(ab_trans); if (ab_purpose) diff --git a/src/import-export/aqb/gnc-ab-utils.h b/src/import-export/aqb/gnc-ab-utils.h index 12d112ad3f..641f299ec7 100644 --- a/src/import-export/aqb/gnc-ab-utils.h +++ b/src/import-export/aqb/gnc-ab-utils.h @@ -70,11 +70,12 @@ G_BEGIN_DECLS # define AQBANKING_VERSION_4_EXACTLY #endif -#define GNC_PREFS_GROUP_AQBANKING "dialogs.import.hbci" -#define GNC_PREF_FORMAT_SWIFT940 "format-swift-mt940" -#define GNC_PREF_FORMAT_SWIFT942 "format-swift-mt942" -#define GNC_PREF_FORMAT_DTAUS "format-dtaus" -#define GNC_PREF_VERBOSE_DEBUG "verbose-debug" +#define GNC_PREFS_GROUP_AQBANKING "dialogs.import.hbci" +#define GNC_PREF_FORMAT_SWIFT940 "format-swift-mt940" +#define GNC_PREF_FORMAT_SWIFT942 "format-swift-mt942" +#define GNC_PREF_FORMAT_DTAUS "format-dtaus" +#define GNC_PREF_USE_TRANSACTION_TXT "use-ns-transaction-text" +#define GNC_PREF_VERBOSE_DEBUG "verbose-debug" typedef struct _GncABImExContextImport GncABImExContextImport; diff --git a/src/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in.in b/src/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in.in index f12289c392..4eccf0f59c 100644 --- a/src/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in.in +++ b/src/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in.in @@ -20,6 +20,11 @@ Remember the PIN in memory If active, the PIN for HBCI/AqBanking actions will be remembered in memory during a session. Otherwise it will have to be entered again each time during a session when it is needed. + + true + Put the transaction text in front of the purpose of a transaction. + Some banks place part of transaction description as "transaction text" in the MT940 file. Normally GNUcash ignores this text. However by activating this option, the transaction text is used for the transaction description too. + false Verbose HBCI debug messages From 768df3b70974a9f55ea21aad05ebcb4a8b647e86 Mon Sep 17 00:00:00 2001 From: Ueli Niederer Date: Thu, 30 Mar 2017 20:53:45 +0200 Subject: [PATCH 3/6] Obey GNUcash coding style Corrected brace position. --- src/import-export/aqb/gnc-ab-utils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/import-export/aqb/gnc-ab-utils.c b/src/import-export/aqb/gnc-ab-utils.c index b3db650219..3419ec4bcd 100644 --- a/src/import-export/aqb/gnc-ab-utils.c +++ b/src/import-export/aqb/gnc-ab-utils.c @@ -319,7 +319,7 @@ join_ab_strings_cb(const gchar *str, gpointer user_data) if (!str || !*str) return NULL; - + tmp = g_strdup(str); g_strstrip(tmp); gnc_utf8_strip_invalid(tmp); @@ -369,7 +369,8 @@ gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans) g_return_val_if_fail(ab_trans, g_strdup("")); - if (gnc_prefs_get_bool(GNC_PREFS_GROUP_AQBANKING, GNC_PREF_USE_TRANSACTION_TXT)) { + if (gnc_prefs_get_bool(GNC_PREFS_GROUP_AQBANKING, GNC_PREF_USE_TRANSACTION_TXT)) + { /* According to AqBanking, some of the non-swift lines have a special * meaning. Some banks place valuable text into the transaction text, * hence we put this text in front of the purpose. */ From 844a6db32b95aa540c0c27497fdf3ef98fc06a40 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 2 Apr 2017 09:22:16 -0700 Subject: [PATCH 4/6] Bug 780845 - link in github repo README file needs correction/editing --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 4f208e4479..812e9646cc 100644 --- a/README +++ b/README @@ -333,7 +333,7 @@ Before you start developing GnuCash, you should do the following: 1. Read http://wiki.gnucash.org/wiki/Development 2. Look over the doxygen-generated documentation at - http://code.gnucash.org/docs/HEAD/ + http://code.gnucash.org/docs/MAINT/ 3. Go to the GnuCash website and skim the archives of the GnuCash development mailing list. From e20009a08da7c83d3a3d35bcec6c336dfccfc293 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 3 Apr 2017 21:16:43 -0700 Subject: [PATCH 5/6] Save Changes Bug 780889 - Split-register transactions result in invalid... price:type "transaction". Add 'transaction' to the schema and document it in gnc-pricedb.h. --- src/doc/xml/gnucash-v2.rnc | 2 +- src/engine/gnc-pricedb.c | 3 ++- src/engine/gnc-pricedb.h | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/doc/xml/gnucash-v2.rnc b/src/doc/xml/gnucash-v2.rnc index 7a66c92db3..752b03a3c6 100644 --- a/src/doc/xml/gnucash-v2.rnc +++ b/src/doc/xml/gnucash-v2.rnc @@ -199,7 +199,7 @@ Price = element price { # from the doc string of gnc_price_class_init in src/engine/gnc-pricedb.c - element price:type { "bid" | "ask" | "last" | "nav" | "unknown" }?, + element price:type { "bid" | "ask" | "last" | "nav" | "transaction" | "unknown" }?, element price:value { GncNumeric } } diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c index f777f5f67f..37aee847d9 100644 --- a/src/engine/gnc-pricedb.c +++ b/src/engine/gnc-pricedb.c @@ -225,7 +225,8 @@ gnc_price_class_init(GNCPriceClass *klass) "Quote type", "The quote type is a string describing the " "type of a price quote. Types possible now " - "are 'bid', 'ask', 'last', 'nav' and 'unknown'.", + "are 'bid', 'ask', 'last', 'nav', 'transaction', " + "and 'unknown'.", NULL, G_PARAM_READWRITE)); diff --git a/src/engine/gnc-pricedb.h b/src/engine/gnc-pricedb.h index 5c3a62533f..304aee5f03 100644 --- a/src/engine/gnc-pricedb.h +++ b/src/engine/gnc-pricedb.h @@ -116,8 +116,10 @@ GType gnc_pricedb_get_type(void); many strings in users' databases, so this string must be translated on output instead of always being used in untranslated form). - - type: the type of quote - types possible right now are bid, ask, - last, nav, and unknown. + - type: the type of quote - types possible right now are bid, ask, last, + nav, transaction, and unknown. 'Transaction' is set when the price is + created from an amount and value in a Split and is not available for users + to set via the GUI. \par Implementation Details: From a2687bcbe35f98c4646842fdc225f11b58c4a46f Mon Sep 17 00:00:00 2001 From: Mike Alexander Date: Tue, 4 Apr 2017 02:23:44 -0400 Subject: [PATCH 6/6] Fix the SWIG Guile wrapping of functions that have a "struct tm" parameter. The biggest problem was that a pointer to an out of scope struct tm was passed to the wrapped function. With opt level 2, clang doesn't bother setting the contents of the struct since it goes out of scope without being used. This caused the transaction report to never report anything since the start and end times it got were ridiculous. Also most functions that take a struct tm pointer can change the contents of the struct (if only to normalize it) so pass the new values back to Scheme. Finally all calls to gnc_localtime and gnc_gmtime from Scheme leaked a struct tm and calling gnc_tm_free from Scheme is a really bad idea so don't wrap it. --- src/base-typemaps.i | 63 +++++++++++++++++++++++++++++++-------------- src/engine/engine.i | 4 +++ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/base-typemaps.i b/src/base-typemaps.i index 727949fb05..187b64ea63 100644 --- a/src/base-typemaps.i +++ b/src/base-typemaps.i @@ -72,23 +72,23 @@ typedef char gchar; %typemap(in) time64 * (time64 t) "t = scm_to_int64($input); $1 = &t;" %typemap(out) time64 * " $result = ($1) ? scm_from_int64(*($1)) : SCM_BOOL_F; " -%typemap(in) struct tm * { +%typemap(in) struct tm * (struct tm t) { SCM tm = $input; - struct tm t = { - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 0)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 1)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 2)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 3)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 4)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 5)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 6)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 7)), - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 8)), -#ifdef HAVE_STRUCT_TM_GMTOFF - scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 9)), - scm_to_locale_string(SCM_SIMPLE_VECTOR_REF(tm, 10)), -#endif - }; + SCM zone; + t.tm_sec = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 0)); + t.tm_min = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 1)); + t.tm_hour = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 2)); + t.tm_mday = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 3)); + t.tm_mon = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 4)); + t.tm_year = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 5)); + t.tm_wday = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 6)); + t.tm_yday = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 7)); + t.tm_isdst = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 8)); +%#ifdef HAVE_STRUCT_TM_GMTOFF + t.tm_gmtoff = scm_to_int(SCM_SIMPLE_VECTOR_REF(tm, 9)); + zone = SCM_SIMPLE_VECTOR_REF(tm, 10); + t.tm_zone = SCM_UNBNDP(zone) ? NULL : scm_to_locale_string(zone); +%#endif $1 = &t; } @@ -104,15 +104,38 @@ typedef char gchar; SCM_SIMPLE_VECTOR_SET(tm, 6, scm_from_int(t->tm_wday)); SCM_SIMPLE_VECTOR_SET(tm, 7, scm_from_int(t->tm_yday)); SCM_SIMPLE_VECTOR_SET(tm, 8, scm_from_int(t->tm_isdst)); -#ifdef HAVE_STRUCT_TM_GMTOFF +%#ifdef HAVE_STRUCT_TM_GMTOFF SCM_SIMPLE_VECTOR_SET(tm, 9, scm_from_long(t->tm_gmtoff)); - SCM_SIMPLE_VECTOR_SET(tm, 10, scm_from_locale_string(t->tm_zone)); -#else + SCM_SIMPLE_VECTOR_SET(tm, 10, scm_from_locale_string(t->tm_zone?t->tm_zone:"Unset")); +%#else SCM_SIMPLE_VECTOR_SET(tm, 9, scm_from_long(0)); SCM_SIMPLE_VECTOR_SET(tm, 10, scm_from_locale_string("GMT")); -#endif +%#endif $result = tm; } + +%typemap(newfree) struct tm * "gnc_tm_free($1);" + +%typemap(argout) struct tm * { + struct tm* t = $1; + SCM tm = $input; + SCM_SIMPLE_VECTOR_SET(tm, 0, scm_from_int(t->tm_sec)); + SCM_SIMPLE_VECTOR_SET(tm, 1, scm_from_int(t->tm_min)); + SCM_SIMPLE_VECTOR_SET(tm, 2, scm_from_int(t->tm_hour)); + SCM_SIMPLE_VECTOR_SET(tm, 3, scm_from_int(t->tm_mday)); + SCM_SIMPLE_VECTOR_SET(tm, 4, scm_from_int(t->tm_mon)); + SCM_SIMPLE_VECTOR_SET(tm, 5, scm_from_int(t->tm_year)); + SCM_SIMPLE_VECTOR_SET(tm, 6, scm_from_int(t->tm_wday)); + SCM_SIMPLE_VECTOR_SET(tm, 7, scm_from_int(t->tm_yday)); + SCM_SIMPLE_VECTOR_SET(tm, 8, scm_from_int(t->tm_isdst)); +%#ifdef HAVE_STRUCT_TM_GMTOFF + SCM_SIMPLE_VECTOR_SET(tm, 9, scm_from_long(t->tm_gmtoff)); + SCM_SIMPLE_VECTOR_SET(tm, 10, scm_from_locale_string(t->tm_zone?t->tm_zone:"Unset")); +%#else + SCM_SIMPLE_VECTOR_SET(tm, 9, scm_from_long(0)); + SCM_SIMPLE_VECTOR_SET(tm, 10, scm_from_locale_string("GMT")); +%#endif + } %define GLIST_HELPER_INOUT(ListType, ElemSwigType) %typemap(in) ListType * { diff --git a/src/engine/engine.i b/src/engine/engine.i index 14c1214e5c..9001eb6b48 100644 --- a/src/engine/engine.i +++ b/src/engine/engine.i @@ -107,6 +107,9 @@ functions. */ %newobject xaccSplitGetCorrAccountFullName; %newobject gnc_numeric_to_string; +%newobject gnc_localtime; +%newobject gnc_gmtime; + /* Parse the header file to generate wrappers */ %inline { static QofIdType QOF_ID_BOOK_SCM (void) { return QOF_ID_BOOK; } @@ -168,6 +171,7 @@ void qof_book_kvp_changed (QofBook *book); const char *qof_session_get_url (QofSession *session); %ignore qof_print_date_time_buff; +%ignore gnc_tm_free; %include extern const char *gnc_default_strftime_date_format;