mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'private-kvp' into master again
This was done by branching right before the original merge and redoing a clean merge of the private-kvp branch again. This result was then cherry-picked onto master with git cherry-pick <merge-commit> -m 1 It was done like this because git merge would consider the private-kvp branch already merged even after a revert (see git-revert man page) and won't allow to merge a second time on the same branch. Resolved conflicts: README.dependencies src/app-utils/gnc-sx-instance-model.c src/engine/cap-gains.c src/engine/test/Makefile.am src/gnome/assistant-hierarchy.c src/import-export/import-match-map.c src/import-export/import-utilities.c src/import-export/ofx/gnc-ofx-kvp.c src/libqof/qof/qofbook.cpp src/libqof/qof/qofinstance-p.h src/libqof/qof/qofinstance.cpp src/libqof/qof/test/test-kvp_frame.c src/report/report-gnome/gnc-plugin-page-report.c
This commit is contained in:
parent
ae98012d0c
commit
45cb5504f3
@ -404,7 +404,6 @@ src/import-export/import-backend.c
|
||||
src/import-export/import-commodity-matcher.c
|
||||
src/import-export/import-format-dialog.c
|
||||
src/import-export/import-main-matcher.c
|
||||
src/import-export/import-match-map.c
|
||||
src/import-export/import-match-picker.c
|
||||
src/import-export/import-parse.c
|
||||
src/import-export/import-settings.c
|
||||
|
@ -33,7 +33,7 @@ GncTaxTable* gnc_business_get_default_tax_table (QofBook *book, GncOwnerType own
|
||||
GNCOptionDB *odb;
|
||||
|
||||
odb = gnc_option_db_new_for_type (GNC_ID_BOOK);
|
||||
gnc_option_db_load_from_kvp (odb, qof_book_get_slots (book));
|
||||
qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
|
||||
|
||||
switch (ownertype)
|
||||
{
|
||||
|
@ -102,15 +102,13 @@ get_fy_end(void)
|
||||
{
|
||||
QofBook *book;
|
||||
KvpFrame *book_frame;
|
||||
gint64 month, day;
|
||||
GDate *date = NULL;
|
||||
|
||||
book = gnc_get_current_book();
|
||||
book_frame = qof_book_get_slots(book);
|
||||
month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
|
||||
day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
|
||||
if (g_date_valid_dmy(day, month, 2005 /* not leap year */))
|
||||
return g_date_new_dmy(day, month, G_DATE_BAD_YEAR);
|
||||
return NULL;
|
||||
qof_instance_get (QOF_INSTANCE (book),
|
||||
"fy-end", &date,
|
||||
NULL);
|
||||
return date;
|
||||
}
|
||||
|
||||
time64
|
||||
|
@ -176,10 +176,9 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
|
||||
{
|
||||
GHashTable *var_hash = (GHashTable*)var_hash_data;
|
||||
GList *split_list;
|
||||
kvp_frame *kvpf;
|
||||
kvp_value *kvp_val;
|
||||
Split *s;
|
||||
char *str;
|
||||
gchar *credit_formula = NULL;
|
||||
gchar *debit_formula = NULL;
|
||||
gnc_commodity *first_cmdty = NULL;
|
||||
|
||||
split_list = xaccTransGetSplitList(txn);
|
||||
@ -191,16 +190,16 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
|
||||
for ( ; split_list; split_list = split_list->next)
|
||||
{
|
||||
gnc_commodity *split_cmdty = NULL;
|
||||
GncGUID *acct_guid;
|
||||
GncGUID *acct_guid = NULL;
|
||||
Account *acct;
|
||||
|
||||
s = (Split*)split_list->data;
|
||||
kvpf = xaccSplitGetSlots(s);
|
||||
kvp_val = kvp_frame_get_slot_path(kvpf,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_ACCOUNT,
|
||||
NULL);
|
||||
acct_guid = kvp_value_get_guid(kvp_val);
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (s),
|
||||
"sx-account", &acct_guid,
|
||||
"sx-credit-formula", &credit_formula,
|
||||
"sx-debit-formula", &debit_formula,
|
||||
NULL);
|
||||
acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
|
||||
split_cmdty = xaccAccountGetCommodity(acct);
|
||||
if (first_cmdty == NULL)
|
||||
@ -226,31 +225,16 @@ _get_vars_helper(Transaction *txn, void *var_hash_data)
|
||||
}
|
||||
|
||||
// existing... ------------------------------------------
|
||||
kvp_val = kvp_frame_get_slot_path(kvpf,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL);
|
||||
if (kvp_val != NULL)
|
||||
{
|
||||
str = kvp_value_get_string(kvp_val);
|
||||
if (str && strlen(str) != 0)
|
||||
{
|
||||
gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
kvp_val = kvp_frame_get_slot_path(kvpf,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL);
|
||||
if (kvp_val != NULL)
|
||||
{
|
||||
str = kvp_value_get_string(kvp_val);
|
||||
if (str && strlen(str) != 0)
|
||||
{
|
||||
gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
|
||||
}
|
||||
}
|
||||
if (credit_formula && strlen(credit_formula) != 0)
|
||||
{
|
||||
gnc_sx_parse_vars_from_formula(credit_formula, var_hash, NULL);
|
||||
}
|
||||
if (debit_formula && strlen(debit_formula) != 0)
|
||||
{
|
||||
gnc_sx_parse_vars_from_formula(debit_formula, var_hash, NULL);
|
||||
}
|
||||
g_free (credit_formula);
|
||||
g_free (debit_formula);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -900,31 +884,15 @@ typedef struct _SxTxnCreationData
|
||||
} SxTxnCreationData;
|
||||
|
||||
static gboolean
|
||||
_get_template_split_account(const SchedXaction* sx, const Split *template_split, Account **split_acct, GList **creation_errors)
|
||||
_get_template_split_account(const SchedXaction* sx,
|
||||
const Split *template_split,
|
||||
Account **split_acct,
|
||||
GList **creation_errors)
|
||||
{
|
||||
GncGUID *acct_guid;
|
||||
kvp_frame *split_kvpf;
|
||||
kvp_value *kvp_val;
|
||||
|
||||
split_kvpf = xaccSplitGetSlots(template_split);
|
||||
/* contains the guid of the split's actual account. */
|
||||
kvp_val = kvp_frame_get_slot_path(split_kvpf,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_ACCOUNT,
|
||||
NULL);
|
||||
if (kvp_val == NULL)
|
||||
{
|
||||
GString *err = g_string_new("");
|
||||
g_string_printf(err, "Null account kvp value for SX [%s], cancelling creation.",
|
||||
xaccSchedXactionGetName(sx));
|
||||
g_critical("%s", err->str);
|
||||
if (creation_errors != NULL)
|
||||
*creation_errors = g_list_append(*creation_errors, err);
|
||||
else
|
||||
g_string_free(err, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
acct_guid = kvp_value_get_guid( kvp_val );
|
||||
GncGUID *acct_guid = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (template_split),
|
||||
"sx-account", &acct_guid,
|
||||
NULL);
|
||||
*split_acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
|
||||
if (*split_acct == NULL)
|
||||
{
|
||||
@ -946,34 +914,34 @@ _get_template_split_account(const SchedXaction* sx, const Split *template_split,
|
||||
}
|
||||
|
||||
static void
|
||||
_get_sx_formula_value(const SchedXaction* sx, const Split *template_split, gnc_numeric *numeric, GList **creation_errors, const char *formula_key, const char* numeric_key, GHashTable *variable_bindings)
|
||||
_get_sx_formula_value(const SchedXaction* sx,
|
||||
const Split *template_split,
|
||||
gnc_numeric *numeric,
|
||||
GList **creation_errors,
|
||||
const char *formula_key,
|
||||
const char* numeric_key,
|
||||
GHashTable *variable_bindings)
|
||||
{
|
||||
kvp_frame *split_kvpf;
|
||||
kvp_value *kvp_val;
|
||||
char *formula_str, *parseErrorLoc;
|
||||
|
||||
split_kvpf = xaccSplitGetSlots(template_split);
|
||||
char *formula_str = NULL, *parseErrorLoc = NULL;
|
||||
gnc_numeric *numeric_val = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (template_split),
|
||||
formula_key, &formula_str,
|
||||
numeric_key, &numeric_val,
|
||||
NULL);
|
||||
|
||||
/* First look up the gnc_numeric value in the template split */
|
||||
kvp_val = kvp_frame_get_slot_path(split_kvpf,
|
||||
GNC_SX_ID,
|
||||
numeric_key,
|
||||
NULL);
|
||||
*numeric = kvp_value_get_numeric(kvp_val);
|
||||
if ((gnc_numeric_check(*numeric) == GNC_ERROR_OK)
|
||||
&& !gnc_numeric_zero_p(*numeric))
|
||||
if (numeric_val != NULL &&
|
||||
gnc_numeric_check(*numeric_val) == GNC_ERROR_OK &&
|
||||
!gnc_numeric_zero_p(*numeric_val))
|
||||
{
|
||||
/* Already a valid non-zero result? Then return and don't
|
||||
* parse the string. Luckily we avoid any locale problems with
|
||||
* decimal points here! Phew. */
|
||||
numeric->num = numeric_val->num;
|
||||
numeric->denom = numeric_val->denom;
|
||||
return;
|
||||
}
|
||||
|
||||
kvp_val = kvp_frame_get_slot_path(split_kvpf,
|
||||
GNC_SX_ID,
|
||||
formula_key,
|
||||
NULL);
|
||||
formula_str = kvp_value_get_string(kvp_val);
|
||||
if (formula_str != NULL && strlen(formula_str) != 0)
|
||||
{
|
||||
GHashTable *parser_vars = NULL;
|
||||
@ -1010,13 +978,17 @@ _get_sx_formula_value(const SchedXaction* sx, const Split *template_split, gnc_n
|
||||
static void
|
||||
_get_credit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *credit_num, GList **creation_errors)
|
||||
{
|
||||
_get_sx_formula_value(instance->parent->sx, template_split, credit_num, creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, instance->variable_bindings);
|
||||
_get_sx_formula_value(instance->parent->sx, template_split, credit_num,
|
||||
creation_errors, "sx-credit-formula",
|
||||
"sx-credit-numeric", instance->variable_bindings);
|
||||
}
|
||||
|
||||
static void
|
||||
_get_debit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *debit_num, GList **creation_errors)
|
||||
{
|
||||
_get_sx_formula_value(instance->parent->sx, template_split, debit_num, creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, instance->variable_bindings);
|
||||
_get_sx_formula_value(instance->parent->sx, template_split, debit_num,
|
||||
creation_errors, "sx-debit-formula",
|
||||
"sx-debit-numeric", instance->variable_bindings);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1035,7 +1007,7 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
|
||||
as not finding the approrpiate Accounts and not being able to
|
||||
parse the formula|credit/debit strings. */
|
||||
|
||||
new_txn = xaccTransClone(template_txn);
|
||||
new_txn = xaccTransCloneNoKvp(template_txn);
|
||||
xaccTransBeginEdit(new_txn);
|
||||
|
||||
g_debug("creating template txn desc [%s] for sx [%s]",
|
||||
@ -1044,9 +1016,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
|
||||
|
||||
g_debug("template txn currency is %s", gnc_commodity_get_mnemonic(xaccTransGetCurrency (template_txn)));
|
||||
|
||||
/* clear any copied KVP data */
|
||||
qof_instance_set_slots(QOF_INSTANCE(new_txn), kvp_frame_new());
|
||||
|
||||
/* Bug#500427: copy the notes, if any */
|
||||
if (xaccTransGetNotes(template_txn) != NULL)
|
||||
{
|
||||
@ -1090,9 +1059,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear out any copied Split frame data. */
|
||||
qof_instance_set_slots(QOF_INSTANCE(copying_split), kvp_frame_new());
|
||||
|
||||
split_cmdty = xaccAccountGetCommodity(split_acct);
|
||||
if (first_cmdty == NULL)
|
||||
{
|
||||
@ -1215,13 +1181,10 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
|
||||
}
|
||||
|
||||
{
|
||||
kvp_frame *txn_frame;
|
||||
txn_frame = xaccTransGetSlots(new_txn);
|
||||
kvp_frame_set_guid(txn_frame, "from-sched-xaction",
|
||||
xaccSchedXactionGetGUID(creation_data->instance->parent->sx));
|
||||
/* The transaction was probably marked dirty by xaccTransSetCurrency,
|
||||
* but just in case: */
|
||||
qof_instance_set_dirty (QOF_INSTANCE (new_txn));
|
||||
qof_instance_set (QOF_INSTANCE (new_txn),
|
||||
"from-sched-xaction",
|
||||
xaccSchedXactionGetGUID(creation_data->instance->parent->sx),
|
||||
NULL);
|
||||
}
|
||||
|
||||
xaccTransCommitEdit(new_txn);
|
||||
@ -1631,9 +1594,14 @@ create_cashflow_helper(Transaction *template_txn, void *user_data)
|
||||
gint gncn_error;
|
||||
|
||||
/* Credit value */
|
||||
_get_sx_formula_value(creation_data->sx, template_split, &credit_num, creation_data->creation_errors, GNC_SX_CREDIT_FORMULA, GNC_SX_CREDIT_NUMERIC, NULL);
|
||||
_get_sx_formula_value(creation_data->sx, template_split,
|
||||
&credit_num, creation_data->creation_errors,
|
||||
"sx-credit-formula", "sx-credit-numeric",
|
||||
NULL);
|
||||
/* Debit value */
|
||||
_get_sx_formula_value(creation_data->sx, template_split, &debit_num, creation_data->creation_errors, GNC_SX_DEBIT_FORMULA, GNC_SX_DEBIT_NUMERIC, NULL);
|
||||
_get_sx_formula_value(creation_data->sx, template_split,
|
||||
&debit_num, creation_data->creation_errors,
|
||||
"sx-debit-formula", "sx-debit-numeric", NULL);
|
||||
|
||||
/* The resulting cash flow number: debit minus credit,
|
||||
* multiplied with the count factor. */
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
typedef struct gnc_option GNCOption;
|
||||
typedef struct gnc_option_section GNCOptionSection;
|
||||
typedef struct gnc_option_db GNCOptionDB;
|
||||
/* typedef struct gnc_option_db GNCOptionDB is in qof-book.h */
|
||||
|
||||
typedef int GNCOptionDBHandle;
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
include $(top_srcdir)/test-templates/Makefile.decl
|
||||
|
||||
TESTS = \
|
||||
test-link-module \
|
||||
test-load-module \
|
||||
@ -66,3 +68,17 @@ AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/src/libqof/qof \
|
||||
${GUILE_CFLAGS} \
|
||||
${GLIB_CFLAGS}
|
||||
|
||||
TEST_PROGS += test-app-utils
|
||||
|
||||
noinst_PROGRAMS = ${TEST_PROGS} ${CHECK_PROGS}
|
||||
|
||||
test_app_utils_SOURCES = \
|
||||
test-app-utils.c \
|
||||
test-option-util.c
|
||||
|
||||
test_app_utils_CFLAGS = \
|
||||
${DEFAULT_INCLUDES} \
|
||||
-I${top_srcdir}/${MODULEPATH}/ \
|
||||
-DTESTPROG=test_app_utils \
|
||||
${GLIB_CFLAGS}
|
||||
|
56
src/app-utils/test/test-app-utils.c
Normal file
56
src/app-utils/test/test-app-utils.c
Normal file
@ -0,0 +1,56 @@
|
||||
/********************************************************************
|
||||
* test-app-utils.c: GLib g_test test execution file. *
|
||||
* Copyright 2013 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <qof.h>
|
||||
#include <libguile.h>
|
||||
#include <gnc-module.h>
|
||||
|
||||
extern void test_suite_option_util (void);
|
||||
|
||||
static void
|
||||
guile_main (void *closure, int argc, char **argv)
|
||||
{
|
||||
GNCModule mod;
|
||||
int retval;
|
||||
gnc_module_system_init ();
|
||||
mod = gnc_module_load ("gnucash/app-utils", 0);
|
||||
|
||||
test_suite_option_util ();
|
||||
retval = g_test_run ();
|
||||
|
||||
exit (retval);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
qof_init (); /* Initialize the GObject system */
|
||||
qof_log_init_filename_special ("stderr"); /* Init the log system */
|
||||
g_test_init (&argc, &argv, NULL); /* initialize test program */
|
||||
//qof_log_set_level("gnc", G_LOG_LEVEL_DEBUG);
|
||||
g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
|
||||
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
|
||||
scm_boot_guile (argc, argv, guile_main, NULL);
|
||||
|
||||
}
|
126
src/app-utils/test/test-option-util.c
Normal file
126
src/app-utils/test/test-option-util.c
Normal file
@ -0,0 +1,126 @@
|
||||
/********************************************************************
|
||||
* test-option-util.c: GLib g_test test suite for Split.c. *
|
||||
* Copyright 2013 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* 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, you can retrieve it from *
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html *
|
||||
* or contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
********************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <unittest-support.h>
|
||||
#include <qofbookslots.h>
|
||||
|
||||
#include "../option-util.h"
|
||||
|
||||
static const gchar *suitename = "/app-utils/option-util";
|
||||
void test_suite_option_util (void);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
QofBook *book;
|
||||
GSList *hdlrs;
|
||||
} Fixture;
|
||||
|
||||
/* Expose a mostly-private QofInstance function to load options into
|
||||
* the Book.
|
||||
*/
|
||||
extern KvpFrame *qof_instance_get_slots (QofInstance*);
|
||||
|
||||
static void
|
||||
setup (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
fixture->book = qof_book_new ();
|
||||
fixture->hdlrs = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_kvp (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book;
|
||||
KvpFrame *slots;
|
||||
setup (fixture, pData);
|
||||
book = fixture->book;
|
||||
slots = qof_instance_get_slots (QOF_INSTANCE (book));
|
||||
qof_begin_edit (QOF_INSTANCE (book));
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"trading-accts", "t",
|
||||
"split-action-num-field", "t",
|
||||
"autoreadonly-days", (double)21,
|
||||
NULL);
|
||||
|
||||
kvp_frame_set_string (slots, "options/Business/Company Name",
|
||||
"Bogus Company");
|
||||
qof_commit_edit (QOF_INSTANCE (book));
|
||||
}
|
||||
|
||||
static void
|
||||
teardown (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
qof_book_destroy (fixture->book);
|
||||
g_slist_free_full (fixture->hdlrs, test_free_log_handler);
|
||||
test_clear_error_list();
|
||||
}
|
||||
|
||||
static void
|
||||
test_option_load_from_kvp (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = fixture->book;
|
||||
GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
|
||||
|
||||
qof_book_load_options (book, gnc_option_db_load_from_kvp, odb);
|
||||
g_assert (gnc_option_db_lookup_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_TRADING_ACCOUNTS, FALSE));
|
||||
g_assert_cmpstr (gnc_option_db_lookup_string_option (odb, "Business", "Company Name", FALSE), ==, "Bogus Company");
|
||||
g_assert_cmpfloat (gnc_option_db_lookup_number_option (odb, OPTION_SECTION_ACCOUNTS, OPTION_NAME_AUTO_READONLY_DAYS, FALSE), ==, 21);
|
||||
|
||||
gnc_option_db_destroy (odb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_option_save_to_kvp (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = fixture->book;
|
||||
GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
|
||||
KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
|
||||
|
||||
g_assert (gnc_option_db_set_boolean_option (odb, OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_TRADING_ACCOUNTS,
|
||||
TRUE));
|
||||
g_assert (gnc_option_db_set_string_option (odb, "Business", "Company Name",
|
||||
"Bogus Company"));
|
||||
g_assert (gnc_option_db_set_number_option (odb, OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_AUTO_READONLY_DAYS,
|
||||
17));
|
||||
qof_book_save_options (book, gnc_option_db_save_to_kvp, odb, TRUE);
|
||||
g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Use Trading Accounts"), == , "t");
|
||||
g_assert_cmpstr (kvp_frame_get_string (slots, "options/Business/Company Name"), ==, "Bogus Company");
|
||||
g_assert_cmpfloat (kvp_frame_get_double (slots, "options/Accounts/Day Threshold for Read-Only Transactions (red line)"), ==, 17);
|
||||
|
||||
gnc_option_db_destroy (odb);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test_suite_option_util (void)
|
||||
{
|
||||
GNC_TEST_ADD (suitename, "Option DB Load from KVP", Fixture, NULL, setup_kvp, test_option_load_from_kvp, teardown);
|
||||
GNC_TEST_ADD (suitename, "Option DB Save to KVP", Fixture, NULL, setup, test_option_save_to_kvp, teardown);
|
||||
|
||||
}
|
@ -168,6 +168,9 @@ compare_sxs( QofBook* book_1, QofBook* book_2 )
|
||||
compare_single_sx, "Scheduled transaction lists match" );
|
||||
}
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION */
|
||||
extern KvpFrame *qof_instance_get_slots (const QofInstance *);
|
||||
|
||||
static void
|
||||
compare_single_lot( QofInstance* inst, gpointer user_data )
|
||||
{
|
||||
@ -181,8 +184,8 @@ compare_single_lot( QofInstance* inst, gpointer user_data )
|
||||
gnc_lot_get_account (lot_2), FALSE ));
|
||||
g_assert_cmpint (gnc_lot_is_closed (lot_1), ==, gnc_lot_is_closed (lot_2));
|
||||
|
||||
g_assert (kvp_frame_compare (gnc_lot_get_slots (lot_1),
|
||||
gnc_lot_get_slots (lot_2)) == 0);
|
||||
g_assert (kvp_frame_compare (qof_instance_get_slots (QOF_INSTANCE (lot_1)),
|
||||
qof_instance_get_slots (QOF_INSTANCE (lot_2))) == 0);
|
||||
splits1 = gnc_lot_get_split_list (lot_1);
|
||||
splits2 = gnc_lot_get_split_list (lot_2);
|
||||
g_assert_cmpint (g_list_length (splits1), ==, g_list_length (splits2));
|
||||
|
@ -294,12 +294,14 @@ load_all_accounts( GncSqlBackend* be )
|
||||
{
|
||||
acct_balances_t* balances = (acct_balances_t*)bal->data;
|
||||
|
||||
qof_instance_increase_editlevel (balances->acct);
|
||||
g_object_set( balances->acct,
|
||||
"start-balance", &balances->balance,
|
||||
"start-cleared-balance", &balances->cleared_balance,
|
||||
"start-reconciled-balance", &balances->reconciled_balance,
|
||||
NULL);
|
||||
|
||||
qof_instance_decrease_editlevel (balances->acct);
|
||||
}
|
||||
if ( bal_slist != NULL )
|
||||
{
|
||||
@ -418,7 +420,9 @@ load_account_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, account, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -115,7 +115,9 @@ load_address( const GncSqlBackend* be, GncSqlRow* row,
|
||||
}
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, addr, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1204,7 +1204,11 @@ const GncSqlColumnTableEntry* table_row )
|
||||
s = g_value_get_string( val );
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, s, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1308,7 +1312,11 @@ load_int( const GncSqlBackend* be, GncSqlRow* row,
|
||||
}
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1406,7 +1414,11 @@ load_boolean( const GncSqlBackend* be, GncSqlRow* row,
|
||||
}
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, int_value, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1499,7 +1511,11 @@ load_int64( const GncSqlBackend* be, GncSqlRow* row,
|
||||
}
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, i64_value, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1606,7 +1622,11 @@ load_double( const GncSqlBackend* be, GncSqlRow* row,
|
||||
}
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, d_value, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1705,7 +1725,11 @@ load_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, pGuid, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1912,7 +1936,11 @@ load_timespec( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if (table_row->gobj_param_name != NULL)
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, &ts, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2014,7 +2042,11 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
|
||||
g_date_time_unref (gdt);
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, date, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2048,7 +2080,12 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
|
||||
date = g_date_new_dmy( day, month, year );
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
g_object_set( pObject, table_row->gobj_param_name, date, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set (pObject, table_row->gobj_param_name,
|
||||
date, NULL);
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2187,7 +2224,11 @@ load_numeric( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
g_object_set( pObject, table_row->gobj_param_name, &n, NULL );
|
||||
if (QOF_IS_INSTANCE (pObject))
|
||||
qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -363,7 +363,9 @@ load_billterm_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, term, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -500,7 +500,9 @@ load_budget_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, budget, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -283,7 +283,9 @@ load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else if ( setter != NULL )
|
||||
{
|
||||
|
@ -303,7 +303,9 @@ load_invoice_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, invoice, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -235,7 +235,9 @@ load_lot_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, lot, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -220,7 +220,9 @@ load_order_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, order, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -156,7 +156,9 @@ load_owner( const GncSqlBackend* be, GncSqlRow* row,
|
||||
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, &owner, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -523,7 +523,9 @@ load_taxtable_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, taxtable, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -415,6 +415,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
|
||||
"end-reconciled-balance", &pnew_end_r_bal,
|
||||
NULL );
|
||||
|
||||
qof_instance_increase_editlevel (balns-acc);
|
||||
if ( !gnc_numeric_eq( *pnew_end_bal, balns->end_bal ) )
|
||||
{
|
||||
adj = gnc_numeric_sub( balns->end_bal, *pnew_end_bal,
|
||||
@ -422,6 +423,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
|
||||
balns->start_bal = gnc_numeric_add( balns->start_bal, adj,
|
||||
GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
|
||||
g_object_set( balns->acc, "start-balance", &balns->start_bal, NULL );
|
||||
qof_instance_decrease_editlevel (balns-acc);
|
||||
}
|
||||
if ( !gnc_numeric_eq( *pnew_end_c_bal, balns->end_cleared_bal ) )
|
||||
{
|
||||
@ -439,6 +441,7 @@ query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
|
||||
GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
|
||||
g_object_set( balns->acc, "start-reconciled-balance", &balns->start_reconciled_bal, NULL );
|
||||
}
|
||||
qof_instance_decrease_editlevel (balns-acc);
|
||||
xaccAccountRecomputeBalance( balns->acc );
|
||||
g_free( pnew_end_bal );
|
||||
g_free( pnew_end_c_bal );
|
||||
@ -1461,7 +1464,9 @@ load_tx_guid( const GncSqlBackend* be, GncSqlRow* row,
|
||||
{
|
||||
if ( table_row->gobj_param_name != NULL )
|
||||
{
|
||||
qof_instance_increase_editlevel (pObject);
|
||||
g_object_set( pObject, table_row->gobj_param_name, tx, NULL );
|
||||
qof_instance_decrease_editlevel (pObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -71,6 +71,9 @@ const gchar *account_version_string = "2.0.0";
|
||||
#define act_hidden_string "act:hidden"
|
||||
#define act_placeholder_string "act:placeholder"
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION */
|
||||
extern KvpFrame *qof_instance_get_slots (const QofInstance *);
|
||||
|
||||
xmlNodePtr
|
||||
gnc_account_dom_tree_create(Account *act,
|
||||
gboolean exporting,
|
||||
@ -134,7 +137,7 @@ gnc_account_dom_tree_create(Account *act,
|
||||
xmlAddChild(ret, text_to_dom_tree(act_description_string, str));
|
||||
}
|
||||
|
||||
kf = xaccAccountGetSlots(act);
|
||||
kf = qof_instance_get_slots (QOF_INSTANCE (act));
|
||||
if (kf)
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree(act_slots_string, kf);
|
||||
@ -370,7 +373,7 @@ account_slots_handler (xmlNodePtr node, gpointer act_pdata)
|
||||
struct account_pdata *pdata = act_pdata;
|
||||
|
||||
return dom_tree_to_kvp_frame_given
|
||||
(node, xaccAccountGetSlots (pdata->account));
|
||||
(node, qof_instance_get_slots (QOF_INSTANCE (pdata->account)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -109,10 +109,10 @@ gnc_book_dom_tree_create(QofBook *book)
|
||||
xmlAddChild(ret, guid_to_dom_tree(book_id_string,
|
||||
qof_book_get_guid(book)));
|
||||
|
||||
if (qof_book_get_slots(book))
|
||||
if (qof_instance_get_slots (QOF_INSTANCE (book)))
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
|
||||
qof_book_get_slots(book));
|
||||
qof_instance_get_slots (QOF_INSTANCE (book)));
|
||||
if (kvpnode)
|
||||
xmlAddChild(ret, kvpnode);
|
||||
}
|
||||
@ -162,10 +162,10 @@ write_book_parts(FILE *out, QofBook *book)
|
||||
if (ferror(out) || fprintf(out, "\n") < 0)
|
||||
return FALSE;
|
||||
|
||||
if (qof_book_get_slots(book))
|
||||
if (qof_instance_get_slots (QOF_INSTANCE (book)))
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string,
|
||||
qof_book_get_slots(book));
|
||||
qof_instance_get_slots (QOF_INSTANCE (book)));
|
||||
if (kvpnode)
|
||||
{
|
||||
xmlElemDump(out, NULL, kvpnode);
|
||||
@ -203,7 +203,7 @@ book_slots_handler (xmlNodePtr node, gpointer book_pdata)
|
||||
|
||||
/* the below works only because the get is gaurenteed to return
|
||||
* a frame, even if its empty */
|
||||
success = dom_tree_to_kvp_frame_given (node, qof_book_get_slots (book));
|
||||
success = dom_tree_to_kvp_frame_given (node, qof_instance_get_slots (QOF_INSTANCE (book)));
|
||||
|
||||
g_return_val_if_fail(success, FALSE);
|
||||
|
||||
|
@ -72,6 +72,9 @@ const gchar *invoice_version_string = "2.0.0";
|
||||
#define invoice_tochargeamt_string "invoice:charge-amt"
|
||||
#define invoice_slots_string "invoice:slots"
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION */
|
||||
extern KvpFrame *qof_instance_get_slots (const QofInstance *);
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
@ -410,7 +413,7 @@ invoice_slots_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return dom_tree_to_kvp_frame_given
|
||||
(node, xaccAccountGetSlots (pdata->invoice));
|
||||
(node, qof_instance_get_slots (QOF_INSTANCE (pdata->invoice)));
|
||||
}
|
||||
|
||||
static struct dom_tree_handler invoice_handlers_v2[] =
|
||||
|
@ -53,6 +53,8 @@ const gchar *lot_version_string = "2.0.0";
|
||||
#define gnc_lot_string "gnc:lot"
|
||||
#define lot_id_string "lot:id"
|
||||
#define lot_slots_string "lot:slots"
|
||||
/* EFFECTIVE FRIEND FUNCTION */
|
||||
extern KvpFrame *qof_instance_get_slots (const QofInstance *);
|
||||
|
||||
xmlNodePtr
|
||||
gnc_lot_dom_tree_create(GNCLot *lot)
|
||||
@ -66,7 +68,7 @@ gnc_lot_dom_tree_create(GNCLot *lot)
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(lot_id_string, gnc_lot_get_guid(lot)));
|
||||
|
||||
kf = gnc_lot_get_slots (lot);
|
||||
kf = qof_instance_get_slots (QOF_INSTANCE (lot));
|
||||
if (kf)
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree(lot_slots_string, kf);
|
||||
@ -112,7 +114,7 @@ lot_slots_handler (xmlNodePtr node, gpointer p)
|
||||
|
||||
ENTER("(lot=%p)", pdata->lot);
|
||||
success = dom_tree_to_kvp_frame_given
|
||||
(node, gnc_lot_get_slots (pdata->lot));
|
||||
(node, qof_instance_get_slots (QOF_INSTANCE (pdata->lot)));
|
||||
|
||||
LEAVE("");
|
||||
g_return_val_if_fail(success, FALSE);
|
||||
|
@ -49,6 +49,9 @@
|
||||
|
||||
const gchar *transaction_version_string = "2.0.0";
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION */
|
||||
extern KvpFrame *qof_instance_get_slots (const QofInstance *);
|
||||
|
||||
static void
|
||||
add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num)
|
||||
{
|
||||
@ -129,7 +132,7 @@ split_to_dom_tree(const gchar *tag, Split *spl)
|
||||
}
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots",
|
||||
xaccSplitGetSlots(spl));
|
||||
qof_instance_get_slots (QOF_INSTANCE (spl)));
|
||||
if (kvpnode)
|
||||
{
|
||||
xmlAddChild(ret, kvpnode);
|
||||
@ -192,7 +195,7 @@ gnc_transaction_dom_tree_create(Transaction *trn)
|
||||
|
||||
{
|
||||
xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots",
|
||||
xaccTransGetSlots(trn));
|
||||
qof_instance_get_slots (QOF_INSTANCE (trn)));
|
||||
if (kvpnode)
|
||||
{
|
||||
xmlAddChild(ret, kvpnode);
|
||||
@ -368,7 +371,7 @@ spl_slots_handler(xmlNodePtr node, gpointer data)
|
||||
gboolean successful;
|
||||
|
||||
successful = dom_tree_to_kvp_frame_given(node,
|
||||
xaccSplitGetSlots (pdata->split));
|
||||
qof_instance_get_slots (QOF_INSTANCE (pdata->split)));
|
||||
g_return_val_if_fail(successful, FALSE);
|
||||
|
||||
return TRUE;
|
||||
@ -527,7 +530,7 @@ trn_slots_handler(xmlNodePtr node, gpointer trans_pdata)
|
||||
Transaction *trn = pdata->trans;
|
||||
gboolean successful;
|
||||
|
||||
successful = dom_tree_to_kvp_frame_given(node, xaccTransGetSlots(trn));
|
||||
successful = dom_tree_to_kvp_frame_given(node, qof_instance_get_slots (QOF_INSTANCE (trn)));
|
||||
|
||||
g_return_val_if_fail(successful, FALSE);
|
||||
|
||||
|
@ -2182,7 +2182,7 @@ gnc_xml2_parse_with_subst (FileBackend *fbe, QofBook *book, GHashTable *subst)
|
||||
push_data, GNC_BOOK_XML2_FILE);
|
||||
|
||||
if (success)
|
||||
qof_book_kvp_changed(book);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (book));
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ node_and_account_equal(xmlNodePtr node, Account *act)
|
||||
{
|
||||
/* xaccAccountDeleteOldData (act); */
|
||||
|
||||
if (!equals_node_val_vs_kvp_frame(mark, xaccAccountGetSlots(act)))
|
||||
if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots(QOF_INSTANCE (act))))
|
||||
{
|
||||
return g_strdup("slots differ");
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ node_and_transaction_equal(xmlNodePtr node, Transaction *trn)
|
||||
}
|
||||
else if (g_strcmp0((char*)mark->name, "trn:slots") == 0)
|
||||
{
|
||||
if (!equals_node_val_vs_kvp_frame(mark, xaccTransGetSlots(trn)))
|
||||
if (!equals_node_val_vs_kvp_frame(mark, qof_instance_get_slots (QOF_INSTANCE (trn))))
|
||||
{
|
||||
return "slots differ";
|
||||
}
|
||||
|
@ -90,8 +90,6 @@
|
||||
#define GNC_PREF_ACCUM_SPLITS "accumulate-splits"
|
||||
#define GNC_PREF_DAYS_IN_ADVANCE "days-in-advance"
|
||||
|
||||
#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
|
||||
|
||||
void gnc_invoice_window_ok_cb (GtkWidget *widget, gpointer data);
|
||||
void gnc_invoice_window_cancel_cb (GtkWidget *widget, gpointer data);
|
||||
void gnc_invoice_window_help_cb (GtkWidget *widget, gpointer data);
|
||||
@ -681,7 +679,6 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
|
||||
GList * acct_types = NULL;
|
||||
GList * acct_commodities = NULL;
|
||||
QofInstance *owner_inst;
|
||||
KvpFrame *kvpf;
|
||||
EntryList *entries, *entries_iter;
|
||||
|
||||
invoice = iw_get_invoice (iw);
|
||||
@ -726,12 +723,14 @@ gnc_dialog_post_invoice(InvoiceWindow *iw, char *message,
|
||||
/* Get the due date and posted account */
|
||||
*ddue = *postdate;
|
||||
*memo = NULL;
|
||||
|
||||
owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
|
||||
kvpf = qof_instance_get_slots (owner_inst);
|
||||
*acc = xaccAccountLookup (kvp_frame_get_guid (kvpf, LAST_POSTED_TO_ACCT),
|
||||
iw->book);
|
||||
|
||||
{
|
||||
GncGUID *guid = NULL;
|
||||
owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
|
||||
qof_instance_get (owner_inst,
|
||||
"invoice-last-posted-account", &guid,
|
||||
NULL);
|
||||
*acc = xaccAccountLookup (guid, iw->book);
|
||||
}
|
||||
/* Get the default for the accumulate option */
|
||||
*accumulate = gnc_prefs_get_bool(GNC_PREFS_GROUP_INVOICE, GNC_PREF_ACCUM_SPLITS);
|
||||
|
||||
@ -762,8 +761,6 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
|
||||
Timespec ddue, postdate;
|
||||
gboolean accumulate;
|
||||
QofInstance *owner_inst;
|
||||
KvpFrame *kvpf;
|
||||
KvpValue *kvp_val;
|
||||
const char *text;
|
||||
GHashTable *foreign_currs;
|
||||
GHashTableIter foreign_currs_iter;
|
||||
@ -911,14 +908,18 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
|
||||
}
|
||||
|
||||
|
||||
/* Save account as last used account in the kvp frame of the invoice owner */
|
||||
/* Save account as last used account in the owner's
|
||||
* invoice-last-posted-account property.
|
||||
*/
|
||||
owner_inst = qofOwnerGetOwner (gncOwnerGetEndOwner (&(iw->owner)));
|
||||
kvpf = qof_instance_get_slots (owner_inst);
|
||||
kvp_val = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE (acc)));;
|
||||
qof_begin_edit (owner_inst);
|
||||
kvp_frame_set_slot_nc (kvpf, LAST_POSTED_TO_ACCT, kvp_val);
|
||||
qof_instance_set_dirty (owner_inst);
|
||||
qof_commit_edit (owner_inst);
|
||||
{
|
||||
const GncGUID *guid = qof_instance_get_guid (QOF_INSTANCE (acc));
|
||||
qof_begin_edit (owner_inst);
|
||||
qof_instance_set (owner_inst,
|
||||
"invoice-last-posted-account", guid,
|
||||
NULL);
|
||||
qof_commit_edit (owner_inst);
|
||||
}
|
||||
|
||||
/* ... post it ... */
|
||||
if (is_cust_doc)
|
||||
|
@ -452,23 +452,15 @@ gnc_payment_dialog_owner_changed (PaymentWindow *pw)
|
||||
{
|
||||
Account *last_acct = NULL;
|
||||
GncGUID *guid = NULL;
|
||||
KvpValue* value;
|
||||
KvpFrame* slots;
|
||||
GncOwner *owner = &pw->owner;
|
||||
|
||||
/* If the owner changed, the initial invoice is no longer valid */
|
||||
pw->invoice = NULL;
|
||||
|
||||
/* Now handle the account tree */
|
||||
slots = gncOwnerGetSlots(owner);
|
||||
if (slots)
|
||||
{
|
||||
value = kvp_frame_get_slot_path(slots, "payment", "last_acct", NULL);
|
||||
if (value)
|
||||
{
|
||||
guid = kvp_value_get_guid(value);
|
||||
}
|
||||
}
|
||||
qof_instance_get (QOF_INSTANCE (owner),
|
||||
"payment-last-account", &guid,
|
||||
NULL);
|
||||
|
||||
/* refresh the post and acc available accounts, but cleanup first */
|
||||
if (pw->acct_types)
|
||||
@ -514,20 +506,17 @@ gnc_payment_dialog_post_to_changed (PaymentWindow *pw)
|
||||
static void
|
||||
gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc)
|
||||
{
|
||||
KvpValue* value;
|
||||
KvpFrame* slots = gncOwnerGetSlots(&pw->owner);
|
||||
GncOwner *owner = &pw->owner;
|
||||
const GncGUID *guid;
|
||||
|
||||
if (!acc) return;
|
||||
if (!slots) return;
|
||||
|
||||
value = kvp_value_new_guid(xaccAccountGetGUID(acc));
|
||||
if (!value) return;
|
||||
|
||||
xaccAccountBeginEdit (acc);
|
||||
kvp_frame_set_slot_path(slots, value, "payment", "last_acct", NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (acc));
|
||||
xaccAccountCommitEdit (acc);
|
||||
kvp_value_delete(value);
|
||||
guid = xaccAccountGetGUID(acc);
|
||||
qof_begin_edit (QOF_INSTANCE (owner));
|
||||
qof_instance_set (QOF_INSTANCE (owner),
|
||||
"payment-last-account", guid,
|
||||
NULL);
|
||||
qof_commit_edit (QOF_INSTANCE (owner));
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,10 +67,12 @@ static void gnc_features_init ()
|
||||
g_strdup (known_features[i].desc));
|
||||
}
|
||||
|
||||
static void gnc_features_test_one(const gchar *key, KvpValue *value, gpointer data)
|
||||
static void gnc_features_test_one(gpointer pkey, gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *key = (const gchar*)pkey;
|
||||
const gchar *feature_desc = (const gchar*)value;
|
||||
GList **unknown_features;
|
||||
gchar *feature_desc;
|
||||
|
||||
g_assert(data);
|
||||
unknown_features = (GList**) data;
|
||||
@ -80,54 +82,47 @@ static void gnc_features_test_one(const gchar *key, KvpValue *value, gpointer da
|
||||
return;
|
||||
|
||||
/* It is unknown, so add the description to the unknown features list: */
|
||||
feature_desc = kvp_value_get_string(value);
|
||||
g_assert(feature_desc);
|
||||
|
||||
*unknown_features = g_list_prepend(*unknown_features, feature_desc);
|
||||
*unknown_features = g_list_prepend(*unknown_features,
|
||||
(gpointer)feature_desc);
|
||||
}
|
||||
|
||||
/* Check if the session requires features unknown to this version of GnuCash.
|
||||
*
|
||||
* Returns a message to display if we found unknown features, NULL if we're okay.
|
||||
* Returns a message to display if we found unknown features, NULL if
|
||||
* we're okay.
|
||||
*/
|
||||
gchar *gnc_features_test_unknown (QofBook *book)
|
||||
{
|
||||
KvpFrame *frame = qof_book_get_slots (book);
|
||||
KvpValue *value;
|
||||
|
||||
/* Setup the known_features hash table */
|
||||
gnc_features_init();
|
||||
|
||||
g_assert(frame);
|
||||
value = kvp_frame_get_value(frame, "features");
|
||||
GList* features_list = NULL;
|
||||
GHashTable *features_used = qof_book_get_features (book);
|
||||
|
||||
if (value)
|
||||
/* Iterate over the members of this frame for unknown features */
|
||||
g_hash_table_foreach (features_used, &gnc_features_test_one,
|
||||
&features_list);
|
||||
if (features_list)
|
||||
{
|
||||
GList* features_list = NULL;
|
||||
frame = kvp_value_get_frame(value);
|
||||
g_assert(frame);
|
||||
|
||||
/* Iterate over the members of this frame for unknown features */
|
||||
kvp_frame_for_each_slot(frame, &gnc_features_test_one, &features_list);
|
||||
if (features_list)
|
||||
{
|
||||
GList *i;
|
||||
char* msg = g_strdup(
|
||||
_("This Dataset contains features not supported by this "
|
||||
"version of GnuCash. You must use a newer version of "
|
||||
"GnuCash in order to support the following features:"
|
||||
GList *i;
|
||||
char* msg = g_strdup(_("This Dataset contains features not supported "
|
||||
"by this version of GnuCash. You must use a "
|
||||
"newer version of GnuCash in order to support "
|
||||
"the following features:"
|
||||
));
|
||||
|
||||
for (i = features_list; i; i = i->next)
|
||||
{
|
||||
char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
|
||||
g_free (msg);
|
||||
msg = tmp;
|
||||
}
|
||||
for (i = features_list; i; i = i->next)
|
||||
{
|
||||
char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
|
||||
g_free (msg);
|
||||
msg = tmp;
|
||||
}
|
||||
|
||||
g_list_free(features_list);
|
||||
return msg;
|
||||
}
|
||||
g_list_free(features_list);
|
||||
return msg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -135,9 +130,7 @@ gchar *gnc_features_test_unknown (QofBook *book)
|
||||
|
||||
void gnc_features_set_used (QofBook *book, const gchar *feature)
|
||||
{
|
||||
KvpFrame *frame;
|
||||
const gchar *description;
|
||||
gchar *kvp_path;
|
||||
|
||||
g_return_if_fail (book);
|
||||
g_return_if_fail (feature);
|
||||
@ -152,10 +145,7 @@ void gnc_features_set_used (QofBook *book, const gchar *feature)
|
||||
return;
|
||||
}
|
||||
|
||||
frame = qof_book_get_slots (book);
|
||||
kvp_path = g_strconcat ("/features/", feature, NULL);
|
||||
kvp_frame_set_string (frame, kvp_path, description);
|
||||
qof_book_kvp_changed (book);
|
||||
qof_book_set_feature (book, feature, description);
|
||||
|
||||
|
||||
}
|
||||
|
@ -38,12 +38,20 @@
|
||||
#include "gnc-glib-utils.h"
|
||||
#include "gnc-lot.h"
|
||||
#include "gnc-pricedb.h"
|
||||
#include "qofinstance-p.h"
|
||||
|
||||
static QofLogModule log_module = GNC_MOD_ACCOUNT;
|
||||
|
||||
/* The Canonical Account Separator. Pre-Initialized. */
|
||||
static gchar account_separator[8] = ".";
|
||||
static gunichar account_uc_separator = ':';
|
||||
/* Predefined KVP paths */
|
||||
static const char *KEY_ASSOC_INCOME_ACCOUNT = "ofx/associated-income-account";
|
||||
#define AB_KEY "hbci"
|
||||
#define AB_ACCOUNT_ID "account-id"
|
||||
#define AB_ACCOUNT_UID "account-uid"
|
||||
#define AB_BANK_CODE "bank-code"
|
||||
#define AB_TRANS_RETRIEVAL "trans-retrieval"
|
||||
|
||||
enum
|
||||
{
|
||||
@ -53,37 +61,48 @@ enum
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_FULL_NAME,
|
||||
PROP_CODE,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_COLOR,
|
||||
PROP_NOTES,
|
||||
PROP_TYPE,
|
||||
PROP_NAME, /* Table */
|
||||
PROP_FULL_NAME, /* Constructed */
|
||||
PROP_CODE, /* Table */
|
||||
PROP_DESCRIPTION, /* Table */
|
||||
PROP_COLOR, /* KVP */
|
||||
PROP_NOTES, /* KVP */
|
||||
PROP_TYPE, /* Table */
|
||||
|
||||
PROP_COMMODITY,
|
||||
PROP_COMMODITY_SCU,
|
||||
PROP_NON_STD_SCU,
|
||||
PROP_SORT_DIRTY,
|
||||
PROP_BALANCE_DIRTY,
|
||||
PROP_START_BALANCE,
|
||||
PROP_START_CLEARED_BALANCE,
|
||||
PROP_START_RECONCILED_BALANCE,
|
||||
PROP_END_BALANCE,
|
||||
PROP_END_CLEARED_BALANCE,
|
||||
PROP_END_RECONCILED_BALANCE,
|
||||
// PROP_PARENT, /* Table, Not a property */
|
||||
PROP_COMMODITY, /* Table */
|
||||
PROP_COMMODITY_SCU, /* Table */
|
||||
PROP_NON_STD_SCU, /* Table */
|
||||
PROP_END_BALANCE, /* Constructed */
|
||||
PROP_END_CLEARED_BALANCE, /* Constructed */
|
||||
PROP_END_RECONCILED_BALANCE, /* Constructed */
|
||||
|
||||
PROP_POLICY,
|
||||
PROP_MARK,
|
||||
PROP_TAX_RELATED,
|
||||
PROP_TAX_CODE,
|
||||
PROP_TAX_SOURCE,
|
||||
PROP_TAX_COPY_NUMBER,
|
||||
PROP_TAX_RELATED, /* KVP */
|
||||
PROP_TAX_CODE, /* KVP */
|
||||
PROP_TAX_SOURCE, /* KVP */
|
||||
PROP_TAX_COPY_NUMBER, /* KVP */
|
||||
|
||||
PROP_HIDDEN,
|
||||
PROP_PLACEHOLDER,
|
||||
PROP_FILTER,
|
||||
PROP_SORT_ORDER,
|
||||
PROP_HIDDEN, /* Table slot exists, but in KVP in memory & xml */
|
||||
PROP_PLACEHOLDER, /* Table slot exists, but in KVP in memory & xml */
|
||||
PROP_FILTER, /* KVP */
|
||||
PROP_SORT_ORDER, /* KVP */
|
||||
|
||||
PROP_LOT_NEXT_ID, /* KVP */
|
||||
PROP_ONLINE_ACCOUNT, /* KVP */
|
||||
PROP_OFX_INCOME_ACCOUNT, /* KVP */
|
||||
PROP_AB_ACCOUNT_ID, /* KVP */
|
||||
PROP_AB_ACCOUNT_UID, /* KVP */
|
||||
PROP_AB_BANK_CODE, /* KVP */
|
||||
PROP_AB_TRANS_RETRIEVAL, /* KVP */
|
||||
|
||||
PROP_RUNTIME_0,
|
||||
PROP_POLICY, /* Cached Value */
|
||||
PROP_MARK, /* Runtime Value */
|
||||
PROP_SORT_DIRTY, /* Runtime Value */
|
||||
PROP_BALANCE_DIRTY, /* Runtime Value */
|
||||
PROP_START_BALANCE, /* Runtime Value */
|
||||
PROP_START_CLEARED_BALANCE, /* Runtime Value */
|
||||
PROP_START_RECONCILED_BALANCE, /* Runtime Value */
|
||||
};
|
||||
|
||||
#define GET_PRIVATE(o) \
|
||||
@ -282,6 +301,8 @@ gnc_account_get_property (GObject *object,
|
||||
{
|
||||
Account *account;
|
||||
AccountPrivate *priv;
|
||||
const gchar *key;
|
||||
GValue *temp;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(object));
|
||||
|
||||
@ -377,6 +398,36 @@ gnc_account_get_property (GObject *object,
|
||||
case PROP_SORT_ORDER:
|
||||
g_value_set_string(value, xaccAccountGetSortOrder(account));
|
||||
break;
|
||||
case PROP_LOT_NEXT_ID:
|
||||
key = "lot-mgmt/next-id";
|
||||
/* Pre-set the value in case the frame is empty */
|
||||
g_value_set_int64 (value, 0);
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_OFX_INCOME_ACCOUNT:
|
||||
key = KEY_ASSOC_INCOME_ACCOUNT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_ACCOUNT_ID:
|
||||
key = AB_KEY "/" AB_ACCOUNT_ID;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_ACCOUNT_UID:
|
||||
key = AB_KEY "/" AB_ACCOUNT_UID;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_BANK_CODE:
|
||||
key = AB_KEY "/" AB_BANK_CODE;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_TRANS_RETRIEVAL:
|
||||
key = AB_KEY "/" AB_TRANS_RETRIEVAL;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -391,10 +442,13 @@ gnc_account_set_property (GObject *object,
|
||||
{
|
||||
Account *account;
|
||||
gnc_numeric *number;
|
||||
const gchar *key = NULL;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(object));
|
||||
|
||||
account = GNC_ACCOUNT(object);
|
||||
if (prop_id < PROP_RUNTIME_0)
|
||||
g_assert (qof_instance_get_editlevel(account));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@ -476,6 +530,34 @@ gnc_account_set_property (GObject *object,
|
||||
case PROP_SORT_ORDER:
|
||||
xaccAccountSetSortOrder(account, g_value_get_string(value));
|
||||
break;
|
||||
case PROP_LOT_NEXT_ID:
|
||||
key = "lot-mgmt/next-id";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_OFX_INCOME_ACCOUNT:
|
||||
key = KEY_ASSOC_INCOME_ACCOUNT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_ACCOUNT_ID:
|
||||
key = AB_KEY "/" AB_ACCOUNT_ID;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_ACCOUNT_UID:
|
||||
key = AB_KEY "/" AB_ACCOUNT_UID;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_BANK_CODE:
|
||||
key = AB_KEY "/" AB_BANK_CODE;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
case PROP_AB_TRANS_RETRIEVAL:
|
||||
key = AB_KEY "/" AB_TRANS_RETRIEVAL;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -833,6 +915,77 @@ gnc_account_class_init (AccountClass *klass)
|
||||
"the sort order to be recalled.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_LOT_NEXT_ID,
|
||||
g_param_spec_int64 ("lot-next-id",
|
||||
"Lot Next ID",
|
||||
"Tracks the next id to use in gnc_lot_make_default.",
|
||||
(gint64)1,
|
||||
G_MAXINT64,
|
||||
(gint64)1,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_ONLINE_ACCOUNT,
|
||||
g_param_spec_string ("online-id",
|
||||
"Online Account ID",
|
||||
"The online account which corresponds to this "
|
||||
"account for OFX import",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_OFX_INCOME_ACCOUNT,
|
||||
g_param_spec_boxed("ofx-income-account",
|
||||
"Associated income account",
|
||||
"Used by the OFX importer.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_AB_ACCOUNT_ID,
|
||||
g_param_spec_string ("ab-account-id",
|
||||
"AQBanking Account ID",
|
||||
"The AqBanking account which corresponds to this "
|
||||
"account for AQBanking import",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_AB_BANK_CODE,
|
||||
g_param_spec_string ("ab-bank-code",
|
||||
"AQBanking Bank Code",
|
||||
"The online account which corresponds to this "
|
||||
"account for AQBanking import",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_AB_ACCOUNT_UID,
|
||||
g_param_spec_int64 ("ab-account-uid",
|
||||
"AQBanking Account UID",
|
||||
"Tracks the next id to use in gnc_lot_make_default.",
|
||||
(gint64)1,
|
||||
G_MAXINT64,
|
||||
(gint64)1,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_AB_TRANS_RETRIEVAL,
|
||||
g_param_spec_boxed("ab-trans-retrieval",
|
||||
"AQBanking Last Transaction Retrieval",
|
||||
"The time of the last transaction retrieval for this "
|
||||
"account.",
|
||||
GNC_TYPE_TIMESPEC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4279,6 +4432,80 @@ xaccAccountSetLastNum (Account *acc, const char *num)
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
|
||||
static Account *
|
||||
GetOrMakeOrphanAccount (Account *root, gnc_commodity * currency)
|
||||
{
|
||||
char * accname;
|
||||
Account * acc;
|
||||
|
||||
g_return_val_if_fail (root, NULL);
|
||||
|
||||
/* build the account name */
|
||||
if (!currency)
|
||||
{
|
||||
PERR ("No currency specified!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
accname = g_strconcat (_("Orphaned Gains"), "-",
|
||||
gnc_commodity_get_mnemonic (currency), NULL);
|
||||
|
||||
/* See if we've got one of these going already ... */
|
||||
acc = gnc_account_lookup_by_name(root, accname);
|
||||
|
||||
if (acc == NULL)
|
||||
{
|
||||
/* Guess not. We'll have to build one. */
|
||||
acc = xaccMallocAccount (gnc_account_get_book(root));
|
||||
xaccAccountBeginEdit (acc);
|
||||
xaccAccountSetName (acc, accname);
|
||||
xaccAccountSetCommodity (acc, currency);
|
||||
xaccAccountSetType (acc, ACCT_TYPE_INCOME);
|
||||
xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
|
||||
xaccAccountSetNotes (acc,
|
||||
_("Realized Gains or Losses from "
|
||||
"Commodity or Trading Accounts "
|
||||
"that haven't been recorded elsewhere."));
|
||||
|
||||
/* Hang the account off the root. */
|
||||
gnc_account_append_child (root, acc);
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
|
||||
g_free (accname);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
Account *
|
||||
xaccAccountGainsAccount (Account *acc, gnc_commodity *curr)
|
||||
{
|
||||
KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (acc));
|
||||
const gchar *curr_name = gnc_commodity_get_unique_name (curr);
|
||||
GncGUID *guid;
|
||||
Account *gains_account;
|
||||
|
||||
frame = kvp_frame_get_frame_slash (frame, "/lot-mgmt/gains-act/");
|
||||
guid = kvp_frame_get_guid (frame, curr_name);
|
||||
if (guid == NULL) /* No gains account for this currency */
|
||||
{
|
||||
gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc),
|
||||
curr);
|
||||
guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account));
|
||||
xaccAccountBeginEdit (acc);
|
||||
{
|
||||
kvp_frame_set_guid (frame, curr_name, guid);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (acc));
|
||||
}
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
else
|
||||
gains_account = xaccAccountLookup (guid,
|
||||
qof_instance_get_book(acc));
|
||||
|
||||
return gains_account;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -4718,6 +4945,508 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc,
|
||||
return xaccAccountStagedTransactionTraversal(acc, 42, proc, data);
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
/* The following functions are used by
|
||||
* src/import-export/import-backend.c to manipulate the contra-account
|
||||
* matching data. See src/import-export/import-backend.c for explanations.
|
||||
*/
|
||||
/* FIXME: These data are stored per-account in KVP and the functions
|
||||
* work directly on KVP data structures. This prevents moving KVP to a
|
||||
* backend-only abstraction.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct _GncImportMatchMap
|
||||
{
|
||||
kvp_frame * frame;
|
||||
Account * acc;
|
||||
QofBook * book;
|
||||
} GncImportMatchMap;
|
||||
|
||||
#define IMAP_FRAME "import-map"
|
||||
#define IMAP_FRAME_BAYES "import-map-bayes"
|
||||
GncImportMatchMap * gnc_account_create_imap (Account *acc);
|
||||
Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category,
|
||||
const char *key);
|
||||
void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
|
||||
const char *key, Account *acc);
|
||||
Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
|
||||
void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
|
||||
Account *acc);
|
||||
|
||||
/* Obtain an ImportMatchMap object from an Account or a Book */
|
||||
GncImportMatchMap *
|
||||
gnc_account_create_imap (Account *acc)
|
||||
{
|
||||
GncImportMatchMap *imap;
|
||||
kvp_frame *frame;
|
||||
|
||||
if (!acc) return NULL;
|
||||
frame = qof_instance_get_slots (QOF_INSTANCE (acc));
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
|
||||
imap = g_new0(GncImportMatchMap, 1);
|
||||
imap->frame = frame;
|
||||
|
||||
/* Cache the book for easy lookups; store the account/book for
|
||||
* marking dirtiness
|
||||
*/
|
||||
imap->acc = acc;
|
||||
imap->book = gnc_account_get_book (acc);
|
||||
|
||||
return imap;
|
||||
}
|
||||
|
||||
/* Look up an Account in the map */
|
||||
Account*
|
||||
gnc_imap_find_account (GncImportMatchMap *imap,
|
||||
const char *category,
|
||||
const char *key)
|
||||
{
|
||||
kvp_value *value;
|
||||
GncGUID * guid;
|
||||
|
||||
if (!imap || !key) return NULL;
|
||||
if (!category)
|
||||
{
|
||||
category = key;
|
||||
key = NULL;
|
||||
}
|
||||
|
||||
value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME,
|
||||
category, key, NULL);
|
||||
if (!value) return NULL;
|
||||
|
||||
guid = kvp_value_get_guid (value);
|
||||
return xaccAccountLookup (guid, imap->book);
|
||||
}
|
||||
|
||||
/* Store an Account in the map */
|
||||
void
|
||||
gnc_imap_add_account (GncImportMatchMap *imap,
|
||||
const char *category,
|
||||
const char *key,
|
||||
Account *acc)
|
||||
{
|
||||
kvp_value *value;
|
||||
|
||||
if (!imap || !key || !acc || (strlen (key) == 0)) return;
|
||||
if (!category)
|
||||
{
|
||||
category = key;
|
||||
key = NULL;
|
||||
}
|
||||
g_return_if_fail (acc != NULL);
|
||||
|
||||
value = kvp_value_new_guid (xaccAccountGetGUID (acc));
|
||||
g_return_if_fail (value != NULL);
|
||||
xaccAccountBeginEdit (imap->acc);
|
||||
kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
|
||||
xaccAccountCommitEdit (imap->acc);
|
||||
kvp_value_delete (value);
|
||||
|
||||
/* XXX Mark the account (or book) as dirty! */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Below here is the bayes transaction to account matching system
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
struct account_token_count
|
||||
{
|
||||
char* account_name;
|
||||
gint64 token_count; /**< occurances of a given token for this account_name */
|
||||
};
|
||||
|
||||
/** total_count and the token_count for a given account let us calculate the
|
||||
* probability of a given account with any single token
|
||||
*/
|
||||
struct token_accounts_info
|
||||
{
|
||||
GList *accounts; /**< array of struct account_token_count */
|
||||
gint64 total_count;
|
||||
};
|
||||
|
||||
/** gpointer is a pointer to a struct token_accounts_info
|
||||
* \note Can always assume that keys are unique, reduces code in this function
|
||||
*/
|
||||
static void
|
||||
buildTokenInfo(const char *key, kvp_value *value, gpointer data)
|
||||
{
|
||||
struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;
|
||||
struct account_token_count* this_account;
|
||||
|
||||
// PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key,
|
||||
// (long)kvp_value_get_gint64(value));
|
||||
|
||||
/* add the count to the total_count */
|
||||
tokenInfo->total_count += kvp_value_get_gint64(value);
|
||||
|
||||
/* allocate a new structure for this account and it's token count */
|
||||
this_account = (struct account_token_count*)
|
||||
g_new0(struct account_token_count, 1);
|
||||
|
||||
/* fill in the account name and number of tokens found for this account name */
|
||||
this_account->account_name = (char*)key;
|
||||
this_account->token_count = kvp_value_get_gint64(value);
|
||||
|
||||
/* append onto the glist a pointer to the new account_token_count structure */
|
||||
tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);
|
||||
}
|
||||
|
||||
/** intermediate values used to calculate the bayes probability of a given account
|
||||
where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),
|
||||
product_difference is (1-a) * (1-b)
|
||||
*/
|
||||
struct account_probability
|
||||
{
|
||||
double product; /* product of probabilities */
|
||||
double product_difference; /* product of (1-probabilities) */
|
||||
};
|
||||
|
||||
/** convert a hash table of account names and (struct account_probability*)
|
||||
into a hash table of 100000x the percentage match value, ie. 10% would be
|
||||
0.10 * 100000 = 10000
|
||||
*/
|
||||
#define PROBABILITY_FACTOR 100000
|
||||
static void
|
||||
buildProbabilities(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
GHashTable *final_probabilities = (GHashTable*)data;
|
||||
struct account_probability *account_p = (struct account_probability*)value;
|
||||
|
||||
/* P(AB) = A*B / [A*B + (1-A)*(1-B)]
|
||||
* NOTE: so we only keep track of a running product(A*B*C...)
|
||||
* and product difference ((1-A)(1-B)...)
|
||||
*/
|
||||
gint32 probability =
|
||||
(account_p->product /
|
||||
(account_p->product + account_p->product_difference))
|
||||
* PROBABILITY_FACTOR;
|
||||
|
||||
PINFO("P('%s') = '%d'\n", (char*)key, probability);
|
||||
|
||||
g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
|
||||
}
|
||||
|
||||
/** Frees an array of the same time that buildProperties built */
|
||||
static void
|
||||
freeProbabilities(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
/* free up the struct account_probability that was allocated
|
||||
* in gnc_account_find_account_bayes()
|
||||
*/
|
||||
g_free(value);
|
||||
}
|
||||
|
||||
/** holds an account name and its corresponding integer probability
|
||||
the integer probability is some factor of 10
|
||||
*/
|
||||
struct account_info
|
||||
{
|
||||
char* account_name;
|
||||
gint32 probability;
|
||||
};
|
||||
|
||||
/** Find the highest probability and the corresponding account name
|
||||
store in data, a (struct account_info*)
|
||||
NOTE: this is a g_hash_table_foreach() function for a hash table of entries
|
||||
key is a pointer to the account name, value is a gint32, 100000x
|
||||
the probability for this account
|
||||
*/
|
||||
static void
|
||||
highestProbability(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
struct account_info *account_i = (struct account_info*)data;
|
||||
|
||||
/* if the current probability is greater than the stored, store the current */
|
||||
if (GPOINTER_TO_INT(value) > account_i->probability)
|
||||
{
|
||||
/* Save the new highest probability and the assoaciated account name */
|
||||
account_i->probability = GPOINTER_TO_INT(value);
|
||||
account_i->account_name = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define threshold (.90 * PROBABILITY_FACTOR) /* 90% */
|
||||
|
||||
/** Look up an Account in the map */
|
||||
Account*
|
||||
gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens)
|
||||
{
|
||||
struct token_accounts_info tokenInfo; /**< holds the accounts and total
|
||||
* token count for a single token */
|
||||
GList *current_token; /**< pointer to the current
|
||||
* token from the input GList
|
||||
* tokens */
|
||||
GList *current_account_token; /**< pointer to the struct
|
||||
* account_token_count */
|
||||
struct account_token_count *account_c; /**< an account name and the number
|
||||
* of times a token has appeared
|
||||
* for the account */
|
||||
struct account_probability *account_p; /**< intermediate storage of values
|
||||
* to compute the bayes probability
|
||||
* of an account */
|
||||
GHashTable *running_probabilities = g_hash_table_new(g_str_hash,
|
||||
g_str_equal);
|
||||
GHashTable *final_probabilities = g_hash_table_new(g_str_hash,
|
||||
g_str_equal);
|
||||
struct account_info account_i;
|
||||
kvp_value* value;
|
||||
kvp_frame* token_frame;
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
/* check to see if the imap is NULL */
|
||||
if (!imap)
|
||||
{
|
||||
PINFO("imap is null, returning null");
|
||||
LEAVE(" ");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the probability for each account that contains any of the tokens
|
||||
* in the input tokens list
|
||||
*/
|
||||
for (current_token = tokens; current_token;
|
||||
current_token = current_token->next)
|
||||
{
|
||||
/* zero out the token_accounts_info structure */
|
||||
memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
|
||||
|
||||
PINFO("token: '%s'", (char*)current_token->data);
|
||||
|
||||
/* find the slot for the given token off of the source account
|
||||
* for these tokens, search off of the IMAP_FRAME_BAYES path so
|
||||
* we aren't looking from the parent of the entire kvp tree
|
||||
*/
|
||||
value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data, NULL);
|
||||
|
||||
/* if value is null we should skip over this token */
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
/* convert the slot(value) into a the frame that contains the
|
||||
* list of accounts
|
||||
*/
|
||||
token_frame = kvp_value_get_frame(value);
|
||||
|
||||
/* token_frame should NEVER be null */
|
||||
if (!token_frame)
|
||||
{
|
||||
PERR("token '%s' has no accounts", (char*)current_token->data);
|
||||
continue; /* skip over this token */
|
||||
}
|
||||
|
||||
/* process the accounts for this token, adding the account if it
|
||||
* doesn't already exist or adding to the existing accounts token
|
||||
* count if it does
|
||||
*/
|
||||
kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
|
||||
|
||||
/* for each account we have just found, see if the account
|
||||
* already exists in the list of account probabilities, if not
|
||||
* add it
|
||||
*/
|
||||
for (current_account_token = tokenInfo.accounts; current_account_token;
|
||||
current_account_token = current_account_token->next)
|
||||
{
|
||||
/* get the account name and corresponding token count */
|
||||
account_c = (struct account_token_count*)current_account_token->data;
|
||||
|
||||
PINFO("account_c->account_name('%s'), "
|
||||
"account_c->token_count('%ld')/total_count('%ld')",
|
||||
account_c->account_name, (long)account_c->token_count,
|
||||
(long)tokenInfo.total_count);
|
||||
|
||||
account_p = g_hash_table_lookup(running_probabilities,
|
||||
account_c->account_name);
|
||||
|
||||
/* if the account exists in the list then continue
|
||||
* the running probablities
|
||||
*/
|
||||
if (account_p)
|
||||
{
|
||||
account_p->product = (((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count)
|
||||
* account_p->product);
|
||||
account_p->product_difference =
|
||||
((double)1 - ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count))
|
||||
* account_p->product_difference;
|
||||
PINFO("product == %f, product_difference == %f",
|
||||
account_p->product, account_p->product_difference);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add a new entry */
|
||||
PINFO("adding a new entry for this account");
|
||||
account_p = (struct account_probability*)
|
||||
g_new0(struct account_probability, 1);
|
||||
|
||||
/* set the product and product difference values */
|
||||
account_p->product = ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count);
|
||||
account_p->product_difference =
|
||||
(double)1 - ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count);
|
||||
|
||||
PINFO("product == %f, product_difference == %f",
|
||||
account_p->product, account_p->product_difference);
|
||||
|
||||
/* add the account name and (struct account_probability*)
|
||||
* to the hash table */
|
||||
g_hash_table_insert(running_probabilities,
|
||||
account_c->account_name, account_p);
|
||||
}
|
||||
} /* for all accounts in tokenInfo */
|
||||
|
||||
/* free the data in tokenInfo */
|
||||
for (current_account_token = tokenInfo.accounts; current_account_token;
|
||||
current_account_token = current_account_token->next)
|
||||
{
|
||||
/* free up each struct account_token_count we allocated */
|
||||
g_free((struct account_token_count*)current_account_token->data);
|
||||
}
|
||||
|
||||
g_list_free(tokenInfo.accounts); /* free the accounts GList */
|
||||
}
|
||||
|
||||
/* build a hash table of account names and their final probabilities
|
||||
* from each entry in the running_probabilties hash table
|
||||
*/
|
||||
g_hash_table_foreach(running_probabilities, buildProbabilities,
|
||||
final_probabilities);
|
||||
|
||||
/* find the highest probabilty and the corresponding account */
|
||||
memset(&account_i, 0, sizeof(struct account_info));
|
||||
g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
|
||||
|
||||
/* free each element of the running_probabilities hash */
|
||||
g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
|
||||
|
||||
/* free the hash tables */
|
||||
g_hash_table_destroy(running_probabilities);
|
||||
g_hash_table_destroy(final_probabilities);
|
||||
|
||||
PINFO("highest P('%s') = '%d'",
|
||||
account_i.account_name ? account_i.account_name : "(null)",
|
||||
account_i.probability);
|
||||
|
||||
/* has this probability met our threshold? */
|
||||
if (account_i.probability >= threshold)
|
||||
{
|
||||
PINFO("found match");
|
||||
LEAVE(" ");
|
||||
return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
|
||||
account_i.account_name);
|
||||
}
|
||||
|
||||
PINFO("no match");
|
||||
LEAVE(" ");
|
||||
|
||||
return NULL; /* we didn't meet our threshold, return NULL for an account */
|
||||
}
|
||||
|
||||
|
||||
/** Updates the imap for a given account using a list of tokens */
|
||||
void
|
||||
gnc_imap_add_account_bayes(GncImportMatchMap *imap,
|
||||
GList *tokens,
|
||||
Account *acc)
|
||||
{
|
||||
GList *current_token;
|
||||
kvp_value *value;
|
||||
gint64 token_count;
|
||||
char* account_fullname;
|
||||
kvp_value *new_value; /* the value that will be added back into
|
||||
* the kvp tree */
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
/* if imap is null return */
|
||||
if (!imap)
|
||||
{
|
||||
LEAVE(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (acc != NULL);
|
||||
account_fullname = gnc_account_get_full_name(acc);
|
||||
xaccAccountBeginEdit (imap->acc);
|
||||
|
||||
PINFO("account name: '%s'\n", account_fullname);
|
||||
|
||||
/* process each token in the list */
|
||||
for (current_token = g_list_first(tokens); current_token;
|
||||
current_token = current_token->next)
|
||||
{
|
||||
/* Jump to next iteration if the pointer is not valid or if the
|
||||
string is empty. In HBCI import we almost always get an empty
|
||||
string, which doesn't work in the kvp loopkup later. So we
|
||||
skip this case here. */
|
||||
if (!current_token->data || (*((char*)current_token->data) == '\0'))
|
||||
continue;
|
||||
|
||||
/* start off with no tokens for this account */
|
||||
token_count = 0;
|
||||
|
||||
PINFO("adding token '%s'\n", (char*)current_token->data);
|
||||
|
||||
/* is this token/account_name already in the kvp tree? */
|
||||
value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data,
|
||||
account_fullname,
|
||||
NULL);
|
||||
|
||||
/* if the token/account is already in the tree, read the current
|
||||
* value from the tree and use this for the basis of the value we
|
||||
* are putting back
|
||||
*/
|
||||
if (value)
|
||||
{
|
||||
PINFO("found existing value of '%ld'\n",
|
||||
(long)kvp_value_get_gint64(value));
|
||||
|
||||
/* convert this value back into an integer */
|
||||
token_count += kvp_value_get_gint64(value);
|
||||
}
|
||||
|
||||
/* increment the token count */
|
||||
token_count++;
|
||||
|
||||
/* create a new value */
|
||||
new_value = kvp_value_new_gint64(token_count);
|
||||
|
||||
/* insert the value into the kvp tree at
|
||||
* /imap->frame/IMAP_FRAME/token_string/account_name_string
|
||||
*/
|
||||
kvp_frame_set_slot_path(imap->frame, new_value,
|
||||
IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data,
|
||||
account_fullname,
|
||||
NULL);
|
||||
/* kvp_frame_set_slot_path() copied the value so we
|
||||
* need to delete this one ;-) */
|
||||
kvp_value_delete(new_value);
|
||||
}
|
||||
|
||||
/* free up the account fullname string */
|
||||
qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
|
||||
xaccAccountCommitEdit (imap->acc);
|
||||
g_free(account_fullname);
|
||||
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
/* QofObject function implementation and registration */
|
||||
|
||||
|
@ -417,6 +417,17 @@ void xaccAccountSortSplits (Account *acc, gboolean force);
|
||||
*/
|
||||
gchar * gnc_account_get_full_name (const Account *account);
|
||||
|
||||
/** Retrieve the gains account used by this account for the indicated
|
||||
* currency, creating and recording a new one if necessary.
|
||||
*
|
||||
* FIXME: There is at present no interface to designate an existing
|
||||
* account, and the new account name is hard coded to
|
||||
* "Orphaned Gains -- CUR"
|
||||
*
|
||||
* FIXME: There is no provision for creating separate accounts for
|
||||
* anything other than currency, e.g. holding period of a security.
|
||||
*/
|
||||
Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr);
|
||||
/** Set a string that identifies the Finance::Quote backend that
|
||||
* should be used to retrieve online prices. See price-quotes.scm
|
||||
* for more information
|
||||
@ -860,8 +871,6 @@ gboolean xaccAccountGetReconcileChildrenStatus(const Account *account);
|
||||
*/
|
||||
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor);
|
||||
|
||||
#define xaccAccountGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Lookup Accounts and Subaccounts by name or code
|
||||
|
@ -150,6 +150,9 @@ sxtg_is_dirty(const QofCollection *col)
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
|
||||
extern void qof_instance_mark_clean (QofInstance *);
|
||||
|
||||
static void
|
||||
sxtg_mark_clean(QofCollection *col)
|
||||
{
|
||||
@ -372,9 +375,9 @@ gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
|
||||
for (; splits != NULL; splits = splits->next)
|
||||
{
|
||||
Split *s = (Split*)splits->data;
|
||||
KvpFrame *frame = kvp_frame_get_frame(xaccSplitGetSlots(s), GNC_SX_ID);
|
||||
GncGUID *sx_split_acct_guid = kvp_frame_get_guid(frame, GNC_SX_ACCOUNT);
|
||||
if (guid_equal(acct_guid, sx_split_acct_guid))
|
||||
GncGUID *guid = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
|
||||
if (guid_equal(acct_guid, guid))
|
||||
{
|
||||
rtn = g_list_append(rtn, sx);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "Transaction.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "engine-helpers.h"
|
||||
#include "qofinstance-p.h"
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "gnc.engine.sx"
|
||||
@ -43,19 +44,19 @@
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_ENABLED,
|
||||
PROP_NUM_OCCURANCE,
|
||||
PROP_REM_OCCURANCE,
|
||||
PROP_AUTO_CREATE,
|
||||
PROP_AUTO_CREATE_NOTIFY,
|
||||
PROP_ADVANCE_CREATION_DAYS,
|
||||
PROP_ADVANCE_REMINDER_DAYS,
|
||||
PROP_START_DATE,
|
||||
PROP_END_DATE,
|
||||
PROP_LAST_OCCURANCE_DATE,
|
||||
PROP_INSTANCE_COUNT,
|
||||
PROP_TEMPLATE_ACCOUNT
|
||||
PROP_NAME, /* Table */
|
||||
PROP_ENABLED, /* Table */
|
||||
PROP_START_DATE, /* Table */
|
||||
PROP_END_DATE, /* Table */
|
||||
PROP_LAST_OCCURANCE_DATE, /* Table */
|
||||
PROP_NUM_OCCURANCE, /* Table */
|
||||
PROP_REM_OCCURANCE, /* Table */
|
||||
PROP_AUTO_CREATE, /* Table */
|
||||
PROP_AUTO_CREATE_NOTIFY, /* Table */
|
||||
PROP_ADVANCE_CREATION_DAYS, /* Table */
|
||||
PROP_ADVANCE_REMINDER_DAYS, /* Table */
|
||||
PROP_INSTANCE_COUNT, /* Table */
|
||||
PROP_TEMPLATE_ACCOUNT /* Table */
|
||||
};
|
||||
|
||||
/* GObject initialization */
|
||||
@ -173,6 +174,8 @@ gnc_schedxaction_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_SCHEDXACTION(object));
|
||||
|
||||
sx = GNC_SCHEDXACTION(object);
|
||||
g_assert (qof_instance_get_editlevel(sx));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
@ -1042,8 +1045,8 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
|
||||
Transaction *parent_trans, QofBook *book)
|
||||
{
|
||||
Split *split;
|
||||
KvpFrame *split_frame;
|
||||
KvpValue *tmp_value;
|
||||
const gchar *credit_formula;
|
||||
const gchar *debit_formula;
|
||||
const GncGUID *acc_guid;
|
||||
|
||||
split = xaccMallocSplit(book);
|
||||
@ -1059,40 +1062,14 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
|
||||
xaccAccountInsertSplit(parent_acct,
|
||||
split);
|
||||
|
||||
split_frame = xaccSplitGetSlots(split);
|
||||
|
||||
tmp_value
|
||||
= kvp_value_new_string(gnc_ttsplitinfo_get_credit_formula(s_info));
|
||||
|
||||
kvp_frame_set_slot_path(split_frame,
|
||||
tmp_value,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL);
|
||||
kvp_value_delete(tmp_value);
|
||||
|
||||
tmp_value
|
||||
= kvp_value_new_string(gnc_ttsplitinfo_get_debit_formula(s_info));
|
||||
|
||||
kvp_frame_set_slot_path(split_frame,
|
||||
tmp_value,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL);
|
||||
|
||||
kvp_value_delete(tmp_value);
|
||||
|
||||
credit_formula = gnc_ttsplitinfo_get_credit_formula(s_info);
|
||||
debit_formula = gnc_ttsplitinfo_get_debit_formula(s_info);
|
||||
acc_guid = qof_entity_get_guid(QOF_INSTANCE(gnc_ttsplitinfo_get_account(s_info)));
|
||||
|
||||
tmp_value = kvp_value_new_guid(acc_guid);
|
||||
|
||||
kvp_frame_set_slot_path(split_frame,
|
||||
tmp_value,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_ACCOUNT,
|
||||
NULL);
|
||||
|
||||
kvp_value_delete(tmp_value);
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"sx-credit-formula", credit_formula,
|
||||
"sx-debit-formula", debit_formula,
|
||||
"sx-account", acc_guid,
|
||||
NULL);
|
||||
|
||||
return split;
|
||||
}
|
||||
|
@ -304,15 +304,7 @@ void gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData );
|
||||
GList *gnc_sx_get_defer_instances( SchedXaction *sx );
|
||||
|
||||
/* #defines for KvpFrame strings and QOF */
|
||||
#define GNC_SX_ID "sched-xaction"
|
||||
#define GNC_SX_ACCOUNT "account"
|
||||
#define GNC_SX_CREDIT_FORMULA "credit-formula"
|
||||
#define GNC_SX_DEBIT_FORMULA "debit-formula"
|
||||
#define GNC_SX_CREDIT_NUMERIC "credit-numeric"
|
||||
#define GNC_SX_DEBIT_NUMERIC "debit-numeric"
|
||||
#define GNC_SX_SHARES "shares"
|
||||
#define GNC_SX_AMOUNT "amnt"
|
||||
#define GNC_SX_FROM_SCHED_XACTION "from-sched-xaction"
|
||||
#define GNC_SX_FREQ_SPEC "scheduled-frequency"
|
||||
#define GNC_SX_NAME "sched-xname"
|
||||
#define GNC_SX_START_DATE "sched-start-date"
|
||||
|
@ -1133,6 +1133,9 @@ xaccAccountScrubCommodity (Account *account)
|
||||
|
||||
/* ================================================================ */
|
||||
|
||||
/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
|
||||
extern void qof_instance_set_dirty (QofInstance*);
|
||||
|
||||
static void
|
||||
xaccAccountDeleteOldData (Account *account)
|
||||
{
|
||||
|
@ -157,7 +157,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
||||
|
||||
if (!lot) return;
|
||||
|
||||
ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
||||
ENTER ("lot=%s", gnc_lot_get_title(lot));
|
||||
|
||||
for (snode = gnc_lot_get_split_list(lot); snode; snode = snode->next)
|
||||
{
|
||||
@ -216,7 +216,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
||||
}
|
||||
}
|
||||
|
||||
LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
||||
LEAVE ("lot=%s", gnc_lot_get_title(lot));
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-lot.h"
|
||||
#include "gnc-event.h"
|
||||
#include "qofinstance-p.h"
|
||||
|
||||
const char *void_former_amt_str = "void-former-amount";
|
||||
const char *void_former_val_str = "void-former-value";
|
||||
@ -60,17 +61,40 @@ const char *void_former_val_str = "void-former-value";
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_ENGINE;
|
||||
|
||||
/* KVP key values used for SX info stored Split's slots. */
|
||||
#define GNC_SX_ID "sched-xaction"
|
||||
#define GNC_SX_ACCOUNT "account"
|
||||
#define GNC_SX_CREDIT_FORMULA "credit-formula"
|
||||
#define GNC_SX_DEBIT_FORMULA "debit-formula"
|
||||
#define GNC_SX_CREDIT_NUMERIC "credit-numeric"
|
||||
#define GNC_SX_DEBIT_NUMERIC "debit-numeric"
|
||||
#define GNC_SX_SHARES "shares"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ACTION,
|
||||
PROP_MEMO,
|
||||
PROP_VALUE,
|
||||
PROP_AMOUNT,
|
||||
PROP_RECONCILE_DATE,
|
||||
PROP_TX,
|
||||
PROP_ACCOUNT,
|
||||
PROP_LOT
|
||||
PROP_TX, /* Table */
|
||||
PROP_ACCOUNT, /* Table */
|
||||
PROP_MEMO, /* Table */
|
||||
PROP_ACTION, /* Table */
|
||||
// PROP_RECONCILE_STATE, /* Table */
|
||||
PROP_RECONCILE_DATE, /* Table */
|
||||
PROP_VALUE, /* Table, in 2 fields */
|
||||
PROP_SX_ACCOUNT, /* KVP */
|
||||
PROP_SX_CREDIT_FORMULA, /* KVP */
|
||||
PROP_SX_CREDIT_NUMERIC, /* KVP */
|
||||
PROP_SX_DEBIT_FORMULA, /* KVP */
|
||||
PROP_SX_DEBIT_NUMERIC, /* KVP */
|
||||
PROP_SX_SHARES, /* KVP */
|
||||
PROP_LOT, /* KVP */
|
||||
PROP_ONLINE_ACCOUNT, /* KVP */
|
||||
PROP_LOT_SPLIT, /* KVP */
|
||||
PROP_PEER_GUID, /* KVP */
|
||||
PROP_GAINS_SPLIT, /* KVP */
|
||||
PROP_GAINS_SOURCE, /* KVP */
|
||||
PROP_RUNTIME_0,
|
||||
PROP_AMOUNT, /* Runtime */
|
||||
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -126,6 +150,7 @@ gnc_split_get_property(GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
Split *split;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_SPLIT(object));
|
||||
|
||||
@ -156,6 +181,50 @@ gnc_split_get_property(GObject *object,
|
||||
case PROP_LOT:
|
||||
g_value_take_object(value, split->lot);
|
||||
break;
|
||||
case PROP_SX_CREDIT_FORMULA:
|
||||
key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_CREDIT_NUMERIC:
|
||||
key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_DEBIT_FORMULA:
|
||||
key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_DEBIT_NUMERIC:
|
||||
key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_ACCOUNT:
|
||||
key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_SHARES:
|
||||
key = GNC_SX_ID "/" GNC_SX_SHARES;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_LOT_SPLIT:
|
||||
key = "lot-split";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_PEER_GUID:
|
||||
key = "peer_guid";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_GAINS_SPLIT:
|
||||
key = "gains-split";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_GAINS_SOURCE:
|
||||
key = "gains-source";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -170,10 +239,14 @@ gnc_split_set_property(GObject *object,
|
||||
{
|
||||
Split *split;
|
||||
gnc_numeric* number;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_SPLIT(object));
|
||||
|
||||
split = GNC_SPLIT(object);
|
||||
if (prop_id < PROP_RUNTIME_0 && split->parent != NULL)
|
||||
g_assert (qof_instance_get_editlevel(split->parent));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTION:
|
||||
@ -202,6 +275,50 @@ gnc_split_set_property(GObject *object,
|
||||
case PROP_LOT:
|
||||
xaccSplitSetLot(split, g_value_get_object(value));
|
||||
break;
|
||||
case PROP_SX_CREDIT_FORMULA:
|
||||
key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_CREDIT_NUMERIC:
|
||||
key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_DEBIT_FORMULA:
|
||||
key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_DEBIT_NUMERIC:
|
||||
key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_ACCOUNT:
|
||||
key = GNC_SX_ID "/" GNC_SX_ACCOUNT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_SX_SHARES:
|
||||
key = GNC_SX_ID "/" GNC_SX_SHARES;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_LOT_SPLIT:
|
||||
key = "lot-split";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_PEER_GUID:
|
||||
key = "peer_guid";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_GAINS_SPLIT:
|
||||
key = "gains-split";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
case PROP_GAINS_SOURCE:
|
||||
key = "gains-source";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (split), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -299,6 +416,122 @@ gnc_split_class_init(SplitClass* klass)
|
||||
"The lot that this split belongs to.",
|
||||
GNC_TYPE_LOT,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_DEBIT_FORMULA,
|
||||
g_param_spec_string("sx-debit-formula",
|
||||
"Schedule Transaction Debit Formula",
|
||||
"The formula used to calculate the actual debit "
|
||||
"amount when a real split is generated from this "
|
||||
"SX split.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_DEBIT_NUMERIC,
|
||||
g_param_spec_boxed("sx-debit-numeric",
|
||||
"Scheduled Transaction Debit Numeric",
|
||||
"Numeric value to plug into the Debit Formula when a "
|
||||
"real split is generated from this SX split.",
|
||||
GNC_TYPE_NUMERIC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_CREDIT_FORMULA,
|
||||
g_param_spec_string("sx-credit-formula",
|
||||
"Schedule Transaction Credit Formula",
|
||||
"The formula used to calculate the actual credit "
|
||||
"amount when a real split is generated from this "
|
||||
"SX split.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_CREDIT_NUMERIC,
|
||||
g_param_spec_boxed("sx-credit-numeric",
|
||||
"Scheduled Transaction Credit Numeric",
|
||||
"Numeric value to plug into the Credit Formula when a "
|
||||
"real split is generated from this SX split.",
|
||||
GNC_TYPE_NUMERIC,
|
||||
G_PARAM_READWRITE));
|
||||
/* FIXME: PROP_SX_SHARES should be stored as a gnc_numeric, but the function
|
||||
* which uses it, gnc_template_register_save_shares_cell, stores a
|
||||
* phony string. This is maintained until backwards compatibility can
|
||||
* be established.
|
||||
*/
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_SHARES,
|
||||
g_param_spec_string("sx-shares",
|
||||
"Scheduled Transaction Shares",
|
||||
"Numeric value of shares to insert in a new split when "
|
||||
"it's generated from this SX split.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_SX_ACCOUNT,
|
||||
g_param_spec_boxed("sx-account",
|
||||
"Scheduled Transaction Account",
|
||||
"The target account for a scheduled transaction split.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_ONLINE_ACCOUNT,
|
||||
g_param_spec_string ("online-id",
|
||||
"Online Account ID",
|
||||
"The online account which corresponds to this "
|
||||
"account for OFX/HCBI import",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_LOT_SPLIT,
|
||||
g_param_spec_int64 ("lot-split",
|
||||
"Lot Split",
|
||||
"Indicates that the split was divided into two "
|
||||
"splits in order to balance a lot capital gains "
|
||||
"transaction. Contains a timestamp of the action.",
|
||||
G_MININT64, G_MAXINT64, 0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PEER_GUID,
|
||||
g_param_spec_boxed ("peer-guid",
|
||||
"Peer GUID",
|
||||
"The other split in the division.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_GAINS_SPLIT,
|
||||
g_param_spec_boxed ("gains-split",
|
||||
"Gains Split",
|
||||
"The capital gains split associated with this "
|
||||
"split when this split represents the proceeds "
|
||||
"from the sale of a commodity inside a Lot.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_GAINS_SOURCE,
|
||||
g_param_spec_boxed ("gains-source",
|
||||
"Gains Source",
|
||||
"The source split for which this split this is "
|
||||
"the gains split. ",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -406,7 +639,7 @@ xaccDupeSplit (const Split *s)
|
||||
}
|
||||
|
||||
Split *
|
||||
xaccSplitClone (const Split *s)
|
||||
xaccSplitCloneNoKvp (const Split *s)
|
||||
{
|
||||
Split *split = g_object_new (GNC_TYPE_SPLIT, NULL);
|
||||
|
||||
@ -424,10 +657,8 @@ xaccSplitClone (const Split *s)
|
||||
split->gains = GAINS_STATUS_UNKNOWN;
|
||||
split->gains_split = NULL;
|
||||
|
||||
qof_instance_init_data(&split->inst, GNC_ID_SPLIT, qof_instance_get_book(s));
|
||||
kvp_frame_delete(split->inst.kvp_data);
|
||||
split->inst.kvp_data = kvp_frame_copy(s->inst.kvp_data);
|
||||
|
||||
qof_instance_init_data(&split->inst, GNC_ID_SPLIT,
|
||||
qof_instance_get_book(s));
|
||||
xaccAccountInsertSplit(s->acc, split);
|
||||
if (s->lot)
|
||||
{
|
||||
@ -437,6 +668,11 @@ xaccSplitClone (const Split *s)
|
||||
return split;
|
||||
}
|
||||
|
||||
void
|
||||
xaccSplitCopyKvp (const Split *from, Split *to)
|
||||
{
|
||||
to->inst.kvp_data = kvp_frame_copy(from->inst.kvp_data);
|
||||
}
|
||||
|
||||
/*################## Added for Reg2 #################*/
|
||||
|
||||
@ -954,26 +1190,6 @@ get_commodity_denom(const Split * s)
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* xaccSplitGetSlots
|
||||
********************************************************************/
|
||||
|
||||
KvpFrame *
|
||||
xaccSplitGetSlots (const Split * s)
|
||||
{
|
||||
return qof_instance_get_slots(QOF_INSTANCE(s));
|
||||
}
|
||||
/* Used for testing only: _get_random_split in test-engine-stuff.c */
|
||||
void
|
||||
xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)
|
||||
{
|
||||
if (!s || !frm) return;
|
||||
xaccTransBeginEdit(s->parent);
|
||||
qof_instance_set_slots(QOF_INSTANCE(s), frm);
|
||||
xaccTransCommitEdit(s->parent);
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -2115,7 +2331,7 @@ gboolean xaccSplitRegister (void)
|
||||
{ SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL },
|
||||
{ SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL },
|
||||
{ SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL },
|
||||
{ SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)xaccSplitGetSlots, NULL },
|
||||
{ SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
|
||||
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL },
|
||||
{
|
||||
QOF_PARAM_GUID, QOF_TYPE_GUID,
|
||||
|
@ -144,20 +144,6 @@ GNCLot * xaccSplitGetLot (const Split *split);
|
||||
/** Assigns the split to a specific Lot */
|
||||
void xaccSplitSetLot(Split* split, GNCLot* lot);
|
||||
|
||||
|
||||
/** Returns the KvpFrame slots of this split for direct editing.
|
||||
*
|
||||
* Split slots are used to store arbitrary strings, numbers, and
|
||||
* structures which aren't members of the transaction struct. See
|
||||
* kvp_doc.txt for reserved slot names.
|
||||
*/
|
||||
KvpFrame *xaccSplitGetSlots(const Split *split);
|
||||
|
||||
/** Set the KvpFrame slots of this split to the given frm by directly
|
||||
* using the frm pointer (i.e. non-copying). */
|
||||
void xaccSplitSetSlots_nc(Split *s, KvpFrame *frm);
|
||||
|
||||
|
||||
/** The memo is an arbitrary string associated with a split. It is
|
||||
* intended to hold a short (zero to forty character) string that is
|
||||
* displayed by the GUI along with this split. Users typically type
|
||||
|
@ -146,7 +146,8 @@ struct _SplitClass
|
||||
*/
|
||||
void xaccFreeSplit (Split *split); /* frees memory */
|
||||
|
||||
Split * xaccSplitClone (const Split *s);
|
||||
Split *xaccSplitCloneNoKvp (const Split *s);
|
||||
void xaccSplitCopyKvp (const Split *from, Split *to);
|
||||
|
||||
Split *xaccDupeSplit (const Split *s);
|
||||
void mark_split (Split *s);
|
||||
|
@ -184,6 +184,7 @@ const char *assoc_uri_str = "assoc_uri";
|
||||
#define TRANS_TXN_TYPE_KVP "trans-txn-type"
|
||||
#define TRANS_READ_ONLY_REASON "trans-read-only"
|
||||
#define TRANS_REVERSED_BY "reversed-by"
|
||||
#define GNC_SX_FROM "from-sched-xaction"
|
||||
|
||||
#define ISO_DATELENGTH 32 /* length of an iso 8601 date string. */
|
||||
|
||||
@ -193,11 +194,14 @@ static QofLogModule log_module = GNC_MOD_ENGINE;
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NUM,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_CURRENCY,
|
||||
PROP_POST_DATE,
|
||||
PROP_ENTER_DATE
|
||||
PROP_CURRENCY, /* Table */
|
||||
PROP_NUM, /* Table */
|
||||
PROP_POST_DATE, /* Table */
|
||||
PROP_ENTER_DATE, /* Table */
|
||||
PROP_DESCRIPTION, /* Table */
|
||||
PROP_INVOICE, /* KVP */
|
||||
PROP_SX_TXN, /* KVP */
|
||||
PROP_ONLINE_ACCOUNT,/* KVP */
|
||||
};
|
||||
|
||||
void
|
||||
@ -303,6 +307,9 @@ gnc_transaction_get_property(GObject* object,
|
||||
GParamSpec* pspec)
|
||||
{
|
||||
Transaction* tx;
|
||||
KvpFrame *frame;
|
||||
gchar *key;
|
||||
GValue *temp;
|
||||
|
||||
g_return_if_fail(GNC_IS_TRANSACTION(object));
|
||||
|
||||
@ -324,6 +331,18 @@ gnc_transaction_get_property(GObject* object,
|
||||
case PROP_ENTER_DATE:
|
||||
g_value_set_boxed(value, &tx->date_entered);
|
||||
break;
|
||||
case PROP_INVOICE:
|
||||
key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
case PROP_SX_TXN:
|
||||
key = GNC_SX_FROM;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_get_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -337,10 +356,14 @@ gnc_transaction_set_property(GObject* object,
|
||||
GParamSpec* pspec)
|
||||
{
|
||||
Transaction* tx;
|
||||
KvpFrame *frame;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_TRANSACTION(object));
|
||||
|
||||
tx = GNC_TRANSACTION(object);
|
||||
g_assert (qof_instance_get_editlevel(tx));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NUM:
|
||||
@ -358,6 +381,18 @@ gnc_transaction_set_property(GObject* object,
|
||||
case PROP_ENTER_DATE:
|
||||
xaccTransSetDateEnteredTS(tx, g_value_get_boxed(value));
|
||||
break;
|
||||
case PROP_INVOICE:
|
||||
key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
case PROP_SX_TXN:
|
||||
key = GNC_SX_FROM;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
case PROP_ONLINE_ACCOUNT:
|
||||
key = "online_id";
|
||||
qof_instance_set_kvp (QOF_INSTANCE (tx), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -426,6 +461,36 @@ gnc_transaction_class_init(TransactionClass* klass)
|
||||
"The date the transaction was entered.",
|
||||
GNC_TYPE_TIMESPEC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_INVOICE,
|
||||
g_param_spec_boxed("invoice",
|
||||
"Invoice attached to lot",
|
||||
"Used by GncInvoice",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_SX_TXN,
|
||||
g_param_spec_boxed("from-sched-xaction",
|
||||
"From Scheduled Transaction",
|
||||
"Used by Scheduled Transastions to record the "
|
||||
"originating template transaction for created "
|
||||
"transactions",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_ONLINE_ACCOUNT,
|
||||
g_param_spec_string ("online-id",
|
||||
"Online Account ID",
|
||||
"The online account which corresponds to this "
|
||||
"account for OFX/HCBI import",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -532,9 +597,8 @@ xaccTransSortSplits (Transaction *trans)
|
||||
* This routine is prone to programmer snafu if not used correctly.
|
||||
* It is used only by the edit-rollback code.
|
||||
*/
|
||||
/* Actually, it *is* public, and used by Period.c */
|
||||
Transaction *
|
||||
xaccDupeTransaction (const Transaction *from)
|
||||
static Transaction *
|
||||
dupe_trans (const Transaction *from)
|
||||
{
|
||||
Transaction *to;
|
||||
GList *node;
|
||||
@ -571,10 +635,11 @@ xaccDupeTransaction (const Transaction *from)
|
||||
|
||||
/********************************************************************\
|
||||
* Use this routine to externally duplicate a transaction. It creates
|
||||
* a full fledged transaction with unique guid, splits, etc.
|
||||
* a full fledged transaction with unique guid, splits, etc. and
|
||||
* writes it to the database.
|
||||
\********************************************************************/
|
||||
Transaction *
|
||||
xaccTransClone (const Transaction *from)
|
||||
xaccTransCloneNoKvp (const Transaction *from)
|
||||
{
|
||||
Transaction *to;
|
||||
Split *split;
|
||||
@ -593,14 +658,13 @@ xaccTransClone (const Transaction *from)
|
||||
|
||||
to->orig = NULL;
|
||||
|
||||
qof_instance_init_data (&to->inst, GNC_ID_TRANS, qof_instance_get_book(from));
|
||||
kvp_frame_delete (to->inst.kvp_data);
|
||||
to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data);
|
||||
qof_instance_init_data (&to->inst, GNC_ID_TRANS,
|
||||
qof_instance_get_book(from));
|
||||
|
||||
xaccTransBeginEdit(to);
|
||||
for (node = from->splits; node; node = node->next)
|
||||
{
|
||||
split = xaccSplitClone(node->data);
|
||||
split = xaccSplitCloneNoKvp(node->data);
|
||||
split->parent = to;
|
||||
to->splits = g_list_append (to->splits, split);
|
||||
}
|
||||
@ -611,11 +675,28 @@ xaccTransClone (const Transaction *from)
|
||||
return to;
|
||||
}
|
||||
|
||||
Transaction *
|
||||
xaccTransClone (const Transaction *from)
|
||||
{
|
||||
Transaction *to = xaccTransCloneNoKvp (from);
|
||||
int i = 0;
|
||||
int length = g_list_length (from->splits);
|
||||
|
||||
xaccTransBeginEdit (to);
|
||||
to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data);
|
||||
g_assert (g_list_length (to->splits) == length);
|
||||
for (i = 0; i < length; ++i)
|
||||
xaccSplitCopyKvp (g_list_nth_data (from->splits, i),
|
||||
g_list_nth_data (to->splits, i));
|
||||
xaccTransCommitEdit (to);
|
||||
return to;
|
||||
}
|
||||
|
||||
/*################## Added for Reg2 #################*/
|
||||
|
||||
/********************************************************************\
|
||||
* Copy a transaction to the 'clipboard' transaction using
|
||||
* xaccDupeTransaction. The 'clipboard' transaction must never
|
||||
* dupe_trans. The 'clipboard' transaction must never
|
||||
* be dereferenced.
|
||||
\********************************************************************/
|
||||
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
|
||||
@ -625,7 +706,7 @@ Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
|
||||
if (!from_trans)
|
||||
return NULL;
|
||||
|
||||
to_trans = xaccDupeTransaction(from_trans);
|
||||
to_trans = dupe_trans(from_trans);
|
||||
return to_trans;
|
||||
}
|
||||
|
||||
@ -642,7 +723,7 @@ xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
|
||||
/********************************************************************\
|
||||
* This function explicitly must robustly handle some unusual input.
|
||||
*
|
||||
* 'from_trans' may be a duped trans (see xaccDupeTransaction), so its
|
||||
* 'from_trans' may be a duped trans (see dupe_trans), so its
|
||||
* splits may not really belong to the accounts that they say they do.
|
||||
*
|
||||
* 'from_acc' need not be a valid account. It may be an already freed
|
||||
@ -1309,7 +1390,7 @@ xaccTransBeginEdit (Transaction *trans)
|
||||
|
||||
/* Make a clone of the transaction; we will use this
|
||||
* in case we need to roll-back the edit. */
|
||||
trans->orig = xaccDupeTransaction (trans);
|
||||
trans->orig = dupe_trans (trans);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -2615,6 +2696,7 @@ xaccTransFindSplitByAccount(const Transaction *trans, const Account *acc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
/* QofObject function implementation */
|
||||
@ -2776,6 +2858,7 @@ _utest_trans_fill_functions (void)
|
||||
func->trans_on_error = trans_on_error;
|
||||
func->trans_cleanup_commit = trans_cleanup_commit;
|
||||
func->xaccTransScrubGainsDate = xaccTransScrubGainsDate;
|
||||
func->dupe_trans = dupe_trans;
|
||||
return func;
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,12 @@ void xaccTransDestroy (Transaction *trans);
|
||||
*/
|
||||
Transaction * xaccTransClone (const Transaction *t);
|
||||
|
||||
/**
|
||||
The xaccTransCloneNoKvp() method will create a complete copy of an
|
||||
existing transaction except that the KVP slots will be empty.
|
||||
*/
|
||||
Transaction * xaccTransCloneNoKvp (const Transaction *t);
|
||||
|
||||
/** Equality.
|
||||
*
|
||||
* @param ta First transaction to compare
|
||||
@ -223,7 +229,7 @@ Transaction * xaccTransLookup (const GncGUID *guid, QofBook *book);
|
||||
/*################## Added for Reg2 #################*/
|
||||
|
||||
/** Copy a transaction to the 'clipboard' transaction using
|
||||
* xaccDupeTransaction. The 'clipboard' transaction must never
|
||||
* dupe_transaction. The 'clipboard' transaction must never
|
||||
* be dereferenced.
|
||||
*/
|
||||
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans);
|
||||
@ -749,8 +755,6 @@ void xaccTransDump (const Transaction *trans, const char *tag);
|
||||
#define xaccTransGetGUID(X) qof_entity_get_guid(QOF_INSTANCE(X))
|
||||
/** \deprecated */
|
||||
#define xaccTransReturnGUID(X) (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
|
||||
/** \deprecated */
|
||||
#define xaccTransGetSlots(X) qof_instance_get_slots (QOF_INSTANCE(X))
|
||||
|
||||
#endif /* XACC_TRANSACTION_H */
|
||||
/** @} */
|
||||
|
@ -186,6 +186,7 @@ typedef struct
|
||||
void (*trans_on_error)(Transaction*, QofBackendError);
|
||||
void (*trans_cleanup_commit)(Transaction*);
|
||||
void (*xaccTransScrubGainsDate)(Transaction*);
|
||||
Transaction *(*dupe_trans)(const Transaction*);
|
||||
|
||||
} TransTestFunctions;
|
||||
|
||||
|
@ -215,150 +215,6 @@ xaccAccountFindLatestOpenLot (Account *acc, gnc_numeric sign,
|
||||
return lot;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
/* Similar to GetOrMakeAccount, but different in important ways */
|
||||
|
||||
static Account *
|
||||
GetOrMakeLotOrphanAccount (Account *root, gnc_commodity * currency)
|
||||
{
|
||||
char * accname;
|
||||
Account * acc;
|
||||
|
||||
g_return_val_if_fail (root, NULL);
|
||||
|
||||
/* build the account name */
|
||||
if (!currency)
|
||||
{
|
||||
PERR ("No currency specified!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
accname = g_strconcat (_("Orphaned Gains"), "-",
|
||||
gnc_commodity_get_mnemonic (currency), NULL);
|
||||
|
||||
/* See if we've got one of these going already ... */
|
||||
acc = gnc_account_lookup_by_name(root, accname);
|
||||
|
||||
if (acc == NULL)
|
||||
{
|
||||
/* Guess not. We'll have to build one. */
|
||||
acc = xaccMallocAccount (gnc_account_get_book(root));
|
||||
xaccAccountBeginEdit (acc);
|
||||
xaccAccountSetName (acc, accname);
|
||||
xaccAccountSetCommodity (acc, currency);
|
||||
xaccAccountSetType (acc, ACCT_TYPE_INCOME);
|
||||
xaccAccountSetDescription (acc, _("Realized Gain/Loss"));
|
||||
xaccAccountSetNotes (acc,
|
||||
_("Realized Gains or Losses from "
|
||||
"Commodity or Trading Accounts "
|
||||
"that haven't been recorded elsewhere."));
|
||||
|
||||
/* Hang the account off the root. */
|
||||
gnc_account_append_child (root, acc);
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
|
||||
g_free (accname);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
xaccAccountSetDefaultGainAccount (Account *acc, const Account *gain_acct)
|
||||
{
|
||||
KvpFrame *cwd;
|
||||
KvpValue *vvv;
|
||||
const char * cur_name;
|
||||
gnc_commodity *acc_comm;
|
||||
|
||||
if (!acc || !gain_acct) return;
|
||||
|
||||
cwd = xaccAccountGetSlots (acc);
|
||||
cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
|
||||
|
||||
/* Accounts are indexed by thier unique currency name */
|
||||
acc_comm = xaccAccountGetCommodity(acc);
|
||||
cur_name = gnc_commodity_get_unique_name (acc_comm);
|
||||
|
||||
xaccAccountBeginEdit (acc);
|
||||
vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
|
||||
kvp_frame_set_slot_nc (cwd, cur_name, vvv);
|
||||
qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
Account *
|
||||
xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency)
|
||||
{
|
||||
Account *gain_acct = NULL;
|
||||
KvpFrame *cwd;
|
||||
KvpValue *vvv;
|
||||
GncGUID * gain_acct_guid;
|
||||
const char * cur_name;
|
||||
|
||||
if (!acc || !currency) return NULL;
|
||||
|
||||
cwd = xaccAccountGetSlots (acc);
|
||||
cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
|
||||
|
||||
/* Accounts are indexed by thier unique currency name */
|
||||
cur_name = gnc_commodity_get_unique_name (currency);
|
||||
vvv = kvp_frame_get_slot (cwd, cur_name);
|
||||
gain_acct_guid = kvp_value_get_guid (vvv);
|
||||
|
||||
gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
|
||||
return gain_acct;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
/* Functionally identical to the following:
|
||||
* if (!xaccAccountGetDefaultGainAccount()) {
|
||||
* xaccAccountSetDefaultGainAccount (); }
|
||||
* except that it saves a few cycles.
|
||||
*/
|
||||
|
||||
static Account *
|
||||
GetOrMakeGainAcct (Account *acc, gnc_commodity * currency)
|
||||
{
|
||||
Account *gain_acct = NULL;
|
||||
KvpFrame *cwd;
|
||||
KvpValue *vvv;
|
||||
GncGUID * gain_acct_guid;
|
||||
const char * cur_name;
|
||||
|
||||
cwd = xaccAccountGetSlots (acc);
|
||||
cwd = kvp_frame_get_frame_slash (cwd, "/lot-mgmt/gains-act/");
|
||||
|
||||
/* Accounts are indexed by thier unique currency name */
|
||||
cur_name = gnc_commodity_get_unique_name (currency);
|
||||
vvv = kvp_frame_get_slot (cwd, cur_name);
|
||||
gain_acct_guid = kvp_value_get_guid (vvv);
|
||||
|
||||
gain_acct = xaccAccountLookup (gain_acct_guid, qof_instance_get_book(acc));
|
||||
|
||||
/* If there is no default place to put gains/losses
|
||||
* for this account, then create such a place */
|
||||
if (NULL == gain_acct)
|
||||
{
|
||||
Account *root;
|
||||
|
||||
xaccAccountBeginEdit (acc);
|
||||
root = gnc_account_get_root(acc);
|
||||
gain_acct = GetOrMakeLotOrphanAccount (root, currency);
|
||||
|
||||
vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
|
||||
kvp_frame_set_slot_nc (cwd, cur_name, vvv);
|
||||
qof_instance_set_slots(QOF_INSTANCE(acc), acc->inst.kvp_data);
|
||||
xaccAccountCommitEdit (acc);
|
||||
|
||||
}
|
||||
return gain_acct;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
Split *
|
||||
@ -541,22 +397,18 @@ xaccSplitAssignToLot (Split *split, GNCLot *lot)
|
||||
ts = xaccSplitRetDateReconciledTS (split);
|
||||
xaccSplitSetDateReconciledTS (new_split, &ts);
|
||||
|
||||
/* We do not copy the KVP tree, as it seems like a dangerous
|
||||
* thing to do. If the user wants to access stuff in the 'old'
|
||||
* kvp tree from the 'new' split, they shoudl follow the
|
||||
* 'split-lot' pointers. Yes, this is complicated, but what
|
||||
* else can one do ??
|
||||
/* Set the lot-split and peer_guid properties on the two
|
||||
* splits to indicate that they're linked.
|
||||
*/
|
||||
/* Add kvp markup to indicate that these two splits used
|
||||
* to be one before being 'split'
|
||||
*/
|
||||
gnc_kvp_bag_add (split->inst.kvp_data, "lot-split", now,
|
||||
"peer_guid", xaccSplitGetGUID (new_split),
|
||||
NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"lot-split", now,
|
||||
"peer_guid", xaccSplitGetGUID (new_split),
|
||||
NULL);
|
||||
|
||||
gnc_kvp_bag_add (new_split->inst.kvp_data, "lot-split", now,
|
||||
"peer_guid", xaccSplitGetGUID (split),
|
||||
NULL);
|
||||
qof_instance_set (QOF_INSTANCE (new_split),
|
||||
"lot-split", now,
|
||||
"peer_guid", xaccSplitGetGUID (split),
|
||||
NULL);
|
||||
|
||||
xaccAccountInsertSplit (acc, new_split);
|
||||
xaccTransAppendSplit (trans, new_split);
|
||||
@ -633,15 +485,14 @@ xaccSplitAssign (Split *split)
|
||||
Split *
|
||||
xaccSplitGetCapGainsSplit (const Split *split)
|
||||
{
|
||||
KvpValue *val;
|
||||
GncGUID *gains_guid;
|
||||
Split *gains_split;
|
||||
|
||||
if (!split) return NULL;
|
||||
|
||||
val = kvp_frame_get_slot (split->inst.kvp_data, "gains-split");
|
||||
if (!val) return NULL;
|
||||
gains_guid = kvp_value_get_guid (val);
|
||||
qof_instance_get (QOF_INSTANCE (split),
|
||||
"gains-split", &gains_guid,
|
||||
NULL);
|
||||
if (!gains_guid) return NULL;
|
||||
|
||||
/* Both splits will be in the same collection, so search there. */
|
||||
@ -656,15 +507,14 @@ xaccSplitGetCapGainsSplit (const Split *split)
|
||||
Split *
|
||||
xaccSplitGetGainsSourceSplit (const Split *split)
|
||||
{
|
||||
KvpValue *val;
|
||||
GncGUID *source_guid;
|
||||
Split *source_split;
|
||||
|
||||
if (!split) return NULL;
|
||||
|
||||
val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source");
|
||||
if (!val) return NULL;
|
||||
source_guid = kvp_value_get_guid (val);
|
||||
qof_instance_get (QOF_INSTANCE (split),
|
||||
"gains-source", &source_guid,
|
||||
NULL);
|
||||
if (!source_guid) return NULL;
|
||||
|
||||
/* Both splits will be in the same collection, so search there. */
|
||||
@ -697,8 +547,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
currency = split->parent->common_currency;
|
||||
|
||||
ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split,
|
||||
split->gains_split, split->gains,
|
||||
kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
||||
split->gains_split, split->gains, gnc_lot_get_title(lot));
|
||||
|
||||
/* Make sure the status flags and pointers are initialized */
|
||||
xaccSplitDetermineGainStatus(split);
|
||||
@ -942,7 +791,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
(FALSE == gnc_commodity_equiv (currency,
|
||||
xaccAccountGetCommodity(gain_acc))))
|
||||
{
|
||||
gain_acc = GetOrMakeGainAcct (lot_acc, currency);
|
||||
gain_acc = xaccAccountGainsAccount (lot_acc, currency);
|
||||
}
|
||||
|
||||
xaccAccountBeginEdit (gain_acc);
|
||||
@ -965,17 +814,18 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
xaccSplitSetMemo (lot_split, _("Realized Gain/Loss"));
|
||||
xaccSplitSetMemo (gain_split, _("Realized Gain/Loss"));
|
||||
|
||||
/* For the new transaction, install KVP markup indicating
|
||||
/* For the new transaction, set the split properties indicating
|
||||
* that this is the gains transaction that corresponds
|
||||
* to the gains source.
|
||||
*/
|
||||
xaccTransBeginEdit (base_txn);
|
||||
kvp_frame_set_guid (split->inst.kvp_data, "gains-split",
|
||||
xaccSplitGetGUID (lot_split));
|
||||
qof_instance_set_dirty (QOF_INSTANCE (split));
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"gains-split", xaccSplitGetGUID (lot_split),
|
||||
NULL);
|
||||
xaccTransCommitEdit (base_txn);
|
||||
kvp_frame_set_guid (lot_split->inst.kvp_data, "gains-source",
|
||||
xaccSplitGetGUID (split));
|
||||
qof_instance_set (QOF_INSTANCE (lot_split),
|
||||
"gains-source", xaccSplitGetGUID (split),
|
||||
NULL);
|
||||
|
||||
}
|
||||
else
|
||||
@ -1031,7 +881,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
xaccSplitSetAmount (gain_split, negvalue);
|
||||
xaccSplitSetValue (gain_split, negvalue);
|
||||
|
||||
/* Some short-cuts to help avoid the above kvp lookup. */
|
||||
/* Some short-cuts to help avoid the above property lookup. */
|
||||
split->gains = GAINS_STATUS_CLEAN;
|
||||
split->gains_split = lot_split;
|
||||
lot_split->gains = GAINS_STATUS_GAINS;
|
||||
|
@ -124,25 +124,6 @@ GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
|
||||
gnc_numeric sign,
|
||||
gnc_commodity *currency);
|
||||
|
||||
/** The xaccAccountGetDefaultGainAccount() routine will return
|
||||
* the account to which realized gains/losses may be posted.
|
||||
* Because gains may be in different currencies, one must
|
||||
* specify the currency type in which the gains will be posted.
|
||||
* This routine does nothing more than return the value of
|
||||
* the "/lot-mgmt/gains-act/XXX" key, where XXX is the unique
|
||||
* currency name. IOf there is no default account for this
|
||||
* currency, NULL will be returned.
|
||||
*/
|
||||
Account * xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency);
|
||||
|
||||
/** The xaccAccountSetDefaultGainAccount() routine can be used
|
||||
* to set the account to which realized gains/losses will be
|
||||
* posted by default. This routine does nothing more than set
|
||||
* value of the "/lot-mgmt/gains-act/XXX" key, where XXX is the
|
||||
* unique currency name of the currency of gains account.
|
||||
*/
|
||||
void xaccAccountSetDefaultGainAccount (Account *acc, const Account *gains_acct);
|
||||
|
||||
/** The xaccSplitGetCapGainsSplit() routine returns the split
|
||||
* that records the cap gains for this split. It returns NULL
|
||||
* if not found. This routine does nothing more than search for
|
||||
|
@ -140,10 +140,18 @@ functions. */
|
||||
|
||||
QofSession * qof_session_new (void);
|
||||
QofBook * qof_session_get_book (QofSession *session);
|
||||
|
||||
// TODO: Maybe unroll
|
||||
void qof_book_kvp_changed (QofBook *book);
|
||||
|
||||
/* This horror is to permit the scheme options in
|
||||
* src/app-utils/options.scm to read and write the book's KVP (another
|
||||
* horror) directly. It should be refactored into book functions that
|
||||
* handle the KVP access.
|
||||
*/
|
||||
%inline {
|
||||
KvpFrame *qof_book_get_slots (QofBook *book);
|
||||
extern KvpFrame *qof_instance_get_slots (QofInstance*);
|
||||
KvpFrame *qof_book_get_slots (QofBook *book) {
|
||||
return qof_instance_get_slots (QOF_INSTANCE (book));
|
||||
}
|
||||
}
|
||||
// TODO: Unroll/remove
|
||||
const char *qof_session_get_url (QofSession *session);
|
||||
|
||||
@ -173,7 +181,6 @@ SplitList * qof_query_run_subquery (QofQuery *q, const QofQuery *q);
|
||||
%include <qofbookslots.h>
|
||||
%include <qofbook.h>
|
||||
|
||||
KvpFrame* qof_book_get_slots(QofBook* book);
|
||||
%ignore GNC_DENOM_AUTO;
|
||||
%ignore GNCNumericErrorCodes;
|
||||
%ignore GNC_ERROR_OK;
|
||||
|
@ -22,29 +22,31 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <time.h>
|
||||
#include "qof.h"
|
||||
#include "qofbookslots.h"
|
||||
#include <qof.h>
|
||||
#include <qofbookslots.h>
|
||||
#include <gnc-gdate-utils.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "Account.h"
|
||||
|
||||
#include "gnc-budget.h"
|
||||
#include "gnc-commodity.h"
|
||||
#include "gnc-gdate-utils.h"
|
||||
|
||||
static QofLogModule log_module = GNC_MOD_ENGINE;
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_NUM_PERIODS,
|
||||
PROP_RECURRENCE,
|
||||
PROP_NAME, /* Table */
|
||||
PROP_DESCRIPTION, /* Table */
|
||||
PROP_NUM_PERIODS, /* Table */
|
||||
PROP_RUNTIME_0,
|
||||
PROP_RECURRENCE, /* Cached pointer; Recurrence table holds budget guid */
|
||||
};
|
||||
|
||||
struct budget_s
|
||||
@ -156,6 +158,9 @@ gnc_budget_set_property( GObject* object,
|
||||
g_return_if_fail(GNC_IS_BUDGET(object));
|
||||
|
||||
budget = GNC_BUDGET(object);
|
||||
if (prop_id < PROP_RUNTIME_0)
|
||||
g_assert (qof_instance_get_editlevel(budget));
|
||||
|
||||
switch ( prop_id )
|
||||
{
|
||||
case PROP_NAME:
|
||||
@ -626,31 +631,23 @@ gnc_budget_get_default (QofBook *book)
|
||||
{
|
||||
QofCollection *col;
|
||||
GncBudget *bgt = NULL;
|
||||
kvp_value *kvp_default_budget;
|
||||
const GncGUID *default_budget_guid;
|
||||
const GncGUID *default_budget_guid = NULL;
|
||||
|
||||
g_return_val_if_fail(book, NULL);
|
||||
|
||||
/* See if there is a budget selected in the KVP perferences */
|
||||
|
||||
kvp_default_budget = kvp_frame_get_slot_path(qof_book_get_slots (book),
|
||||
KVP_OPTION_PATH,
|
||||
OPTION_SECTION_BUDGETING,
|
||||
OPTION_NAME_DEFAULT_BUDGET,
|
||||
NULL);
|
||||
|
||||
if (kvp_default_budget != NULL )
|
||||
qof_instance_get (QOF_INSTANCE (book),
|
||||
"default-budget", &default_budget_guid,
|
||||
NULL);
|
||||
if (default_budget_guid != NULL)
|
||||
{
|
||||
default_budget_guid = kvp_value_get_guid(kvp_default_budget);
|
||||
if (default_budget_guid != NULL)
|
||||
{
|
||||
col = qof_book_get_collection(book, GNC_ID_BUDGET);
|
||||
bgt = (GncBudget *) qof_collection_lookup_entity(col,
|
||||
default_budget_guid);
|
||||
}
|
||||
col = qof_book_get_collection(book, GNC_ID_BUDGET);
|
||||
bgt = (GncBudget *) qof_collection_lookup_entity(col,
|
||||
default_budget_guid);
|
||||
}
|
||||
|
||||
/* Revert to 2.2.x behavior if there is no defined budget in KVP */
|
||||
/* Revert to 2.2.x behavior if the book has no default budget. */
|
||||
|
||||
if ( bgt == NULL )
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
* *
|
||||
*******************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
@ -33,6 +33,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <regex.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-commodity.h"
|
||||
#include "gnc-prefs.h"
|
||||
@ -47,16 +48,16 @@ static QofLogModule log_module = GNC_MOD_COMMODITY;
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAMESPACE,
|
||||
PROP_FULL_NAME,
|
||||
PROP_MNEMONIC,
|
||||
PROP_PRINTNAME,
|
||||
PROP_CUSIP,
|
||||
PROP_FRACTION,
|
||||
PROP_UNIQUE_NAME,
|
||||
PROP_QUOTE_FLAG,
|
||||
PROP_QUOTE_SOURCE,
|
||||
PROP_QUOTE_TZ,
|
||||
PROP_NAMESPACE, /* Table */
|
||||
PROP_FULL_NAME, /* Table */
|
||||
PROP_MNEMONIC, /* Table */
|
||||
PROP_PRINTNAME, /* Constructed */
|
||||
PROP_CUSIP, /* Table */
|
||||
PROP_FRACTION, /* Table */
|
||||
PROP_UNIQUE_NAME, /* Constructed */
|
||||
PROP_QUOTE_FLAG, /* Table */
|
||||
PROP_QUOTE_SOURCE, /* Table */
|
||||
PROP_QUOTE_TZ, /* Table */
|
||||
};
|
||||
|
||||
struct gnc_commodity_s
|
||||
@ -698,6 +699,7 @@ gnc_commodity_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_COMMODITY(object));
|
||||
|
||||
commodity = GNC_COMMODITY(object);
|
||||
g_assert (qof_instance_get_editlevel(commodity));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
|
@ -251,5 +251,16 @@ void gnc_engine_add_commit_error_callback( EngineCommitErrorCallback cb, gpointe
|
||||
|
||||
void gnc_engine_signal_commit_error( QofBackendError errcode );
|
||||
|
||||
/** STRING CONSTANTS **********************************************
|
||||
* Used to declare constant KVP keys used in more than one class
|
||||
*/
|
||||
#define GNC_INVOICE_ID "gncInvoice"
|
||||
#define GNC_INVOICE_GUID "invoice-guid"
|
||||
#define GNC_OWNER_ID "gncOwner"
|
||||
#define GNC_OWNER_TYPE "owner-type"
|
||||
#define GNC_OWNER_GUID "owner-guid"
|
||||
#define GNC_SX_ID "sched-xaction"
|
||||
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
@ -39,10 +39,11 @@
|
||||
* Copyright (c) 2002,2003 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "AccountP.h"
|
||||
@ -63,8 +64,15 @@ struct gnc_lot_s
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_IS_CLOSED,
|
||||
PROP_MARKER
|
||||
// PROP_ACCOUNT, /* Table */
|
||||
PROP_IS_CLOSED, /* Table */
|
||||
|
||||
PROP_INVOICE, /* KVP */
|
||||
PROP_OWNER_TYPE, /* KVP */
|
||||
PROP_OWNER_GUID, /* KVP */
|
||||
|
||||
PROP_RUNTIME_0,
|
||||
PROP_MARKER, /* Runtime */
|
||||
};
|
||||
|
||||
typedef struct LotPrivate
|
||||
@ -93,6 +101,11 @@ typedef struct LotPrivate
|
||||
|
||||
/* ============================================================= */
|
||||
|
||||
static void gnc_lot_set_invoice (GNCLot* lot, GncGUID *guid);
|
||||
static GncGUID *gnc_lot_get_invoice (GNCLot* lot);
|
||||
|
||||
/* ============================================================= */
|
||||
|
||||
/* GObject Initialization */
|
||||
G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
|
||||
|
||||
@ -125,6 +138,9 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
|
||||
{
|
||||
GNCLot* lot;
|
||||
LotPrivate* priv;
|
||||
KvpFrame *frame;
|
||||
gchar *key;
|
||||
GValue *temp;
|
||||
|
||||
g_return_if_fail(GNC_IS_LOT(object));
|
||||
|
||||
@ -138,18 +154,41 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec*
|
||||
case PROP_MARKER:
|
||||
g_value_set_int(value, priv->marker);
|
||||
break;
|
||||
case PROP_INVOICE:
|
||||
key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
case PROP_OWNER_TYPE:
|
||||
key = GNC_OWNER_ID"/" GNC_OWNER_TYPE;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
case PROP_OWNER_GUID:
|
||||
key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
|
||||
gnc_lot_set_property (GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec)
|
||||
{
|
||||
GNCLot* lot;
|
||||
LotPrivate* priv;
|
||||
KvpFrame *frame;
|
||||
gchar *key = NULL;
|
||||
|
||||
g_return_if_fail(GNC_IS_LOT(object));
|
||||
|
||||
lot = GNC_LOT(object);
|
||||
if (prop_id < PROP_RUNTIME_0)
|
||||
g_assert (qof_instance_get_editlevel(lot));
|
||||
|
||||
priv = GET_PRIVATE(lot);
|
||||
switch (prop_id)
|
||||
{
|
||||
@ -159,7 +198,22 @@ gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParam
|
||||
case PROP_MARKER:
|
||||
priv->marker = g_value_get_int(value);
|
||||
break;
|
||||
}
|
||||
case PROP_INVOICE:
|
||||
key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
case PROP_OWNER_TYPE:
|
||||
key = GNC_OWNER_ID "/" GNC_OWNER_TYPE;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
case PROP_OWNER_GUID:
|
||||
key = GNC_OWNER_ID "/" GNC_OWNER_GUID;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (lot), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -193,8 +247,32 @@ gnc_lot_class_init(GNCLotClass* klass)
|
||||
0, G_MAXINT8, 0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_INVOICE,
|
||||
g_param_spec_boxed("invoice",
|
||||
"Invoice attached to lot",
|
||||
"Used by GncInvoice",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_OWNER_TYPE,
|
||||
g_param_spec_int64("owner-type",
|
||||
"Owning Entity Type of lot",
|
||||
"Used by GncOwner",
|
||||
0, G_MAXINT64, 0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_OWNER_GUID,
|
||||
g_param_spec_boxed("owner-guid",
|
||||
"Owner attached to lot",
|
||||
"Used by GncOwner",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
GNCLot *
|
||||
@ -333,12 +411,6 @@ gnc_lot_set_closed_unknown(GNCLot* lot)
|
||||
}
|
||||
}
|
||||
|
||||
KvpFrame *
|
||||
gnc_lot_get_slots (const GNCLot *lot)
|
||||
{
|
||||
return qof_instance_get_slots(QOF_INSTANCE(lot));
|
||||
}
|
||||
|
||||
SplitList *
|
||||
gnc_lot_get_split_list (const GNCLot *lot)
|
||||
{
|
||||
@ -363,14 +435,16 @@ const char *
|
||||
gnc_lot_get_title (const GNCLot *lot)
|
||||
{
|
||||
if (!lot) return NULL;
|
||||
return kvp_frame_get_string (gnc_lot_get_slots(lot), "/title");
|
||||
return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
|
||||
"/title");
|
||||
}
|
||||
|
||||
const char *
|
||||
gnc_lot_get_notes (const GNCLot *lot)
|
||||
{
|
||||
if (!lot) return NULL;
|
||||
return kvp_frame_get_string (gnc_lot_get_slots(lot), "/notes");
|
||||
return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)),
|
||||
"/notes");
|
||||
}
|
||||
|
||||
void
|
||||
@ -379,7 +453,8 @@ gnc_lot_set_title (GNCLot *lot, const char *str)
|
||||
if (!lot) return;
|
||||
qof_begin_edit(QOF_INSTANCE(lot));
|
||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||
kvp_frame_set_str (gnc_lot_get_slots(lot), "/title", str);
|
||||
kvp_frame_set_str (qof_instance_get_slots(QOF_INSTANCE (lot)),
|
||||
"/title", str);
|
||||
gnc_lot_commit_edit(lot);
|
||||
}
|
||||
|
||||
@ -389,7 +464,8 @@ gnc_lot_set_notes (GNCLot *lot, const char *str)
|
||||
if (!lot) return;
|
||||
gnc_lot_begin_edit(lot);
|
||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||
kvp_frame_set_str (gnc_lot_get_slots(lot), "/notes", str);
|
||||
kvp_frame_set_str (qof_instance_get_slots (QOF_INSTANCE (lot)),
|
||||
"/notes", str);
|
||||
gnc_lot_commit_edit(lot);
|
||||
}
|
||||
|
||||
@ -675,20 +751,20 @@ gboolean gnc_lot_register (void)
|
||||
GNCLot * gnc_lot_make_default (Account *acc)
|
||||
{
|
||||
GNCLot * lot;
|
||||
gint64 id;
|
||||
char buff[200];
|
||||
gint64 id = 0;
|
||||
gchar *buff;
|
||||
|
||||
lot = gnc_lot_new (qof_instance_get_book(acc));
|
||||
|
||||
/* Provide a reasonable title for the new lot */
|
||||
xaccAccountBeginEdit (acc);
|
||||
id = kvp_frame_get_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id");
|
||||
snprintf (buff, 200, ("%s %" G_GINT64_FORMAT), _("Lot"), id);
|
||||
kvp_frame_set_str (gnc_lot_get_slots (lot), "/title", buff);
|
||||
qof_instance_get (QOF_INSTANCE (acc), "lot-next-id", &id, NULL);
|
||||
buff = g_strdup_printf ("%s %" G_GINT64_FORMAT, _("Lot"), id);
|
||||
gnc_lot_set_title (lot, buff);
|
||||
id ++;
|
||||
kvp_frame_set_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id", id);
|
||||
qof_instance_set_dirty (QOF_INSTANCE(acc));
|
||||
qof_instance_set (QOF_INSTANCE (acc), "lot-next-id", id, NULL);
|
||||
xaccAccountCommitEdit (acc);
|
||||
g_free (buff);
|
||||
return lot;
|
||||
}
|
||||
|
||||
|
@ -165,11 +165,6 @@ const char * gnc_lot_get_notes (const GNCLot *);
|
||||
void gnc_lot_set_title (GNCLot *, const char *);
|
||||
void gnc_lot_set_notes (GNCLot *, const char *);
|
||||
|
||||
/** Every lot has a place to hang kvp data. This routine returns that
|
||||
* place.
|
||||
* */
|
||||
KvpFrame * gnc_lot_get_slots (const GNCLot *);
|
||||
|
||||
/** XXX: Document? */
|
||||
GNCLot * gnc_lot_make_default (Account * acc);
|
||||
|
||||
|
@ -41,12 +41,12 @@ static GNCPrice *lookup_nearest_in_time(GNCPriceDB *db, const gnc_commodity *c,
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_COMMODITY,
|
||||
PROP_CURRENCY,
|
||||
PROP_DATE,
|
||||
PROP_SOURCE,
|
||||
PROP_TYPE,
|
||||
PROP_VALUE
|
||||
PROP_COMMODITY, /* Table */
|
||||
PROP_CURRENCY, /* Table */
|
||||
PROP_DATE, /* Table */
|
||||
PROP_SOURCE, /* Table */
|
||||
PROP_TYPE, /* Table */
|
||||
PROP_VALUE, /* Table, 2 fields (numeric) */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -123,6 +123,8 @@ gnc_price_set_property(GObject* object, guint prop_id, const GValue* value, GPar
|
||||
g_return_if_fail(GNC_IS_PRICE(object));
|
||||
|
||||
price = GNC_PRICE(object);
|
||||
g_assert (qof_instance_get_editlevel(price));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
|
@ -25,9 +25,10 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncAddress.h"
|
||||
#include "gncAddressP.h"
|
||||
|
@ -26,9 +26,10 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-engine.h"
|
||||
#include "gncBillTermP.h"
|
||||
@ -192,6 +193,8 @@ gnc_billterm_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_BILLTERM(object));
|
||||
|
||||
bt = GNC_BILLTERM(object);
|
||||
g_assert (qof_instance_get_editlevel(bt));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
|
@ -37,6 +37,12 @@
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
|
||||
/* KVP key for report PDF directories */
|
||||
#define OWNER_EXPORT_PDF_DIRNAME "export-pdf-directory"
|
||||
#define LAST_POSTED_TO_ACCT "last-posted-to-acct"
|
||||
#define GNC_PAYMENT "payment"
|
||||
#define GNC_LAST_ACCOUNT "last_acct"
|
||||
|
||||
/* @deprecated backwards-compat definitions */
|
||||
#define GNC_BILLTERM_MODULE_NAME GNC_ID_BILLTERM
|
||||
#define GNC_CUSTOMER_MODULE_NAME GNC_ID_CUSTOMER
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-commodity.h"
|
||||
|
||||
@ -96,7 +97,10 @@ void mark_customer (GncCustomer *customer)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME
|
||||
PROP_NAME,
|
||||
PROP_PDF_DIRNAME,
|
||||
PROP_LAST_POSTED,
|
||||
PROP_PAYMENT_LAST_ACCT,
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -126,7 +130,7 @@ gnc_customer_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncCustomer *cust;
|
||||
|
||||
gchar *key;
|
||||
g_return_if_fail(GNC_IS_CUSTOMER(object));
|
||||
|
||||
cust = GNC_CUSTOMER(object);
|
||||
@ -135,6 +139,18 @@ gnc_customer_get_property (GObject *object,
|
||||
case PROP_NAME:
|
||||
g_value_set_string(value, cust->name);
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -144,19 +160,34 @@ gnc_customer_get_property (GObject *object,
|
||||
static void
|
||||
gnc_customer_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncCustomer *cust;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_CUSTOMER(object));
|
||||
|
||||
cust = GNC_CUSTOMER(object);
|
||||
g_assert (qof_instance_get_editlevel(cust));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
gncCustomerSetName(cust, g_value_get_string(value));
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -242,6 +273,39 @@ gnc_customer_class_init (GncCustomerClass *klass)
|
||||
"customer name.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PDF_DIRNAME,
|
||||
g_param_spec_string ("export-pdf-dir",
|
||||
"Export PDF Directory Name",
|
||||
"A subdirectory for exporting PDF reports which is "
|
||||
"appended to the target directory when writing them "
|
||||
"out. It is retrieved from preferences and stored on "
|
||||
"each 'Owner' object which prints items after "
|
||||
"printing.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_LAST_POSTED,
|
||||
g_param_spec_boxed("invoice-last-posted-account",
|
||||
"Invoice Last Posted Account",
|
||||
"The last account to which an invoice belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_PAYMENT_LAST_ACCT,
|
||||
g_param_spec_boxed("payment-last-account",
|
||||
"Payment Last Account",
|
||||
"The last account to which an payment belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* Create/Destroy Functions */
|
||||
@ -866,7 +930,6 @@ gboolean gncCustomerRegister (void)
|
||||
(QofSetterFunc)gncCustomerSetTaxTableOverride
|
||||
},
|
||||
{ CUSTOMER_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncCustomerGetTerms, (QofSetterFunc)gncCustomerSetTerms },
|
||||
{ CUSTOMER_SLOTS, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
|
||||
{ QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetActive, (QofSetterFunc)gncCustomerSetActive },
|
||||
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
||||
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
||||
|
@ -26,10 +26,11 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "gnc-commodity.h"
|
||||
@ -79,16 +80,19 @@ void mark_employee (GncEmployee *employee)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_USERNAME,
|
||||
PROP_ID,
|
||||
PROP_ACTIVE,
|
||||
PROP_LANGUAGE,
|
||||
PROP_CURRENCY,
|
||||
PROP_ACL,
|
||||
PROP_ADDRESS,
|
||||
PROP_WORKDAY,
|
||||
PROP_RATE,
|
||||
PROP_CCARD
|
||||
PROP_USERNAME, /* Table */
|
||||
PROP_ID, /* Table */
|
||||
PROP_LANGUAGE, /* Table */
|
||||
PROP_ACL, /* Table */
|
||||
PROP_ACTIVE, /* Table */
|
||||
PROP_CURRENCY, /* Table */
|
||||
PROP_CCARD, /* Table */
|
||||
PROP_WORKDAY, /* Table (numeric) */
|
||||
PROP_RATE, /* Table (numeric) */
|
||||
PROP_ADDRESS, /* Table, 8 fields */
|
||||
PROP_PDF_DIRNAME, /* KVP */
|
||||
PROP_LAST_POSTED, /* KVP */
|
||||
PROP_PAYMENT_LAST_ACCT, /* KVP */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -124,6 +128,7 @@ gnc_employee_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncEmployee *emp;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_EMPLOYEE(object));
|
||||
|
||||
@ -160,6 +165,18 @@ gnc_employee_get_property (GObject *object,
|
||||
case PROP_CCARD:
|
||||
g_value_take_object(value, emp->ccard_acc);
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -173,10 +190,13 @@ gnc_employee_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncEmployee *emp;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_EMPLOYEE(object));
|
||||
|
||||
emp = GNC_EMPLOYEE(object);
|
||||
g_assert (qof_instance_get_editlevel(emp));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_USERNAME:
|
||||
@ -209,6 +229,18 @@ gnc_employee_set_property (GObject *object,
|
||||
case PROP_CCARD:
|
||||
gncEmployeeSetCCard(emp, g_value_get_object(value));
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (emp), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -367,6 +399,39 @@ gnc_employee_class_init (GncEmployeeClass *klass)
|
||||
"The credit card account for this employee.",
|
||||
GNC_TYPE_ACCOUNT,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PDF_DIRNAME,
|
||||
g_param_spec_string ("export-pdf-dir",
|
||||
"Export PDF Directory Name",
|
||||
"A subdirectory for exporting PDF reports which is "
|
||||
"appended to the target directory when writing them "
|
||||
"out. It is retrieved from preferences and stored on "
|
||||
"each 'Owner' object which prints items after "
|
||||
"printing.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_LAST_POSTED,
|
||||
g_param_spec_boxed("invoice-last-posted-account",
|
||||
"Invoice Last Posted Account",
|
||||
"The last account to which an invoice belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_PAYMENT_LAST_ACCT,
|
||||
g_param_spec_boxed("payment-last-account",
|
||||
"Payment Last Account",
|
||||
"The last account to which an payment belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* Create/Destroy Functions */
|
||||
|
@ -25,9 +25,10 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-commodity.h"
|
||||
|
||||
@ -211,7 +212,32 @@ void mark_entry (GncEntry *entry)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DESCRIPTION
|
||||
// PROP_DATE, /* Table */
|
||||
// PROP_DATE_ENTERED, /* Table */
|
||||
PROP_DESCRIPTION, /* Table */
|
||||
// PROP_ACTION, /* Table */
|
||||
// PROP_NOTES, /* Table */
|
||||
// PROP_QUANTITY, /* Table (numeric) */
|
||||
// PROP_I_ACCT, /* Table */
|
||||
// PROP_I_PRICE, /* Table (numeric) */
|
||||
// PROP_I_DISCOUNT, /* Table (numeric) */
|
||||
// PROP_INVOICE, /* Table */
|
||||
// PROP_I_DISC_TYPE, /* Table */
|
||||
// PROP_I_DISC_HOW, /* Table */
|
||||
// PROP_I_TAXABLE, /* Table */
|
||||
// PROP_I_TAX_INCL, /* Table */
|
||||
// PROP_I_TAXTABLE, /* Table */
|
||||
// PROP_B_ACCT, /* Table */
|
||||
// PROP_B_PRICE, /* Table (numeric) */
|
||||
// PROP_BILL, /* Table */
|
||||
// PROP_B_TAXTABLE_1, /* Table */
|
||||
// PROP_B_TAX_INCL, /* Table */
|
||||
// PROP_B_TAXTABLE, /* Table */
|
||||
// PROP_B_PAYTYPE, /* Table */
|
||||
// PROP_BILLABLE, /* Table */
|
||||
// PROP_BILLTO_TYPE, /* Table */
|
||||
// PROP_BILLTO, /* Table */
|
||||
// PROP_ORDER, /* Table */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -267,6 +293,8 @@ gnc_entry_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_ENTRY(object));
|
||||
|
||||
entry = GNC_ENTRY(object);
|
||||
g_assert (qof_instance_get_editlevel(entry));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DESCRIPTION:
|
||||
|
@ -27,10 +27,11 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "Transaction.h"
|
||||
#include "Account.h"
|
||||
@ -81,8 +82,6 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
|
||||
|
||||
#define _GNC_MOD_NAME GNC_ID_INVOICE
|
||||
|
||||
#define GNC_INVOICE_ID "gncInvoice"
|
||||
#define GNC_INVOICE_GUID "invoice-guid"
|
||||
#define GNC_INVOICE_IS_CN "credit-note"
|
||||
|
||||
#define SET_STR(obj, member, str) { \
|
||||
@ -113,7 +112,22 @@ QofBook * gncInvoiceGetBook(GncInvoice *x)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NOTES
|
||||
// PROP_ID, /* Table */
|
||||
// PROP_DATE_OPENED, /* Table */
|
||||
// PROP_DATE_POSTED, /* Table */
|
||||
PROP_NOTES, /* Table */
|
||||
// PROP_ACTIVE, /* Table */
|
||||
// PROP_CURRENCY, /* Table */
|
||||
// PROP_OWNER_TYPE, /* Table */
|
||||
// PROP_OWNER, /* Table */
|
||||
// PROP_TERMS, /* Table */
|
||||
// PROP_BILLING_ID, /* Table */
|
||||
// PROP_POST_TXN, /* Table */
|
||||
// PROP_POST_LOT, /* Table */
|
||||
// PROP_POST_ACCOUNT, /* Table */
|
||||
// PROP_BILLTO_TYPE, /* Table */
|
||||
// PROP_BILLTO, /* Table */
|
||||
// PROP_CHARGE_AMOUNT, /* Table, (numeric) */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -169,6 +183,8 @@ gnc_invoice_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_INVOICE(object));
|
||||
|
||||
inv = GNC_INVOICE(object);
|
||||
g_assert (qof_instance_get_editlevel(inv));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NOTES:
|
||||
@ -1133,52 +1149,37 @@ qofInvoiceSetJob (GncInvoice *invoice, GncJob *job)
|
||||
static void
|
||||
gncInvoiceDetachFromLot (GNCLot *lot)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
|
||||
if (!lot) return;
|
||||
|
||||
gnc_lot_begin_edit (lot);
|
||||
kvp = gnc_lot_get_slots (lot);
|
||||
kvp_frame_set_slot_path (kvp, NULL, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (lot));
|
||||
qof_instance_set (QOF_INSTANCE (lot), "invoice", NULL, NULL);
|
||||
gnc_lot_commit_edit (lot);
|
||||
}
|
||||
|
||||
static void
|
||||
gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
KvpValue *value;
|
||||
|
||||
GncGUID *guid;
|
||||
if (!invoice || !lot)
|
||||
return;
|
||||
|
||||
if (invoice->posted_lot) return; /* Cannot reset invoice's lot */
|
||||
|
||||
guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (invoice));
|
||||
gnc_lot_begin_edit (lot);
|
||||
kvp = gnc_lot_get_slots (lot);
|
||||
value = kvp_value_new_guid (qof_instance_get_guid (QOF_INSTANCE(invoice)));
|
||||
kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (lot));
|
||||
qof_instance_set (QOF_INSTANCE (lot), "invoice", guid, NULL);
|
||||
gnc_lot_commit_edit (lot);
|
||||
kvp_value_delete (value);
|
||||
gncInvoiceSetPostedLot (invoice, lot);
|
||||
}
|
||||
|
||||
GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
KvpValue *value;
|
||||
GncGUID *guid;
|
||||
GncGUID *guid = NULL;
|
||||
QofBook *book;
|
||||
|
||||
if (!lot) return NULL;
|
||||
|
||||
book = gnc_lot_get_book (lot);
|
||||
kvp = gnc_lot_get_slots (lot);
|
||||
value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
|
||||
if (!value) return NULL;
|
||||
|
||||
guid = kvp_value_get_guid (value);
|
||||
qof_instance_get (QOF_INSTANCE (lot), "invoice", &guid, NULL);
|
||||
return gncInvoiceLookup(book, guid);
|
||||
}
|
||||
|
||||
@ -1194,10 +1195,8 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
|
||||
if (invoice->posted_txn) return; /* Cannot reset invoice's txn */
|
||||
|
||||
xaccTransBeginEdit (txn);
|
||||
kvp = xaccTransGetSlots (txn);
|
||||
value = kvp_value_new_guid (qof_instance_get_guid(QOF_INSTANCE(invoice)));
|
||||
kvp_frame_set_slot_path (kvp, value, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
|
||||
kvp_value_delete (value);
|
||||
qof_instance_set (QOF_INSTANCE (txn), "invoice",
|
||||
qof_instance_get_guid (QOF_INSTANCE (invoice)), NULL);
|
||||
xaccTransSetTxnType (txn, TXN_TYPE_INVOICE);
|
||||
xaccTransCommitEdit (txn);
|
||||
gncInvoiceSetPostedTxn (invoice, txn);
|
||||
@ -1206,19 +1205,13 @@ gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
|
||||
GncInvoice *
|
||||
gncInvoiceGetInvoiceFromTxn (const Transaction *txn)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
KvpValue *value;
|
||||
GncGUID *guid;
|
||||
GncGUID *guid = NULL;
|
||||
QofBook *book;
|
||||
|
||||
if (!txn) return NULL;
|
||||
|
||||
book = xaccTransGetBook (txn);
|
||||
kvp = xaccTransGetSlots (txn);
|
||||
value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
|
||||
if (!value) return NULL;
|
||||
|
||||
guid = kvp_value_get_guid (value);
|
||||
qof_instance_get (QOF_INSTANCE (txn), "invoice", &guid, NULL);
|
||||
return gncInvoiceLookup(book, guid);
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,7 @@ GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot);
|
||||
*/
|
||||
static inline GncInvoice * gncInvoiceLookup (const QofBook *book, const GncGUID *guid)
|
||||
{
|
||||
if (book == NULL || guid == NULL) return NULL;
|
||||
QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_INVOICE, GncInvoice);
|
||||
}
|
||||
|
||||
@ -305,7 +306,6 @@ QofBook *gncInvoiceGetBook(GncInvoice *x);
|
||||
/** deprecated functions */
|
||||
#define gncInvoiceGetGUID(x) qof_instance_get_guid(QOF_INSTANCE(x))
|
||||
#define gncInvoiceRetGUID(x) (x ? *(qof_instance_get_guid(QOF_INSTANCE(x))) : *(guid_null()))
|
||||
#define gncInvoiceLookupDirect(G,B) gncInvoiceLookup((B),&(G))
|
||||
|
||||
/** Test support function used by test-dbi-business-stuff.c */
|
||||
gboolean gncInvoiceEqual(const GncInvoice *a, const GncInvoice *b);
|
||||
|
@ -26,10 +26,11 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-features.h"
|
||||
#include "gncInvoice.h"
|
||||
@ -71,7 +72,13 @@ void mark_job (GncJob *job)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME
|
||||
// PROP_ID, /* Table */
|
||||
PROP_NAME, /* Table */
|
||||
// PROP_REFERENCE, /* Table */
|
||||
// PROP_ACTIVE, /* Table */
|
||||
// PROP_OWNER_TYPE, /* Table */
|
||||
// PROP_OWNER, /* Table */
|
||||
PROP_PDF_DIRNAME, /* KVP */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -101,6 +108,7 @@ gnc_job_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncJob *job;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_JOB(object));
|
||||
|
||||
@ -110,6 +118,10 @@ gnc_job_get_property (GObject *object,
|
||||
case PROP_NAME:
|
||||
g_value_set_string(value, job->name);
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (job), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -123,15 +135,22 @@ gnc_job_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncJob *job;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_JOB(object));
|
||||
|
||||
job = GNC_JOB(object);
|
||||
g_assert (qof_instance_get_editlevel(job));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
gncJobSetName(job, g_value_get_string(value));
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (job), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -177,6 +196,19 @@ gnc_job_class_init (GncJobClass *klass)
|
||||
"by the GUI as the job mnemonic.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PDF_DIRNAME,
|
||||
g_param_spec_string ("export-pdf-dir",
|
||||
"Export PDF Directory Name",
|
||||
"A subdirectory for exporting PDF reports which is "
|
||||
"appended to the target directory when writing them "
|
||||
"out. It is retrieved from preferences and stored on "
|
||||
"each 'Owner' object which prints items after "
|
||||
"printing.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* Create/Destroy Functions */
|
||||
|
@ -25,10 +25,11 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncEntry.h"
|
||||
#include "gncEntryP.h"
|
||||
@ -84,12 +85,14 @@ void mark_order (GncOrder *order)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ID,
|
||||
PROP_NOTES,
|
||||
PROP_ACTIVE,
|
||||
PROP_DATE_OPENED,
|
||||
PROP_DATE_CLOSED,
|
||||
PROP_REFERENCE
|
||||
PROP_ID, /* Table */
|
||||
PROP_NOTES, /* Table */
|
||||
PROP_REFERENCE, /* Table */
|
||||
PROP_ACTIVE, /* Table */
|
||||
PROP_DATE_OPENED, /* Table */
|
||||
PROP_DATE_CLOSED, /* Table */
|
||||
// PROP_OWNER_TYPE, /* Table */
|
||||
// PROP_OWNER, /* Table */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -160,6 +163,8 @@ gnc_order_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_ORDER(object));
|
||||
|
||||
order = GNC_ORDER(object);
|
||||
g_assert (qof_instance_get_editlevel(order));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
|
@ -29,11 +29,12 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h> /* for memcpy() */
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncCustomerP.h"
|
||||
#include "gncEmployeeP.h"
|
||||
@ -50,8 +51,6 @@
|
||||
#define _GNC_MOD_NAME GNC_ID_OWNER
|
||||
|
||||
#define GNC_OWNER_ID "gncOwner"
|
||||
#define GNC_OWNER_TYPE "owner-type"
|
||||
#define GNC_OWNER_GUID "owner-guid"
|
||||
|
||||
GncOwner * gncOwnerNew (void)
|
||||
{
|
||||
@ -99,6 +98,36 @@ void gncOwnerBeginEdit (GncOwner *owner)
|
||||
}
|
||||
}
|
||||
|
||||
void gncOwnerCommitEdit (GncOwner *owner)
|
||||
{
|
||||
if (!owner) return;
|
||||
switch (owner->type)
|
||||
{
|
||||
case GNC_OWNER_NONE :
|
||||
case GNC_OWNER_UNDEFINED :
|
||||
break;
|
||||
case GNC_OWNER_CUSTOMER :
|
||||
{
|
||||
gncCustomerCommitEdit(owner->owner.customer);
|
||||
break;
|
||||
}
|
||||
case GNC_OWNER_JOB :
|
||||
{
|
||||
gncJobCommitEdit(owner->owner.job);
|
||||
break;
|
||||
}
|
||||
case GNC_OWNER_VENDOR :
|
||||
{
|
||||
gncVendorCommitEdit(owner->owner.vendor);
|
||||
break;
|
||||
}
|
||||
case GNC_OWNER_EMPLOYEE :
|
||||
{
|
||||
gncEmployeeCommitEdit(owner->owner.employee);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gncOwnerDestroy (GncOwner *owner)
|
||||
{
|
||||
@ -567,52 +596,31 @@ const GncGUID * gncOwnerGetEndGUID (const GncOwner *owner)
|
||||
|
||||
void gncOwnerAttachToLot (const GncOwner *owner, GNCLot *lot)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
KvpValue *value;
|
||||
|
||||
if (!owner || !lot)
|
||||
if (!owner || !lot)
|
||||
return;
|
||||
|
||||
kvp = gnc_lot_get_slots (lot);
|
||||
gnc_lot_begin_edit (lot);
|
||||
|
||||
value = kvp_value_new_gint64 (gncOwnerGetType (owner));
|
||||
kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
|
||||
kvp_value_delete (value);
|
||||
|
||||
value = kvp_value_new_guid (gncOwnerGetGUID (owner));
|
||||
kvp_frame_set_slot_path (kvp, value, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (lot));
|
||||
qof_instance_set (QOF_INSTANCE (lot),
|
||||
"owner-type", (gint64)gncOwnerGetType (owner),
|
||||
"owner-guid", gncOwnerGetGUID (owner),
|
||||
NULL);
|
||||
gnc_lot_commit_edit (lot);
|
||||
kvp_value_delete (value);
|
||||
|
||||
}
|
||||
|
||||
gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
|
||||
{
|
||||
KvpFrame *kvp;
|
||||
KvpValue *value;
|
||||
GncGUID *guid;
|
||||
GncGUID *guid = NULL;
|
||||
QofBook *book;
|
||||
GncOwnerType type;
|
||||
GncOwnerType type = GNC_OWNER_NONE;
|
||||
|
||||
if (!lot || !owner) return FALSE;
|
||||
|
||||
book = gnc_lot_get_book (lot);
|
||||
kvp = gnc_lot_get_slots (lot);
|
||||
|
||||
value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_TYPE, NULL);
|
||||
if (!value) return FALSE;
|
||||
|
||||
type = kvp_value_get_gint64 (value);
|
||||
|
||||
value = kvp_frame_get_slot_path (kvp, GNC_OWNER_ID, GNC_OWNER_GUID, NULL);
|
||||
if (!value) return FALSE;
|
||||
|
||||
guid = kvp_value_get_guid (value);
|
||||
if (!guid)
|
||||
return FALSE;
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (lot),
|
||||
"owner-type", &type,
|
||||
"owner-guid", &guid,
|
||||
NULL);
|
||||
switch (type)
|
||||
{
|
||||
case GNC_OWNER_CUSTOMER:
|
||||
@ -640,23 +648,6 @@ gboolean gncOwnerIsValid (const GncOwner *owner)
|
||||
return (owner->owner.undefined != NULL);
|
||||
}
|
||||
|
||||
KvpFrame* gncOwnerGetSlots(GncOwner* owner)
|
||||
{
|
||||
if (!owner) return NULL;
|
||||
|
||||
switch (gncOwnerGetType(owner))
|
||||
{
|
||||
case GNC_OWNER_CUSTOMER:
|
||||
case GNC_OWNER_VENDOR:
|
||||
case GNC_OWNER_EMPLOYEE:
|
||||
return qof_instance_get_slots(QOF_INSTANCE(owner->owner.undefined));
|
||||
case GNC_OWNER_JOB:
|
||||
return gncOwnerGetSlots(gncJobGetOwner(gncOwnerGetJob(owner)));
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gncOwnerLotMatchOwnerFunc (GNCLot *lot, gpointer user_data)
|
||||
{
|
||||
|
@ -197,9 +197,6 @@ gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner);
|
||||
|
||||
gboolean gncOwnerGetOwnerFromTypeGuid (QofBook *book, GncOwner *owner, QofIdType type, GncGUID *guid);
|
||||
|
||||
/** Get the kvp-frame from the underlying owner object */
|
||||
KvpFrame* gncOwnerGetSlots(GncOwner* owner);
|
||||
|
||||
/**
|
||||
* Create a lot for a payment to the owner using the other
|
||||
* parameters passed in. If a transaction is set, this transaction will be
|
||||
@ -307,6 +304,7 @@ void gncOwnerFree (GncOwner *owner);
|
||||
* without knowing its type.
|
||||
*/
|
||||
void gncOwnerBeginEdit (GncOwner *owner);
|
||||
void gncOwnerCommitEdit (GncOwner *owner);
|
||||
void gncOwnerDestroy (GncOwner *owner);
|
||||
|
||||
#endif /* GNC_OWNER_H_ */
|
||||
|
@ -26,9 +26,10 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-features.h"
|
||||
#include "gncTaxTableP.h"
|
||||
@ -208,9 +209,10 @@ gncTaxTableRemoveChild (GncTaxTable *table, const GncTaxTable *child)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_INVISIBLE,
|
||||
PROP_REFCOUNT
|
||||
PROP_NAME, /* Table */
|
||||
PROP_INVISIBLE, /* Table */
|
||||
PROP_REFCOUNT, /* Table */
|
||||
// PROP_PARENT, /* Table */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -272,6 +274,8 @@ gnc_taxtable_set_property (GObject *object,
|
||||
g_return_if_fail(GNC_IS_TAXTABLE(object));
|
||||
|
||||
tt = GNC_TAXTABLE(object);
|
||||
g_assert (qof_instance_get_editlevel(tt));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
|
@ -26,10 +26,11 @@
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gnc-commodity.h"
|
||||
#include "gncAddressP.h"
|
||||
@ -88,17 +89,20 @@ void mark_vendor (GncVendor *vendor)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_ID,
|
||||
PROP_NOTES,
|
||||
PROP_CURRENCY,
|
||||
PROP_ACTIVE,
|
||||
PROP_TAXTABLE_OVERRIDE,
|
||||
PROP_BILLTERMS,
|
||||
PROP_TAXTABLE,
|
||||
PROP_ADDRESS,
|
||||
PROP_TAX_INCLUDED,
|
||||
PROP_TAX_INCLUDED_STR
|
||||
PROP_NAME, /* Table */
|
||||
PROP_ID, /* Table */
|
||||
PROP_NOTES, /* Table */
|
||||
PROP_CURRENCY, /* Table */
|
||||
PROP_ACTIVE, /* Table */
|
||||
PROP_TAXTABLE_OVERRIDE, /* Table */
|
||||
PROP_BILLTERMS, /* Table */
|
||||
PROP_TAXTABLE, /* Table */
|
||||
PROP_ADDRESS, /* Table, 8 fields */
|
||||
PROP_TAX_INCLUDED, /* Table */
|
||||
PROP_TAX_INCLUDED_STR, /* Alternate setter for PROP_TAX_INCLUDED */
|
||||
PROP_PDF_DIRNAME, /* KVP */
|
||||
PROP_LAST_POSTED, /* KVP */
|
||||
PROP_PAYMENT_LAST_ACCT, /* KVP */
|
||||
};
|
||||
|
||||
/* GObject Initialization */
|
||||
@ -134,6 +138,7 @@ gnc_vendor_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncVendor *vendor;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_VENDOR(object));
|
||||
|
||||
@ -173,6 +178,18 @@ gnc_vendor_get_property (GObject *object,
|
||||
case PROP_TAX_INCLUDED_STR:
|
||||
g_value_set_string(value, qofVendorGetTaxIncluded(vendor));
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_get_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -186,10 +203,13 @@ gnc_vendor_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GncVendor *vendor;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail(GNC_IS_VENDOR(object));
|
||||
|
||||
vendor = GNC_VENDOR(object);
|
||||
g_assert (qof_instance_get_editlevel(vendor));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
@ -225,6 +245,18 @@ gnc_vendor_set_property (GObject *object,
|
||||
case PROP_TAX_INCLUDED_STR:
|
||||
qofVendorSetTaxIncluded(vendor, g_value_get_string(value));
|
||||
break;
|
||||
case PROP_PDF_DIRNAME:
|
||||
key = OWNER_EXPORT_PDF_DIRNAME;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
case PROP_LAST_POSTED:
|
||||
key = LAST_POSTED_TO_ACCT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
case PROP_PAYMENT_LAST_ACCT:
|
||||
key = GNC_PAYMENT "/" GNC_LAST_ACCOUNT;
|
||||
qof_instance_set_kvp (QOF_INSTANCE (vendor), key, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
@ -390,6 +422,38 @@ gnc_vendor_class_init (GncVendorClass *klass)
|
||||
"The tax-included-string property contains a character version of tax-included.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PDF_DIRNAME,
|
||||
g_param_spec_string ("export-pdf-dir",
|
||||
"Export PDF Directory Name",
|
||||
"A subdirectory for exporting PDF reports which is "
|
||||
"appended to the target directory when writing them "
|
||||
"out. It is retrieved from preferences and stored on "
|
||||
"each 'Owner' object which prints items after "
|
||||
"printing.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_LAST_POSTED,
|
||||
g_param_spec_boxed("invoice-last-posted-account",
|
||||
"Invoice Last Posted Account",
|
||||
"The last account to which an invoice belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(
|
||||
gobject_class,
|
||||
PROP_PAYMENT_LAST_ACCT,
|
||||
g_param_spec_boxed("payment-last-account",
|
||||
"Payment Last Account",
|
||||
"The last account to which an payment belonging to "
|
||||
"this owner was posted.",
|
||||
GNC_TYPE_GUID,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* Create/Destroy Functions */
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "AccountP.h"
|
||||
@ -1339,7 +1340,7 @@ get_random_split(QofBook *book, Account *acct, Transaction *trn)
|
||||
else
|
||||
g_assert(!gnc_numeric_positive_p(amt)); /* non-positive amt */
|
||||
|
||||
xaccSplitSetSlots_nc(ret, get_random_kvp_frame());
|
||||
qof_instance_set_slots(QOF_INSTANCE (ret), get_random_kvp_frame());
|
||||
xaccTransCommitEdit(trn);
|
||||
|
||||
return ret;
|
||||
@ -1366,7 +1367,7 @@ make_random_changes_to_split (Split *split)
|
||||
xaccSplitSetDateReconciledTS (split, ts);
|
||||
g_free(ts);
|
||||
|
||||
xaccSplitSetSlots_nc (split, get_random_kvp_frame());
|
||||
qof_instance_set_slots (QOF_INSTANCE (split), get_random_kvp_frame());
|
||||
|
||||
/* Don't change share values/prices here, since that would
|
||||
* throw transactions out of balance. Do that in the corresponding
|
||||
@ -2169,13 +2170,13 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
|
||||
}
|
||||
|
||||
if (query_types & SPLIT_KVP_QT)
|
||||
add_kvp_query (q, xaccSplitGetSlots (s), GNC_ID_SPLIT);
|
||||
add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (s)), GNC_ID_SPLIT);
|
||||
|
||||
if (query_types & TRANS_KVP_QT)
|
||||
add_kvp_query (q, xaccTransGetSlots (trans), GNC_ID_TRANS);
|
||||
add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (trans)), GNC_ID_TRANS);
|
||||
|
||||
if (query_types & ACCOUNT_KVP_QT)
|
||||
add_kvp_query (q, xaccAccountGetSlots (a), GNC_ID_ACCOUNT);
|
||||
add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (a)), GNC_ID_ACCOUNT);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ test_engine_SOURCES = \
|
||||
utest-Account.c \
|
||||
utest-Budget.c \
|
||||
utest-Invoice.c \
|
||||
test-engine-kvp-properties.c \
|
||||
dummy.cpp
|
||||
|
||||
test_engine_LDADD = \
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "cashobjects.h"
|
||||
#include "test-stuff.h"
|
||||
#include "test-engine-stuff.h"
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
@ -61,7 +62,9 @@ run_test (void)
|
||||
/*****/
|
||||
|
||||
five = gnc_numeric_create(5, 1);
|
||||
qof_instance_increase_editlevel (acc);
|
||||
g_object_set(acc, "start-balance", &five, NULL);
|
||||
qof_instance_decrease_editlevel (acc);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
|
@ -24,9 +24,11 @@
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
#include <qof.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "cashobjects.h"
|
||||
#include "gncCustomerP.h"
|
||||
#include "gncInvoiceP.h"
|
||||
|
@ -24,9 +24,11 @@
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
#include <qof.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncEmployeeP.h"
|
||||
#include "gncCustomerP.h"
|
||||
#include "gncJobP.h"
|
||||
|
458
src/engine/test/test-engine-kvp-properties.c
Normal file
458
src/engine/test/test-engine-kvp-properties.c
Normal file
@ -0,0 +1,458 @@
|
||||
/********************************************************************
|
||||
* test-engine-kvp-properties.c: GLib g_test test suite for *
|
||||
* KVP-based properties in several engine classes. *
|
||||
* Copyright 2013 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
|
||||
/**
|
||||
* Test Engine KVP Properties Acceptance testing for KVP Properties
|
||||
* added to various engine classes to make private the internals of
|
||||
* KVP storage used for a variety of parameters on several engine
|
||||
* classes.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <qof.h>
|
||||
#include <unittest-support.h>
|
||||
#include "../Transaction.h"
|
||||
#include "../Split.h"
|
||||
#include "../Account.h"
|
||||
#include "../SchedXAction.h"
|
||||
#include "../gncCustomer.h"
|
||||
#include "../gncEmployee.h"
|
||||
#include "../gncJob.h"
|
||||
#include "../gncVendor.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
Account *acct;
|
||||
Transaction *trans;
|
||||
Split *split;
|
||||
GNCLot *lot;
|
||||
GncCustomer *cust;
|
||||
GncEmployee *emp;
|
||||
GncJob *job;
|
||||
GncVendor *vend;
|
||||
};
|
||||
GSList *hdlrs;
|
||||
} Fixture;
|
||||
|
||||
/* Prototype to shut clang up */
|
||||
void test_suite_engine_kvp_properties (void);
|
||||
|
||||
/* Private QofInstance functions needed for testing */
|
||||
extern void qof_instance_mark_clean (QofInstance*);
|
||||
|
||||
const gchar *suitename = "/engine/kvp-properties";
|
||||
|
||||
static void
|
||||
setup_account (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->acct = xaccMallocAccount (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_trans (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->trans = xaccMallocTransaction (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_split (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->split = xaccMallocSplit (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_lot (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->lot = gnc_lot_new (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_customer (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->cust = gncCustomerCreate (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_employee (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->emp = gncEmployeeCreate (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_job (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->job = gncJobCreate (book);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_vendor (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
fixture->vend = gncVendorCreate (book);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
/* It doesn't actually matter which union member we use here, they're
|
||||
* all QofInstances, so this will work for any of them.
|
||||
*/
|
||||
QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->acct));
|
||||
test_destroy (fixture->acct);
|
||||
test_destroy (book);
|
||||
}
|
||||
|
||||
static void
|
||||
test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gint64 next_id = 12345678909876;
|
||||
gint64 ab_acct_uid = 67890987654321;
|
||||
gint64 next_id_r, ab_acct_uid_r;
|
||||
gchar *online_id = "my online id";
|
||||
gchar *ab_acct_id = "1234-5678-9087";
|
||||
gchar *ab_bank_code = "0032340";
|
||||
gchar *online_id_r, *ab_acct_id_r, *ab_bank_code_r;
|
||||
GncGUID *ofx_income_acct = guid_malloc ();
|
||||
GncGUID *ofx_income_acct_r;
|
||||
Timespec trans_retr = timespec_now ();
|
||||
Timespec *trans_retr_r;
|
||||
|
||||
xaccAccountBeginEdit (fixture->acct);
|
||||
qof_instance_set (QOF_INSTANCE (fixture->acct),
|
||||
"lot-next-id", next_id,
|
||||
"online-id", online_id,
|
||||
"ofx-income-account", ofx_income_acct,
|
||||
"ab-account-id", ab_acct_id,
|
||||
"ab-bank-code", ab_bank_code,
|
||||
"ab-account-uid", ab_acct_uid,
|
||||
"ab-trans-retrieval", &trans_retr,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->acct));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->acct),
|
||||
"lot-next-id", &next_id_r,
|
||||
"online-id", &online_id_r,
|
||||
"ofx-income-account", &ofx_income_acct_r,
|
||||
"ab-account-id", &ab_acct_id_r,
|
||||
"ab-bank-code", &ab_bank_code_r,
|
||||
"ab-account-uid", &ab_acct_uid_r,
|
||||
"ab-trans-retrieval", &trans_retr_r,
|
||||
NULL);
|
||||
g_assert_cmpint (next_id, ==, next_id_r);
|
||||
g_assert_cmpstr (online_id, ==, online_id_r);
|
||||
g_assert (guid_equal (ofx_income_acct, ofx_income_acct_r));
|
||||
g_assert_cmpstr (ab_acct_id, ==, ab_acct_id_r);
|
||||
g_assert_cmpstr (ab_bank_code, ==, ab_bank_code_r);
|
||||
g_assert_cmpint (ab_acct_uid, ==, ab_acct_uid_r);
|
||||
g_assert (timespec_equal (&trans_retr, trans_retr_r));
|
||||
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
|
||||
}
|
||||
|
||||
static void
|
||||
test_trans_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GncGUID *invoice = guid_malloc ();
|
||||
GncGUID *from_sx = guid_malloc ();
|
||||
GncGUID *invoice_r, *from_sx_r;
|
||||
gchar *online_id = "my online id";
|
||||
gchar *online_id_r;
|
||||
|
||||
xaccTransBeginEdit (fixture->trans);
|
||||
qof_instance_set (QOF_INSTANCE (fixture->trans),
|
||||
"invoice", invoice,
|
||||
"from-sched-xaction", from_sx,
|
||||
"online-id", online_id,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->trans));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->trans),
|
||||
"invoice", &invoice_r,
|
||||
"from-sched-xaction", &from_sx_r,
|
||||
"online-id", &online_id_r,
|
||||
NULL);
|
||||
g_assert (guid_equal (invoice, invoice_r));
|
||||
g_assert (guid_equal (from_sx, from_sx_r));
|
||||
g_assert_cmpstr (online_id, ==, online_id_r);
|
||||
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
|
||||
guid_free (invoice);
|
||||
guid_free (invoice_r);
|
||||
guid_free (from_sx);
|
||||
guid_free (from_sx_r);
|
||||
g_free (online_id_r);
|
||||
}
|
||||
|
||||
static void
|
||||
test_split_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gchar *debit_formula = "e^xdydx";
|
||||
gchar *credit_formula = "seccostansin";
|
||||
gchar *sx_shares = "43";
|
||||
gchar *online_id = "my_online_id";
|
||||
gchar *debit_formula_r, *credit_formula_r, *sx_shares_r;
|
||||
gchar *online_id_r;
|
||||
GncGUID *sx_account = guid_malloc ();
|
||||
GncGUID *sx_account_r;
|
||||
gnc_numeric debit_numeric = gnc_numeric_create (123, 456);
|
||||
gnc_numeric credit_numeric = gnc_numeric_create (789, 456);
|
||||
gnc_numeric *debit_numeric_r, *credit_numeric_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->split));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->split),
|
||||
"sx-debit-formula", debit_formula,
|
||||
"sx-debit-numeric", &debit_numeric,
|
||||
"sx-credit-formula", credit_formula,
|
||||
"sx-credit-numeric", &credit_numeric,
|
||||
"sx-account", sx_account,
|
||||
"sx-shares", sx_shares,
|
||||
"online-id", online_id,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->split));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->split),
|
||||
"sx-debit-formula", &debit_formula_r,
|
||||
"sx-debit-numeric", &debit_numeric_r,
|
||||
"sx-credit-formula", &credit_formula_r,
|
||||
"sx-credit-numeric", &credit_numeric_r,
|
||||
"sx-account", &sx_account_r,
|
||||
"sx-shares", &sx_shares_r,
|
||||
"online-id", &online_id_r,
|
||||
NULL);
|
||||
g_assert_cmpstr (debit_formula, ==, debit_formula_r);
|
||||
g_assert (gnc_numeric_equal (debit_numeric, *debit_numeric_r));
|
||||
g_assert_cmpstr (credit_formula, ==, credit_formula_r);
|
||||
g_assert (gnc_numeric_equal (credit_numeric, *credit_numeric_r));
|
||||
g_assert (guid_equal (sx_account, sx_account_r));
|
||||
g_assert_cmpstr (sx_shares, ==, sx_shares_r);
|
||||
g_assert_cmpstr (online_id, ==, online_id_r);
|
||||
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
|
||||
g_free (debit_formula_r);
|
||||
g_free (debit_numeric_r);
|
||||
g_free (credit_formula_r);
|
||||
g_free (credit_numeric_r);
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->split));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->split),
|
||||
"sx-credit-formula", NULL,
|
||||
NULL);
|
||||
qof_instance_get (QOF_INSTANCE (fixture->split),
|
||||
"sx-credit-formula", &credit_numeric_r,
|
||||
NULL);
|
||||
g_assert (credit_numeric_r == NULL);
|
||||
g_free (sx_shares_r);
|
||||
g_free (online_id_r);
|
||||
guid_free (sx_account);
|
||||
guid_free (sx_account_r);
|
||||
}
|
||||
|
||||
static void
|
||||
test_lot_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GncGUID *invoice = guid_malloc ();
|
||||
GncGUID *invoice_r;
|
||||
gint64 owner_type = 47;
|
||||
gint64 owner_type_r;
|
||||
GncGUID *owner = guid_malloc ();
|
||||
GncGUID *owner_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->lot));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->lot),
|
||||
"invoice", invoice,
|
||||
"owner-type", owner_type,
|
||||
"owner-guid", owner,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->lot));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->lot),
|
||||
"invoice", &invoice_r,
|
||||
"owner-type", &owner_type_r,
|
||||
"owner-guid", &owner_r,
|
||||
NULL);
|
||||
g_assert (guid_equal (invoice, invoice_r));
|
||||
g_assert_cmpint (owner_type, ==, owner_type_r);
|
||||
g_assert (guid_equal (owner, owner_r));
|
||||
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
|
||||
guid_free (invoice);
|
||||
guid_free (invoice_r);
|
||||
guid_free (owner);
|
||||
guid_free (owner_r);
|
||||
}
|
||||
|
||||
static void
|
||||
test_customer_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gchar *pdf_dir = "/foo/bar/baz";
|
||||
gchar *pdf_dir_r;
|
||||
GncGUID *inv_acct = guid_malloc ();
|
||||
GncGUID *pmt_acct = guid_malloc ();
|
||||
GncGUID *inv_acct_r, *pmt_acct_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->cust));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->cust),
|
||||
"export-pdf-dir", pdf_dir,
|
||||
"invoice-last-posted-account", inv_acct,
|
||||
"payment-last-account", pmt_acct,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->cust)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->cust));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->cust),
|
||||
"export-pdf-dir", &pdf_dir_r,
|
||||
"invoice-last-posted-account", &inv_acct_r,
|
||||
"payment-last-account", &pmt_acct_r,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
|
||||
g_assert (guid_equal (inv_acct, inv_acct_r));
|
||||
g_assert (guid_equal (pmt_acct, pmt_acct_r));
|
||||
guid_free (inv_acct);
|
||||
guid_free (inv_acct_r);
|
||||
guid_free (pmt_acct);
|
||||
guid_free (pmt_acct_r);
|
||||
g_free (pdf_dir_r);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_employee_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gchar *pdf_dir = "/foo/bar/baz";
|
||||
gchar *pdf_dir_r;
|
||||
GncGUID *inv_acct = guid_malloc ();
|
||||
GncGUID *pmt_acct = guid_malloc ();
|
||||
GncGUID *inv_acct_r, *pmt_acct_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->emp));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->emp),
|
||||
"export-pdf-dir", pdf_dir,
|
||||
"invoice-last-posted-account", inv_acct,
|
||||
"payment-last-account", pmt_acct,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->emp)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->emp));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->emp),
|
||||
"export-pdf-dir", &pdf_dir_r,
|
||||
"invoice-last-posted-account", &inv_acct_r,
|
||||
"payment-last-account", &pmt_acct_r,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
|
||||
g_assert (guid_equal (inv_acct, inv_acct_r));
|
||||
g_assert (guid_equal (pmt_acct, pmt_acct_r));
|
||||
guid_free (inv_acct);
|
||||
guid_free (inv_acct_r);
|
||||
guid_free (pmt_acct);
|
||||
guid_free (pmt_acct_r);
|
||||
g_free (pdf_dir_r);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_job_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gchar *pdf_dir = "/foo/bar/baz";
|
||||
gchar *pdf_dir_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->job));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->job),
|
||||
"export-pdf-dir", pdf_dir,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->job)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->job));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->job),
|
||||
"export-pdf-dir", &pdf_dir_r,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
|
||||
g_free (pdf_dir_r);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gchar *pdf_dir = "/foo/bar/baz";
|
||||
gchar *pdf_dir_r;
|
||||
GncGUID *inv_acct = guid_malloc ();
|
||||
GncGUID *pmt_acct = guid_malloc ();
|
||||
GncGUID *inv_acct_r, *pmt_acct_r;
|
||||
|
||||
qof_begin_edit (QOF_INSTANCE (fixture->vend));
|
||||
qof_instance_set (QOF_INSTANCE (fixture->vend),
|
||||
"export-pdf-dir", pdf_dir,
|
||||
"invoice-last-posted-account", inv_acct,
|
||||
"payment-last-account", pmt_acct,
|
||||
NULL);
|
||||
|
||||
g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->vend)));
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->vend));
|
||||
|
||||
qof_instance_get (QOF_INSTANCE (fixture->vend),
|
||||
"export-pdf-dir", &pdf_dir_r,
|
||||
"invoice-last-posted-account", &inv_acct_r,
|
||||
"payment-last-account", &pmt_acct_r,
|
||||
NULL);
|
||||
|
||||
g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
|
||||
g_assert (guid_equal (inv_acct, inv_acct_r));
|
||||
g_assert (guid_equal (pmt_acct, pmt_acct_r));
|
||||
guid_free (inv_acct);
|
||||
guid_free (inv_acct_r);
|
||||
guid_free (pmt_acct);
|
||||
guid_free (pmt_acct_r);
|
||||
g_free (pdf_dir_r);
|
||||
|
||||
}
|
||||
|
||||
void test_suite_engine_kvp_properties (void)
|
||||
{
|
||||
GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Job", Fixture, NULL, setup_job, test_job_kvp_properties, teardown);
|
||||
GNC_TEST_ADD (suitename, "Vendor", Fixture, NULL, setup_vendor, test_vendor_kvp_properties, teardown);
|
||||
}
|
@ -31,6 +31,7 @@ extern void test_suite_budget();
|
||||
extern void test_suite_gncInvoice();
|
||||
extern void test_suite_transaction();
|
||||
extern void test_suite_split();
|
||||
extern void test_suite_engine_kvp_properties (void);
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
@ -49,6 +50,7 @@ main (int argc,
|
||||
test_suite_gncInvoice();
|
||||
test_suite_transaction();
|
||||
test_suite_split();
|
||||
test_suite_engine_kvp_properties ();
|
||||
|
||||
return g_test_run( );
|
||||
}
|
||||
|
@ -24,9 +24,11 @@
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
#include <qof.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncJobP.h"
|
||||
#include "gncInvoiceP.h"
|
||||
#include "gncCustomerP.h"
|
||||
|
@ -24,8 +24,10 @@
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#include "gncInvoiceP.h"
|
||||
#include "gncCustomerP.h"
|
||||
#include "gncJobP.h"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <unittest-support.h>
|
||||
#include <gnc-event.h>
|
||||
#include <gnc-gdate-utils.h>
|
||||
#include <qofinstance-p.h>
|
||||
/* Add specific headers for this class */
|
||||
#include "../Account.h"
|
||||
#include "../AccountP.h"
|
||||
@ -444,11 +445,11 @@ test_gnc_account_name_violations_errmsg ()
|
||||
message = gnc_account_name_violations_errmsg (separator, nonames);
|
||||
g_assert (message == NULL);
|
||||
validation_message = g_strdup_printf (
|
||||
"The separator character \"%s\" is used in one or more account "
|
||||
"names.\n\nThis will result in unexpected behaviour. "
|
||||
"Either change the account names or choose another separator "
|
||||
"character.\n\nBelow you will find the list of invalid account names:\n"
|
||||
"%s", separator, account_list);
|
||||
"The separator character \"%s\" is used in one or more account "
|
||||
"names.\n\nThis will result in unexpected behaviour. "
|
||||
"Either change the account names or choose another separator "
|
||||
"character.\n\nBelow you will find the list of invalid account names:\n"
|
||||
"%s", separator, account_list);
|
||||
message = gnc_account_name_violations_errmsg (separator, badnames);
|
||||
g_assert_cmpstr ( message, == , validation_message);
|
||||
g_free (validation_message);
|
||||
@ -1356,6 +1357,8 @@ test_xaccAccountOrder ( )
|
||||
g_assert (xaccAccountOrder (ab, aa) == 1);
|
||||
|
||||
ab = xaccMallocAccount (book);
|
||||
qof_instance_increase_editlevel (aa);
|
||||
qof_instance_increase_editlevel (ab);
|
||||
g_object_set (G_OBJECT (aa),
|
||||
"code", "3333",
|
||||
"type", ACCT_TYPE_ASSET,
|
||||
@ -1398,6 +1401,8 @@ test_xaccAccountOrder ( )
|
||||
"name", "bar",
|
||||
NULL);
|
||||
g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
|
||||
qof_instance_decrease_editlevel (aa);
|
||||
qof_instance_decrease_editlevel (ab);
|
||||
|
||||
xaccAccountBeginEdit (aa);
|
||||
xaccAccountDestroy (aa);
|
||||
@ -2157,7 +2162,9 @@ test_xaccAccountType_Stuff (void)
|
||||
g_assert_cmpstr (typestr_uc, == , typename);
|
||||
g_free (typestr_uc);
|
||||
|
||||
qof_instance_increase_editlevel (acc);
|
||||
g_object_set (acc, "type", type, NULL);
|
||||
qof_instance_decrease_editlevel (acc);
|
||||
if (type == ACCT_TYPE_STOCK || type == ACCT_TYPE_MUTUAL ||
|
||||
type == ACCT_TYPE_CURRENCY)
|
||||
g_assert (xaccAccountIsPriced (acc));
|
||||
@ -2401,11 +2408,13 @@ test_gnc_account_merge_children (Fixture *fixture, gconstpointer pData)
|
||||
*/
|
||||
sig4 = test_signal_new (QOF_INSTANCE (div), QOF_EVENT_MODIFY, NULL);
|
||||
sig5 = test_signal_new (QOF_INSTANCE (div1), QOF_EVENT_MODIFY, NULL);
|
||||
qof_instance_increase_editlevel (div1);
|
||||
g_object_set (div1, "name", "div", NULL);
|
||||
qof_instance_decrease_editlevel (div1);
|
||||
gnc_account_merge_children (taxable);
|
||||
g_assert_cmpint (gnc_account_n_descendants (taxable), == , taxable_desc - 1);
|
||||
test_signal_assert_hits (sig4, 1);
|
||||
test_signal_assert_hits (sig5, 4);
|
||||
test_signal_assert_hits (sig5, 3);
|
||||
test_signal_free (sig4);
|
||||
test_signal_free (sig5);
|
||||
gnc_account_merge_children (expense);
|
||||
|
@ -38,7 +38,7 @@ extern "C"
|
||||
#include <TransactionP.h>
|
||||
#include <gnc-lot.h>
|
||||
#include <gnc-event.h>
|
||||
#include <qofbookslots.h>
|
||||
#include <qofinstance-p.h>
|
||||
|
||||
#ifdef HAVE_GLIB_2_38
|
||||
#define _Q "'"
|
||||
@ -318,15 +318,15 @@ test_xaccDupeSplit (Fixture *fixture, gconstpointer pData)
|
||||
g_assert (split->gains_split != f_split->gains_split);
|
||||
|
||||
}
|
||||
/* xaccSplitClone
|
||||
/* xaccSplitCloneNoKvp
|
||||
Split *
|
||||
xaccSplitClone (const Split *s)// C: 1
|
||||
xaccSplitCloneNoKvp (const Split *s)// C: 1
|
||||
*/
|
||||
static void
|
||||
test_xaccSplitClone (Fixture *fixture, gconstpointer pData)
|
||||
test_xaccSplitCloneNoKvp (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Split *f_split = fixture->split;
|
||||
Split *split = xaccSplitClone (f_split);
|
||||
Split *split = xaccSplitCloneNoKvp (f_split);
|
||||
|
||||
g_assert (split != fixture->split);
|
||||
g_assert (qof_instance_get_guid (split) != qof_instance_get_guid (f_split));
|
||||
@ -339,7 +339,7 @@ test_xaccSplitClone (Fixture *fixture, gconstpointer pData)
|
||||
g_assert (split->lot == f_split->lot);
|
||||
g_assert_cmpstr (split->memo, ==, f_split->memo);
|
||||
g_assert_cmpstr (split->action, ==, f_split->action);
|
||||
g_assert (kvp_frame_compare (split->inst.kvp_data, f_split->inst.kvp_data) == 0);
|
||||
g_assert (kvp_frame_is_empty (split->inst.kvp_data));
|
||||
g_assert_cmpint (split->reconciled, ==, f_split->reconciled);
|
||||
g_assert (timespec_equal (&(split->date_reconciled), &(f_split->date_reconciled)));
|
||||
g_assert (gnc_numeric_equal (split->value, f_split->value));
|
||||
@ -417,7 +417,7 @@ xaccSplitEqual(const Split *sa, const Split *sb,// C: 2 in 2 SCM: 1
|
||||
static void
|
||||
test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Split *split1 = xaccSplitClone (fixture->split);
|
||||
Split *split1 = xaccSplitCloneNoKvp (fixture->split);
|
||||
Split *split2 = xaccDupeSplit (fixture->split);
|
||||
gchar *msg01 = "[xaccSplitEqual] one is NULL";
|
||||
gchar *msg02 = "[xaccSplitEqual] GUIDs differ";
|
||||
@ -468,9 +468,11 @@ test_xaccSplitEqual (Fixture *fixture, gconstpointer pData)
|
||||
split1->parent = fixture->split->parent;
|
||||
g_assert (xaccSplitEqual (fixture->split, split1, FALSE, TRUE, TRUE) == TRUE);
|
||||
/* Now set the GUIDs equal and see that the comparison passes */
|
||||
qof_instance_increase_editlevel (split1->parent);
|
||||
g_object_set (G_OBJECT (split1),
|
||||
"guid", qof_instance_get_guid (QOF_INSTANCE(fixture->split)),
|
||||
NULL);
|
||||
qof_instance_increase_editlevel (split1->parent);
|
||||
g_assert (xaccSplitEqual (fixture->split, split1, TRUE, TRUE, TRUE) == TRUE);
|
||||
g_assert_cmpint (checkA.hits, ==, 3);
|
||||
g_assert_cmpint (checkB.hits, ==, 1);
|
||||
@ -607,10 +609,12 @@ test_xaccSplitCommitEdit (Fixture *fixture, gconstpointer pData)
|
||||
g_assert_cmpint (checkB.hits, ==, 2);
|
||||
|
||||
qof_instance_mark_clean (QOF_INSTANCE (fixture->split->parent));
|
||||
qof_instance_increase_editlevel (fixture->split->acc);
|
||||
g_object_set (fixture->split->acc,
|
||||
"sort-dirty", FALSE,
|
||||
"balance-dirty", FALSE,
|
||||
NULL);
|
||||
qof_instance_decrease_editlevel (fixture->split->acc);
|
||||
|
||||
qof_instance_set_dirty (QOF_INSTANCE (fixture->split));
|
||||
xaccSplitCommitEdit (fixture->split);
|
||||
@ -780,16 +784,6 @@ test_get_commodity_denom (Fixture *fixture, gconstpointer pData)
|
||||
fixture->split->acc = acc;
|
||||
g_assert_cmpint (fixture->func->get_commodity_denom (fixture->split), ==, denom);
|
||||
}
|
||||
/* xaccSplitGetSlots
|
||||
KvpFrame *
|
||||
xaccSplitGetSlots (const Split * s)// C: 17 in 8
|
||||
Simple passthrough, no test.
|
||||
*/
|
||||
// Not Used
|
||||
/* xaccSplitSetSlots_nc
|
||||
void
|
||||
xaccSplitSetSlots_nc(Split *s, KvpFrame *frm)//
|
||||
*/
|
||||
/* xaccSplitSetSharePriceAndAmount
|
||||
void
|
||||
xaccSplitSetSharePriceAndAmount (Split *s, gnc_numeric price, gnc_numeric amt)// C: 1
|
||||
@ -1115,8 +1109,9 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
const char *slot_path;
|
||||
Split *split = fixture->split;
|
||||
Split *o_split = xaccMallocSplit (xaccSplitGetBook (split));
|
||||
Transaction *o_txn = xaccMallocTransaction (xaccSplitGetBook (split));
|
||||
QofBook *book = xaccSplitGetBook (split);
|
||||
Split *o_split = xaccMallocSplit (book);
|
||||
Transaction *o_txn = xaccMallocTransaction (book);
|
||||
Transaction *txn = split->parent;
|
||||
|
||||
g_assert_cmpint (xaccSplitOrder (split, split), ==, 0);
|
||||
@ -1155,11 +1150,12 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
|
||||
*/
|
||||
|
||||
/* create correct slot path */
|
||||
slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/",
|
||||
OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_NUM_FIELD_SOURCE, NULL );
|
||||
g_assert( slot_path != NULL );
|
||||
g_test_message( "Testing with use-split-action-for-num set to true - t" );
|
||||
qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "t" );
|
||||
qof_book_begin_edit (book);
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"split-action-num-field", "t",
|
||||
NULL);
|
||||
qof_book_commit_edit (book);
|
||||
g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == TRUE);
|
||||
|
||||
g_assert_cmpint (xaccSplitOrder (split, o_split), ==, -1);
|
||||
@ -1171,7 +1167,11 @@ test_xaccSplitOrder (Fixture *fixture, gconstpointer pData)
|
||||
o_split->action = NULL;
|
||||
split->action = "foo";
|
||||
o_split->parent = NULL;
|
||||
qof_book_set_string_option( xaccSplitGetBook (split), slot_path, "f" );
|
||||
qof_book_begin_edit (book);
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"split-action-num-field", "f",
|
||||
NULL);
|
||||
qof_book_commit_edit (book);
|
||||
g_assert(qof_book_use_split_action_for_num_field(xaccSplitGetBook(split)) == FALSE);
|
||||
split->parent = NULL;
|
||||
/* This should return > 0 because o_split has no memo string */
|
||||
@ -1772,7 +1772,6 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
|
||||
Split *split2 = xaccMallocSplit (book);
|
||||
Account *acc2 = xaccMallocAccount (book);
|
||||
KvpValue *kvptrue = kvp_value_new_string ("t");
|
||||
KvpFrame *book_slots = qof_book_get_slots (book);
|
||||
|
||||
g_assert (xaccSplitGetOtherSplit (NULL) == NULL);
|
||||
g_assert (xaccSplitGetOtherSplit (split1) == NULL);
|
||||
@ -1801,9 +1800,11 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
|
||||
g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split") == NULL);
|
||||
kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", NULL);
|
||||
g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split") == NULL);
|
||||
kvp_frame_set_slot_path (book_slots, kvptrue, KVP_OPTION_PATH,
|
||||
OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_TRADING_ACCOUNTS, NULL);
|
||||
qof_book_begin_edit (book);
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"trading-accts", "t",
|
||||
NULL);
|
||||
qof_book_commit_edit (book);
|
||||
g_assert (xaccTransUseTradingAccounts (txn));
|
||||
g_assert (xaccSplitGetOtherSplit (split) == NULL);
|
||||
split2->acc = acc2;
|
||||
@ -1882,7 +1883,7 @@ test_suite_split (void)
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc split set & get property", test_gnc_split_set_get_property);
|
||||
GNC_TEST_ADD (suitename, "xaccMallocSplit", Fixture, NULL, setup, test_xaccMallocSplit, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccDupeSplit", Fixture, NULL, setup, test_xaccDupeSplit, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccSplitClone", Fixture, NULL, setup, test_xaccSplitClone, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccSplitCloneNoKvp", Fixture, NULL, setup, test_xaccSplitCloneNoKvp, teardown);
|
||||
GNC_TEST_ADD (suitename, "mark split", Fixture, NULL, setup, test_mark_split, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccSplitEqualCheckBal", Fixture, NULL, setup, test_xaccSplitEqualCheckBal, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccSplitEqual", Fixture, NULL, setup, test_xaccSplitEqual, teardown);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/********************************************************************
|
||||
* utest-Transaction.c: GLib g_test test suite for Transaction.c. *
|
||||
* utest-Transaction.c: GLib g_test test suite for Transaction.c. *
|
||||
* Copyright 2012 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
@ -33,7 +33,6 @@
|
||||
#include "../gnc-lot.h"
|
||||
#include "../gnc-event.h"
|
||||
#include <qof.h>
|
||||
#include <qofbookslots.h>
|
||||
#include <qofbackend-p.h>
|
||||
|
||||
#ifdef HAVE_GLIB_2_38
|
||||
@ -569,12 +568,12 @@ test_xaccTransSortSplits (Fixture *fixture, gconstpointer pData)
|
||||
|
||||
xaccTransCommitEdit (txn);
|
||||
}
|
||||
/* xaccDupeTransaction
|
||||
Transaction *
|
||||
xaccDupeTransaction (const Transaction *from)// Local: 1:0:0
|
||||
/* dupe_trans
|
||||
static Transaction *
|
||||
dupe_trans (const Transaction *from)// Local: 1:0:0
|
||||
*/
|
||||
static void
|
||||
test_xaccDupeTransaction (Fixture *fixture, gconstpointer pData)
|
||||
test_dupe_trans (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Timespec posted = gnc_dmy2timespec (12, 7, 2011);
|
||||
Timespec entered = gnc_dmy2timespec (14, 7, 2011);
|
||||
@ -587,7 +586,7 @@ test_xaccDupeTransaction (Fixture *fixture, gconstpointer pData)
|
||||
kvp_frame_set_string (old->inst.kvp_data, "/foo/bar/baz",
|
||||
"The Great Waldo Pepper");
|
||||
|
||||
new = xaccDupeTransaction (old);
|
||||
new = fixture->func->dupe_trans (old);
|
||||
|
||||
g_assert_cmpstr (new->num, ==, old->num);
|
||||
g_assert_cmpstr (new->description, ==, old->description);
|
||||
@ -1048,14 +1047,14 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
|
||||
Account *acc1 = xaccMallocAccount (book);
|
||||
Account *acc2 = xaccMallocAccount (book);
|
||||
gnc_numeric value;
|
||||
gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
|
||||
OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_TRADING_ACCOUNTS);
|
||||
MonetaryList *mlist;
|
||||
qof_book_begin_edit (book);
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"trading-accts", "t",
|
||||
NULL);
|
||||
qof_book_commit_edit (book);
|
||||
|
||||
qof_book_set_string_option( book, trading_account_path, "t" );
|
||||
g_free (trading_account_path);
|
||||
/* Without trading splits, the list is unbalanced */
|
||||
/* Without trading splits, the list is unbalanced */
|
||||
mlist = xaccTransGetImbalance (fixture->txn);
|
||||
g_assert_cmpint (g_list_length (mlist), ==, 2);
|
||||
gnc_monetary_list_free (mlist);
|
||||
@ -1135,12 +1134,13 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
|
||||
Split *split2 = xaccMallocSplit (book);
|
||||
Account *acc1 = xaccMallocAccount (book);
|
||||
Account *acc2 = xaccMallocAccount (book);
|
||||
gchar *trading_account_path = g_strdup_printf("%s/%s/%s", KVP_OPTION_PATH,
|
||||
OPTION_SECTION_ACCOUNTS,
|
||||
OPTION_NAME_TRADING_ACCOUNTS);
|
||||
|
||||
qof_book_set_string_option( book, trading_account_path, "t" );
|
||||
g_free (trading_account_path);
|
||||
qof_book_begin_edit (book);
|
||||
qof_instance_set (QOF_INSTANCE (book),
|
||||
"trading-accts", "t",
|
||||
NULL);
|
||||
qof_book_commit_edit (book);
|
||||
|
||||
xaccAccountSetCommodity (acc1, fixture->curr);
|
||||
xaccAccountSetCommodity (acc2, fixture->comm);
|
||||
xaccAccountSetType (acc1, ACCT_TYPE_TRADING);
|
||||
@ -1398,29 +1398,27 @@ void
|
||||
xaccTransDestroy (Transaction *trans)// C: 26 in 15 SCM: 4 in 4 Local: 3:0:0
|
||||
*/
|
||||
static void
|
||||
test_xaccTransDestroy ()
|
||||
test_xaccTransDestroy (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
QofBook *book = qof_book_new ();
|
||||
Transaction *txn = xaccMallocTransaction (book);
|
||||
Transaction *dupe = xaccDupeTransaction (txn);
|
||||
Transaction *txn = fixture->txn;
|
||||
QofBook *book = qof_instance_get_book (QOF_INSTANCE (txn));
|
||||
Transaction *dupe = xaccTransClone (txn);
|
||||
|
||||
xaccTransBeginEdit (txn);
|
||||
g_assert (!qof_instance_get_destroying (QOF_INSTANCE (txn)));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
|
||||
xaccTransDestroy (txn);
|
||||
g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
|
||||
xaccTransRollbackEdit (txn);
|
||||
qof_book_mark_readonly (book);
|
||||
xaccTransBeginEdit (txn);
|
||||
xaccTransDestroy (txn);
|
||||
g_assert (qof_instance_get_destroying (QOF_INSTANCE (txn)));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, TRUE, TRUE));
|
||||
g_assert (xaccTransEqual (txn, dupe, FALSE, TRUE, FALSE, TRUE));
|
||||
xaccTransRollbackEdit (txn);
|
||||
|
||||
test_destroy (txn);
|
||||
test_destroy (dupe);
|
||||
test_destroy (book);
|
||||
}
|
||||
/* destroy_gains
|
||||
static void
|
||||
@ -1645,10 +1643,6 @@ test_xaccTransCommitEdit (void)
|
||||
xaccTransSetCurrency (txn, curr);
|
||||
xaccSplitSetParent (split1, txn);
|
||||
xaccSplitSetParent (split2, txn);
|
||||
/* xaccTransCommitEdit doesn't do anything with kvp
|
||||
kvp_frame_set_double (frame, "/qux/quux/corge", 123.456);
|
||||
qof_instance_set_slots (QOF_INSTANCE (txn), frame);
|
||||
*/
|
||||
}
|
||||
/* Setup's done, now test: */
|
||||
xaccTransCommitEdit (txn);
|
||||
@ -1790,7 +1784,7 @@ static void
|
||||
test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
Transaction *txnA = fixture->txn;
|
||||
Transaction *txnB = xaccDupeTransaction (txnA);
|
||||
Transaction *txnB = fixture->func->dupe_trans (txnA);
|
||||
|
||||
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, NULL, NULL), ==, -1);
|
||||
g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, txnA, NULL), ==, 1);
|
||||
@ -2042,7 +2036,7 @@ test_suite_transaction (void)
|
||||
GNC_TEST_ADD (suitename, "gnc transaction set/get property", Fixture, NULL, setup, test_gnc_transaction_set_get_property, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccMallocTransaction", Fixture, NULL, setup, test_xaccMallocTransaction, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccTransSortSplits", Fixture, NULL, setup, test_xaccTransSortSplits, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccDupeTransaction", Fixture, NULL, setup, test_xaccDupeTransaction, teardown);
|
||||
GNC_TEST_ADD (suitename, "dupe_trans", Fixture, NULL, setup, test_dupe_trans, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccTransClone", Fixture, NULL, setup, test_xaccTransClone, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard, teardown);
|
||||
GNC_TEST_ADD (suitename, "xaccTransCopyFromClipBoard No-Start", Fixture, NULL, setup, test_xaccTransCopyFromClipBoard_no_start, teardown);
|
||||
@ -2063,7 +2057,7 @@ test_suite_transaction (void)
|
||||
|
||||
GNC_TEST_ADD (suitename, "xaccTransSetCurrency", Fixture, NULL, setup, test_xaccTransSetCurrency, teardown);
|
||||
GNC_TEST_ADD_FUNC (suitename, "xaccTransBeginEdit", test_xaccTransBeginEdit);
|
||||
GNC_TEST_ADD_FUNC (suitename, "xaccTransDestroy", test_xaccTransDestroy);
|
||||
GNC_TEST_ADD (suitename, "xaccTransDestroy", Fixture, NULL, setup, test_xaccTransDestroy, teardown);
|
||||
GNC_TEST_ADD (suitename, "destroy gains", GainsFixture, NULL, setup_with_gains, test_destroy_gains, teardown_with_gains);
|
||||
GNC_TEST_ADD (suitename, "do destroy", GainsFixture, NULL, setup_with_gains, test_do_destroy, teardown_with_gains);
|
||||
GNC_TEST_ADD (suitename, "was trans emptied", Fixture, NULL, setup, test_was_trans_emptied, teardown);
|
||||
|
@ -1054,7 +1054,7 @@ gnc_preferences_dialog_create(void)
|
||||
GtkWidget *dialog, *notebook, *label, *image;
|
||||
GtkWidget *box, *date, *period, *currency;
|
||||
GHashTable *prefs_table;
|
||||
GDate* gdate;
|
||||
GDate* gdate = NULL;
|
||||
gchar buf[128];
|
||||
GtkListStore *store;
|
||||
GtkTreePath *path;
|
||||
@ -1120,16 +1120,10 @@ gnc_preferences_dialog_create(void)
|
||||
|
||||
|
||||
book = gnc_get_current_book();
|
||||
book_frame = qof_book_get_slots(book);
|
||||
month = kvp_frame_get_gint64(book_frame, "/book/fyear_end/month");
|
||||
day = kvp_frame_get_gint64(book_frame, "/book/fyear_end/day");
|
||||
date_is_valid = g_date_valid_dmy(day, month, 2005 /* not leap year */);
|
||||
if (date_is_valid)
|
||||
{
|
||||
g_date_clear(&fy_end, 1);
|
||||
g_date_set_dmy(&fy_end, day, month, G_DATE_BAD_YEAR);
|
||||
}
|
||||
|
||||
g_date_clear (&fy_end, 1);
|
||||
qof_instance_get (QOF_INSTANCE (book),
|
||||
"fy-end", &fy_end,
|
||||
NULL);
|
||||
box = GTK_WIDGET(gtk_builder_get_object (builder,
|
||||
"pref/" GNC_PREFS_GROUP_ACCT_SUMMARY "/" GNC_PREF_START_PERIOD));
|
||||
period = gnc_period_select_new(TRUE);
|
||||
|
@ -3973,20 +3973,21 @@ gnc_book_options_dialog_apply_cb(GNCOptionWin * optionwin,
|
||||
gpointer user_data)
|
||||
{
|
||||
GNCOptionDB * options = user_data;
|
||||
kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
|
||||
gboolean use_split_action_for_num_before =
|
||||
qof_book_use_split_action_for_num_field (gnc_get_current_book ());
|
||||
gboolean use_split_action_for_num_after;
|
||||
QofBook *book = gnc_get_current_book ();
|
||||
|
||||
if (!options) return;
|
||||
|
||||
gnc_option_db_commit (options);
|
||||
gnc_option_db_save_to_kvp (options, slots, TRUE);
|
||||
qof_book_kvp_changed (gnc_get_current_book());
|
||||
qof_book_begin_edit (book);
|
||||
qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
|
||||
use_split_action_for_num_after =
|
||||
qof_book_use_split_action_for_num_field (gnc_get_current_book ());
|
||||
if (use_split_action_for_num_before != use_split_action_for_num_after)
|
||||
gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
|
||||
qof_book_commit_edit (book);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4002,12 +4003,12 @@ gnc_book_options_dialog_close_cb(GNCOptionWin * optionwin,
|
||||
GtkWidget *
|
||||
gnc_book_options_dialog_cb (gboolean modal, gchar *title)
|
||||
{
|
||||
kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
|
||||
QofBook *book = gnc_get_current_book ();
|
||||
GNCOptionDB *options;
|
||||
GNCOptionWin *optionwin;
|
||||
|
||||
options = gnc_option_db_new_for_type (QOF_ID_BOOK);
|
||||
gnc_option_db_load_from_kvp (options, slots);
|
||||
qof_book_load_options (book, gnc_option_db_load_from_kvp, options);
|
||||
gnc_option_db_clean (options);
|
||||
|
||||
optionwin = gnc_options_dialog_new_modal (modal,
|
||||
|
@ -397,30 +397,20 @@ const char *
|
||||
gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
|
||||
{
|
||||
static char *name = NULL;
|
||||
Account *account;
|
||||
GncGUID *guid = NULL;
|
||||
|
||||
kvp_frame *kvpf;
|
||||
/* Callers either g_strdup the return or use it as a temp for comparison,
|
||||
so we keep our static ref and free it on every call. */
|
||||
g_free (name);
|
||||
|
||||
if (!split)
|
||||
return NULL;
|
||||
|
||||
kvpf = xaccSplitGetSlots (split);
|
||||
|
||||
g_free (name);
|
||||
|
||||
if (kvpf)
|
||||
{
|
||||
Account *account;
|
||||
GncGUID *guid;
|
||||
|
||||
guid = kvp_value_get_guid(
|
||||
kvp_frame_get_slot_path (kvpf, "sched-xaction", "account", NULL));
|
||||
|
||||
account = xaccAccountLookup (guid, gnc_get_current_book ());
|
||||
|
||||
name = account ? gnc_get_account_name_for_register (account) : NULL;
|
||||
}
|
||||
else
|
||||
name = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (split),
|
||||
"sx-account", &guid,
|
||||
NULL);
|
||||
account = xaccAccountLookup (guid, gnc_get_current_book ());
|
||||
name = account ? gnc_get_account_name_for_register (account) : NULL;
|
||||
|
||||
return name;
|
||||
}
|
||||
@ -429,20 +419,27 @@ gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
|
||||
const char *
|
||||
gnc_tree_util_split_reg_template_get_fdebt_entry (Split *split)
|
||||
{
|
||||
kvp_frame *kvpf = xaccSplitGetSlots (split);
|
||||
gchar *formula = NULL;
|
||||
|
||||
return kvp_value_get_string(
|
||||
kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
|
||||
g_return_val_if_fail (split != NULL, NULL);
|
||||
qof_instance_get (QOF_INSTANCE (split),
|
||||
"sx-debit-formula", &formula,
|
||||
NULL);
|
||||
|
||||
return formula;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
gnc_tree_util_split_reg_template_get_fcred_entry (Split *split)
|
||||
{
|
||||
kvp_frame *kvpf = xaccSplitGetSlots (split);
|
||||
gchar *formula = NULL;
|
||||
|
||||
return kvp_value_get_string(
|
||||
kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
|
||||
g_return_val_if_fail (split != NULL, NULL);
|
||||
qof_instance_get (QOF_INSTANCE (split),
|
||||
"sx-credit-formula", &formula,
|
||||
NULL);
|
||||
|
||||
return formula;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1730,43 +1730,44 @@ gtva_currency_changed_cb (void)
|
||||
gtva_update_column_names (ptr->data);
|
||||
}
|
||||
}
|
||||
/* This function implements a custom mapping between an account's KVP
|
||||
* and the cell renderer's 'text' property. */
|
||||
/* Retrieve a specified account string property and put the result
|
||||
* into the tree column's text property.
|
||||
*/
|
||||
static void
|
||||
account_cell_kvp_data_func (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *s_model,
|
||||
GtkTreeIter *s_iter,
|
||||
gpointer key)
|
||||
account_cell_property_data_func (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *s_model,
|
||||
GtkTreeIter *s_iter,
|
||||
gpointer key)
|
||||
{
|
||||
Account *account;
|
||||
kvp_frame * frame;
|
||||
gchar *string = NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model));
|
||||
account = gnc_tree_view_account_get_account_from_iter(s_model, s_iter);
|
||||
frame = xaccAccountGetSlots(account);
|
||||
|
||||
g_object_set (G_OBJECT (cell),
|
||||
"text", kvp_frame_get_string(frame, (gchar *)key),
|
||||
"xalign", 0.0,
|
||||
NULL);
|
||||
qof_instance_get (QOF_INSTANCE (account),
|
||||
key, &string,
|
||||
NULL);
|
||||
if (string == NULL)
|
||||
string = "";
|
||||
|
||||
g_object_set (G_OBJECT (cell), "text", string, "xalign", 0.0, NULL);
|
||||
}
|
||||
|
||||
|
||||
GtkTreeViewColumn *
|
||||
gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
|
||||
gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
|
||||
const gchar *column_title,
|
||||
const gchar *kvp_key)
|
||||
const gchar *propname)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
g_return_val_if_fail (GNC_IS_TREE_VIEW_ACCOUNT (view), NULL);
|
||||
g_return_val_if_fail (kvp_key != NULL, NULL);
|
||||
g_return_val_if_fail (propname != NULL, NULL);
|
||||
|
||||
column = gnc_tree_view_add_text_column(GNC_TREE_VIEW(view), column_title,
|
||||
kvp_key, NULL, "Sample text",
|
||||
propname, NULL, "Sample text",
|
||||
-1, -1, NULL);
|
||||
|
||||
/* This new kvp column has only had one renderer added to it so
|
||||
@ -1775,8 +1776,8 @@ gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
|
||||
g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
|
||||
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer,
|
||||
account_cell_kvp_data_func,
|
||||
g_strdup(kvp_key), g_free);
|
||||
account_cell_property_data_func,
|
||||
g_strdup(propname), g_free);
|
||||
return column;
|
||||
}
|
||||
|
||||
|
@ -203,20 +203,19 @@ void gnc_tree_view_account_notes_edited_cb(Account *account, GtkTreeViewColumn *
|
||||
|
||||
/** Add a new column to the set of columns in an account tree view.
|
||||
* This column will be visible as soon as it is added and will
|
||||
* display the contents of the specified KVP slot.
|
||||
* display the contents of the specified account property
|
||||
*
|
||||
* @param view A pointer to an account tree view.
|
||||
*
|
||||
* @param column_title The title for this new column.
|
||||
*
|
||||
* @param kvp_key The lookup key to use for looking up data in the
|
||||
* account KVP structures. The value associated with this key is what
|
||||
* will be displayed in the column.
|
||||
* @param propname The g_object_property name of the desired
|
||||
* value. This must be a string property.
|
||||
*/
|
||||
GtkTreeViewColumn *
|
||||
gnc_tree_view_account_add_kvp_column (GncTreeViewAccount *view,
|
||||
const gchar *column_title,
|
||||
const gchar *kvp_key);
|
||||
gnc_tree_view_account_add_property_column (GncTreeViewAccount *view,
|
||||
const gchar *column_title,
|
||||
const gchar *propname);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -4801,9 +4801,8 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
|
||||
if (viewcol == COL_TRANSFERVOID)
|
||||
{
|
||||
Account *template_acc;
|
||||
Account *acct;
|
||||
const GncGUID *acctGUID;
|
||||
kvp_frame *kvpf;
|
||||
Account *acct;
|
||||
|
||||
/* save the account GncGUID into the kvp_data. */
|
||||
view->priv->stop_cell_move = FALSE;
|
||||
@ -4822,9 +4821,9 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
|
||||
}
|
||||
|
||||
acctGUID = xaccAccountGetGUID (acct);
|
||||
kvpf = xaccSplitGetSlots (split);
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_guid (acctGUID),
|
||||
GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"sx-account", acctGUID,
|
||||
NULL);
|
||||
|
||||
template_acc = gnc_tree_model_split_reg_get_template_account (model);
|
||||
|
||||
@ -4844,20 +4843,11 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
|
||||
/* Setup the debit and credit fields */
|
||||
if (viewcol == COL_DEBIT)
|
||||
{
|
||||
kvp_frame *kvpf;
|
||||
char *error_loc;
|
||||
gnc_numeric new_value;
|
||||
gboolean parse_result;
|
||||
|
||||
kvpf = xaccSplitGetSlots (split);
|
||||
|
||||
DEBUG ("kvp_frame debit before: %s\n", kvp_frame_to_string (kvpf));
|
||||
|
||||
/* Setup the debit formula */
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL);
|
||||
|
||||
/* If the value can be parsed into a numeric result, store that
|
||||
* numeric value additionally. See above comment.*/
|
||||
@ -4866,45 +4856,22 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
|
||||
{
|
||||
new_value = gnc_numeric_zero();
|
||||
}
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_NUMERIC,
|
||||
NULL);
|
||||
|
||||
DEBUG ("kvp_frame debit after: %s\n", kvp_frame_to_string (kvpf));
|
||||
|
||||
/* Blank the credit formula */
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL);
|
||||
|
||||
new_value = gnc_numeric_zero();
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_NUMERIC,
|
||||
NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"sx-debit-formula", new_text,
|
||||
"sx-debit-numeric", &new_value,
|
||||
"sx-credit-formula", NULL,
|
||||
"sx-credit-numeric", NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Setup the debit and credit fields */
|
||||
if (viewcol == COL_CREDIT)
|
||||
{
|
||||
kvp_frame *kvpf;
|
||||
char *error_loc;
|
||||
gnc_numeric new_value;
|
||||
gboolean parse_result;
|
||||
|
||||
kvpf = xaccSplitGetSlots (split);
|
||||
|
||||
DEBUG ("kvp_frame credit before: %s\n", kvp_frame_to_string (kvpf));
|
||||
|
||||
/* Setup the credit formula */
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL);
|
||||
|
||||
/* If the value can be parsed into a numeric result (without any
|
||||
/* If the value can be parsed into a numeric result (without any
|
||||
* further variable definitions), store that numeric value
|
||||
* additionally in the kvp. Otherwise store a zero numeric
|
||||
* there.*/
|
||||
@ -4913,24 +4880,12 @@ gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
|
||||
{
|
||||
new_value = gnc_numeric_zero();
|
||||
}
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_NUMERIC,
|
||||
NULL);
|
||||
|
||||
DEBUG ("kvp_frame credit after: %s\n", kvp_frame_to_string (kvpf));
|
||||
|
||||
/* Blank the debit formula */
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL);
|
||||
|
||||
new_value = gnc_numeric_zero();
|
||||
kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_NUMERIC,
|
||||
NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split),
|
||||
"sx-credit-formula", new_text,
|
||||
"sx-credit-numeric", &new_value,
|
||||
"sx-debit-formula", NULL,
|
||||
"sx-debit-numeric", NULL,
|
||||
NULL);
|
||||
}
|
||||
/* set the amount to an innocuous value */
|
||||
xaccSplitSetValue (split, gnc_numeric_create (0, 1));
|
||||
|
@ -1008,18 +1008,17 @@ finish_book_options_helper(GNCOptionWin * optionwin,
|
||||
gpointer user_data)
|
||||
{
|
||||
GNCOptionDB * options = user_data;
|
||||
kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
|
||||
QofBook *book = gnc_get_current_book ();
|
||||
gboolean use_split_action_for_num_before =
|
||||
qof_book_use_split_action_for_num_field (gnc_get_current_book ());
|
||||
qof_book_use_split_action_for_num_field (book);
|
||||
gboolean use_split_action_for_num_after;
|
||||
|
||||
if (!options) return;
|
||||
|
||||
gnc_option_db_commit (options);
|
||||
gnc_option_db_save_to_kvp (options, slots, TRUE);
|
||||
qof_book_kvp_changed (gnc_get_current_book());
|
||||
qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE);
|
||||
use_split_action_for_num_after =
|
||||
qof_book_use_split_action_for_num_field (gnc_get_current_book ());
|
||||
qof_book_use_split_action_for_num_field (book);
|
||||
if (use_split_action_for_num_before != use_split_action_for_num_after)
|
||||
gnc_book_option_num_field_source_change_cb (use_split_action_for_num_after);
|
||||
}
|
||||
@ -1119,11 +1118,11 @@ book_options_dialog_close_cb(GNCOptionWin * optionwin,
|
||||
static void
|
||||
assistant_instert_book_options_page (hierarchy_data *data)
|
||||
{
|
||||
kvp_frame *slots = qof_book_get_slots (gnc_get_current_book ());
|
||||
GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
|
||||
|
||||
data->options = gnc_option_db_new_for_type (QOF_ID_BOOK);
|
||||
gnc_option_db_load_from_kvp (data->options, slots);
|
||||
qof_book_load_options (gnc_get_current_book (),
|
||||
gnc_option_db_load_from_kvp, data->options);
|
||||
gnc_option_db_clean (data->options);
|
||||
|
||||
data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options"));
|
||||
|
@ -549,9 +549,7 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
|
||||
int numIters, i;
|
||||
GHashTable *vars, *txns;
|
||||
GList *splitList = NULL;
|
||||
char *str;
|
||||
kvp_frame *f;
|
||||
kvp_value *v;
|
||||
gchar *credit_formula = NULL, *debit_formula = NULL;
|
||||
Split *s;
|
||||
Transaction *t;
|
||||
gnc_numeric tmp;
|
||||
@ -559,8 +557,10 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
|
||||
gpointer unusedKey, unusedValue;
|
||||
|
||||
unbalanceable = FALSE; /* innocent until proven guilty */
|
||||
vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)gnc_sx_variable_free);
|
||||
txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
|
||||
vars = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify)gnc_sx_variable_free);
|
||||
txns = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
||||
g_free);
|
||||
numIters = NUM_ITERS_NO_VARS;
|
||||
/**
|
||||
* Plan:
|
||||
@ -604,10 +604,10 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
|
||||
|
||||
for ( ; splitList; splitList = splitList->next )
|
||||
{
|
||||
GncGUID *acct_guid;
|
||||
Account *acct;
|
||||
gnc_commodity *split_cmdty;
|
||||
txnCreditDebitSums *tcds;
|
||||
GncGUID *acct_guid = NULL;
|
||||
Account *acct = NULL;
|
||||
gnc_commodity *split_cmdty = NULL;
|
||||
txnCreditDebitSums *tcds = NULL;
|
||||
|
||||
s = (Split*)splitList->data;
|
||||
t = xaccSplitGetParent( s );
|
||||
@ -622,14 +622,11 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
|
||||
g_hash_table_insert( txns, (gpointer)t, (gpointer)tcds );
|
||||
}
|
||||
|
||||
f = xaccSplitGetSlots( s );
|
||||
|
||||
/* contains the guid of the split's actual account. */
|
||||
v = kvp_frame_get_slot_path(f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_ACCOUNT,
|
||||
NULL);
|
||||
acct_guid = kvp_value_get_guid( v );
|
||||
qof_instance_get (QOF_INSTANCE (s),
|
||||
"sx-account", &acct_guid,
|
||||
"sx-credit-formula", &credit_formula,
|
||||
"sx-debit-formula", &debit_formula,
|
||||
NULL);
|
||||
acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
|
||||
split_cmdty = xaccAccountGetCommodity(acct);
|
||||
if (base_cmdty == NULL)
|
||||
@ -638,62 +635,48 @@ gnc_sxed_check_consistent( GncSxEditorDialog *sxed )
|
||||
}
|
||||
multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
|
||||
|
||||
v = kvp_frame_get_slot_path( f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL );
|
||||
if ( v
|
||||
&& (str = kvp_value_get_string(v))
|
||||
&& strlen( str ) != 0 )
|
||||
{
|
||||
if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
if ( g_strcmp0 (credit_formula, "") != 0 &&
|
||||
gnc_sx_parse_vars_from_formula(credit_formula, vars,
|
||||
&tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse credit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse credit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
tcds->creditSum =
|
||||
gnc_numeric_add( tcds->creditSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
v = kvp_frame_get_slot_path( f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL );
|
||||
if ( v
|
||||
&& (str = kvp_value_get_string(v))
|
||||
&& strlen(str) != 0 )
|
||||
{
|
||||
if ( gnc_sx_parse_vars_from_formula( str, vars, &tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
return FALSE;
|
||||
}
|
||||
tcds->creditSum =
|
||||
gnc_numeric_add( tcds->creditSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
if ( g_strcmp0 (debit_formula, "") != 0 &&
|
||||
gnc_sx_parse_vars_from_formula( debit_formula, vars,
|
||||
&tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse debit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
(gchar*)errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse debit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
(gchar*)errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
|
||||
g_hash_table_foreach( txns,
|
||||
check_credit_debit_balance,
|
||||
|
@ -546,9 +546,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
|
||||
int numIters, i;
|
||||
GHashTable *vars, *txns;
|
||||
GList *splitList = NULL;
|
||||
char *str;
|
||||
kvp_frame *f;
|
||||
kvp_value *v;
|
||||
char *credit_formula = NULL, *debit_formula = NULL;
|
||||
Split *s;
|
||||
Transaction *t;
|
||||
gnc_numeric tmp;
|
||||
@ -597,7 +595,7 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
|
||||
|
||||
for (; splitList; splitList = splitList->next)
|
||||
{
|
||||
GncGUID *acct_guid;
|
||||
GncGUID *acct_guid = NULL;
|
||||
Account *acct;
|
||||
gnc_commodity *split_cmdty;
|
||||
txnCreditDebitSums *tcds;
|
||||
@ -615,77 +613,60 @@ gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
|
||||
g_hash_table_insert (txns, (gpointer)t, (gpointer)tcds);
|
||||
}
|
||||
|
||||
f = xaccSplitGetSlots (s);
|
||||
|
||||
/* contains the guid of the split's actual account. */
|
||||
v = kvp_frame_get_slot_path (f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_ACCOUNT,
|
||||
NULL);
|
||||
acct_guid = kvp_value_get_guid (v);
|
||||
acct = xaccAccountLookup (acct_guid, gnc_get_current_book ());
|
||||
split_cmdty = xaccAccountGetCommodity (acct);
|
||||
qof_instance_get (QOF_INSTANCE (s),
|
||||
"sx-account", &acct_guid,
|
||||
"sx-credit-formula", &credit_formula,
|
||||
"sx-debit-formula", &debit_formula,
|
||||
NULL);
|
||||
acct = xaccAccountLookup( acct_guid, gnc_get_current_book ());
|
||||
split_cmdty = xaccAccountGetCommodity(acct);
|
||||
if (base_cmdty == NULL)
|
||||
{
|
||||
base_cmdty = split_cmdty;
|
||||
}
|
||||
multi_commodity |= !gnc_commodity_equal (split_cmdty, base_cmdty);
|
||||
multi_commodity |= !gnc_commodity_equal(split_cmdty, base_cmdty);
|
||||
|
||||
v = kvp_frame_get_slot_path (f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_CREDIT_FORMULA,
|
||||
NULL);
|
||||
if (v
|
||||
&& (str = kvp_value_get_string (v))
|
||||
&& strlen( str ) != 0)
|
||||
{
|
||||
if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
|
||||
{
|
||||
GString *errStr;
|
||||
if ( g_strcmp0 (credit_formula, "") != 0 &&
|
||||
gnc_sx_parse_vars_from_formula(credit_formula, vars,
|
||||
&tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
|
||||
errStr = g_string_sized_new (32);
|
||||
g_string_printf (errStr,
|
||||
_( "Couldn't parse credit formula for "
|
||||
"split \"%s\"."),
|
||||
xaccSplitGetMemo (s));
|
||||
gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
|
||||
errStr->str);
|
||||
g_string_free (errStr, TRUE);
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse credit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
tcds->creditSum =
|
||||
gnc_numeric_add (tcds->creditSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
v = kvp_frame_get_slot_path (f,
|
||||
GNC_SX_ID,
|
||||
GNC_SX_DEBIT_FORMULA,
|
||||
NULL);
|
||||
if (v
|
||||
&& (str = kvp_value_get_string (v))
|
||||
&& strlen(str) != 0 )
|
||||
{
|
||||
if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
|
||||
{
|
||||
GString *errStr;
|
||||
return FALSE;
|
||||
}
|
||||
tcds->creditSum =
|
||||
gnc_numeric_add( tcds->creditSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
if ( g_strcmp0 (debit_formula, "") != 0 &&
|
||||
gnc_sx_parse_vars_from_formula( debit_formula, vars,
|
||||
&tmp ) < 0 )
|
||||
{
|
||||
GString *errStr;
|
||||
|
||||
errStr = g_string_sized_new (32);
|
||||
g_string_printf (errStr,
|
||||
_( "Couldn't parse debit formula for "
|
||||
"split \"%s\"."),
|
||||
xaccSplitGetMemo (s));
|
||||
gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
|
||||
(gchar*)errStr->str);
|
||||
g_string_free (errStr, TRUE);
|
||||
errStr = g_string_sized_new( 32 );
|
||||
g_string_printf( errStr,
|
||||
_( "Couldn't parse debit formula for "
|
||||
"split \"%s\"." ),
|
||||
xaccSplitGetMemo( s ) );
|
||||
gnc_error_dialog( GTK_WIDGET(sxed->dialog), "%s",
|
||||
(gchar*)errStr->str );
|
||||
g_string_free( errStr, TRUE );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
tcds->debitSum = gnc_numeric_add (tcds->debitSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
tcds->debitSum = gnc_numeric_add( tcds->debitSum, tmp, 100,
|
||||
(GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) );
|
||||
tmp = gnc_numeric_zero();
|
||||
}
|
||||
|
||||
g_hash_table_foreach (txns,
|
||||
|
@ -3646,39 +3646,30 @@ gnc_plugin_page_register2_cmd_schedule (GtkAction *action,
|
||||
/* If the transaction has a sched-xact KVP frame, then go to the editor
|
||||
* for the existing SX; otherwise, do the sx-from-trans dialog. */
|
||||
{
|
||||
kvp_frame *txn_frame;
|
||||
kvp_value *kvp_val;
|
||||
/* set a kvp-frame element in the transaction indicating and
|
||||
* pointing-to the SX this was created from. */
|
||||
txn_frame = xaccTransGetSlots (trans);
|
||||
if ( txn_frame != NULL )
|
||||
{
|
||||
kvp_val = kvp_frame_get_slot (txn_frame, "from-sched-xaction");
|
||||
if (kvp_val)
|
||||
{
|
||||
GncGUID *fromSXId = kvp_value_get_guid (kvp_val);
|
||||
SchedXaction *theSX = NULL;
|
||||
GList *sxElts;
|
||||
GncGUID *fromSXId = NULL;
|
||||
SchedXaction *theSX = NULL;
|
||||
GList *sxElts;
|
||||
qof_instance_get (QOF_INSTANCE (trans),
|
||||
"from-sched-xaction", &fromSXId,
|
||||
NULL);
|
||||
|
||||
/* Get the correct SX */
|
||||
for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
|
||||
(!theSX) && sxElts;
|
||||
sxElts = sxElts->next )
|
||||
{
|
||||
SchedXaction *sx = (SchedXaction*)sxElts->data;
|
||||
theSX =
|
||||
((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
|
||||
? sx : NULL);
|
||||
}
|
||||
/* Get the correct SX */
|
||||
for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
|
||||
(!theSX) && sxElts;
|
||||
sxElts = sxElts->next )
|
||||
{
|
||||
SchedXaction *sx = (SchedXaction*)sxElts->data;
|
||||
theSX =
|
||||
((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
|
||||
? sx : NULL);
|
||||
}
|
||||
|
||||
if (theSX)
|
||||
{
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
|
||||
LEAVE(" ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theSX)
|
||||
{
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
|
||||
LEAVE(" ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
gnc_sx_create_from_trans (trans);
|
||||
LEAVE(" ");
|
||||
|
@ -1387,38 +1387,29 @@ gsr_default_schedule_handler( GNCSplitReg *gsr, gpointer data )
|
||||
/* If the transaction has a sched-xact KVP frame, then go to the editor
|
||||
* for the existing SX; otherwise, do the sx-from-trans dialog. */
|
||||
{
|
||||
kvp_frame *txn_frame;
|
||||
kvp_value *kvp_val;
|
||||
/* set a kvp-frame element in the transaction indicating and
|
||||
* pointing-to the SX this was created from. */
|
||||
txn_frame = xaccTransGetSlots( pending_trans );
|
||||
if ( txn_frame != NULL )
|
||||
{
|
||||
kvp_val = kvp_frame_get_slot( txn_frame, "from-sched-xaction" );
|
||||
if ( kvp_val )
|
||||
{
|
||||
GncGUID *fromSXId = kvp_value_get_guid( kvp_val );
|
||||
SchedXaction *theSX = NULL;
|
||||
GList *sxElts;
|
||||
GncGUID *fromSXId = NULL;
|
||||
SchedXaction *theSX = NULL;
|
||||
GList *sxElts;
|
||||
qof_instance_get (QOF_INSTANCE (pending_trans),
|
||||
"from-sched-xaction", &fromSXId,
|
||||
NULL);
|
||||
|
||||
/* Get the correct SX */
|
||||
for ( sxElts = gnc_book_get_schedxactions(gnc_get_current_book())->sx_list;
|
||||
(!theSX) && sxElts;
|
||||
sxElts = sxElts->next )
|
||||
{
|
||||
SchedXaction *sx = (SchedXaction*)sxElts->data;
|
||||
theSX =
|
||||
( ( guid_equal( xaccSchedXactionGetGUID( sx ), fromSXId ) )
|
||||
? sx : NULL );
|
||||
}
|
||||
/* Get the correct SX */
|
||||
for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
|
||||
(!theSX) && sxElts;
|
||||
sxElts = sxElts->next )
|
||||
{
|
||||
SchedXaction *sx = (SchedXaction*)sxElts->data;
|
||||
theSX =
|
||||
((guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
|
||||
? sx : NULL);
|
||||
}
|
||||
|
||||
if ( theSX )
|
||||
{
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( theSX )
|
||||
{
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(theSX, FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gnc_sx_create_from_trans(pending_trans);
|
||||
|
@ -18,13 +18,11 @@ libgncmod_generic_import_la_SOURCES = \
|
||||
import-parse.c \
|
||||
import-utilities.c \
|
||||
import-settings.c \
|
||||
import-match-map.c \
|
||||
import-main-matcher.c \
|
||||
gncmod-generic-import.c
|
||||
|
||||
gncincludedir = ${GNC_INCLUDE_DIR}
|
||||
gncinclude_HEADERS = \
|
||||
import-match-map.h \
|
||||
import-parse.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
@ -32,7 +30,6 @@ noinst_HEADERS = \
|
||||
import-backend.h \
|
||||
import-commodity-matcher.h \
|
||||
import-main-matcher.h \
|
||||
import-match-map.h \
|
||||
import-match-picker.h \
|
||||
import-settings.h \
|
||||
import-utilities.h
|
||||
|
@ -32,134 +32,105 @@
|
||||
|
||||
#include "gnc-ab-kvp.h"
|
||||
|
||||
#define AB_KEY "hbci"
|
||||
#define AB_ACCOUNT_ID "account-id"
|
||||
#define AB_ACCOUNT_UID "account-uid"
|
||||
#define AB_BANK_CODE "bank-code"
|
||||
#define AB_TRANS_RETRIEVAL "trans-retrieval"
|
||||
#define AB_TEMPLATES "template-list"
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN;
|
||||
|
||||
static kvp_frame *gnc_ab_get_account_kvp(const Account *a, gboolean create);
|
||||
static kvp_frame *gnc_ab_get_book_kvp(QofBook *b, gboolean create);
|
||||
|
||||
const gchar *
|
||||
gnc_ab_get_account_accountid(const Account *a)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
|
||||
kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_ID);
|
||||
return kvp_value_get_string(value);
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (a),
|
||||
"ab-account-id", &id,
|
||||
NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ab_set_account_accountid(Account *a, const gchar *id)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
|
||||
kvp_value *value = kvp_value_new_string(id);
|
||||
xaccAccountBeginEdit(a);
|
||||
kvp_frame_set_slot_nc(frame, AB_ACCOUNT_ID, value);
|
||||
qof_instance_set_dirty(QOF_INSTANCE (a));
|
||||
qof_instance_set (QOF_INSTANCE (a),
|
||||
"ab-account-id", id,
|
||||
NULL);
|
||||
xaccAccountCommitEdit(a);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gnc_ab_get_account_bankcode(const Account *a)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
|
||||
kvp_value *value = kvp_frame_get_slot(frame, AB_BANK_CODE);
|
||||
return kvp_value_get_string(value);
|
||||
gchar *code = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (a),
|
||||
"ab-bank-code", &code,
|
||||
NULL);
|
||||
return code;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ab_set_account_bankcode(Account *a, const gchar *code)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
|
||||
kvp_value *value = kvp_value_new_string(code);
|
||||
xaccAccountBeginEdit(a);
|
||||
kvp_frame_set_slot_nc(frame, AB_BANK_CODE, value);
|
||||
qof_instance_set_dirty(QOF_INSTANCE (a));
|
||||
qof_instance_set (QOF_INSTANCE (a),
|
||||
"ab-bank-code", code,
|
||||
NULL);
|
||||
xaccAccountCommitEdit(a);
|
||||
}
|
||||
|
||||
guint32
|
||||
gnc_ab_get_account_uid(const Account *a)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
|
||||
kvp_value *value = kvp_frame_get_slot(frame, AB_ACCOUNT_UID);
|
||||
return (guint32) kvp_value_get_gint64(value);
|
||||
guint64 uid = 0LL;
|
||||
qof_instance_get (QOF_INSTANCE (a),
|
||||
"ab-account-uid", &uid,
|
||||
NULL);
|
||||
return (guint32)uid;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ab_set_account_uid(Account *a, guint32 uid)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
|
||||
kvp_value *value = kvp_value_new_gint64(uid);
|
||||
xaccAccountBeginEdit(a);
|
||||
kvp_frame_set_slot_nc(frame, AB_ACCOUNT_UID, value);
|
||||
qof_instance_set_dirty(QOF_INSTANCE (a));
|
||||
qof_instance_set (QOF_INSTANCE (a),
|
||||
"ab-account-uid", (guint64)uid,
|
||||
NULL);
|
||||
xaccAccountCommitEdit(a);
|
||||
}
|
||||
|
||||
Timespec
|
||||
gnc_ab_get_account_trans_retrieval(const Account *a)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, FALSE);
|
||||
kvp_value *value = kvp_frame_get_slot(frame, AB_TRANS_RETRIEVAL);
|
||||
return kvp_value_get_timespec(value);
|
||||
Timespec t = {0LL, 0LL};
|
||||
qof_instance_get (QOF_INSTANCE (a),
|
||||
"ab-trans-retrieval", &t,
|
||||
NULL);
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ab_set_account_trans_retrieval(Account *a, Timespec time)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_account_kvp(a, TRUE);
|
||||
kvp_value *value = kvp_value_new_timespec(time);
|
||||
xaccAccountBeginEdit(a);
|
||||
kvp_frame_set_slot_nc(frame, AB_TRANS_RETRIEVAL, value);
|
||||
qof_instance_set_dirty(QOF_INSTANCE (a));
|
||||
qof_instance_set (QOF_INSTANCE (a),
|
||||
"ab-trans-retrieval", &time,
|
||||
NULL);
|
||||
xaccAccountCommitEdit(a);
|
||||
}
|
||||
|
||||
GList *
|
||||
gnc_ab_get_book_template_list(QofBook *b)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_book_kvp(b, FALSE);
|
||||
kvp_value *value = kvp_frame_get_slot(frame, AB_TEMPLATES);
|
||||
return kvp_value_get_glist(value);
|
||||
GList *template_list = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (b),
|
||||
"ab-templates", &template_list,
|
||||
NULL);
|
||||
return template_list;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_ab_set_book_template_list(QofBook *b, GList *template_list)
|
||||
{
|
||||
kvp_frame *frame = gnc_ab_get_book_kvp(b, TRUE);
|
||||
kvp_value *value = kvp_value_new_glist_nc(template_list);
|
||||
kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value);
|
||||
qof_book_kvp_changed (b);
|
||||
}
|
||||
|
||||
static kvp_frame *
|
||||
gnc_ab_get_account_kvp(const Account *a, gboolean create)
|
||||
{
|
||||
kvp_frame *toplevel = xaccAccountGetSlots(a);
|
||||
kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
|
||||
if (!result && create)
|
||||
{
|
||||
result = kvp_frame_new();
|
||||
kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static kvp_frame *
|
||||
gnc_ab_get_book_kvp(QofBook *b, gboolean create)
|
||||
{
|
||||
kvp_frame *toplevel = qof_book_get_slots(b);
|
||||
kvp_frame *result = kvp_frame_get_frame(toplevel, AB_KEY);
|
||||
if (!result && create)
|
||||
{
|
||||
result = kvp_frame_new();
|
||||
kvp_frame_add_frame_nc(toplevel, AB_KEY, result);
|
||||
}
|
||||
return result;
|
||||
qof_instance_set (QOF_INSTANCE (b),
|
||||
"ab-templates", &template_list,
|
||||
NULL);
|
||||
}
|
||||
|
@ -114,8 +114,8 @@ build_acct_tree(AccountPickerDialog *picker)
|
||||
g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
|
||||
|
||||
/* Add our custom column. */
|
||||
col = gnc_tree_view_account_add_kvp_column (picker->account_tree,
|
||||
_("Account ID"), "online_id");
|
||||
col = gnc_tree_view_account_add_property_column (picker->account_tree,
|
||||
_("Account ID"), "online-id");
|
||||
g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(picker->account_tree_sw),
|
||||
|
@ -44,6 +44,40 @@
|
||||
#include "gnc-prefs.h"
|
||||
#include "gnc-ui-util.h"
|
||||
|
||||
/* Private interface to Account GncImportMatchMap functions */
|
||||
|
||||
/** @{
|
||||
Obtain an ImportMatchMap object from an Account */
|
||||
extern GncImportMatchMap * gnc_account_create_imap (Account *acc);
|
||||
/*@}*/
|
||||
|
||||
/* Look up an Account in the map */
|
||||
extern 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. */
|
||||
extern void gnc_imap_add_account (GncImportMatchMap *imap,
|
||||
const char *category,
|
||||
const char *key, Account *acc);
|
||||
|
||||
/* Look up an Account in the map from a GList* of pointers to strings(tokens)
|
||||
from the current transaction */
|
||||
extern Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap,
|
||||
GList* tokens);
|
||||
|
||||
/* Store an Account in the map. This mapping is immediatly stored in
|
||||
the underlying kvp frame, regardless of whether the MatchMap is
|
||||
destroyed later or not. */
|
||||
extern void gnc_imap_add_account_bayes (GncImportMatchMap *imap,
|
||||
GList* tokens,
|
||||
Account *acc);
|
||||
|
||||
#define GNCIMPORT_DESC "desc"
|
||||
#define GNCIMPORT_MEMO "memo"
|
||||
#define GNCIMPORT_PAYEE "payee"
|
||||
|
||||
/********************************************************************\
|
||||
* Constants *
|
||||
@ -457,6 +491,15 @@ TransactionGetTokens(GNCImportTransInfo *info)
|
||||
/* return the pointer to the GList */
|
||||
return tokens;
|
||||
}
|
||||
/* Destroy an import map. But all stored entries will still continue
|
||||
* to exist in the underlying kvp frame of the account.
|
||||
*/
|
||||
static void
|
||||
gnc_imap_destroy (GncImportMatchMap *imap)
|
||||
{
|
||||
if (!imap) return;
|
||||
g_free (imap);
|
||||
}
|
||||
|
||||
/* searches using the GNCImportTransInfo through all existing transactions
|
||||
* if there is an exact match of the description and memo
|
||||
@ -471,7 +514,7 @@ matchmap_find_destination (GncImportMatchMap *matchmap, GNCImportTransInfo *info
|
||||
|
||||
g_assert (info);
|
||||
tmp_map = ((matchmap != NULL) ? matchmap :
|
||||
gnc_imap_create_from_account
|
||||
gnc_account_create_imap
|
||||
(xaccSplitGetAccount
|
||||
(gnc_import_TransInfo_get_fsplit (info))));
|
||||
|
||||
@ -541,7 +584,7 @@ matchmap_store_destination (GncImportMatchMap *matchmap,
|
||||
|
||||
tmp_matchmap = ((matchmap != NULL) ?
|
||||
matchmap :
|
||||
gnc_imap_create_from_account
|
||||
gnc_account_create_imap
|
||||
(xaccSplitGetAccount
|
||||
(gnc_import_TransInfo_get_fsplit (trans_info))));
|
||||
|
||||
|
@ -29,11 +29,11 @@
|
||||
#define TRANSACTION_MATCHER_H
|
||||
|
||||
#include "Transaction.h"
|
||||
#include "import-match-map.h"
|
||||
#include "import-settings.h"
|
||||
|
||||
typedef struct _transactioninfo GNCImportTransInfo;
|
||||
typedef struct _matchinfo GNCImportMatchInfo;
|
||||
typedef struct _GncImportMatchMap GncImportMatchMap;
|
||||
|
||||
typedef enum _action
|
||||
{
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "import-settings.h"
|
||||
#include "import-match-map.h"
|
||||
#include "import-match-picker.h"
|
||||
#include "import-backend.h"
|
||||
#include "import-account-matcher.h"
|
||||
|
@ -1,545 +0,0 @@
|
||||
/********************************************************************\
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @internal
|
||||
@file import-match-map.c
|
||||
@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 Copyright (C) 2002,2003 Derek Atkins <derek@ihtfp.com>
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include "import-match-map.h"
|
||||
#include "gnc-ui-util.h"
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/********************************************************************\
|
||||
* Constants *
|
||||
\********************************************************************/
|
||||
|
||||
static QofLogModule log_module = GNC_MOD_IMPORT;
|
||||
|
||||
|
||||
struct _GncImportMatchMap
|
||||
{
|
||||
kvp_frame * frame;
|
||||
Account * acc;
|
||||
QofBook * book;
|
||||
};
|
||||
|
||||
#define IMAP_FRAME "import-map"
|
||||
#define IMAP_FRAME_BAYES "import-map-bayes"
|
||||
|
||||
static GncImportMatchMap *
|
||||
gnc_imap_create_from_frame (kvp_frame *frame, Account *acc, QofBook *book)
|
||||
{
|
||||
GncImportMatchMap *imap;
|
||||
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
g_return_val_if_fail ((acc && !book) || (!acc && book), NULL);
|
||||
|
||||
imap = g_new0(GncImportMatchMap, 1);
|
||||
imap->frame = frame;
|
||||
|
||||
/* Cache the book for easy lookups; store the account/book for
|
||||
* marking dirtiness
|
||||
*/
|
||||
if (acc)
|
||||
book = gnc_account_get_book (acc);
|
||||
imap->acc = acc;
|
||||
imap->book = book;
|
||||
|
||||
return imap;
|
||||
}
|
||||
|
||||
/** Obtain an ImportMatchMap object from an Account or a Book */
|
||||
GncImportMatchMap * gnc_imap_create_from_account (Account *acc)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
|
||||
if (!acc) return NULL;
|
||||
frame = xaccAccountGetSlots (acc);
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
|
||||
return gnc_imap_create_from_frame (frame, acc, NULL);
|
||||
}
|
||||
|
||||
GncImportMatchMap * gnc_imap_create_from_book (QofBook *book)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
|
||||
if (!book) return NULL;
|
||||
frame = qof_book_get_slots (book);
|
||||
g_return_val_if_fail (frame != NULL, NULL);
|
||||
|
||||
return gnc_imap_create_from_frame (frame, NULL, book);
|
||||
}
|
||||
|
||||
/** Destroy an import map */
|
||||
void gnc_imap_destroy (GncImportMatchMap *imap)
|
||||
{
|
||||
if (!imap) return;
|
||||
g_free (imap);
|
||||
}
|
||||
|
||||
/** Clear an import map -- this removes ALL entries in the map */
|
||||
void gnc_imap_clear (GncImportMatchMap *imap)
|
||||
{
|
||||
if (!imap) return;
|
||||
xaccAccountBeginEdit (imap->acc);
|
||||
/* Clear the IMAP_FRAME kvp */
|
||||
kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME);
|
||||
|
||||
/* Clear the bayes kvp, IMAP_FRAME_BAYES */
|
||||
kvp_frame_set_slot_path (imap->frame, NULL, IMAP_FRAME_BAYES);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
|
||||
xaccAccountCommitEdit (imap->acc);
|
||||
}
|
||||
|
||||
/** Look up an Account in the map */
|
||||
Account * gnc_imap_find_account (GncImportMatchMap *imap, const char *category,
|
||||
const char *key)
|
||||
{
|
||||
kvp_value *value;
|
||||
GncGUID * guid;
|
||||
|
||||
if (!imap || !key) return NULL;
|
||||
if (!category)
|
||||
{
|
||||
category = key;
|
||||
key = NULL;
|
||||
}
|
||||
|
||||
value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME, category, key, NULL);
|
||||
if (!value) return NULL;
|
||||
|
||||
guid = kvp_value_get_guid (value);
|
||||
return xaccAccountLookup (guid, imap->book);
|
||||
}
|
||||
|
||||
/** Store an Account in the map */
|
||||
void gnc_imap_add_account (GncImportMatchMap *imap, const char *category,
|
||||
const char *key, Account *acc)
|
||||
{
|
||||
kvp_value *value;
|
||||
|
||||
if (!imap || !key || !acc || (strlen (key) == 0)) return;
|
||||
if (!category)
|
||||
{
|
||||
category = key;
|
||||
key = NULL;
|
||||
}
|
||||
g_return_if_fail (acc != NULL);
|
||||
|
||||
value = kvp_value_new_guid (xaccAccountGetGUID (acc));
|
||||
g_return_if_fail (value != NULL);
|
||||
xaccAccountBeginEdit (imap->acc);
|
||||
kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
|
||||
xaccAccountCommitEdit (imap->acc);
|
||||
kvp_value_delete (value);
|
||||
|
||||
/* XXX Mark the account (or book) as dirty! */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Below here is the bayes transaction to account matching system
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
struct account_token_count
|
||||
{
|
||||
char* account_name;
|
||||
gint64 token_count; /**< occurances of a given token for this account_name */
|
||||
};
|
||||
|
||||
/** total_count and the token_count for a given account let us calculate the
|
||||
* probability of a given account with any single token
|
||||
*/
|
||||
struct token_accounts_info
|
||||
{
|
||||
GList *accounts; /**< array of struct account_token_count */
|
||||
gint64 total_count;
|
||||
};
|
||||
|
||||
/** gpointer is a pointer to a struct token_accounts_info
|
||||
* \note Can always assume that keys are unique, reduces code in this function
|
||||
*/
|
||||
static void buildTokenInfo(const char *key, kvp_value *value, gpointer data)
|
||||
{
|
||||
struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;
|
||||
struct account_token_count* this_account;
|
||||
|
||||
// PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key,
|
||||
// (long)kvp_value_get_gint64(value));
|
||||
|
||||
/* add the count to the total_count */
|
||||
tokenInfo->total_count += kvp_value_get_gint64(value);
|
||||
|
||||
/* allocate a new structure for this account and it's token count */
|
||||
this_account = (struct account_token_count*)
|
||||
g_new0(struct account_token_count, 1);
|
||||
|
||||
/* fill in the account name and number of tokens found for this account name */
|
||||
this_account->account_name = (char*)key;
|
||||
this_account->token_count = kvp_value_get_gint64(value);
|
||||
|
||||
/* append onto the glist a pointer to the new account_token_count structure */
|
||||
tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);
|
||||
}
|
||||
|
||||
/** intermediate values used to calculate the bayes probability of a given account
|
||||
where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),
|
||||
product_difference is (1-a) * (1-b)
|
||||
*/
|
||||
struct account_probability
|
||||
{
|
||||
double product; /* product of probabilities */
|
||||
double product_difference; /* product of (1-probabilities) */
|
||||
};
|
||||
|
||||
/** convert a hash table of account names and (struct account_probability*)
|
||||
into a hash table of 100000x the percentage match value, ie. 10% would be
|
||||
0.10 * 100000 = 10000
|
||||
*/
|
||||
#define PROBABILITY_FACTOR 100000
|
||||
static void buildProbabilities(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
GHashTable *final_probabilities = (GHashTable*)data;
|
||||
struct account_probability *account_p = (struct account_probability*)value;
|
||||
|
||||
/* P(AB) = A*B / [A*B + (1-A)*(1-B)]
|
||||
* NOTE: so we only keep track of a running product(A*B*C...)
|
||||
* and product difference ((1-A)(1-B)...)
|
||||
*/
|
||||
gint32 probability =
|
||||
(account_p->product /
|
||||
(account_p->product + account_p->product_difference))
|
||||
* PROBABILITY_FACTOR;
|
||||
|
||||
PINFO("P('%s') = '%d'\n", (char*)key, probability);
|
||||
|
||||
g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
|
||||
}
|
||||
|
||||
/** Frees an array of the same time that buildProperties built */
|
||||
static void freeProbabilities(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
/* free up the struct account_probability that was allocated
|
||||
* in gnc_imap_find_account_bayes()
|
||||
*/
|
||||
g_free(value);
|
||||
}
|
||||
|
||||
/** holds an account name and its corresponding integer probability
|
||||
the integer probability is some factor of 10
|
||||
*/
|
||||
struct account_info
|
||||
{
|
||||
char* account_name;
|
||||
gint32 probability;
|
||||
};
|
||||
|
||||
/** Find the highest probability and the corresponding account name
|
||||
store in data, a (struct account_info*)
|
||||
NOTE: this is a g_hash_table_foreach() function for a hash table of entries
|
||||
key is a pointer to the account name, value is a gint32, 100000x
|
||||
the probability for this account
|
||||
*/
|
||||
static void highestProbability(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
struct account_info *account_i = (struct account_info*)data;
|
||||
|
||||
/* if the current probability is greater than the stored, store the current */
|
||||
if (GPOINTER_TO_INT(value) > account_i->probability)
|
||||
{
|
||||
/* Save the new highest probability and the assoaciated account name */
|
||||
account_i->probability = GPOINTER_TO_INT(value);
|
||||
account_i->account_name = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define threshold (.90 * PROBABILITY_FACTOR) /* 90% */
|
||||
|
||||
/** Look up an Account in the map */
|
||||
Account* gnc_imap_find_account_bayes(GncImportMatchMap *imap, GList *tokens)
|
||||
{
|
||||
struct token_accounts_info tokenInfo; /**< holds the accounts and total
|
||||
* token count for a single token */
|
||||
GList *current_token; /**< pointer to the current token from the
|
||||
* input GList *tokens */
|
||||
GList *current_account_token; /**< pointer to the struct
|
||||
* account_token_count */
|
||||
struct account_token_count *account_c; /**< an account name and the number
|
||||
* of times a token has appeared
|
||||
* for the account */
|
||||
struct account_probability *account_p; /**< intermediate storage of values
|
||||
* to compute the bayes probability
|
||||
* of an account */
|
||||
GHashTable *running_probabilities = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
GHashTable *final_probabilities = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
struct account_info account_i;
|
||||
kvp_value* value;
|
||||
kvp_frame* token_frame;
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
/* check to see if the imap is NULL */
|
||||
if (!imap)
|
||||
{
|
||||
PINFO("imap is null, returning null");
|
||||
LEAVE(" ");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the probability for each account that contains any of the tokens
|
||||
* in the input tokens list
|
||||
*/
|
||||
for (current_token = tokens; current_token; current_token = current_token->next)
|
||||
{
|
||||
/* zero out the token_accounts_info structure */
|
||||
memset(&tokenInfo, 0, sizeof(struct token_accounts_info));
|
||||
|
||||
PINFO("token: '%s'", (char*)current_token->data);
|
||||
|
||||
/* find the slot for the given token off of the source account
|
||||
* for these tokens, search off of the IMAP_FRAME_BAYES path so
|
||||
* we aren't looking from the parent of the entire kvp tree
|
||||
*/
|
||||
value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data, NULL);
|
||||
|
||||
/* if value is null we should skip over this token */
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
/* convert the slot(value) into a the frame that contains the
|
||||
* list of accounts
|
||||
*/
|
||||
token_frame = kvp_value_get_frame(value);
|
||||
|
||||
/* token_frame should NEVER be null */
|
||||
if (!token_frame)
|
||||
{
|
||||
PERR("token '%s' has no accounts", (char*)current_token->data);
|
||||
continue; /* skip over this token */
|
||||
}
|
||||
|
||||
/* process the accounts for this token, adding the account if it
|
||||
* doesn't already exist or adding to the existing accounts token
|
||||
* count if it does
|
||||
*/
|
||||
kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo);
|
||||
|
||||
/* for each account we have just found, see if the account already exists
|
||||
* in the list of account probabilities, if not add it
|
||||
*/
|
||||
for (current_account_token = tokenInfo.accounts; current_account_token;
|
||||
current_account_token = current_account_token->next)
|
||||
{
|
||||
/* get the account name and corresponding token count */
|
||||
account_c = (struct account_token_count*)current_account_token->data;
|
||||
|
||||
PINFO("account_c->account_name('%s'), "
|
||||
"account_c->token_count('%ld')/total_count('%ld')",
|
||||
account_c->account_name, (long)account_c->token_count,
|
||||
(long)tokenInfo.total_count);
|
||||
|
||||
account_p = g_hash_table_lookup(running_probabilities,
|
||||
account_c->account_name);
|
||||
|
||||
/* if the account exists in the list then continue
|
||||
* the running probablities
|
||||
*/
|
||||
if (account_p)
|
||||
{
|
||||
account_p->product =
|
||||
((double)account_c->token_count / (double)tokenInfo.total_count)
|
||||
* account_p->product;
|
||||
account_p->product_difference =
|
||||
((double)1 - ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count))
|
||||
* account_p->product_difference;
|
||||
PINFO("product == %f, product_difference == %f",
|
||||
account_p->product, account_p->product_difference);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add a new entry */
|
||||
PINFO("adding a new entry for this account");
|
||||
account_p = (struct account_probability*)
|
||||
g_new0(struct account_probability, 1);
|
||||
|
||||
/* set the product and product difference values */
|
||||
account_p->product = ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count);
|
||||
account_p->product_difference =
|
||||
(double)1 - ((double)account_c->token_count /
|
||||
(double)tokenInfo.total_count);
|
||||
|
||||
PINFO("product == %f, product_difference == %f",
|
||||
account_p->product, account_p->product_difference);
|
||||
|
||||
/* add the account name and (struct account_probability*)
|
||||
* to the hash table */
|
||||
g_hash_table_insert(running_probabilities,
|
||||
account_c->account_name, account_p);
|
||||
}
|
||||
} /* for all accounts in tokenInfo */
|
||||
|
||||
/* free the data in tokenInfo */
|
||||
for (current_account_token = tokenInfo.accounts; current_account_token;
|
||||
current_account_token = current_account_token->next)
|
||||
{
|
||||
/* free up each struct account_token_count we allocated */
|
||||
g_free((struct account_token_count*)current_account_token->data);
|
||||
}
|
||||
|
||||
g_list_free(tokenInfo.accounts); /* free the accounts GList */
|
||||
}
|
||||
|
||||
/* build a hash table of account names and their final probabilities
|
||||
* from each entry in the running_probabilties hash table
|
||||
*/
|
||||
g_hash_table_foreach(running_probabilities, buildProbabilities,
|
||||
final_probabilities);
|
||||
|
||||
/* find the highest probabilty and the corresponding account */
|
||||
memset(&account_i, 0, sizeof(struct account_info));
|
||||
g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
|
||||
|
||||
/* free each element of the running_probabilities hash */
|
||||
g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
|
||||
|
||||
/* free the hash tables */
|
||||
g_hash_table_destroy(running_probabilities);
|
||||
g_hash_table_destroy(final_probabilities);
|
||||
|
||||
PINFO("highest P('%s') = '%d'",
|
||||
account_i.account_name ? account_i.account_name : "(null)",
|
||||
account_i.probability);
|
||||
|
||||
/* has this probability met our threshold? */
|
||||
if (account_i.probability >= threshold)
|
||||
{
|
||||
PINFO("found match");
|
||||
LEAVE(" ");
|
||||
return gnc_account_lookup_by_full_name(gnc_book_get_root_account(imap->book),
|
||||
account_i.account_name);
|
||||
}
|
||||
|
||||
PINFO("no match");
|
||||
LEAVE(" ");
|
||||
|
||||
return NULL; /* we didn't meet our threshold, return NULL for an account */
|
||||
}
|
||||
|
||||
|
||||
/** Updates the imap for a given account using a list of tokens */
|
||||
void gnc_imap_add_account_bayes(GncImportMatchMap *imap, GList *tokens, Account *acc)
|
||||
{
|
||||
GList *current_token;
|
||||
kvp_value *value;
|
||||
gint64 token_count;
|
||||
char* account_fullname;
|
||||
kvp_value *new_value; /* the value that will be added back into the kvp tree */
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
/* if imap is null return */
|
||||
if (!imap)
|
||||
{
|
||||
LEAVE(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (acc != NULL);
|
||||
account_fullname = gnc_account_get_full_name(acc);
|
||||
xaccAccountBeginEdit (imap->acc);
|
||||
|
||||
PINFO("account name: '%s'\n", account_fullname);
|
||||
|
||||
/* process each token in the list */
|
||||
for (current_token = g_list_first(tokens); current_token;
|
||||
current_token = current_token->next)
|
||||
{
|
||||
/* Jump to next iteration if the pointer is not valid or if the
|
||||
string is empty. In HBCI import we almost always get an empty
|
||||
string, which doesn't work in the kvp loopkup later. So we
|
||||
skip this case here. */
|
||||
if (!current_token->data || (*((char*)current_token->data) == '\0'))
|
||||
continue;
|
||||
|
||||
/* start off with no tokens for this account */
|
||||
token_count = 0;
|
||||
|
||||
PINFO("adding token '%s'\n", (char*)current_token->data);
|
||||
|
||||
/* is this token/account_name already in the kvp tree? */
|
||||
value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data, account_fullname,
|
||||
NULL);
|
||||
|
||||
/* if the token/account is already in the tree, read the current
|
||||
* value from the tree and use this for the basis of the value we
|
||||
* are putting back
|
||||
*/
|
||||
if (value)
|
||||
{
|
||||
PINFO("found existing value of '%ld'\n",
|
||||
(long)kvp_value_get_gint64(value));
|
||||
|
||||
/* convert this value back into an integer */
|
||||
token_count += kvp_value_get_gint64(value);
|
||||
}
|
||||
|
||||
/* increment the token count */
|
||||
token_count++;
|
||||
|
||||
/* create a new value */
|
||||
new_value = kvp_value_new_gint64(token_count);
|
||||
|
||||
/* insert the value into the kvp tree at
|
||||
* /imap->frame/IMAP_FRAME/token_string/account_name_string
|
||||
*/
|
||||
kvp_frame_set_slot_path(imap->frame, new_value, IMAP_FRAME_BAYES,
|
||||
(char*)current_token->data, account_fullname, NULL);
|
||||
/* kvp_frame_set_slot_path() copied the value so we
|
||||
* need to delete this one ;-) */
|
||||
kvp_value_delete(new_value);
|
||||
}
|
||||
|
||||
/* free up the account fullname string */
|
||||
qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
|
||||
xaccAccountCommitEdit (imap->acc);
|
||||
g_free(account_fullname);
|
||||
|
||||
LEAVE(" ");
|
||||
}
|
||||
|
||||
/** @} */
|
@ -1,84 +0,0 @@
|
||||
/********************************************************************\
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
\********************************************************************/
|
||||
/** @addtogroup Import_Export
|
||||
@{ */
|
||||
/** @file import-match-map.h
|
||||
@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 Copyright (C) 2002,2003 Derek Atkins <derek@ihtfp.com>
|
||||
*/
|
||||
#ifndef GNC_IMPORT_MATCH_MAP_H
|
||||
#define GNC_IMPORT_MATCH_MAP_H
|
||||
|
||||
typedef struct _GncImportMatchMap GncImportMatchMap;
|
||||
|
||||
#include "Account.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 (QofBook *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);
|
||||
|
||||
/** Look up an Account in the map from a GList* of pointers to strings(tokens)
|
||||
from the current transaction */
|
||||
Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
|
||||
|
||||
/** Store an Account in the map. This mapping is immediatly stored in
|
||||
the underlying kvp frame, regardless of whether the MatchMap is
|
||||
destroyed later or not. */
|
||||
void gnc_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
|
||||
Account *acc);
|
||||
|
||||
|
||||
/** @name 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 */
|
||||
/**@}*/
|
@ -40,42 +40,36 @@
|
||||
* Account, Transaction and Split
|
||||
\********************************************************************/
|
||||
|
||||
const gchar * gnc_import_get_acc_online_id(Account * account)
|
||||
const gchar * gnc_import_get_acc_online_id (Account * account)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
frame = xaccAccountGetSlots(account);
|
||||
return kvp_frame_get_string(frame, "online_id");
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (account), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Used in the midst of editing a transaction; make it save the
|
||||
* account data. */
|
||||
void gnc_import_set_acc_online_id(Account * account,
|
||||
const gchar * string_value)
|
||||
void gnc_import_set_acc_online_id (Account *account, const gchar *id)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
g_return_if_fail (account != NULL);
|
||||
frame = xaccAccountGetSlots(account);
|
||||
xaccAccountBeginEdit (account);
|
||||
kvp_frame_set_str(frame, "online_id", string_value);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (account));
|
||||
qof_instance_set (QOF_INSTANCE (account), "online-id", &id, NULL);
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
const gchar * gnc_import_get_trans_online_id(Transaction * transaction)
|
||||
const gchar * gnc_import_get_trans_online_id (Transaction * transaction)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
frame = xaccTransGetSlots(transaction);
|
||||
return kvp_frame_get_string(frame, "online_id");
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
/* Not actually used */
|
||||
void gnc_import_set_trans_online_id(Transaction * transaction,
|
||||
const gchar * string_value)
|
||||
void gnc_import_set_trans_online_id (Transaction *transaction,
|
||||
const gchar *id)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
g_return_if_fail (transaction != NULL);
|
||||
xaccTransBeginEdit (transaction);
|
||||
frame = xaccTransGetSlots(transaction);
|
||||
kvp_frame_set_str (frame, "online_id", string_value);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (transaction));
|
||||
qof_instance_set (QOF_INSTANCE (transaction), "online-id", &id, NULL);
|
||||
xaccTransCommitEdit (transaction);
|
||||
}
|
||||
|
||||
@ -86,24 +80,19 @@ gboolean gnc_import_trans_has_online_id(Transaction * transaction)
|
||||
return (online_id != NULL && strlen(online_id) > 0);
|
||||
}
|
||||
|
||||
const gchar * gnc_import_get_split_online_id(Split * split)
|
||||
const gchar * gnc_import_get_split_online_id (Split * split)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
frame = xaccSplitGetSlots(split);
|
||||
return kvp_frame_get_string(frame, "online_id");
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (split), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
/* Used several places in a transaction edit where many other
|
||||
* parameters are also being set, so individual commits wouldn't be
|
||||
* appropriate. */
|
||||
void gnc_import_set_split_online_id(Split * split,
|
||||
const gchar * string_value)
|
||||
* appropriate. Besides, there isn't a function for one.*/
|
||||
void gnc_import_set_split_online_id (Split *split, const gchar *id)
|
||||
{
|
||||
kvp_frame * frame;
|
||||
xaccTransBeginEdit (xaccSplitGetParent (split));
|
||||
frame = xaccSplitGetSlots(split);
|
||||
kvp_frame_set_str (frame, "online_id", string_value);
|
||||
qof_instance_set_dirty (QOF_INSTANCE (split));
|
||||
xaccTransCommitEdit (xaccSplitGetParent (split));
|
||||
g_return_if_fail (split != NULL);
|
||||
qof_instance_set (QOF_INSTANCE (split), "online-id", &id, NULL);
|
||||
}
|
||||
|
||||
gboolean gnc_import_split_has_online_id(Split * split)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user