Sync the g2 branch with the gnome2-merge-4 tag. (2003-10-24)

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/branches/gnucash-gnome2-dev@9639 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton
2003-10-25 06:48:33 +00:00
parent f18e02a4c6
commit ab053b2149
196 changed files with 6278 additions and 5137 deletions

View File

@@ -1,3 +1,28 @@
/*********************************************************************
* businessmod-core.c
* module definition/initialization for the core Business module
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
@@ -17,13 +42,18 @@ test_string_fcn (GncAddress *address, const char *message,
static void
test_address (void)
{
QofEntity ent;
GncAddress *address;
GNCBook *book = gnc_book_new ();
QofBook *book = qof_book_new ();
ent.e_type = "asdf";
ent.guid = *guid_null();
/* Test creation/destruction */
{
do_test (gncAddressCreate (NULL, NULL, NULL) == NULL, "address create NULL");
address = gncAddressCreate (book, NULL, "x");
do_test (gncAddressCreate (NULL, NULL) == NULL, "address create NULL");
address = gncAddressCreate (book, &ent);
do_test (address != NULL, "address create");
gncAddressDestroy (address);
@@ -32,7 +62,7 @@ test_address (void)
/* Test setting routines */
{
address = gncAddressCreate (book, NULL, "x");
address = gncAddressCreate (book, &ent);
test_string_fcn (address, "Name", gncAddressSetName, gncAddressGetName);
test_string_fcn (address, "Addr1", gncAddressSetAddr1, gncAddressGetAddr1);
test_string_fcn (address, "Addr2", gncAddressSetAddr2, gncAddressGetAddr2);

View File

@@ -1,3 +1,28 @@
/*********************************************************************
* test-business.c
* Test the business code.
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
@@ -13,10 +38,10 @@
#define TEST_MODULE_DESC "Test Business"
#if 0
static GList * get_list (GNCBook *, gboolean show_all);
static GList * get_list (QofBook *, gboolean show_all);
static const char * printable (gpointer obj);
static void test_printable (const char *name, gpointer obj);
static void test_get_list (GNCBook *, const char *);
static void test_get_list (QofBook *, const char *);
static GncBusinessObject bus_obj = {
GNC_BUSINESS_VERSION,
@@ -45,12 +70,12 @@ static void test_business (void)
"test description return");
}
test_get_list ((GNCBook*)1, TEST_MODULE_NAME);
test_get_list ((QofBook*)1, TEST_MODULE_NAME);
test_printable (TEST_MODULE_NAME, (gpointer)1);
}
static GList *
get_list (GNCBook *book, gboolean show_all)
get_list (QofBook *book, gboolean show_all)
{
do_test (book != NULL, "get_list: NULL business");
success ("called get_list callback");
@@ -66,7 +91,7 @@ printable (gpointer obj)
}
static void
test_get_list (GNCBook *book, const char *name)
test_get_list (QofBook *book, const char *name)
{
GList *res;

View File

@@ -1,3 +1,28 @@
/*********************************************************************
* test-customer.c
* Test the customer object
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
@@ -13,34 +38,43 @@
static int count = 0;
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, const char *str),
const char * (*get)(GncCustomer *));
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gnc_numeric),
gnc_numeric (*get)(GncCustomer *));
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gboolean),
gboolean (*get) (GncCustomer *));
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gint),
gint (*get) (GncCustomer *));
#endif
extern QofBackend * libgncmod_backend_file_LTX_gnc_backend_new(void);
static void
test_customer (void)
{
GNCBook *book;
QofBackend *fbe;
QofBook *book;
GncCustomer *customer;
book = gnc_book_new ();
book = qof_book_new ();
/* The book *must* have a backend to pass the test of the 'dirty' flag */
/* See the README file for details */
fbe = libgncmod_backend_file_LTX_gnc_backend_new();
qof_book_set_backend (book, fbe);
/* Test creation/destruction */
{
@@ -83,12 +117,12 @@ test_customer (void)
{
GList *list;
list = gncBusinessGetList (book, GNC_CUSTOMER_MODULE_NAME, TRUE);
list = gncBusinessGetList (book, GNC_ID_CUSTOMER, TRUE);
do_test (list != NULL, "getList all");
do_test (g_list_length (list) == count, "correct length: all");
g_list_free (list);
list = gncBusinessGetList (book, GNC_CUSTOMER_MODULE_NAME, FALSE);
list = gncBusinessGetList (book, GNC_ID_CUSTOMER, FALSE);
do_test (list != NULL, "getList active");
do_test (g_list_length (list) == 1, "correct length: active");
g_list_free (list);
@@ -99,7 +133,7 @@ test_customer (void)
const char *res;
gncCustomerSetName (customer, str);
res = gncObjectPrintable (GNC_CUSTOMER_MODULE_NAME, customer);
res = gncObjectPrintable (GNC_ID_CUSTOMER, customer);
do_test (res != NULL, "Printable NULL?");
do_test (safe_strcmp (str, res) == 0, "Printable equals");
}
@@ -118,7 +152,7 @@ test_customer (void)
}
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, const char *str),
const char * (*get)(GncCustomer *))
{
@@ -137,7 +171,7 @@ test_string_fcn (GNCBook *book, const char *message,
}
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gnc_numeric),
gnc_numeric (*get)(GncCustomer *))
{
@@ -156,7 +190,7 @@ test_numeric_fcn (GNCBook *book, const char *message,
}
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gboolean),
gboolean (*get) (GncCustomer *))
{
@@ -178,7 +212,7 @@ test_bool_fcn (GNCBook *book, const char *message,
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncCustomer *, gint),
gint (*get) (GncCustomer *))
{

View File

@@ -1,10 +1,36 @@
/*********************************************************************
* test-employee.c
* Test the employee object.
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
#include "guid.h"
#include "gnc-module.h"
#include "gnc-engine-util.h"
#include "gncObject.h"
#include "qofinstance.h"
#include "qofobject.h"
#include "gncEmployee.h"
#include "gncEmployeeP.h"
@@ -13,41 +39,49 @@
static int count = 0;
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, const char *str),
const char * (*get)(GncEmployee *));
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gnc_numeric),
gnc_numeric (*get)(GncEmployee *));
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gboolean),
gboolean (*get) (GncEmployee *));
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gint),
gint (*get) (GncEmployee *));
#endif
extern QofBackend * libgncmod_backend_file_LTX_gnc_backend_new(void);
static void
test_employee (void)
{
GNCBook *book;
QofBackend *fbe;
QofBook *book;
GncEmployee *employee;
book = gnc_book_new ();
book = qof_book_new ();
/* The book *must* have a backend to pass the test of the 'dirty' flag */
/* See the README file for details */
fbe = libgncmod_backend_file_LTX_gnc_backend_new();
qof_book_set_backend (book, fbe);
/* Test creation/destruction */
{
do_test (gncEmployeeCreate (NULL) == NULL, "employee create NULL");
employee = gncEmployeeCreate (book);
do_test (employee != NULL, "employee create");
do_test (gncEmployeeGetBook (employee) == book,
do_test (qof_instance_get_book(QOF_INSTANCE(employee)) == book,
"getbook");
gncEmployeeBeginEdit (employee);
@@ -74,7 +108,7 @@ test_employee (void)
guid_new (&guid);
employee = gncEmployeeCreate (book); count++;
gncEmployeeSetGUID (employee, &guid);
do_test (guid_equal (&guid, gncEmployeeGetGUID (employee)), "guid compare");
do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(employee))), "guid compare");
}
#if 0
{
@@ -98,14 +132,14 @@ test_employee (void)
addr = gncEmployeeGetAddr (employee);
gncAddressSetName (addr, str);
res = gncObjectPrintable (GNC_EMPLOYEE_MODULE_NAME, employee);
res = qof_object_printable (GNC_ID_EMPLOYEE, employee);
do_test (res != NULL, "Printable NULL?");
do_test (safe_strcmp (str, res) == 0, "Printable equals");
}
}
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, const char *str),
const char * (*get)(GncEmployee *))
{
@@ -124,7 +158,7 @@ test_string_fcn (GNCBook *book, const char *message,
}
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gnc_numeric),
gnc_numeric (*get)(GncEmployee *))
{
@@ -143,7 +177,7 @@ test_numeric_fcn (GNCBook *book, const char *message,
}
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gboolean),
gboolean (*get) (GncEmployee *))
{
@@ -165,7 +199,7 @@ test_bool_fcn (GNCBook *book, const char *message,
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncEmployee *, gint),
gint (*get) (GncEmployee *))
{

View File

@@ -1,10 +1,35 @@
/*********************************************************************
* test-job.c
* Test the job object.
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
#include "guid.h"
#include "gnc-module.h"
#include "gnc-engine-util.h"
#include "gncObject.h"
#include "qofobject.h"
#include "gncJob.h"
#include "gncJobP.h"
@@ -13,43 +38,51 @@
static int count = 0;
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, const char *str),
const char * (*get)(GncJob *));
#if 0
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gnc_numeric),
gnc_numeric (*get)(GncJob *));
#endif
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gboolean),
gboolean (*get) (GncJob *));
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gint),
gint (*get) (GncJob *));
#endif
extern QofBackend * libgncmod_backend_file_LTX_gnc_backend_new(void);
static void
test_job (void)
{
GNCBook *book;
QofBackend *fbe;
QofBook *book;
GncJob *job;
book = gnc_book_new ();
book = qof_book_new ();
/* The book *must* have a backend to pass the test of the 'dirty' flag */
/* See the README file for details */
fbe = libgncmod_backend_file_LTX_gnc_backend_new();
qof_book_set_backend (book, fbe);
/* Test creation/destruction */
{
do_test (gncJobCreate (NULL) == NULL, "job create NULL");
job = gncJobCreate (book);
do_test (job != NULL, "job create");
do_test (gncJobGetBook (job) == book,
do_test (qof_instance_get_book(QOF_INSTANCE(job)) == book,
"getbook");
gncJobBeginEdit (job);
@@ -70,18 +103,18 @@ test_job (void)
guid_new (&guid);
job = gncJobCreate (book); count++;
gncJobSetGUID (job, &guid);
do_test (guid_equal (&guid, gncJobGetGUID (job)), "guid compare");
do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(job))), "guid compare");
}
#if 0
{
GList *list;
list = gncBusinessGetList (book, GNC_JOB_MODULE_NAME, TRUE);
list = gncBusinessGetList (book, GNC_ID_JOB, TRUE);
do_test (list != NULL, "getList all");
do_test (g_list_length (list) == count, "correct length: all");
g_list_free (list);
list = gncBusinessGetList (book, GNC_JOB_MODULE_NAME, FALSE);
list = gncBusinessGetList (book, GNC_ID_JOB, FALSE);
do_test (list != NULL, "getList active");
do_test (g_list_length (list) == 1, "correct length: active");
g_list_free (list);
@@ -92,7 +125,7 @@ test_job (void)
const char *res;
gncJobSetName (job, str);
res = gncObjectPrintable (GNC_JOB_MODULE_NAME, job);
res = qof_object_printable (GNC_ID_JOB, job);
do_test (res != NULL, "Printable NULL?");
do_test (safe_strcmp (str, res) == 0, "Printable equals");
}
@@ -122,78 +155,78 @@ test_job (void)
}
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, const char *str),
const char * (*get)(GncJob *))
{
GncJob *job = gncJobCreate (book);
char const *str = get_random_string ();
do_test (!gncJobIsDirty (job), "test if start dirty");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test if start dirty");
gncJobBeginEdit (job);
set (job, str);
do_test (gncJobIsDirty (job), "test dirty later");
do_test (qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty later");
gncJobCommitEdit (job);
do_test (!gncJobIsDirty (job), "test dirty after commit");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty after commit");
do_test (safe_strcmp (get (job), str) == 0, message);
gncJobSetActive (job, FALSE); count++;
}
#if 0
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gnc_numeric),
gnc_numeric (*get)(GncJob *))
{
GncJob *job = gncJobCreate (book);
gnc_numeric num = gnc_numeric_create (17, 1);
do_test (!gncJobIsDirty (job), "test if start dirty");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test if start dirty");
gncJobBeginEdit (job);
set (job, num);
do_test (gncJobIsDirty (job), "test dirty later");
do_test (qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty later");
gncJobCommitEdit (job);
do_test (!gncJobIsDirty (job), "test dirty after commit");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty after commit");
do_test (gnc_numeric_equal (get (job), num), message);
gncJobSetActive (job, FALSE); count++;
}
#endif
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gboolean),
gboolean (*get) (GncJob *))
{
GncJob *job = gncJobCreate (book);
gboolean num = get_random_boolean ();
do_test (!gncJobIsDirty (job), "test if start dirty");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test if start dirty");
gncJobBeginEdit (job);
set (job, FALSE);
set (job, TRUE);
set (job, num);
do_test (gncJobIsDirty (job), "test dirty later");
do_test (qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty later");
gncJobCommitEdit (job);
do_test (!gncJobIsDirty (job), "test dirty after commit");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty after commit");
do_test (get (job) == num, message);
gncJobSetActive (job, FALSE); count++;
}
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncJob *, gint),
gint (*get) (GncJob *))
{
GncJob *job = gncJobCreate (book);
gint num = 17;
do_test (!gncJobIsDirty (job), "test if start dirty");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test if start dirty");
gncJobBeginEdit (job);
set (job, num);
do_test (gncJobIsDirty (job), "test dirty later");
do_test (qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty later");
gncJobCommitEdit (job);
do_test (!gncJobIsDirty (job), "test dirty after commit");
do_test (!qof_instance_is_dirty (QOF_INSTANCE(job)), "test dirty after commit");
do_test (get (job) == num, message);
gncJobSetActive (job, FALSE); count++;
}

View File

@@ -1,3 +1,27 @@
/*********************************************************************
* test-load-module.c
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <libguile.h>

View File

@@ -1,10 +1,35 @@
/*********************************************************************
* test-vendor.c
* Test the vendor object.
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#include <glib.h>
#include <libguile.h>
#include "guid.h"
#include "gnc-module.h"
#include "gnc-engine-util.h"
#include "gncObject.h"
#include "qofobject.h"
#include "gncVendor.h"
#include "gncVendorP.h"
@@ -13,43 +38,51 @@
static int count = 0;
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, const char *str),
const char * (*get)(GncVendor *));
#if 0
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gnc_numeric),
gnc_numeric (*get)(GncVendor *));
#endif
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gboolean),
gboolean (*get) (GncVendor *));
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gint),
gint (*get) (GncVendor *));
#endif
extern QofBackend * libgncmod_backend_file_LTX_gnc_backend_new(void);
static void
test_vendor (void)
{
GNCBook *book;
QofBackend *fbe;
QofBook *book;
GncVendor *vendor;
book = gnc_book_new ();
book = qof_book_new ();
/* The book *must* have a backend to pass the test of the 'dirty' flag */
/* See the README file for details */
fbe = libgncmod_backend_file_LTX_gnc_backend_new();
qof_book_set_backend (book, fbe);
/* Test creation/destruction */
{
do_test (gncVendorCreate (NULL) == NULL, "vendor create NULL");
vendor = gncVendorCreate (book);
do_test (vendor != NULL, "vendor create");
do_test (gncVendorGetBook (vendor) == book,
do_test (qof_instance_get_book (QOF_INSTANCE(vendor)) == book,
"getbook");
gncVendorBeginEdit (vendor);
@@ -75,18 +108,18 @@ test_vendor (void)
guid_new (&guid);
vendor = gncVendorCreate (book); count++;
gncVendorSetGUID (vendor, &guid);
do_test (guid_equal (&guid, gncVendorGetGUID (vendor)), "guid compare");
do_test (guid_equal (&guid, qof_instance_get_guid(QOF_INSTANCE(vendor))), "guid compare");
}
#if 0
{
GList *list;
list = gncBusinessGetList (book, GNC_VENDOR_MODULE_NAME, TRUE);
list = gncBusinessGetList (book, GNC_ID_VENDOR, TRUE);
do_test (list != NULL, "getList all");
do_test (g_list_length (list) == count, "correct length: all");
g_list_free (list);
list = gncBusinessGetList (book, GNC_VENDOR_MODULE_NAME, FALSE);
list = gncBusinessGetList (book, GNC_ID_VENDOR, FALSE);
do_test (list != NULL, "getList active");
do_test (g_list_length (list) == 1, "correct length: active");
g_list_free (list);
@@ -97,14 +130,14 @@ test_vendor (void)
const char *res;
gncVendorSetName (vendor, str);
res = gncObjectPrintable (GNC_VENDOR_MODULE_NAME, vendor);
res = qof_object_printable (GNC_ID_VENDOR, vendor);
do_test (res != NULL, "Printable NULL?");
do_test (safe_strcmp (str, res) == 0, "Printable equals");
}
}
static void
test_string_fcn (GNCBook *book, const char *message,
test_string_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, const char *str),
const char * (*get)(GncVendor *))
{
@@ -123,7 +156,7 @@ test_string_fcn (GNCBook *book, const char *message,
#if 0
static void
test_numeric_fcn (GNCBook *book, const char *message,
test_numeric_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gnc_numeric),
gnc_numeric (*get)(GncVendor *))
{
@@ -142,7 +175,7 @@ test_numeric_fcn (GNCBook *book, const char *message,
#endif
static void
test_bool_fcn (GNCBook *book, const char *message,
test_bool_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gboolean),
gboolean (*get) (GncVendor *))
{
@@ -163,7 +196,7 @@ test_bool_fcn (GNCBook *book, const char *message,
#if 0
static void
test_gint_fcn (GNCBook *book, const char *message,
test_gint_fcn (QofBook *book, const char *message,
void (*set) (GncVendor *, gint),
gint (*get) (GncVendor *))
{

View File

@@ -3,6 +3,23 @@
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2001, 2002 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,7 +2,24 @@
* business-gnome-utils.h -- General GUI Utilities for GNC Business Objects
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2001
* Copyright (C) 2001 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_BUSINESS_GNOME_UTILS_H_

View File

@@ -3,6 +3,23 @@
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2002 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,7 +2,24 @@
* business-options.h -- Initialize the Business Options
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2002
* Copyright (C) 2002 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_BUSINESS_OPTIONS_H_

View File

@@ -3,6 +3,23 @@
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2002 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,7 +2,24 @@
* business-urls.h -- Initialize HTML for business code
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2002
* Copyright (C) 2002 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_BUSINESS_URLS_H_

View File

@@ -3,6 +3,24 @@
* module definition/initialization for the Business GNOME UI module
*
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*
*********************************************************************/
#ifdef HAVE_CONFIG_H

View File

@@ -2,6 +2,23 @@
* dialog-billterms.c -- Dialog to create and edit billing terms
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-billterms.h -- Dialog to create and edit billing terms
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef _DIALOG_BILLTERMS_H

View File

@@ -2,6 +2,23 @@
* dialog-customer.c -- Dialog for Customer entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-customer.h -- Dialog(s) for Customer search and entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
@@ -15,10 +32,10 @@ typedef struct _customer_window CustomerWindow;
/* Functions to create and edit a customer */
CustomerWindow * gnc_ui_customer_edit (GncCustomer *cust);
CustomerWindow * gnc_ui_customer_new (GNCBook *book);
CustomerWindow * gnc_ui_customer_new (QofBook *book);
/* Search for customers */
GNCSearchWindow *gnc_customer_search (GncCustomer *start, GNCBook *book);
GNCSearchWindow *gnc_customer_search (GncCustomer *start, QofBook *book);
/*
* These callbacks are for use with the gnc_general_search widget

View File

@@ -2,6 +2,23 @@
* dialog-date-close.c -- Dialog to ask a question and request a date
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-date-close.h -- Dialog to ask a question and request a date
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef _DIALOG_DATE_CLOSE_H

View File

@@ -2,6 +2,23 @@
* dialog-employee.c -- Dialog for Employee entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-employee.h -- Dialog(s) for Employee search and entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
@@ -15,10 +32,10 @@ typedef struct _employee_window EmployeeWindow;
/* Functions to edit and create employees */
EmployeeWindow * gnc_ui_employee_edit (GncEmployee *employee);
EmployeeWindow * gnc_ui_employee_new (GNCBook *book);
EmployeeWindow * gnc_ui_employee_new (QofBook *book);
/* Search for an employee */
GNCSearchWindow * gnc_employee_search (GncEmployee *start, GNCBook *book);
GNCSearchWindow * gnc_employee_search (GncEmployee *start, QofBook *book);
/*
* These callbacks are for use with the gnc_general_search widget

View File

@@ -2,6 +2,23 @@
* dialog-invoice.c -- Dialog for Invoice entry
* Copyright (C) 2001,2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"
@@ -43,7 +60,7 @@
#include "dialog-payment.h"
#include "dialog-tax-table.h"
#include "dialog-billterms.h"
#include "AccWindow.h"
#include "dialog-account.h"
#include "guile-mappings.h"
#include "dialog-query-list.h"

View File

@@ -2,6 +2,23 @@
* dialog-invoice.h -- Dialog(s) for Invoice search and entry
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
@@ -10,6 +27,7 @@
typedef struct _invoice_window InvoiceWindow;
#include "qofbook.h"
#include "gncInvoice.h"
#include "gncOwner.h"
#include "dialog-search.h"
@@ -17,10 +35,10 @@ typedef struct _invoice_window InvoiceWindow;
/* Create and edit an invoice */
InvoiceWindow * gnc_ui_invoice_edit (GncInvoice *invoice);
InvoiceWindow * gnc_ui_invoice_new (GncOwner *owner, GNCBook *book);
InvoiceWindow * gnc_ui_invoice_new (GncOwner *owner, QofBook *book);
/* Search for invoices */
GNCSearchWindow * gnc_invoice_search (GncInvoice *start, GncOwner *owner, GNCBook *book);
GNCSearchWindow * gnc_invoice_search (GncInvoice *start, GncOwner *owner, QofBook *book);
/*
* These callbacks are for use with the gnc_general_search widget
@@ -33,6 +51,6 @@ GNCSearchWindow * gnc_invoice_search_edit (gpointer start, gpointer book);
void gnc_business_call_owner_report (GncOwner *owner, Account *acc);
DialogQueryList *gnc_invoice_show_bills_due (GNCBook *book, double days_in_advance);
DialogQueryList *gnc_invoice_show_bills_due (QofBook *book, double days_in_advance);
#endif /* GNC_DIALOG_INVOICE_H_ */

View File

@@ -2,6 +2,23 @@
* dialog-job.c -- Dialog for Job entry
* Copyright (C) 2001, 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-job.h -- Dialog(s) for Job search and entry
* Copyright (C) 2001,2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/

View File

@@ -2,6 +2,23 @@
* dialog-order.c -- Dialog for Order entry
* Copyright (C) 2001,2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-order.h -- Dialog(s) for Order search and entry
* Copyright (C) 2001,2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/

View File

@@ -2,6 +2,23 @@
* dialog-payment.c -- Dialog for payment entry
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-payment.h -- Dialog to enter payments
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef _DIALOG_PAYMENT_H

View File

@@ -2,6 +2,23 @@
* dialog-vendor.c -- Dialog for Vendor entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-vendor.h -- Dialog(s) for Vendor search and entry
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
@@ -15,10 +32,10 @@ typedef struct _vendor_window VendorWindow;
/* Create or Edit Vendors */
VendorWindow * gnc_ui_vendor_edit (GncVendor *vendor);
VendorWindow * gnc_ui_vendor_new (GNCBook *book);
VendorWindow * gnc_ui_vendor_new (QofBook *book);
/* Search for vendors */
GNCSearchWindow * gnc_vendor_search (GncVendor *start, GNCBook *book);
GNCSearchWindow * gnc_vendor_search (GncVendor *start, QofBook *book);
/*
* These callbacks are for use with the gnc_general_search widget

View File

@@ -2,6 +2,23 @@
* gncEntryLedger.c -- a Ledger widget for entering GncEntry objects
* Copyright (C) 2001, 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE
@@ -11,7 +28,7 @@
#include <glib.h>
#include "Account.h"
#include "AccWindow.h"
#include "dialog-account.h"
#include "gnc-ui-util.h"
#include "combocell.h"
#include "pricecell.h"

View File

@@ -2,6 +2,23 @@
* gncEntryLedger.h -- a ledger widget for manipulating GncEntry's
* Copyright (C) 2001, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_ENTRY_LEDGER_H

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerControl.c -- Control for GncEntry ledger
* Copyright (C) 2001, 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE
@@ -11,8 +28,8 @@
#include <glib.h>
#include "Account.h"
#include "AccWindow.h"
#include "combocell.h"
#include "dialog-account.h"
#include "gnc-component-manager.h"
#include "gnc-ui.h"
#include "gnc-ui-util.h"

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerControl.h -- Control of GncEntry Manipulation Widget
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_ENTRY_LEDGER_CONTROL_H

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerDisplay.c -- handle the display management for an Entry Ledger
* Copyright (C) 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerLayout.c -- Layout for GncEntry ledger
* Copyright (C) 2001, 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerLayout.h -- Layout of GncEntry Manipulation Widget
* Copyright (C) 2001 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_ENTRY_LEDGER_LAYOUT_H

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerLoad.c -- a Ledger widget for entering GncEntry objects
* Copyright (C) 2001, 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerModel.c -- Model for GncEntry ledger
* Copyright (C) 2001, 2002, 2003 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#define _GNU_SOURCE

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerModel.h -- Model of GncEntry Manipulation Widget
* Copyright (C) 2001, 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_ENTRY_LEDGER_MODEL_H

View File

@@ -2,6 +2,23 @@
* gncEntryLedgerP.h -- a ledger widget for manipulating GncEntry's
* Copyright (C) 2001, 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_ENTRY_LEDGERP_H

View File

@@ -3,6 +3,7 @@
;;
;; By Derek Atkins <warlord@MIT.EDU> taken from the original...
;; By Robert Merkel (rgmerk@mira.net)
;; Copyright (c) 2002, 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as

View File

@@ -3,6 +3,24 @@
;; load the business report definitions
;;
;; Copyright (c) 2002 Derek Atkins <derek@ihtfp.com>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, contact:
;;
;; Free Software Foundation Voice: +1-617-542-5942
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
;; Boston, MA 02111-1307, USA gnu@gnu.org
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-module (gnucash report business-reports))

View File

@@ -2,7 +2,26 @@
;; fancy-invoice.scm -- a Fancy Invoice Report, used to print a GncInvoice
;;
;; Created by: Derek Atkins <warlord@MIT.EDU>
;; Copyright (c) 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, contact:
;;
;; Free Software Foundation Voice: +1-617-542-5942
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
;; Boston, MA 02111-1307, USA gnu@gnu.org
;; Fancy Invoice customized from "invoice.scm"
;; Customized by: Oliver Jones <gnucash at oliverstech dot com>
;;
@@ -14,13 +33,15 @@
;; Hint: you may set your default options here until a way to save report
;; options will be implemented.
;;
;; You will need to upgrade to gtkhtml-1.1 for the latest features or it won't look right.
;; gtkhtml doesn't have support for table colgroup, tbody, thead and rules
;; tags yet. When it will, the invoice will look even better.
;; You will need to upgrade to gtkhtml-1.1 for the latest features or
;; it won't look right. gtkhtml doesn't have support for table
;; colgroup, tbody, thead and rules tags yet. When it will, the
;; invoice will look even better.
;;
;; This is a quick and dirty hack. The proper way to do this (when I or someone
;; else will have time) is to have the user supply an HTML template. The most common
;; used templates will be distributed with gnucash.
;; This is a quick and dirty hack. The proper way to do this (when I
;; or someone else will have time) is to have the user supply an HTML
;; template. The most common used templates will be distributed with
;; gnucash.
(define-module (gnucash report fancy-invoice))

View File

@@ -2,7 +2,25 @@
;; invoice.scm -- an Invoice Report, used to print a GncInvoice
;;
;; Created by: Derek Atkins <warlord@MIT.EDU>
;; Copyright (c) 2002, 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, contact:
;;
;; Free Software Foundation Voice: +1-617-542-5942
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
;; Boston, MA 02111-1307, USA gnu@gnu.org
(define-module (gnucash report invoice))

View File

@@ -4,7 +4,25 @@
;; company (the owner) applied to an account.
;;
;; Created by: Derek Atkins <warlord@MIT.EDU>
;; Copyright (c) 2002, 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, contact:
;;
;; Free Software Foundation Voice: +1-617-542-5942
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
;; Boston, MA 02111-1307, USA gnu@gnu.org
(define-module (gnucash report owner-report))

View File

@@ -2,6 +2,7 @@
;; payables.scm : accounts payable aging report
;;
;; By Derek Atkins <warlord@MIT.EDU>
;; Copyright (c) 2002, 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as

View File

@@ -2,6 +2,7 @@
;; receivables.scm : accounts receivable aging report
;;
;; By Derek Atkins <warlord@MIT.EDU>
;; Copyright (c) 2002, 2003 Derek Atkins <warlord@MIT.EDU>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as

View File

@@ -3,6 +3,23 @@
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2003 Derek Atkins
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,7 +2,24 @@
* business-options.h -- non-GUI Option Utilities for GNC Business Objects
*
* Written By: Derek Atkins <warlord@MIT.EDU>
* Copyright (C) 2003
* Copyright (C) 2003 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef GNC_BUSINESS_OPTIONS_UTILS_H_

View File

@@ -105,6 +105,12 @@
gnc:*business-label* (N_ "Default Vendor TaxTable")
"f" (N_ "The default tax table to apply to vendors.")
(lambda () #f) #f))
(reg-option
(gnc:make-dateformat-option
gnc:*business-label* (N_ "Fancy Date Format")
"g" (N_ "The default date format used for fancy printed dates")
#f))
)
(gnc:register-kvp-option-generator gnc:id-book book-options-generator)

View File

@@ -3,6 +3,23 @@
* module definition/initialization for the Business Utilitizes module
*
* Copyright (c) 2003 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*********************************************************************/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-tax-table.c -- Dialog to create and edit tax-tables
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#include "config.h"

View File

@@ -2,6 +2,23 @@
* dialog-tax-table.h -- Dialog to create and edit tax-tables
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*/
#ifndef _DIALOG_TAX_TABLE_H

View File

@@ -3,6 +3,23 @@
* module definition/initialization for the Business Tax Table Dialog module
*
* Copyright (c) 2002 Derek Atkins <warlord@MIT.EDU>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652
* Boston, MA 02111-1307, USA gnu@gnu.org
*********************************************************************/
#include "config.h"

View File

@@ -349,6 +349,12 @@ Open Issues/Questions that Need Discussion:
*) How to handle business objects? e.g. vendors, customers should be
copied into both old and new books. But invoices should be in one
or the other. Need to document which is which.
Copy:
customer -- ok, has guid, has for-each
employee
No-op:
address -- do nothing
*) Discussion Q: What should the naming convention be for the different
books? When the XML file backend is used, different books need to be

View File

@@ -61,6 +61,24 @@ in an ad-hoc manner, with no governing framework. This may change,
as there is pressure to support more complex constraints that vary
by region/country, by account type, by industry, etc.
Why Not 'Lazy Evaluation'?
--------------------------
Lazy evaluation is supperfically like constraints, but differs in an
important way. With lazy evaluation, when something changes (e.g.
the posted date) it is marked dirty. Later, when something else needs
something (e.g. the posted date on a gains split), the dirty flag
is examined, and, if dirty, the new/corrected value is computed and
returned.
Simple/ad-hoc lazy evaluation works well when data dependencies are
simple, but it breaks down when there are too many/circular
relationships. It becomes all too easy to get trapped in inifite
loops of corrections. The goal of moving to a formal constraint
system is to introduce specific, well-defined sync points where
constraint checking can be done, without incuring circular
deopendencies. At this time, the sync point is the xaccTransCommitEdit()
subroutine.
List of Constraints
-------------------
The following is a list of the constraints that are currently
@@ -70,7 +88,13 @@ they are, and how they work.
-- Double Entry
-- Double-Balance
-- Date Posted of Gains Transaction
The posted date of the gains transaction is kept in sync with the
posted date on the transaction that is the source of the gains.
See the document 'lots.txt', section 'Cap Gains Actual Implementation'
for details.
-- Value of Gains Transaction
The value recorded by teh gains transaction is kept in sync with
the value

View File

@@ -281,6 +281,11 @@ inventory first. Thus, the profit/loss of the sale corresponds
to the difference in price between when it was bought and sold.
FIFO's are also used in depreciation schedules, and in other places.
Currently the only policy that is implemented in the cap-gains
code is the FIFO policy. I beleive that it's been abstracted
properly, so that it should be easy to add other policies,
e.g. LIFO. See policy.c for what would need to be implemented.
Implementation
==============
@@ -354,11 +359,6 @@ Quick API Overview:
xaccSplitAssignToLot(): If a split is not already in a lot,
then it places it into a lot, using a FIFO accounting policy.
TODO:
-- need to recompute lot membership when source split 'amount' changes.
-- need to recompute gain value when source split value changes.
-- need to copy void status when source split date changes.
Cap Gains Actual Implementation
===============================
Cap Gains are noted by creating a separate transaction with two
@@ -378,22 +378,47 @@ Things kept in sync:
Things not kept in sync:
-- kvp trees
-- description, memo, other things?
-- description, memo, action.
The posted date is kept in sync using a lazy-evaluation scheme.
The posted date is kept in sync using a data-constraint scheme.
If xaccTransactionSetDatePosted() is called, the date change is
accepted, and the split is marked date-dirty. If the posted date
is queried for (using GetDatePosted()), then the transaction is
evaluated. If its a gains-transaction, then it's date is copied
from the source transaction that created the gains.
accepted, and the split is marked date-dirty. When the transaction
is commited (using xaccTransCommitEdit()), the date-dirty flag
is evaluated, and, if needed, the date changes are propagated/rolled
back on the appropriate gains splits. Currently, one can only change
the date on the gains-source transaction; the date on teh
gains-recording split cannot be changed.
The value recorded by the gains transaction is updated whenever
the value of the source changes. The actual update is done by
the xaccSplitComputeCapGains() routine, via xaccScrubLot(), which
is called at the time of xaccTransCommitEdit(). Note that two
different things can affect the gains: a change in the value of
the sale, and a change of the value of the purchase. A set of
dirty flags are used to track these.
If the amount of a plit changes, then the lot that its in becomes
potentially unbalanced. This requires the lot membership to be
recomputed; this in turn may require the split to be split into
peices, or to be recombined into one from several pieces.
TODO:
-- need to copy void status when source split date changes.
-- its possible for the the price, as recorded by one split
to vary wildly from that in another split in the same
transaction. That's bad, prices should be normalized.
Theres a routine to do this, xaccScrubSubSplitPrice()
but its not currently used.
-- write automated test cases to handle each situation.
Conversion
==========
As Lots are put into production, old GnuCash datasets
will need to be converted. Conversion will be done by running
all splits in an account through an accounting FIFO. The goal
of the FIFO is to match up purchases and sales so that these can
be assigned to a Lot.
all splits in an account through an accounting policy (currently,
there is only one policy, a FIFO). The goal of the policy is to
match up purchases and sales so that these can be assigned to a Lot.
The conversion algorithm will work as follows:
@@ -409,7 +434,8 @@ for each account {
}
}
See the file Scrub2.h for details.
See the file Scrub2.h for details of teh low-level API, and Scrub3.h
for the high-level API.
There is a bit of a problem with this conversion proceedure: If the
user had prviously recorded cap gains using a 'handmade' version of
@@ -463,6 +489,10 @@ Basic GUI:
-- button or menu item, 'add notes to this lot'.
todo:
---- change lot viewer to use gnc-query-list
---- after the gnome2 port, add the 'unclaimed splits" window
to the lot viewer, this will allow it to be a simple lot editor.
Status
@@ -477,6 +507,13 @@ Status
These implement a FIFO accounting policy (April 2003)
o Closed/Open lots are handled correctly during book closing.
See src/engine/Period.c (August 2003)
o Work is finished on the automatic computation & tracking
of gain/loss transactions. Most of the engine API is in
src/engine/cap-gains.h although the high-level 'scrub' API
is in src/engine/Scrub3.h. See src/doc/constraints.txt for
a 'big picture' view of how its done. (September 2003)
o A basic lot-viewing GUI is in src/gnome/lot-viewer.c
This GUI cannot 'edit' lots. (August 2003)
o The Postgres backend does not yet support lots.
XXX In particular, the programming API for Lots is currently
@@ -484,14 +521,10 @@ Status
signalled that the lots have changed. This is the case both for
Scrub2.c and for src/gnome/lot-viewer.c (which changes KVP's).
o prototype lot-viewing GUI in src/gnome/lot-viewer.c
This GUI cannot 'edit' lots.
o Need to write extensive test cases to verify the rather complex
constraints between the gains and lots and splits.
o Work has begun on the automatic computation & tracking of gain/loss
transactions. See src/engine/cap-gains.h Routines now exist to
compute these. Need to add infrastructure to auto-recompute as
needed, make use of this in register gui's, etc. A lot of work left.
In particular, what about the cap-gains report?
o Need to write a cap-gains report!

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,8 @@
#include "guid.h"
#include "kvp_frame.h"
#include "qofbook.h"
#include "qofid.h"
#include "qofinstance.h"
typedef gnc_numeric (*xaccGetBalanceFn)( Account *account );
@@ -39,6 +41,9 @@ typedef gnc_numeric (*xaccGetBalanceInCurrencyFn) (Account *account,
gnc_commodity *report_commodity,
gboolean include_children);
#define GNC_IS_ACCOUNT(obj) (QOF_CHECK_TYPE((obj), GNC_ID_ACCOUNT))
#define GNC_ACCOUNT(obj) (QOF_CHECK_CAST((obj), GNC_ID_ACCOUNT, Account))
/** The account types are used to determine how the transaction data
* in the account is displayed. These values can be safely changed
* from one release to the next. Note that if values are added,
@@ -105,17 +110,24 @@ typedef enum
/** Constructor */
Account * xaccMallocAccount (QofBook *book);
/** The xaccCloneAccount() does the same as xaccCloneAccountSimple, except that it
* also uses the 'gemini' kvp value to mark the account from
* which it was copied. */
/** The xaccCloneAccount() does the same as xaccCloneAccountSimple(),
* except that it also also places a pair of GUID-pointers
* of each account to the other, in the other's kvp slot.
* The guid pointers are stored under the under the kvp
* path "gemini".
*/
Account * xaccCloneAccount (const Account *from, QofBook *book);
/** The xaccCloneAccountSimple() routine makes a simple copy of the
* indicated account, placing it in the indicated book. It copies
* the account type, name, description, and the kvp values;
* it does not copy splits/transactions. Note also that it
* does NOT use the 'gemini' kvp value to indicate where it
* was copied from.*/
* it does not copy splits/transactions. The book should have
* a commodity table in it that has commodities with the same
* unique name as the ones being copied in the account (the
* commodities in the clone will be those from the book).
* Note that this routines does *NOT* use the 'gemini' kvp value
* to indicate where it was copied from.
*/
Account * xaccCloneAccountSimple (const Account *from, QofBook *book);
/** The xaccAccountBeginEdit() subroutine is the first phase of
@@ -151,36 +163,17 @@ int xaccAccountOrder (Account **account_1, Account **account_2);
/** @name Account lookup and GUID routines */
/** @{ */
/** The xaccAccountGetGUID() subroutine will return the
* globally unique id associated with that account. */
const GUID * xaccAccountGetGUID (Account *account);
/** The xaccAccountReturnGUID() subroutine returns the
* same GUID as xaccAccountGetGUID, but as a struct. */
GUID xaccAccountReturnGUID (Account *account);
/** deprecated */
#define xaccAccountGetBook(X) qof_instance_get_book(QOF_INSTANCE(X))
#define xaccAccountGetGUID(X) qof_entity_get_guid(QOF_ENTITY(X))
#define xaccAccountReturnGUID(X) (*(qof_entity_get_guid(QOF_ENTITY(X))))
/** The xaccAccountLookup() subroutine will return the
* account associated with the given id, or NULL
* if there is no such account. */
Account * xaccAccountLookup (const GUID *guid, QofBook *book);
#define xaccAccountLookupDirect(g,b) xaccAccountLookup(&(g),b)
/** xaccAccountLookupDirect performs the same function as
* xaccAccountLookup but takes a GUID struct directly. */
Account * xaccAccountLookupDirect (GUID guid, QofBook *book);
/** The xaccAccountLookupTwin() routine will find the "twin" of this
* account 'acc' in the given other 'book' (if the twin exists).
*
* When accounts are copied or cloned, both of the pair are marked
* with the guid of thier copy, thus allowing the sibling-copy of
* an account to be found. Since the sibling may end up in a
* different book, we need a way of finding it, given only that we
* know the book, and that we know its twin.
*
* That's what this routine does. Given some book 'book', and an
* account 'acc', it will find the sibling account of 'acc' that is
* in 'book', and return it. If not found, it returns NULL. This
* routine uses the 'gemini' kvp values to do its work. */
Account * xaccAccountLookupTwin (Account *acc, QofBook *book);
/** @} */
/* ------------------ */
@@ -188,8 +181,6 @@ Account * xaccAccountLookupTwin (Account *acc, QofBook *book);
/** @name Account general setters/getters */
/** @{ */
/** @return The book where the account is stored */
QofBook * xaccAccountGetBook (Account *account);
/** Set the account's type */
void xaccAccountSetType (Account *account, GNCAccountType);
@@ -416,15 +407,11 @@ gboolean xaccAccountGetReconcileChildrenStatus(Account *account);
* Returns false if either one is NULL.
*/
gboolean xaccAccountHasAncestor (Account *account, Account *ancestor);
#define xaccAccountGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
/** @} */
/* ------------------ */
/** @name Account KvpFrame getters/setters */
/** @{ */
KvpFrame * xaccAccountGetSlots (Account *account);
void xaccAccountSetSlots_nc(Account *account, KvpFrame *frame);
/** @} */
/* ------------------ */
@@ -578,8 +565,6 @@ LotList * xaccAccountFindOpenLots (Account *acc,
gpointer user_data, GCompareFunc sort_func);
/*@}*/
/* ------------------ */
/** @name Account Reconciliation information getters/setters */

View File

@@ -46,9 +46,13 @@
#include "gnc-engine.h"
#include "gnc-numeric.h"
#include "kvp_frame.h"
#include "policy.h"
#include "qofbackend.h"
#include "qofbook.h"
#include "qofid.h"
#include "qofinstance.h"
#include "qofinstance-p.h"
/** STRUCTS *********************************************************/
@@ -60,10 +64,7 @@
*/
struct account_s
{
/* public data, describes account */
GUID guid; /* globally unique account id */
QofBook *book; /* the entity_table in which this account is stored */
QofInstance inst;
/* The accountName is an arbitrary string assigned by the user.
* It is intended to a short, 5 to 30 character long string that
@@ -86,12 +87,6 @@ struct account_s
*/
char *description;
/* kvp_data is a key-value pair database for storing simple "extra"
* information in splits, transactions, and accounts. it's NULL
* until accessed. See src/engine/kvp_doc.txt for a list and
* description of the important keys. */
KvpFrame * kvp_data;
/* The type field is the account type, picked from the enumerated
* list that includes BANK, STOCK, CREDIT, INCOME, etc. Its
* intended use is to be a hint to the GUI as to how to display
@@ -130,13 +125,11 @@ struct account_s
SplitList *splits; /* list of split pointers */
LotList *lots; /* list of lot pointers */
/* keep track of nesting level of begin/end edit calls */
gint32 editlevel;
/* Cached pointer to policy method */
GNCPolicy *policy;
gboolean balance_dirty; /* balances in splits incorrect */
gboolean sort_dirty; /* sort order of splits is bad */
gboolean core_dirty; /* fields in this struct have changed */
gboolean do_free; /* in process of being destroyed */
/* The "mark" flag can be used by the user to mark this account
* in any way desired. Handy for specialty traversals of the
@@ -206,14 +199,12 @@ void xaccFreeAccount (Account *account);
void xaccAccountSetVersion (Account*, gint32);
gint32 xaccAccountGetVersion (Account*);
/*
* The xaccGetAccountBackend() subroutine will find the
* persistent-data storage backend associated with this account.
*/
QofBackend * xaccAccountGetBackend (Account *account);
/* Register Accounts with the engine */
gboolean xaccAccountRegister (void);
/** killed for now, need to resurect this or something similar
* * for transactional/dirty kvp. Later. Right now a place holder
* */
#define xaccAccountSetSlots_nc(A,S) qof_instance_set_slots(QOF_INSTANCE(A),S)
#endif /* XACC_ACCOUNT_P_H */

File diff suppressed because it is too large Load Diff

View File

@@ -52,14 +52,17 @@ Currently the only files which include this file are:
*
* This still needs to deal with:
* . exceptions
* . 13 periods: (4 weeks/period 4x13=52 weeks/year)
* . yearly 360/365?
* . re-based frequencies [based around a non-standard [read:
* not-Jan-1-based/fiscal] year]
* . "business days" -- m-f sans holidays [per-user list thereof]
**/
struct gncp_freq_spec {
struct gncp_freq_spec
{
QofEntity entity;
FreqType type;
UIFreqType uift;
UIFreqType uift;
union u {
struct {
/** The date on which the single event occurs. */
@@ -107,8 +110,6 @@ struct gncp_freq_spec {
GList *subSpecs;
} composites;
} s;
GUID guid;
QofEntityTable *entity_table;
};
#endif /* XACC_FREQSPECP_H */

View File

@@ -6,8 +6,7 @@
* QofIdType xaccGUIDType (const GUID * guid, QofBook *book);
*/
#define xaccGUIDType(guid,book) \
qof_entity_type (qof_book_get_entity_table (book), (guid))
#define xaccGUIDType(obj,book) (QOF_ENTITY(obj)->e_type)
/* Equivalent function prototype:
* void xaccGUIDNew (GUID *guid, QofBook *book)

View File

@@ -84,33 +84,51 @@ xaccMallocAccountGroup (QofBook *book)
/********************************************************************\
\********************************************************************/
#define GNC_TOP_GROUP "gnc_top_group"
AccountGroup *
xaccCollGetAccountGroup (QofCollection *col)
{
if (!col) return NULL;
return qof_collection_get_data (col);
}
void
xaccCollSetAccountGroup (QofCollection *col, AccountGroup *grp)
{
AccountGroup *old_grp;
if (!col) return;
old_grp = xaccCollGetAccountGroup (col);
if (old_grp == grp) return;
qof_collection_set_data (col, grp);
xaccAccountGroupBeginEdit (old_grp);
xaccAccountGroupDestroy (old_grp);
}
AccountGroup *
xaccGetAccountGroup (QofBook *book)
{
if (!book) return NULL;
return qof_book_get_data (book, GNC_TOP_GROUP);
QofCollection *col;
if (!book) return NULL;
col = qof_book_get_collection (book, GNC_ID_GROUP);
return xaccCollGetAccountGroup (col);
}
void
xaccSetAccountGroup (QofBook *book, AccountGroup *grp)
{
AccountGroup *old_grp;
QofCollection *col;
if (!book) return;
old_grp = xaccGetAccountGroup (book);
if (old_grp == grp) return;
if (grp && grp->book != book)
{
PERR ("cannot mix and match books freely!");
return;
}
qof_book_set_data (book, GNC_TOP_GROUP, grp);
xaccAccountGroupBeginEdit (old_grp);
xaccAccountGroupDestroy (old_grp);
col = qof_book_get_collection (book, GNC_ID_GROUP);
xaccCollSetAccountGroup (col, grp);
}
/********************************************************************\
@@ -225,7 +243,7 @@ xaccGroupMarkDoFree (AccountGroup *grp)
for (node = grp->accounts; node; node = node->next)
{
Account *account = node->data;
account->do_free = TRUE;
account->inst.do_free = TRUE;
xaccGroupMarkDoFree (account->children);
}
}
@@ -277,13 +295,13 @@ xaccFreeAccountGroup (AccountGroup *grp)
/* FIXME: this and the same code below is kind of hacky.
* actually, all this code seems to assume that
* the account edit levels are all 1. */
if (account->editlevel == 0)
if (account->inst.editlevel == 0)
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
}
account = grp->accounts->data;
if (account->editlevel == 0)
if (account->inst.editlevel == 0)
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
@@ -632,7 +650,7 @@ xaccAccountRemoveGroup (Account *acc)
grp->saved = 0;
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_MODIFY);
}
/********************************************************************\
@@ -653,7 +671,7 @@ xaccGroupRemoveAccount (AccountGroup *grp, Account *acc)
return;
}
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_REMOVE);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_REMOVE);
acc->parent = NULL;
@@ -669,7 +687,7 @@ xaccGroupRemoveAccount (AccountGroup *grp, Account *acc)
xaccFreeAccountGroup (grp);
}
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_MODIFY);
}
/********************************************************************\
@@ -682,7 +700,7 @@ xaccAccountInsertSubAccount (Account *adult, Account *child)
/* if a container for the children doesn't yet exist, add it */
if (adult->children == NULL)
adult->children = xaccMallocAccountGroup (adult->book);
adult->children = xaccMallocAccountGroup (adult->inst.book);
/* set back-pointer to parent */
adult->children->parent = adult;
@@ -692,7 +710,7 @@ xaccAccountInsertSubAccount (Account *adult, Account *child)
xaccGroupInsertAccount (adult->children, child);
gnc_engine_generate_event (&adult->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&adult->inst.entity, GNC_EVENT_MODIFY);
}
/********************************************************************\
@@ -731,8 +749,9 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
xaccGroupRemoveAccount (acc->parent, acc);
/* switch over between books, if needed */
if (grp->book != acc->book)
if (grp->book != acc->inst.book)
{
QofCollection *col;
// xxxxxxxxxxxxxxxxxxxxxxx
/* hack alert -- this implementation is not exactly correct.
* If the entity tables are not identical, then the 'from' book
@@ -747,11 +766,10 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
*/
PWARN ("reparenting accounts accross books is not correctly supported\n");
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_DESTROY);
qof_entity_remove (acc->book->entity_table, &acc->guid);
qof_entity_store (grp->book->entity_table, acc, &acc->guid, GNC_ID_ACCOUNT);
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_CREATE);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_DESTROY);
col = qof_book_get_collection (grp->book, GNC_ID_ACCOUNT);
qof_collection_insert_entity (col, &acc->inst.entity);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_CREATE);
}
}
@@ -760,15 +778,15 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
grp->accounts = g_list_insert_sorted (grp->accounts, acc,
group_sort_helper);
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_ADD);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_ADD);
acc->core_dirty = TRUE;
acc->inst.dirty = TRUE;
xaccAccountCommitEdit (acc);
}
grp->saved = 0;
gnc_engine_generate_event (&acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_MODIFY);
}
/********************************************************************\
@@ -826,9 +844,9 @@ xaccGroupCopyGroup (AccountGroup *to, AccountGroup *from)
group_sort_helper);
to_acc->parent = to;
to_acc->core_dirty = TRUE;
to_acc->inst.dirty = TRUE;
/* copy child accounts too. */
/* Copy child accounts too. */
if (from_acc->children)
{
to_acc->children = xaccMallocAccountGroup (to->book);
@@ -836,7 +854,7 @@ xaccGroupCopyGroup (AccountGroup *to, AccountGroup *from)
xaccGroupCopyGroup (to_acc->children, from_acc->children);
}
xaccAccountCommitEdit (to_acc);
gnc_engine_generate_event (&to_acc->guid, GNC_ID_ACCOUNT, GNC_EVENT_CREATE);
gnc_engine_gen_event (&to_acc->inst.entity, GNC_EVENT_CREATE);
/* make sure that we have a symmetric, uniform number of
* begin-edits, so that subsequent GroupCommitEdit's
@@ -896,14 +914,14 @@ xaccGroupMergeAccounts (AccountGroup *grp)
gb->parent = acc_a;
acc_b->children = NULL;
gnc_engine_generate_event (&acc_a->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_generate_event (&acc_b->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc_a->inst.entity, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc_b->inst.entity, GNC_EVENT_MODIFY);
}
else
{
xaccGroupConcatGroup (ga, gb);
acc_b->children = NULL;
gnc_engine_generate_event (&acc_b->guid, GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&acc_b->inst.entity, GNC_EVENT_MODIFY);
}
}
@@ -917,8 +935,8 @@ xaccGroupMergeAccounts (AccountGroup *grp)
{
Split *split = lp->data;
gnc_engine_generate_event (&xaccSplitGetAccount(split)->guid,
GNC_ID_ACCOUNT, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&xaccSplitGetAccount(split)->inst.entity,
GNC_EVENT_MODIFY);
split->acc = NULL;
xaccAccountInsertSplit (acc_a, split);
}
@@ -930,7 +948,7 @@ xaccGroupMergeAccounts (AccountGroup *grp)
node_b = node_b->prev;
/* remove from list -- node_a is ok, it's before node_b */
gnc_engine_generate_event (&acc_b->guid, GNC_ID_ACCOUNT, GNC_EVENT_REMOVE);
gnc_engine_gen_event (&acc_b->inst.entity, GNC_EVENT_REMOVE);
grp->accounts = g_list_remove (grp->accounts, acc_b);
xaccAccountBeginEdit (acc_b);
@@ -1233,21 +1251,21 @@ group_book_end (QofBook *book)
}
static gboolean
group_is_dirty (QofBook *book)
group_is_dirty (QofCollection *col)
{
return xaccGroupNotSaved(xaccGetAccountGroup(book));
return xaccGroupNotSaved(xaccCollGetAccountGroup(col));
}
static void
group_mark_clean(QofBook *book)
group_mark_clean(QofCollection *col)
{
xaccGroupMarkSaved(xaccGetAccountGroup(book));
xaccGroupMarkSaved(xaccCollGetAccountGroup(col));
}
static QofObject group_object_def =
{
interface_version: QOF_OBJECT_VERSION,
name: GNC_ID_GROUP,
e_type: GNC_ID_GROUP,
type_label: "AccountGroup",
book_begin: group_book_begin,
book_end: group_book_end,

View File

@@ -46,6 +46,7 @@ AccountGroup *xaccMallocAccountGroup (QofBook *book);
* account group associated with the indicated book.
*/
AccountGroup * xaccGetAccountGroup (QofBook *book);
AccountGroup * xaccCollGetAccountGroup (QofCollection *col);
/*
* The xaccAccountDestroy() routine will destroy and free all

View File

@@ -95,6 +95,7 @@ void xaccFreeAccountGroup (AccountGroup *account_group);
/* Set the top-level group in the book */
void xaccSetAccountGroup (QofBook *book, AccountGroup *grp);
void xaccCollSetAccountGroup (QofCollection *col, AccountGroup *grp);
/*
* The xaccGroupGetBackend() subroutine will find the

View File

@@ -44,11 +44,12 @@ libgncmod_engine_la_SOURCES = \
policy.c \
qofbackend.c \
qofbook.c \
qofclass.c \
qofid.c \
qofinstance.c \
qofobject.c \
qofquery.c \
qofquerycore.c \
qofqueryobject.c \
qofsession.c
EXTRA_libgncmod_engine_la_SOURCES = iso-4217-currencies.c
@@ -98,11 +99,12 @@ gncinclude_HEADERS = \
qof.h \
qofbackend.h \
qofbook.h \
qofclass.h \
qofid.h \
qofinstance.h \
qofobject.h \
qofquery.h \
qofquerycore.h \
qofqueryobject.h \
qofsession.h
noinst_HEADERS = \
@@ -126,11 +128,12 @@ noinst_HEADERS = \
policy-p.h \
qofbackend-p.h \
qofbook-p.h \
qofclass-p.h \
qofid-p.h \
qofinstance-p.h \
qofobject-p.h \
qofquery-p.h \
qofquerycore-p.h \
qofqueryobject-p.h \
qofsession-p.h
noinst_SCRIPTS = iso-currencies-to-c

View File

@@ -54,6 +54,14 @@
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_BOOK;
/* ================================================================ */
static inline Account *
xaccAccountLookupTwin (Account *acc, QofBook *book)
{
return (Account *) qof_instance_lookup_twin (QOF_INSTANCE(acc), book);
}
/* ================================================================ */
/* Reparent transaction to new book. This routine does this by
* deleting the transaction in the old book, and creating a copy
@@ -64,13 +72,14 @@ static short module = MOD_BOOK;
void
gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
{
QofCollection *col;
Transaction *newtrans;
GList *node;
if (!trans || !book) return;
/* If this is the same book, its a no-op. */
if (trans->book == book) return;
if (trans->inst.book == book) return;
ENTER ("trans=%p %s", trans, trans->description);
newtrans = xaccDupeTransaction (trans);
@@ -85,10 +94,12 @@ gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
xaccTransDestroy (trans);
xaccTransCommitEdit (trans);
/* fiddle the transaction into place in the new book */
qof_entity_store(book->entity_table, newtrans, &newtrans->guid, GNC_ID_TRANS);
newtrans->book = book;
/* Fiddle the transaction into place in the new book */
col = qof_book_get_collection (book, GNC_ID_TRANS);
qof_collection_insert_entity (col, &newtrans->inst.entity);
newtrans->inst.book = book;
col = qof_book_get_collection (book, GNC_ID_SPLIT);
xaccTransBeginEdit (newtrans);
for (node = newtrans->splits; node; node = node->next)
{
@@ -97,7 +108,7 @@ gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
/* move the split into the new book ... */
s->book = book;
qof_entity_store(book->entity_table, s, &s->guid, GNC_ID_SPLIT);
qof_collection_insert_entity(col, &s->entity);
/* find the twin account, and re-parent to that. */
twin = xaccAccountLookupTwin (s->acc, book);
@@ -114,7 +125,7 @@ gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
}
xaccTransCommitEdit (newtrans);
gnc_engine_generate_event (&newtrans->guid, GNC_ID_TRANS, GNC_EVENT_CREATE);
gnc_engine_gen_event (&newtrans->inst.entity, GNC_EVENT_CREATE);
LEAVE ("trans=%p %s", trans, trans->description);
}
@@ -126,16 +137,17 @@ gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
void
gnc_book_insert_trans (QofBook *book, Transaction *trans)
{
QofCollection *col;
GList *node;
if (!trans || !book) return;
/* If this is the same book, its a no-op. */
if (trans->book == book) return;
if (trans->inst.book == book) return;
/* If the old and new book don't share backends, then clobber-copy;
* i.e. destroy it in one backend, create it in another. */
if (book->backend != trans->book->backend)
if (book->backend != trans->inst.book->backend)
{
gnc_book_insert_trans_clobber (book, trans);
return;
@@ -145,10 +157,11 @@ gnc_book_insert_trans (QofBook *book, Transaction *trans)
/* Fiddle the transaction into place in the new book */
xaccTransBeginEdit (trans);
qof_entity_remove (trans->book->entity_table, &trans->guid);
trans->book = book;
qof_entity_store(book->entity_table, trans, &trans->guid, GNC_ID_TRANS);
col = qof_book_get_collection (book, GNC_ID_TRANS);
trans->inst.book = book;
qof_collection_insert_entity (col, &trans->inst.entity);
col = qof_book_get_collection (book, GNC_ID_SPLIT);
for (node = trans->splits; node; node = node->next)
{
Account *twin;
@@ -157,9 +170,8 @@ gnc_book_insert_trans (QofBook *book, Transaction *trans)
/* Move the splits over (only if they haven't already been moved). */
if (s->book != book)
{
qof_entity_remove (s->book->entity_table, &s->guid);
s->book = book;
qof_entity_store(book->entity_table, s, &s->guid, GNC_ID_SPLIT);
qof_collection_insert_entity (col, &s->entity);
}
/* Find the twin account, and re-parent to that. */
@@ -181,7 +193,7 @@ gnc_book_insert_trans (QofBook *book, Transaction *trans)
}
xaccTransCommitEdit (trans);
gnc_engine_generate_event (&trans->guid, GNC_ID_TRANS, GNC_EVENT_MODIFY);
gnc_engine_gen_event (&trans->inst.entity, GNC_EVENT_MODIFY);
LEAVE ("trans=%p %s", trans, trans->description);
}
@@ -204,6 +216,7 @@ gnc_book_insert_lot_clobber (QofBook *book, GNCLot *lot)
void
gnc_book_insert_lot (QofBook *book, GNCLot *lot)
{
QofCollection *col;
SplitList *snode;
Account *twin;
if (!lot || !book) return;
@@ -217,19 +230,20 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot)
return;
}
ENTER ("lot=%p", lot);
qof_entity_remove (lot->book->entity_table, &lot->guid);
col = qof_book_get_collection (book, GNC_ID_LOT);
lot->book = book;
qof_entity_store(book->entity_table, lot, &lot->guid, GNC_ID_LOT);
qof_collection_insert_entity (col, &lot->entity);
/* Move the splits over (only if they haven't already been moved). */
col = qof_book_get_collection (book, GNC_ID_SPLIT);
for (snode = lot->splits; snode; snode=snode->next)
{
Split *s = snode->data;
if (s->book != book)
{
qof_entity_remove (s->book->entity_table, &s->guid);
s->book = book;
qof_entity_store(book->entity_table, s, &s->guid, GNC_ID_SPLIT);
qof_collection_insert_entity (col, &s->entity);
}
}
@@ -250,14 +264,15 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot)
void
gnc_book_insert_price (QofBook *book, GNCPrice *pr)
{
QofCollection *col;
if (!pr || !book) return;
/* If this is the same book, its a no-op. */
if (pr->book == book) return;
if (pr->inst.book == book) return;
/* If the old and new book don't share backends, then clobber-copy;
* i.e. destroy it in one backend, create it in another. */
if (book->backend != pr->book->backend)
if (book->backend != pr->inst.book->backend)
{
gnc_book_insert_price_clobber (book, pr);
return;
@@ -268,9 +283,9 @@ gnc_book_insert_price (QofBook *book, GNCPrice *pr)
gnc_price_ref (pr);
gnc_price_begin_edit (pr);
qof_entity_remove (pr->book->entity_table, &pr->guid);
pr->book = book;
qof_entity_store(book->entity_table, pr, &pr->guid, GNC_ID_PRICE);
col = qof_book_get_collection (book, GNC_ID_PRICE);
pr->inst.book = book;
qof_collection_insert_entity (col, &pr->inst.entity);
gnc_pricedb_remove_price (pr->db, pr);
gnc_pricedb_add_price (gnc_pricedb_get_db (book), pr);
@@ -583,8 +598,12 @@ gnc_book_partition_txn (QofBook *dest_book, QofBook *src_book, QofQuery *query)
/* Make note of the sibling books */
now = time(0);
gnc_kvp_gemini (src_book->kvp_data, now, "book_guid", &dest_book->guid, NULL);
gnc_kvp_gemini (dest_book->kvp_data, now, "book_guid", &src_book->guid, NULL);
gnc_kvp_bag_add (src_book->kvp_data, "gemini", now,
"book_guid", &dest_book->entity.guid,
NULL);
gnc_kvp_bag_add (dest_book->kvp_data, "gemini", now,
"book_guid", &src_book->entity.guid,
NULL);
LEAVE (" ");
}
@@ -674,19 +693,19 @@ add_closing_balances (AccountGroup *closed_grp,
xaccAccountBeginEdit (twin);
cwd = xaccAccountGetSlots (twin);
kvp_frame_set_guid (cwd, "/book/prev-acct", xaccAccountGetGUID (candidate));
kvp_frame_set_guid (cwd, "/book/prev-book", &closed_book->guid);
kvp_frame_set_guid (cwd, "/book/prev-book", &closed_book->entity.guid);
xaccAccountSetSlots_nc (twin, twin->kvp_data);
xaccAccountSetSlots_nc (twin, twin->inst.kvp_data);
/* -------------------------------- */
/* Add KVP to closed account, indicating where
* the next book is. */
xaccAccountBeginEdit (candidate);
cwd = xaccAccountGetSlots (candidate);
kvp_frame_set_guid (cwd, "/book/next-book", &open_book->guid);
kvp_frame_set_guid (cwd, "/book/next-book", &open_book->entity.guid);
kvp_frame_set_guid (cwd, "/book/next-acct", xaccAccountGetGUID (twin));
xaccAccountSetSlots_nc (candidate, candidate->kvp_data);
xaccAccountSetSlots_nc (candidate, candidate->inst.kvp_data);
/* -------------------------------- */
/* We need to carry a balance on any account that is not
@@ -741,7 +760,7 @@ add_closing_balances (AccountGroup *closed_grp,
/* Add KVP data showing where the balancing
* transaction came from */
cwd = xaccTransGetSlots (trans);
kvp_frame_set_guid (cwd, "/book/closed-book", &closed_book->guid);
kvp_frame_set_guid (cwd, "/book/closed-book", &closed_book->entity.guid);
kvp_frame_set_guid (cwd, "/book/closed-acct", xaccAccountGetGUID(candidate));
xaccTransCommitEdit (trans);
@@ -819,7 +838,7 @@ gnc_book_close_period (QofBook *existing_book, Timespec calve_date,
if (!existing_book) return NULL;
ENTER (" date=%s memo=%s", gnc_print_date(calve_date), memo);
/* Setup closuing book */
/* Setup closing book */
closing_book = qof_book_new();
qof_book_set_backend (closing_book, existing_book->backend);
closing_book->book_open = 'n';
@@ -864,8 +883,8 @@ gnc_book_close_period (QofBook *existing_book, Timespec calve_date,
kvp_frame_set_timespec (partn_cwd, "/book/log-date", ts);
/* Set up pointers to each book from the other. */
kvp_frame_set_guid (partn_cwd, "/book/next-book", &existing_book->guid);
kvp_frame_set_guid (exist_cwd, "/book/prev-book", &closing_book->guid);
kvp_frame_set_guid (partn_cwd, "/book/next-book", &existing_book->entity.guid);
kvp_frame_set_guid (exist_cwd, "/book/prev-book", &closing_book->entity.guid);
/* add in transactions to equity accounts that will
* hold the colsing balances */

View File

@@ -55,14 +55,14 @@
#define gncQueryCorePredicateEqual qof_query_core_predicate_equal
#define QUERYCORE_GUID QOF_QUERYCORE_GUID
#define QUERYCORE_DEBCRED QOF_QUERYCORE_DEBCRED
#define QUERYCORE_BOOLEAN QOF_QUERYCORE_BOOLEAN
#define QUERYCORE_NUMERIC QOF_QUERYCORE_NUMERIC
#define QUERYCORE_STRING QOF_QUERYCORE_STRING
#define QUERYCORE_DATE QOF_QUERYCORE_DATE
#define QUERYCORE_INT64 QOF_QUERYCORE_INT64
#define QUERYCORE_DOUBLE QOF_QUERYCORE_DOUBLE
#define QUERYCORE_GUID QOF_TYPE_GUID
#define QUERYCORE_DEBCRED QOF_TYPE_DEBCRED
#define QUERYCORE_BOOLEAN QOF_TYPE_BOOLEAN
#define QUERYCORE_NUMERIC QOF_TYPE_NUMERIC
#define QUERYCORE_STRING QOF_TYPE_STRING
#define QUERYCORE_DATE QOF_TYPE_DATE
#define QUERYCORE_INT64 QOF_TYPE_INT64
#define QUERYCORE_DOUBLE QOF_TYPE_DOUBLE
#define QueryAccess QofAccessFunc
#define gncQueryCoreToString qof_query_core_to_string

View File

@@ -1,15 +1,12 @@
#include "qofqueryobject.h"
#include "qofclass.h"
#define query_object_def _QofQueryObject
#define QueryObjectDef QofQueryObject
#define query_object_def _QofParam
#define QueryObjectDef QofParam
#define QuerySort QofSortFunc
#define gncQueryObjectRegister qof_query_object_register
#define gncQueryObjectParameterType qof_query_object_parameter_type
#define gncQueryObjectGetParameterGetter qof_query_object_get_parameter_getter
#define gncQueryObjectGetParameter qof_query_object_get_parameter
#define gncQueryObjectInit qof_query_object_init
#define gncQueryObjectShutdown qof_query_object_shutdown
#define gncQueryObjectDefaultSort qof_query_object_default_sort
#define gncQueryObjectRegister qof_class_register
#define gncQueryObjectParameterType qof_class_get_parameter_type
#define gncQueryObjectGetParameterGetter qof_class_get_parameter_getter
#define gncQueryObjectGetParameter qof_class_get_parameter

View File

@@ -35,19 +35,23 @@
#define GNC_SX_BOOK_P_H
#include "qofbook.h"
#include "qofid.h"
/* ====================================================================== */
struct xaccSchedXactionsDef {
QofBook *book;
GList *sx_list;
gboolean sx_notsaved;
};
void gnc_book_set_schedxactions( QofBook *book, GList *newList );
void gnc_collection_set_schedxactions( QofCollection *col, GList *newList );
/* Associate the given template group with a book */
void gnc_book_set_template_group (QofBook *book, AccountGroup *templateGroup);
void gnc_collection_set_template_group (QofCollection *col, AccountGroup *templateGroup);
gboolean gnc_sxtt_register (void);

View File

@@ -45,39 +45,142 @@
#include "SchedXaction.h"
#include "SX-book.h"
#include "SX-book-p.h"
#include "qofbook.h"
#include "qofbook-p.h"
#include "qofinstance.h"
#include "qofinstance-p.h"
#include "qofobject.h"
static short module = MOD_SX;
/* XXX this whole file is crufty, it doesn't really use entities
* in the most efficient/best way */
/* ====================================================================== */
#define GNC_SCHEDXACTIONS "gnc_schedxactions"
SchedXactions *
gnc_book_get_schedxaction_list( QofBook *book )
AccountGroup *
gnc_collection_get_template_group( QofCollection *col )
{
if ( book == NULL ) return NULL;
return qof_book_get_data (book, GNC_SCHEDXACTIONS);
return qof_collection_get_data (col);
}
AccountGroup *
gnc_book_get_template_group( QofBook *book )
{
QofCollection *col;
if (!book) return NULL;
col = qof_book_get_collection (book, GNC_ID_SXTG);
return gnc_collection_get_template_group (col);
}
void
gnc_collection_set_template_group (QofCollection *col, AccountGroup *templateGroup)
{
AccountGroup *old_grp;
if (!col) return;
old_grp = gnc_collection_get_template_group (col);
if (old_grp == templateGroup) return;
qof_collection_set_data (col, templateGroup);
xaccAccountGroupBeginEdit (old_grp);
xaccAccountGroupDestroy (old_grp);
}
void
gnc_book_set_template_group (QofBook *book, AccountGroup *templateGroup)
{
QofCollection *col;
if (!book) return;
if (templateGroup && templateGroup->book != book)
{
PERR ("cannot mix and match books freely!");
return;
}
col = qof_book_get_collection (book, GNC_ID_SXTG);
gnc_collection_set_template_group (col, templateGroup);
}
/* ====================================================================== */
/* gncObject function implementation and registration */
static void
sxtg_book_begin (QofBook *book)
{
gnc_book_set_template_group (book, xaccMallocAccountGroup(book));
}
static void
sxtg_book_end (QofBook *book)
{
gnc_book_set_template_group (book, NULL);
}
static gboolean
sxtg_is_dirty(QofCollection *col)
{
return xaccGroupNotSaved(gnc_collection_get_template_group(col));
}
static void
sxtg_mark_clean(QofCollection *col)
{
xaccGroupMarkSaved(gnc_collection_get_template_group(col));
}
static QofObject sxtg_object_def =
{
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_SXTG,
type_label: "Scheduled Transaction Templates",
book_begin: sxtg_book_begin,
book_end: sxtg_book_end,
is_dirty: sxtg_is_dirty,
mark_clean: sxtg_mark_clean,
foreach: NULL,
printable: NULL,
};
/* ====================================================================== */
SchedXactions *
gnc_collection_get_schedxaction_list( QofCollection *col)
{
return qof_collection_get_data (col);
}
GList *
gnc_collection_get_schedxactions( QofCollection *col)
{
SchedXactions *list;
list = qof_collection_get_data (col);
if (list) return list->sx_list;
return NULL;
}
GList *
gnc_book_get_schedxactions( QofBook *book )
{
SchedXactions *list;
if ( book == NULL ) return NULL;
list = qof_book_get_data (book, GNC_SCHEDXACTIONS);
if (list) return list->sx_list;
return NULL;
QofCollection *col;
col = qof_book_get_collection (book, GNC_ID_SXTT);
return gnc_collection_get_schedxactions (col);
}
void
gnc_book_set_schedxactions( QofBook *book, GList *newList )
gnc_collection_set_schedxactions( QofCollection *col, GList *newList )
{
SchedXactions *old_list, *new_list;
if ( book == NULL ) return;
if ( col == NULL ) return;
old_list = qof_book_get_data (book, GNC_SCHEDXACTIONS);
old_list = qof_collection_get_data (col);
if (old_list && old_list->sx_list == newList)
{
/* Assume the worst, that any 'set' means the data has
@@ -87,108 +190,72 @@ gnc_book_set_schedxactions( QofBook *book, GList *newList )
}
new_list = g_new (SchedXactions, 1);
new_list->book = book;
new_list->sx_list = newList;
new_list->sx_notsaved = TRUE;
if (NULL == newList) new_list->sx_notsaved = FALSE;
qof_book_set_data (book, GNC_SCHEDXACTIONS, new_list);
qof_collection_set_data (col, new_list);
g_free (old_list);
}
/* ====================================================================== */
#define GNC_TEMPLATE_GROUP "gnc_template_group"
AccountGroup *
gnc_book_get_template_group( QofBook *book )
{
if (!book) return NULL;
return qof_book_get_data (book, GNC_TEMPLATE_GROUP);
}
void
gnc_book_set_template_group (QofBook *book, AccountGroup *templateGroup)
gnc_book_set_schedxactions( QofBook *book, GList *newList )
{
AccountGroup *old_grp;
if (!book) return;
QofCollection *col;
if ( book == NULL ) return;
if (templateGroup && templateGroup->book != book)
{
PERR ("cannot mix and match books freely!");
return;
}
old_grp = gnc_book_get_template_group (book);
if (old_grp == templateGroup) return;
qof_book_set_data (book, GNC_TEMPLATE_GROUP, templateGroup);
xaccAccountGroupBeginEdit (old_grp);
xaccAccountGroupDestroy (old_grp);
col = qof_book_get_collection (book, GNC_ID_SXTT);
gnc_collection_set_schedxactions (col, newList);
}
/* ====================================================================== */
/* gncObject function implementation and registration */
/* XXX Its not clear to me if the template group and the sched xactions
* should be treated together or not. I got lazy, and mashed them together.
* For right now, this works. If you feel you need to slit this up into
* two separate gnc Objects, that's OK with me.
*/
/* SX-trans stuff */
static void
sxtt_book_begin (QofBook *book)
{
gnc_book_set_schedxactions (book, NULL);
gnc_book_set_template_group (book, xaccMallocAccountGroup(book));
}
static void
sxtt_book_end (QofBook *book)
{
gnc_book_set_template_group (book, NULL);
gnc_book_set_schedxactions (book, NULL);
}
/* ====================================================================== */
/* dirty flag stuff */
static void
mark_sx_clean(gpointer data, gpointer user_data)
{
SchedXaction *sx = (SchedXaction *) data;
xaccSchedXactionSetDirtyness(sx, FALSE);
qof_instance_mark_clean (QOF_INSTANCE(sx));
}
static void
book_sxns_mark_saved(QofBook *book)
book_sxns_mark_saved(QofCollection *col)
{
SchedXactions *sxl;
sxl = gnc_book_get_schedxaction_list (book);
sxl = gnc_collection_get_schedxaction_list (col);
if (sxl) sxl->sx_notsaved = FALSE;
g_list_foreach(gnc_book_get_schedxactions(book),
g_list_foreach(gnc_collection_get_schedxactions(col),
mark_sx_clean,
NULL);
}
static gboolean
book_sxlist_notsaved(QofBook *book)
book_sxlist_notsaved(QofCollection *col)
{
GList *sxlist;
SchedXaction *sx;
SchedXactions *sxl;
sxl = gnc_book_get_schedxaction_list (book);
if((sxl && sxl->sx_notsaved)
||
xaccGroupNotSaved(gnc_book_get_template_group(book))) return TRUE;
sxl = gnc_collection_get_schedxaction_list (col);
if((sxl && sxl->sx_notsaved)) return TRUE;
for(sxlist = gnc_book_get_schedxactions(book);
for(sxlist = gnc_collection_get_schedxactions(col);
sxlist != NULL;
sxlist = g_list_next(sxlist))
{
SchedXaction *sx;
sx = (SchedXaction *) (sxlist->data);
if (xaccSchedXactionIsDirty( sx ))
return TRUE;
@@ -197,23 +264,15 @@ book_sxlist_notsaved(QofBook *book)
return FALSE;
}
static void
sxtt_mark_clean(QofBook *book)
{
xaccGroupMarkSaved(gnc_book_get_template_group(book));
book_sxns_mark_saved(book);
}
static QofObject sxtt_object_def =
{
interface_version: QOF_OBJECT_VERSION,
name: GNC_ID_SXTT,
type_label: "SXTT",
e_type: GNC_ID_SXTT,
type_label: "Scheduled Transaction Templates",
book_begin: sxtt_book_begin,
book_end: sxtt_book_end,
is_dirty: book_sxlist_notsaved,
mark_clean: sxtt_mark_clean,
mark_clean: book_sxns_mark_saved,
foreach: NULL,
printable: NULL,
};
@@ -221,6 +280,7 @@ static QofObject sxtt_object_def =
gboolean
gnc_sxtt_register (void)
{
return qof_object_register (&sxtg_object_def);
return qof_object_register (&sxtt_object_def);
}

View File

@@ -27,6 +27,9 @@
* @brief Anchor Scheduled Transaction info in a book.
* See src/doc/books.txt for design overview.
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
*
* XXX currently, this is crufty, it should be modified to use
* entities a bit more whole-heartedly than it does.
**/
#ifndef GNC_SX_BOOK_H
@@ -38,15 +41,19 @@
#include "gnc-engine.h"
#include "qofbook.h"
#include "qofid.h"
typedef struct xaccSchedXactionsDef SchedXactions;
SchedXactions * gnc_book_get_schedxaction_list( QofBook *book );
SchedXactions * gnc_collection_get_schedxaction_list( QofCollection *col);
GList * gnc_collection_get_schedxactions( QofCollection *col);
GList * gnc_book_get_schedxactions( QofBook *book );
/** Returns the template group from the book.
**/
AccountGroup * gnc_book_get_template_group (QofBook *book);
AccountGroup * gnc_collection_get_template_group( QofCollection *col );
#endif /* GNC_SX_BOOK_H */
/** @} */

View File

@@ -55,30 +55,25 @@ xaccSchedXactionInit( SchedXaction *sx, QofBook *book)
{
AccountGroup *ag;
sx->entity_table = qof_book_get_entity_table (book);
qof_instance_init (&sx->inst, GNC_ID_SCHEDXACTION, book);
sx->freq = xaccFreqSpecMalloc(book);
qof_entity_guid_new (sx->entity_table, &sx->guid);
qof_entity_store( sx->entity_table, sx,
&sx->guid, GNC_ID_SCHEDXACTION );
g_date_clear( &sx->last_date, 1 );
g_date_clear( &sx->start_date, 1 );
g_date_clear( &sx->end_date, 1 );
sx->num_occurances_total = 0;
sx->kvp_data = kvp_frame_new();
sx->autoCreateOption = FALSE;
sx->autoCreateNotify = FALSE;
sx->advanceCreateDays = 0;
sx->advanceRemindDays = 0;
sx->instance_num = 0;
sx->dirty = TRUE;
sx->deferredList = NULL;
/* create a new template account for our splits */
sx->template_acct = xaccMallocAccount(book);
xaccAccountSetName( sx->template_acct, guid_to_string( &sx->guid ));
xaccAccountSetName( sx->template_acct, guid_to_string( &sx->inst.entity.guid ));
xaccAccountSetCommodity
(sx->template_acct,
gnc_commodity_new( "template", "template",
@@ -97,7 +92,7 @@ xaccSchedXactionMalloc(QofBook *book)
sx = g_new0( SchedXaction, 1 );
xaccSchedXactionInit( sx, book );
gnc_engine_generate_event( &sx->guid, GNC_ID_SCHEDXACTION, GNC_EVENT_CREATE );
gnc_engine_gen_event( &sx->inst.entity, GNC_EVENT_CREATE );
return sx;
}
@@ -133,13 +128,13 @@ delete_template_trans(SchedXaction *sx)
if(! (g_list_find(templ_acct_transactions, split_trans)))
{
templ_acct_transactions
= g_list_prepend(templ_acct_transactions, split_trans);
= g_list_prepend(templ_acct_transactions, split_trans);
}
}
g_list_foreach(templ_acct_transactions,
sxprivTransMapDelete,
NULL);
sxprivTransMapDelete,
NULL);
return;
}
@@ -151,8 +146,7 @@ xaccSchedXactionFree( SchedXaction *sx )
if ( sx == NULL ) return;
xaccFreqSpecFree( sx->freq );
gnc_engine_generate_event( &sx->guid, GNC_ID_SCHEDXACTION, GNC_EVENT_DESTROY );
qof_entity_remove( sx->entity_table, &sx->guid );
gnc_engine_gen_event( &sx->inst.entity, GNC_EVENT_DESTROY );
if ( sx->name )
g_free( sx->name );
@@ -181,29 +175,26 @@ xaccSchedXactionFree( SchedXaction *sx )
sx->deferredList = NULL;
}
qof_instance_release (&sx->inst);
g_free( sx );
return;
}
/* ============================================================ */
FreqSpec *
xaccSchedXactionGetFreqSpec( SchedXaction *sx )
{
return sx->freq;
return sx->freq;
}
void
xaccSchedXactionSetFreqSpec( SchedXaction *sx, FreqSpec *fs )
{
g_return_if_fail( fs );
g_return_if_fail( fs );
xaccFreqSpecFree( sx->freq );
sx->freq = fs;
sx->dirty = TRUE;
xaccFreqSpecFree( sx->freq );
sx->freq = fs;
sx->inst.dirty = TRUE;
}
gchar *
@@ -220,7 +211,7 @@ xaccSchedXactionSetName( SchedXaction *sx, const gchar *newName )
g_free( sx->name );
sx->name = NULL;
}
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
sx->name = g_strdup( newName );
}
@@ -234,7 +225,7 @@ void
xaccSchedXactionSetStartDate( SchedXaction *sx, GDate* newStart )
{
sx->start_date = *newStart;
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
}
gboolean
@@ -264,8 +255,7 @@ xaccSchedXactionSetEndDate( SchedXaction *sx, GDate *newEnd )
}
sx->end_date = *newEnd;
sx->dirty = TRUE;
return;
sx->inst.dirty = TRUE;
}
GDate*
@@ -278,8 +268,7 @@ void
xaccSchedXactionSetLastOccurDate( SchedXaction *sx, GDate* newLastOccur )
{
sx->last_date = *newLastOccur;
sx->dirty = TRUE;
return;
sx->inst.dirty = TRUE;
}
gboolean
@@ -298,8 +287,7 @@ void
xaccSchedXactionSetNumOccur( SchedXaction *sx, gint newNum )
{
sx->num_occurances_remain = sx->num_occurances_total = newNum;
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
}
gint
@@ -313,68 +301,35 @@ xaccSchedXactionSetRemOccur( SchedXaction *sx,
gint numRemain )
{
/* FIXME This condition can be tightened up */
if ( numRemain > sx->num_occurances_total ) {
if ( numRemain > sx->num_occurances_total )
{
PWARN("The number remaining is greater than the total occurrences");
}
else
{
sx->num_occurances_remain = numRemain;
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
}
return;
}
KvpValue *
xaccSchedXactionGetSlot( SchedXaction *sx, const char *slot )
{
if (!sx)
{
return NULL;
}
if (!sx) return NULL;
return kvp_frame_get_slot(sx->kvp_data, slot);
return kvp_frame_get_slot(sx->inst.kvp_data, slot);
}
void
xaccSchedXactionSetSlot( SchedXaction *sx,
const char *slot,
const KvpValue *value )
const char *slot,
const KvpValue *value )
{
if (!sx)
{
return;
}
if (!sx) return;
kvp_frame_set_slot( sx->kvp_data, slot, value );
sx->dirty = TRUE;
return;
}
KvpFrame*
xaccSchedXactionGetSlots( SchedXaction *sx )
{
return sx->kvp_data;
}
void
xaccSchedXactionSetSlots( SchedXaction *sx, KvpFrame *frm )
{
sx->kvp_data = frm;
sx->dirty = TRUE;
}
const GUID*
xaccSchedXactionGetGUID( SchedXaction *sx )
{
return &sx->guid;
}
void
xaccSchedXactionSetGUID( SchedXaction *sx, GUID g )
{
sx->guid = g;
sx->dirty = TRUE;
kvp_frame_set_slot( sx->inst.kvp_data, slot, value );
sx->inst.dirty = TRUE;
}
void
@@ -395,7 +350,7 @@ xaccSchedXactionSetAutoCreate( SchedXaction *sx,
sx->autoCreateOption = newAutoCreate;
sx->autoCreateNotify = newNotify;
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
return;
}
@@ -409,19 +364,19 @@ void
xaccSchedXactionSetAdvanceCreation( SchedXaction *sx, gint createDays )
{
sx->advanceCreateDays = createDays;
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
}
gint
xaccSchedXactionGetAdvanceReminder( SchedXaction *sx )
{
return sx->advanceRemindDays;
return sx->advanceRemindDays;
}
void
xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays )
{
sx->dirty = TRUE;
sx->inst.dirty = TRUE;
sx->advanceRemindDays = reminderDays;
}
@@ -429,64 +384,64 @@ xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays )
GDate
xaccSchedXactionGetNextInstance( SchedXaction *sx, void *stateData )
{
GDate last_occur, next_occur, tmpDate;
GDate last_occur, next_occur, tmpDate;
g_date_clear( &last_occur, 1 );
g_date_clear( &next_occur, 1 );
g_date_clear( &tmpDate, 1 );
g_date_clear( &last_occur, 1 );
g_date_clear( &next_occur, 1 );
g_date_clear( &tmpDate, 1 );
if ( g_date_valid( &sx->last_date ) ) {
last_occur = sx->last_date;
}
if ( g_date_valid( &sx->last_date ) ) {
last_occur = sx->last_date;
}
if ( stateData != NULL ) {
temporalStateData *tsd = (temporalStateData*)stateData;
last_occur = tsd->last_date;
}
if ( stateData != NULL ) {
temporalStateData *tsd = (temporalStateData*)stateData;
last_occur = tsd->last_date;
}
if ( g_date_valid( &sx->start_date ) ) {
if ( g_date_valid(&last_occur) ) {
last_occur =
( g_date_compare( &last_occur,
&sx->start_date ) > 0 ?
last_occur : sx->start_date );
} else {
/* Think about this for a second, and you realize that if the
* start date is _today_, we need a last-occur date such that
* the 'next instance' is after that date, and equal to the
* start date... one day should be good.
*
* This only holds for the first instance [read: if the
* last[-occur]_date is invalid] */
last_occur = sx->start_date;
g_date_subtract_days( &last_occur, 1 );
}
}
if ( g_date_valid( &sx->start_date ) ) {
if ( g_date_valid(&last_occur) ) {
last_occur =
( g_date_compare( &last_occur,
&sx->start_date ) > 0 ?
last_occur : sx->start_date );
} else {
/* Think about this for a second, and you realize that if the
* start date is _today_, we need a last-occur date such that
* the 'next instance' is after that date, and equal to the
* start date... one day should be good.
*
* This only holds for the first instance [read: if the
* last[-occur]_date is invalid] */
last_occur = sx->start_date;
g_date_subtract_days( &last_occur, 1 );
}
}
xaccFreqSpecGetNextInstance( sx->freq, &last_occur, &next_occur );
xaccFreqSpecGetNextInstance( sx->freq, &last_occur, &next_occur );
/* out-of-bounds check */
if ( xaccSchedXactionHasEndDate( sx ) ) {
GDate *end_date = xaccSchedXactionGetEndDate( sx );
if ( g_date_compare( &next_occur, end_date ) > 0 ) {
PINFO( "next_occur past end date" );
g_date_clear( &next_occur, 1 );
}
} else if ( xaccSchedXactionHasOccurDef( sx ) ) {
if ( stateData ) {
temporalStateData *tsd = (temporalStateData*)stateData;
if ( tsd->num_occur_rem == 0 ) {
PINFO( "no more occurances remain" );
g_date_clear( &next_occur, 1 );
}
} else {
if ( sx->num_occurances_remain == 0 ) {
g_date_clear( &next_occur, 1 );
}
}
}
/* out-of-bounds check */
if ( xaccSchedXactionHasEndDate( sx ) ) {
GDate *end_date = xaccSchedXactionGetEndDate( sx );
if ( g_date_compare( &next_occur, end_date ) > 0 ) {
PINFO( "next_occur past end date" );
g_date_clear( &next_occur, 1 );
}
} else if ( xaccSchedXactionHasOccurDef( sx ) ) {
if ( stateData ) {
temporalStateData *tsd = (temporalStateData*)stateData;
if ( tsd->num_occur_rem == 0 ) {
PINFO( "no more occurances remain" );
g_date_clear( &next_occur, 1 );
}
} else {
if ( sx->num_occurances_remain == 0 ) {
g_date_clear( &next_occur, 1 );
}
}
}
return next_occur;
return next_occur;
}
GDate
@@ -494,46 +449,46 @@ xaccSchedXactionGetInstanceAfter( SchedXaction *sx,
GDate *date,
void *stateData )
{
GDate prev_occur, next_occur;
GDate prev_occur, next_occur;
g_date_clear( &prev_occur, 1 );
if ( date ) {
prev_occur = *date;
}
g_date_clear( &prev_occur, 1 );
if ( date ) {
prev_occur = *date;
}
if ( stateData != NULL ) {
temporalStateData *tsd = (temporalStateData*)stateData;
prev_occur = tsd->last_date;
}
if ( stateData != NULL ) {
temporalStateData *tsd = (temporalStateData*)stateData;
prev_occur = tsd->last_date;
}
if ( ! g_date_valid( &prev_occur ) ) {
/* We must be at the beginning. */
prev_occur = sx->start_date;
g_date_subtract_days( &prev_occur, 1 );
}
if ( ! g_date_valid( &prev_occur ) ) {
/* We must be at the beginning. */
prev_occur = sx->start_date;
g_date_subtract_days( &prev_occur, 1 );
}
xaccFreqSpecGetNextInstance( sx->freq, &prev_occur, &next_occur );
xaccFreqSpecGetNextInstance( sx->freq, &prev_occur, &next_occur );
if ( xaccSchedXactionHasEndDate( sx ) ) {
GDate *end_date;
if ( xaccSchedXactionHasEndDate( sx ) ) {
GDate *end_date;
end_date = xaccSchedXactionGetEndDate( sx );
if ( g_date_compare( &next_occur, end_date ) > 0 ) {
g_date_clear( &next_occur, 1 );
}
} else if ( xaccSchedXactionHasOccurDef( sx ) ) {
if ( stateData ) {
temporalStateData *tsd = (temporalStateData*)stateData;
if ( tsd->num_occur_rem == 0 ) {
g_date_clear( &next_occur, 1 );
}
} else {
if ( sx->num_occurances_remain == 0 ) {
g_date_clear( &next_occur, 1 );
}
}
}
return next_occur;
end_date = xaccSchedXactionGetEndDate( sx );
if ( g_date_compare( &next_occur, end_date ) > 0 ) {
g_date_clear( &next_occur, 1 );
}
} else if ( xaccSchedXactionHasOccurDef( sx ) ) {
if ( stateData ) {
temporalStateData *tsd = (temporalStateData*)stateData;
if ( tsd->num_occur_rem == 0 ) {
g_date_clear( &next_occur, 1 );
}
} else {
if ( sx->num_occurances_remain == 0 ) {
g_date_clear( &next_occur, 1 );
}
}
}
return next_occur;
}
gint
@@ -566,23 +521,9 @@ xaccSchedXactionGetSplits( SchedXaction *sx )
return xaccAccountGetSplitList(sx->template_acct);
}
void
xaccSchedXactionSetDirtyness( SchedXaction *sx, gboolean dirty_p)
{
sx->dirty = dirty_p;
return;
}
gboolean
xaccSchedXactionIsDirty(SchedXaction *sx)
{
return sx->dirty;
}
static Split *
pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
Transaction *parent_trans, QofBook *book)
Transaction *parent_trans, QofBook *book)
{
Split *split;
KvpFrame *split_frame;
@@ -592,14 +533,14 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
split = xaccMallocSplit(book);
xaccSplitSetMemo(split,
gnc_ttsplitinfo_get_memo(s_info));
gnc_ttsplitinfo_get_memo(s_info));
xaccSplitSetAction(split,
gnc_ttsplitinfo_get_action(s_info));
gnc_ttsplitinfo_get_action(s_info));
xaccAccountInsertSplit(parent_acct,
split);
split);
split_frame = xaccSplitGetSlots(split);
@@ -607,20 +548,20 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
= 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);
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);
tmp_value,
GNC_SX_ID,
GNC_SX_DEBIT_FORMULA,
NULL);
kvp_value_delete(tmp_value);
@@ -629,10 +570,10 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
tmp_value = kvp_value_new_guid(acc_guid);
kvp_frame_set_slot_path(split_frame,
tmp_value,
GNC_SX_ID,
GNC_SX_ACCOUNT,
NULL);
tmp_value,
GNC_SX_ID,
GNC_SX_ACCOUNT,
NULL);
kvp_value_delete(tmp_value);
@@ -642,7 +583,7 @@ pack_split_info (TTSplitInfo *s_info, Account *parent_acct,
void
xaccSchedXactionSetTemplateTrans(SchedXaction *sx, GList *t_t_list,
QofBook *book)
QofBook *book)
{
Transaction *new_trans;
TTInfo *tti;
@@ -664,20 +605,20 @@ xaccSchedXactionSetTemplateTrans(SchedXaction *sx, GList *t_t_list,
xaccTransBeginEdit(new_trans);
xaccTransSetDescription(new_trans,
gnc_ttinfo_get_description(tti));
gnc_ttinfo_get_description(tti));
xaccTransSetNum(new_trans,
gnc_ttinfo_get_num(tti));
gnc_ttinfo_get_num(tti));
xaccTransSetCurrency( new_trans,
gnc_ttinfo_get_currency(tti) );
gnc_ttinfo_get_currency(tti) );
for(split_list = gnc_ttinfo_get_template_splits(tti);
split_list;
split_list = split_list->next)
split_list;
split_list = split_list->next)
{
s_info = split_list->data;
new_split = pack_split_info(s_info, sx->template_acct,
new_trans, book);
new_trans, book);
xaccTransAppendSplit(new_trans, new_split);
}
xaccTransCommitEdit(new_trans);
@@ -687,72 +628,72 @@ xaccSchedXactionSetTemplateTrans(SchedXaction *sx, GList *t_t_list,
void*
gnc_sx_create_temporal_state( SchedXaction *sx )
{
temporalStateData *toRet =
g_new0( temporalStateData, 1 );
toRet->last_date = sx->last_date;
toRet->num_occur_rem = sx->num_occurances_remain;
toRet->num_inst = sx->instance_num;
return (void*)toRet;
temporalStateData *toRet =
g_new0( temporalStateData, 1 );
toRet->last_date = sx->last_date;
toRet->num_occur_rem = sx->num_occurances_remain;
toRet->num_inst = sx->instance_num;
return (void*)toRet;
}
void
gnc_sx_incr_temporal_state( SchedXaction *sx, void *stateData )
{
GDate unused;
temporalStateData *tsd = (temporalStateData*)stateData;
GDate unused;
temporalStateData *tsd = (temporalStateData*)stateData;
g_date_clear( &unused, 1 );
tsd->last_date =
xaccSchedXactionGetInstanceAfter( sx,
&unused,
stateData );
if ( xaccSchedXactionHasOccurDef( sx ) ) {
tsd->num_occur_rem -= 1;
}
tsd->num_inst += 1;
g_date_clear( &unused, 1 );
tsd->last_date =
xaccSchedXactionGetInstanceAfter( sx,
&unused,
stateData );
if ( xaccSchedXactionHasOccurDef( sx ) ) {
tsd->num_occur_rem -= 1;
}
tsd->num_inst += 1;
}
void
gnc_sx_revert_to_temporal_state( SchedXaction *sx, void *stateData )
{
temporalStateData *tsd = (temporalStateData*)stateData;
sx->last_date = tsd->last_date;
sx->num_occurances_remain = tsd->num_occur_rem;
sx->instance_num = tsd->num_inst;
sx->dirty = TRUE;
temporalStateData *tsd = (temporalStateData*)stateData;
sx->last_date = tsd->last_date;
sx->num_occurances_remain = tsd->num_occur_rem;
sx->instance_num = tsd->num_inst;
sx->inst.dirty = TRUE;
}
void
gnc_sx_destroy_temporal_state( void *stateData )
{
g_free( (temporalStateData*)stateData );
g_free( (temporalStateData*)stateData );
}
void*
gnc_sx_clone_temporal_state( void *stateData )
{
temporalStateData *toRet, *tsd;
tsd = (temporalStateData*)stateData;
toRet = g_memdup( tsd, sizeof( temporalStateData ) );
return (void*)toRet;
temporalStateData *toRet, *tsd;
tsd = (temporalStateData*)stateData;
toRet = g_memdup( tsd, sizeof( temporalStateData ) );
return (void*)toRet;
}
static
gint
_temporal_state_data_cmp( gconstpointer a, gconstpointer b )
{
temporalStateData *tsd_a, *tsd_b;
tsd_a = (temporalStateData*)a;
tsd_b = (temporalStateData*)b;
temporalStateData *tsd_a, *tsd_b;
tsd_a = (temporalStateData*)a;
tsd_b = (temporalStateData*)b;
if ( !tsd_a && !tsd_b )
return 0;
if ( !tsd_a )
return 1;
if ( !tsd_b )
return -1;
return g_date_compare( &tsd_a->last_date,
&tsd_b->last_date );
if ( !tsd_a && !tsd_b )
return 0;
if ( !tsd_a )
return 1;
if ( !tsd_b )
return -1;
return g_date_compare( &tsd_a->last_date,
&tsd_b->last_date );
}
/**
@@ -762,9 +703,9 @@ _temporal_state_data_cmp( gconstpointer a, gconstpointer b )
void
gnc_sx_add_defer_instance( SchedXaction *sx, void *deferStateData )
{
sx->deferredList = g_list_insert_sorted( sx->deferredList,
deferStateData,
_temporal_state_data_cmp );
sx->deferredList = g_list_insert_sorted( sx->deferredList,
deferStateData,
_temporal_state_data_cmp );
}
/**
@@ -774,7 +715,7 @@ gnc_sx_add_defer_instance( SchedXaction *sx, void *deferStateData )
void
gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData )
{
sx->deferredList = g_list_remove( sx->deferredList, deferStateData );
sx->deferredList = g_list_remove( sx->deferredList, deferStateData );
}
/**
@@ -786,6 +727,6 @@ gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData )
GList*
gnc_sx_get_defer_instances( SchedXaction *sx )
{
return sx->deferredList;
return sx->deferredList;
}

View File

@@ -64,21 +64,6 @@ typedef struct gncp_SchedXaction SchedXaction;
**/
SchedXaction *xaccSchedXactionMalloc(QofBook *book);
/**
* @return True if the scheduled transaction is dirty and needs to
* be saved.
**/
gboolean xaccSchedXactionIsDirty(SchedXaction *sx);
/**
* Set dirtyness state. Only save/load code should modify this outside
* SX engine CODE . . .
* (set it to FALSE after backend completes reading in data
*
* FIXME: put this into a private header . . . .
**/
void xaccSchedXactionSetDirtyness(SchedXaction *sx, gboolean dirty_p);
/**
* Cleans up and frees a SchedXaction and it's associated data.
**/
@@ -156,37 +141,6 @@ void xaccSchedXactionSetAdvanceCreation( SchedXaction *sx, gint createDays );
gint xaccSchedXactionGetAdvanceReminder( SchedXaction *sx );
void xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays );
/*
* The following function is slightly risky. If you change
* the retrieved KvpFrame you must mark the SchedXaction
* dirty with xaccSchedXactionSetDirtyness
*/
KvpFrame *xaccSchedXactionGetSlots( SchedXaction *sx );
/**
* Sets the SX kvp data to the given kvp_frame.
* NOTE: This is not copied, but set directly.
**/
void xaccSchedXactionSetSlots( SchedXaction *sx,
KvpFrame *frm );
/**
* Use the following two functions in preference to
* the above two . . .
*/
KvpValue *xaccSchedXactionGetSlot( SchedXaction *sx,
const char *slot );
/*
* This function copies value, so you don't have to
*/
void xaccSchedXactionSetSlot( SchedXaction *sx,
const char *slot,
const KvpValue *value );
const GUID *xaccSchedXactionGetGUID( SchedXaction *sx );
void xaccSchedXactionSetGUID( SchedXaction *sx, GUID g );
///@{
/**
* Temporal state data.
@@ -254,6 +208,19 @@ void gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData );
GList *gnc_sx_get_defer_instances( SchedXaction *sx );
/** deprecated routines */
#define xaccSchedXactionIsDirty(X) qof_instance_is_dirty (QOF_INSTANCE(X))
#define xaccSchedXactionGetGUID(X) qof_entity_get_guid(QOF_ENTITY(X))
#define xaccSchedXactionGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
/** Deprecated, to be replaced with 'dirty' kvp's */
KvpValue *xaccSchedXactionGetSlot( SchedXaction *sx,
const char *slot );
void xaccSchedXactionSetSlot( SchedXaction *sx,
const char *slot,
const KvpValue *value );
#endif /* XACC_SCHEDXACTION_H */
/** @} */

View File

@@ -26,6 +26,8 @@
#include "SchedXaction.h"
#include "qofid.h"
#include "qofid-p.h"
#include "qofinstance-p.h"
/**
* A single scheduled transaction.
@@ -50,6 +52,7 @@
**/
struct gncp_SchedXaction
{
QofInstance inst;
gchar *name;
FreqSpec *freq;
@@ -74,17 +77,10 @@ struct gncp_SchedXaction
gint advanceRemindDays;
Account *template_acct;
GUID guid;
QofEntityTable *entity_table;
/** The list of deferred SX instances. This list is of temporalStateData
* instances. */
GList /* <temporalStateData*> */ *deferredList;
/* Changed since last save? */
gboolean dirty;
KvpFrame *kvp_data;
};
/** Just the variable temporal bits from the SX structure. */
@@ -94,4 +90,6 @@ typedef struct _temporalStateData {
gint num_inst;
} temporalStateData;
#endif
#define xaccSchedXactionSetGUID(X,G) qof_entity_set_guid(QOF_ENTITY(X),(G))
#endif /* XACC_SCHEDXACTION_P_H */

View File

@@ -91,6 +91,7 @@ TransScrubOrphansFast (Transaction *trans, AccountGroup *root)
GList *node;
if (!trans) return;
g_return_if_fail (root);
for (node = trans->splits; node; node = node->next)
{
@@ -221,6 +222,16 @@ xaccSplitScrub (Split *split)
account = xaccSplitGetAccount (split);
}
/* Grrr... the register gnc_split_register_load() line 203 of
* src/register/ledger-core/split-register-load.c will create
* free-floating bogus transactions. Ignore these for now ...
*/
if (!account)
{
PINFO ("Free Floating Transaction!");
return;
}
currency = xaccTransGetCurrency (trans);
/* If the account doesn't have a commodity,
@@ -314,52 +325,60 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
{
Split *balance_split = NULL;
gnc_numeric imbalance;
Account *account;
SplitList *node, *slist;
if (!trans || !root) return;
if (!trans) return;
xaccTransScrubSplits (trans);
/* If the transaction is balanced, nothing more to do */
imbalance = xaccTransGetImbalance (trans);
if (gnc_numeric_zero_p (imbalance)) return;
slist = xaccTransGetSplitList (trans);
if (!slist) return;
if (!parent)
{
Account *account;
GList *node;
if (!root)
{
Split *s = slist->data;
root = xaccAccountGetRoot (s->acc);
}
account = xaccScrubUtilityGetOrMakeAccount (root,
trans->common_currency, _("Imbalance"));
}
else
{
account = parent;
}
imbalance = xaccTransGetImbalance (trans);
if (gnc_numeric_zero_p (imbalance))
if (!account)
{
PERR ("Can't get balancing account");
return;
}
if (!parent)
for (node = slist; node; node = node->next)
{
Split *split = node->data;
if (xaccSplitGetAccount (split) == account)
{
account = xaccScrubUtilityGetOrMakeAccount (root,
trans->common_currency, _("Imbalance"));
}
else
{
account = parent;
balance_split = split;
break;
}
}
if (!account)
return;
/* Put split into account before setting split value */
if (!balance_split)
{
balance_split = xaccMallocSplit (trans->inst.book);
for (node = xaccTransGetSplitList (trans); node; node = node->next)
{
Split *split = node->data;
if (xaccSplitGetAccount (split) == account)
{
balance_split = split;
break;
}
}
/* put split into account before setting split value */
if (!balance_split)
{
balance_split = xaccMallocSplit (root->book);
xaccAccountBeginEdit (account);
xaccAccountInsertSplit (account, balance_split);
xaccAccountCommitEdit (account);
}
xaccAccountBeginEdit (account);
xaccAccountInsertSplit (account, balance_split);
xaccAccountCommitEdit (account);
}
PINFO ("unbalanced transaction");
@@ -367,24 +386,17 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
{
const gnc_commodity *currency;
const gnc_commodity *commodity;
gboolean trans_was_open;
gnc_numeric new_value;
Account *account;
gnc_numeric old_value, new_value;
trans_was_open = xaccTransIsOpen (trans);
if (!trans_was_open)
xaccTransBeginEdit (trans);
xaccTransBeginEdit (trans);
currency = xaccTransGetCurrency (trans);
account = xaccSplitGetAccount (balance_split);
new_value = xaccSplitGetValue (balance_split);
old_value = xaccSplitGetValue (balance_split);
/* Note: We have to round for the commodity's fraction, NOT any
* already existing denominator (bug #104343), because either one
* of the denominators might already be reduced. */
new_value = gnc_numeric_sub (new_value, imbalance,
new_value = gnc_numeric_sub (old_value, imbalance,
gnc_commodity_get_fraction(currency),
GNC_RND_ROUND);
@@ -392,21 +404,13 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
commodity = xaccAccountGetCommodity (account);
if (gnc_commodity_equiv (currency, commodity))
xaccSplitSetAmount (balance_split, new_value);
if (!parent && gnc_numeric_zero_p (new_value))
{
xaccSplitDestroy (balance_split);
balance_split = NULL;
xaccSplitSetAmount (balance_split, new_value);
}
if (balance_split)
xaccTransAppendSplit (trans, balance_split);
xaccTransAppendSplit (trans, balance_split);
xaccSplitScrub (balance_split);
if (!trans_was_open)
xaccTransCommitEdit (trans);
xaccTransCommitEdit (trans);
}
}
@@ -541,7 +545,7 @@ xaccTransScrubCurrency (Transaction *trans)
currency = xaccTransGetCurrency (trans);
if (currency) return;
currency = xaccTransFindOldCommonCurrency (trans, trans->book);
currency = xaccTransFindOldCommonCurrency (trans, trans->inst.book);
if (currency)
{
xaccTransBeginEdit (trans);
@@ -662,10 +666,10 @@ xaccAccountDeleteOldData (Account *account)
{
if (!account) return;
kvp_frame_set_slot_nc (account->kvp_data, "old-currency", NULL);
kvp_frame_set_slot_nc (account->kvp_data, "old-security", NULL);
kvp_frame_set_slot_nc (account->kvp_data, "old-currency-scu", NULL);
kvp_frame_set_slot_nc (account->kvp_data, "old-security-scu", NULL);
kvp_frame_set_slot_nc (account->inst.kvp_data, "old-currency", NULL);
kvp_frame_set_slot_nc (account->inst.kvp_data, "old-security", NULL);
kvp_frame_set_slot_nc (account->inst.kvp_data, "old-currency-scu", NULL);
kvp_frame_set_slot_nc (account->inst.kvp_data, "old-security-scu", NULL);
}
static int

View File

@@ -27,7 +27,7 @@
* Provides a set of functions and utilities for checking and
* repairing ('scrubbing clean') the usage of Lots and lot balances
* in stock and commodity accounts. Broken lots are repaired using
* a first-in, first-out (FIFO) accounting schedule.
* the accounts specific accounting policy (probably FIFO).
*/
#include "config.h"
@@ -98,9 +98,12 @@ xaccLotFill (GNCLot *lot)
{
gnc_numeric lot_baln;
Account *acc;
Split *split;
GNCPolicy *pcy;
if (!lot) return;
acc = lot->account;
pcy = acc->policy;
ENTER ("acc=%s", acc->accountName);
@@ -108,15 +111,17 @@ xaccLotFill (GNCLot *lot)
lot_baln = gnc_lot_get_balance (lot);
if (gnc_numeric_zero_p (lot_baln)) return;
split = pcy->PolicyGetSplit (pcy, lot);
if (!split) return; /* Handle the common case */
xaccAccountBeginEdit (acc);
/* Loop until we've filled up the lot, (i.e. till the
* balance goes to zero) or there are no splits left. */
while (1)
{
Split *split, *subsplit;
Split *subsplit;
split = FIFOPolicyGetSplit (lot, NULL);
subsplit = xaccSplitAssignToLot (split, lot);
if (subsplit == split)
{
@@ -127,6 +132,9 @@ xaccLotFill (GNCLot *lot)
lot_baln = gnc_lot_get_balance (lot);
if (gnc_numeric_zero_p (lot_baln)) break;
split = pcy->PolicyGetSplit (pcy, lot);
if (!split) break;
}
xaccAccountCommitEdit (acc);
LEAVE ("acc=%s", acc->accountName);
@@ -134,23 +142,6 @@ xaccLotFill (GNCLot *lot)
/* ============================================================== */
void
xaccAccountScrubDoubleBalance (Account *acc)
{
LotList *node;
if (!acc) return;
ENTER ("acc=%s", acc->accountName);
for (node = acc->lots; node; node=node->next)
{
GNCLot *lot = node->data;
xaccLotScrubDoubleBalance (lot);
}
LEAVE ("acc=%s", acc->accountName);
}
/* ============================================================== */
void
xaccLotScrubDoubleBalance (GNCLot *lot)
{
@@ -193,9 +184,10 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
}
/* Now, total up the values */
value = gnc_numeric_add_fixed (value, xaccSplitGetValue (s));
PINFO ("Split value=%s Accum Lot value=%s",
gnc_numeric_to_string (xaccSplitGetValue(s)),
value = gnc_numeric_add (value, xaccSplitGetValue (s),
GNC_DENOM_AUTO, GNC_DENOM_EXACT);
PINFO ("Split=%p value=%s Accum Lot value=%s", s,
gnc_numeric_to_string (s->value),
gnc_numeric_to_string (value));
}
@@ -214,43 +206,242 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
}
/* ============================================================== */
/* ================================================================= */
static gpointer
lot_scrub_cb (Account *acc, gpointer data)
static inline gboolean
is_subsplit (Split *split)
{
if (FALSE == xaccAccountHasTrades (acc)) return NULL;
xaccAccountAssignLots (acc);
xaccAccountScrubDoubleBalance (acc);
return NULL;
KvpValue *kval;
/* generic stop-progress conditions */
if (!split) return FALSE;
g_return_val_if_fail (split->parent, FALSE);
/* If there are no sub-splits, then there's nothing to do. */
kval = kvp_frame_get_slot (split->kvp_data, "lot-split");
if (!kval) return FALSE;
return TRUE;
}
void
xaccGroupScrubLotsBalance (AccountGroup *grp)
/* ================================================================= */
void
xaccScrubSubSplitPrice (Split *split, int maxmult, int maxamtscu)
{
if (!grp) return;
xaccGroupForEachAccount (grp, lot_scrub_cb, NULL, TRUE);
gnc_numeric src_amt, src_val;
SplitList *node;
if (FALSE == is_subsplit (split)) return;
ENTER (" ");
/* Get 'price' of the indicated split */
src_amt = xaccSplitGetAmount (split);
src_val = xaccSplitGetValue (split);
/* Loop over splits, adjust each so that it has the same
* ratio (i.e. price). Change the value to get things
* right; do not change the amount */
for (node=split->parent->splits; node; node=node->next)
{
Split *s = node->data;
Transaction *txn = s->parent;
gnc_numeric dst_amt, dst_val, target_val;
gnc_numeric delta;
int scu;
/* Skip the reference split */
if (s == split) continue;
scu = gnc_commodity_get_fraction (txn->common_currency);
dst_amt = xaccSplitGetAmount (s);
dst_val = xaccSplitGetValue (s);
target_val = gnc_numeric_mul (dst_amt, src_val,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
target_val = gnc_numeric_div (target_val, src_amt,
scu, GNC_DENOM_EXACT);
/* If the required price changes are 'small', do nothing.
* That is a case that the user will have to deal with
* manually. This routine is really intended only for
* a gross level of synchronization.
*/
delta = gnc_numeric_sub_fixed (target_val, dst_val);
delta = gnc_numeric_abs (delta);
if (maxmult * delta.num < delta.denom) continue;
/* If the amount is small, pass on that too */
if ((-maxamtscu < dst_amt.num) && (dst_amt.num < maxamtscu)) continue;
/* Make the actual adjustment */
xaccTransBeginEdit (txn);
xaccSplitSetValue (s, target_val);
xaccTransCommitEdit (txn);
}
LEAVE (" ");
}
void
xaccAccountScrubLotsBalance (Account *acc)
/* ================================================================= */
/* Remove the guid of b from a. Note that a may not contain the guid
* of b, (and v.v.) in which case, it will contain other guids which
* establish the links. So merge them back in. */
static void
remove_guids (Split *sa, Split *sb)
{
if (!acc) return;
if (FALSE == xaccAccountHasTrades (acc)) return;
xaccAccountAssignLots (acc);
xaccAccountScrubDoubleBalance (acc);
KvpFrame *ksub;
/* Find and remove the matching guid's */
ksub = gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
"peer_guid", &sb->entity.guid);
if (ksub)
{
gnc_kvp_bag_remove_frame (sa->kvp_data, "lot-split", ksub);
kvp_frame_delete (ksub);
}
/* Now do it in the other direction */
ksub = gnc_kvp_bag_find_by_guid (sb->kvp_data, "lot-split",
"peer_guid", &sa->entity.guid);
if (ksub)
{
gnc_kvp_bag_remove_frame (sb->kvp_data, "lot-split", ksub);
kvp_frame_delete (ksub);
}
/* Finally, merge b's lot-splits, if any, into a's */
/* This is an important step, if it got busted into many pieces. */
gnc_kvp_bag_merge (sa->kvp_data, "lot-split",
sb->kvp_data, "lot-split");
}
void
xaccAccountTreeScrubLotsBalance (Account *acc)
{
if (!acc) return;
/* The merge_splits() routine causes the amount & value of sb
* to be merged into sa; it then destroys sb. It also performs
* some other misc cleanup */
xaccGroupScrubLotsBalance (acc->children);
if (FALSE == xaccAccountHasTrades (acc)) return;
xaccAccountAssignLots (acc);
xaccAccountScrubDoubleBalance (acc);
static void
merge_splits (Split *sa, Split *sb)
{
Account *act;
Transaction *txn;
gnc_numeric amt, val;
act = xaccSplitGetAccount (sb);
xaccAccountBeginEdit (act);
txn = sa->parent;
xaccTransBeginEdit (txn);
/* Remove the guid of sb from the 'gemini' of sa */
remove_guids (sa, sb);
/* Add amount of sb into sa, ditto for value. */
amt = xaccSplitGetAmount (sa);
amt = gnc_numeric_add_fixed (amt, xaccSplitGetAmount (sb));
xaccSplitSetAmount (sa, amt);
val = xaccSplitGetValue (sa);
val = gnc_numeric_add_fixed (val, xaccSplitGetValue (sb));
xaccSplitSetValue (sa, val);
/* Set reconcile to no; after this much violence,
* no way its reconciled. */
xaccSplitSetReconcile (sa, NREC);
/* If sb has associated gains splits, trash them. */
if ((sb->gains_split) &&
(sb->gains_split->gains & GAINS_STATUS_GAINS))
{
Transaction *t = sb->gains_split->parent;
xaccTransBeginEdit (t);
xaccTransDestroy (t);
xaccTransCommitEdit (t);
}
/* Finally, delete sb */
xaccSplitDestroy(sb);
xaccTransCommitEdit (txn);
xaccAccountCommitEdit (act);
}
gboolean
xaccScrubMergeSubSplits (Split *split)
{
gboolean rc = FALSE;
Transaction *txn;
SplitList *node;
GNCLot *lot;
if (FALSE == is_subsplit (split)) return FALSE;
txn = split->parent;
lot = xaccSplitGetLot (split);
ENTER (" ");
restart:
for (node=txn->splits; node; node=node->next)
{
Split *s = node->data;
if (xaccSplitGetLot (s) != lot) continue;
if (s == split) continue;
/* OK, this split is in the same lot (and thus same account)
* as the indicated split. It must be a subsplit (although
* we should double-check the kvp's to be sure). Merge the
* two back together again. */
merge_splits (split, s);
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
gboolean
xaccScrubMergeTransSubSplits (Transaction *txn)
{
gboolean rc = FALSE;
SplitList *node;
if (!txn) return FALSE;
ENTER (" ");
restart:
for (node=txn->splits; node; node=node->next)
{
Split *s = node->data;
if (!xaccScrubMergeSubSplits(s)) continue;
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
gboolean
xaccScrubMergeLotSubSplits (GNCLot *lot)
{
gboolean rc = FALSE;
SplitList *node;
if (!lot) return FALSE;
ENTER (" ");
restart:
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
{
Split *s = node->data;
if (!xaccScrubMergeSubSplits(s)) continue;
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
/* =========================== END OF FILE ======================= */

View File

@@ -1,5 +1,5 @@
/********************************************************************\
* Scrub2.h -- Convert Stock Accounts to use Lots *
* Scrub2.h -- Low-level Lot Management Routines. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -26,11 +26,15 @@
* @author Created by Linas Vepstas March 2003
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
*
*
* Provides a set of functions and utilities for checking and
* repairing ('scrubbing clean') the usage of Lots and lot balances
* in stock and commodity accounts. Broken lots are repaired using
* a first-in, first-out (FIFO) accounting schedule.
* Provides the low-level API for checking and repairing ('scrubbing
* clean') the usage of Lots and lot balances in stock and commodity
* accounts. Broken lots are repaired using a first-in, first-out
* (FIFO) accounting schedule.
*
* This is a 'low-level' API in the sense that each routine accomplishes
* only one particular task needed to clean up a Lot. To clean up a
* Lot as a whole, you almost certainly want to use one of the
* high-level API routines from the Scrub3.h file.
*/
#ifndef XACC_SCRUB2_H
@@ -38,24 +42,6 @@
#include "gnc-engine.h"
/** The xaccGroupScrubLotsBalance() routine walks the
* account tree, and invokes xaccAccountScrubLots()
* and xaccAccountScrubDoubleBalance() on all accounts
* that are trading accounts.
* The xaccAccountTreeScrubLotsBalance() does the same.
* The xaccAccountScrubLotsBalance() will do the same,
* except that it won't descend down to the account
* children.
*
* Most GUI routines will want to use one of these
* xacc[*]ScrubLotsBalance() routines, instead of the
* component ScrubLots() and ScrubDoubleBalance() routines,
* since it usually makes sense to call these together.
*/
void xaccGroupScrubLotsBalance (AccountGroup *grp);
void xaccAccountScrubLotsBalance (Account *acc);
void xaccAccountTreeScrubLotsBalance (Account *acc);
/** The xaccAccountAssignLots() routine will walk over all of
* the splits in an account, and make sure that each belongs
* to a lot. Currently, the default (and only implemented)
@@ -75,21 +61,6 @@ void xaccAccountAssignLots (Account *acc);
*/
void xaccLotFill (GNCLot *lot);
/** The xaccAccountScrubDoubleBalance() routine examines all
* of the closed lots in an account, and verifies that the
* lots are 'double balanced'. By 'double balance', we mean
* that both the sum of the split amounts is zero, and that
* the sum of the split values is zero. If a closed lot is
* found where the sum of the values is not zero, the lot
* is considered to have a 'realized gain or loss' that
* hadn't been correctly handled. This routine then creates
* a balancing transaction so as to record the realized
* gain/loss, adds it to the lot, and adds it to a gain/loss
* account. If there is no default gain/loss account, it
* creates one.
*/
void xaccAccountScrubDoubleBalance (Account *acc);
/** The xaccLotScrubDoubleBalance() routine examines the indicated
* lot. If it is open, it does nothing. If it is closed,
* it then verifies that the lot is 'double balanced'.
@@ -105,5 +76,48 @@ void xaccAccountScrubDoubleBalance (Account *acc);
*/
void xaccLotScrubDoubleBalance (GNCLot *lot);
/** If a split has been pulled apart to make it fit into two (or more)
* lots, then it becomes theoretically possible for each subsplit to
* have a distinct price. But this would be wrong: each subsplit should
* have the same price, within rounding errors. This routine will
* examine the indicated split for sub-splits, and adjust the value
* of each so that they all have the same price.
*
* There is a bit of a problem with the interpretation of 'rounding
* errors' because there are pathological corner cases of small
* amounts. So this routine is loose, hopefully loose enough so
* that the user can manually fine tune without having this routine
* clobber thier work.
*
* This routine ignores price differences smaller than 1/maxmult.
* This routine ignores price differences when the split with a crazy
* price involes only a small amount: specifically, an amount that
* is less than maxamtscu/amount.denom.
*
* Reasonable/recommended values might be maxmult=3, maxamtscu = 2.
*/
void xaccScrubSubSplitPrice (Split *split, int maxmult, int maxamtscu);
/** The xaccScrubMergeSubSplits() routine will merge together
* all of the splits that were at one time split off from this
* split, but are no longer needed to be kept separate. Splits
* might be split up if they need to be divided over multiple
* lots; they can be merged back together if the lots change.
* In particular, two sub-splits may be merged if they are in
* the same lot, or in no lot. Note that, by definition, all
* subsplits belong to the same transaction.
*
* The routine returns TRUE if a merger was performed, else
* it returns FALSE.
*
* The xaccScrubMergeTransSubSplits() routine does the same, except
* that it does it for all of the splits in the transaction.
* The xaccScrubMergeLotSubSplits() routine does the same, except
* that it does it for all of the splits in the lot.
*/
gboolean xaccScrubMergeSubSplits (Split *split);
gboolean xaccScrubMergeTransSubSplits (Transaction *txn);
gboolean xaccScrubMergeLotSubSplits (GNCLot *lot);
#endif /* XACC_SCRUB2_H */
/** @} */

View File

@@ -43,6 +43,8 @@
#include "kvp-util-p.h"
#include "policy-p.h"
#include "Account.h"
#include "AccountP.h"
#include "Group.h"
#include "Scrub2.h"
#include "Scrub3.h"
#include "Transaction.h"
@@ -52,244 +54,20 @@ static short module = MOD_LOT;
/* ================================================================= */
static KvpFrame *
is_subsplit (Split *split)
{
KvpValue *kval;
KvpFrame *ksub;
if (!split) return NULL;
g_return_val_if_fail (split->parent, NULL);
/* If there are no sub-splits, then there's nothing to do. */
kval = kvp_frame_get_slot (split->kvp_data, "lot-split");
if (!kval) return NULL;
ksub = kvp_value_get_frame (kval);
g_return_val_if_fail (ksub, NULL);
return ksub;
}
/* ================================================================= */
void
xaccScrubSubSplitPrice (Split *split)
{
gnc_numeric src_amt, src_val;
SplitList *node;
if (NULL == is_subsplit (split)) return;
ENTER (" ");
/* Get 'price' of the indicated split */
src_amt = xaccSplitGetAmount (split);
src_val = xaccSplitGetValue (split);
/* Loop over splits, adjust each so that it has the same
* ratio (i.e. price). Change the value to get things
* right; do not change the amount */
for (node=split->parent->splits; node; node=node->next)
{
Split *s = node->data;
Transaction *txn = s->parent;
gnc_numeric dst_amt, dst_val, target_val;
gnc_numeric delta;
int scu;
/* Skip the reference split */
if (s == split) continue;
scu = gnc_commodity_get_fraction (txn->common_currency);
dst_amt = xaccSplitGetAmount (s);
dst_val = xaccSplitGetValue (s);
target_val = gnc_numeric_mul (dst_amt, src_val,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
target_val = gnc_numeric_div (target_val, src_amt,
scu, GNC_DENOM_EXACT);
/* If the required price changes are 'small', do nothing.
* That is a case that the user will have to deal with
* manually. This routine is really intended only for
* a gross level of synchronization.
*/
delta = gnc_numeric_sub_fixed (target_val, dst_val);
delta = gnc_numeric_abs (delta);
if (3 * delta.num < delta.denom) continue;
/* If the amount is small, pass on that too */
if ((-2 < dst_amt.num) && (dst_amt.num < 2)) continue;
/* Make the actual adjustment */
xaccTransBeginEdit (txn);
xaccSplitSetValue (s, target_val);
xaccTransCommitEdit (txn);
}
LEAVE (" ");
}
/* ================================================================= */
/* Remove the guid of b from a */
static void
remove_guids (Split *sa, Split *sb)
{
KvpFrame *ksub;
/* Find and remove the matching guid's */
ksub = gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
"peer_guid", &sb->guid);
if (!ksub)
{
PERR ("merging splits that didn't have correct gemini values!");
return;
}
gnc_kvp_bag_remove_frame (sa->kvp_data, "lot-split", ksub);
kvp_frame_delete (ksub);
}
/* The 'merge_splits() routine causes the amount & value of sb
* to be merged into sa; it then destroys sb. It also performs
* some other misc cleanup */
static void
merge_splits (Split *sa, Split *sb)
{
Account *act;
Transaction *txn;
gnc_numeric amt, val;
act = xaccSplitGetAccount (sb);
xaccAccountBeginEdit (act);
txn = sa->parent;
xaccTransBeginEdit (txn);
/* Remove the guid of sb from the 'gemini' of sa */
remove_guids (sa, sb);
/* Add amount of sb into sa, ditto for value. */
amt = xaccSplitGetAmount (sa);
amt = gnc_numeric_add_fixed (amt, xaccSplitGetAmount (sb));
xaccSplitSetAmount (sa, amt);
val = xaccSplitGetValue (sa);
val = gnc_numeric_add_fixed (val, xaccSplitGetValue (sb));
xaccSplitSetValue (sa, val);
/* Set reconcile to no; after this much violence,
* no way its reconciled. */
xaccSplitSetReconcile (sa, NREC);
/* If sb has associated gains splits, trash them. */
if ((sb->gains_split) &&
(sb->gains_split->gains & GAINS_STATUS_GAINS))
{
Transaction *t = sb->gains_split->parent;
xaccTransBeginEdit (t);
xaccTransDestroy (t);
xaccTransCommitEdit (t);
}
/* Finally, delete sb */
xaccSplitDestroy(sb);
xaccTransCommitEdit (txn);
xaccAccountCommitEdit (act);
}
gboolean
xaccScrubMergeSubSplits (Split *split)
{
gboolean rc = FALSE;
Transaction *txn;
KvpFrame *sf;
SplitList *node;
GNCLot *lot;
sf = is_subsplit (split);
if (!sf) return FALSE;
txn = split->parent;
lot = xaccSplitGetLot (split);
ENTER (" ");
restart:
for (node=txn->splits; node; node=node->next)
{
Split *s = node->data;
if (xaccSplitGetLot (s) != lot) continue;
/* OK, this split is in the same lot (and thus same account)
* as the indicated split. It must be a subsplit (although
* we should double-check the kvp's to be sure). Merge the
* two back together again. */
merge_splits (split, s);
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
gboolean
xaccScrubMergeTransSubSplits (Transaction *txn)
{
gboolean rc = FALSE;
SplitList *node;
if (!txn) return FALSE;
ENTER (" ");
restart:
for (node=txn->splits; node; node=node->next)
{
Split *s = node->data;
if (!xaccScrubMergeSubSplits(s)) continue;
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
gboolean
xaccScrubMergeLotSubSplits (GNCLot *lot)
{
gboolean rc = FALSE;
SplitList *node;
if (!lot) return FALSE;
ENTER (" ");
restart:
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
{
Split *s = node->data;
if (!xaccScrubMergeSubSplits(s)) continue;
rc = TRUE;
goto restart;
}
LEAVE (" splits merged=%d", rc);
return rc;
}
/* ================================================================= */
void
gboolean
xaccScrubLot (GNCLot *lot)
{
gboolean splits_deleted = FALSE;
gnc_numeric lot_baln;
gboolean opening_baln_is_pos, lot_baln_is_pos;
Account *acc;
GNCPolicy *pcy;
if (!lot) return;
if (!lot) return FALSE;
ENTER (" ");
acc = gnc_lot_get_account (lot);
pcy = acc->policy;
xaccAccountBeginEdit(acc);
xaccScrubMergeLotSubSplits (lot);
@@ -301,7 +79,7 @@ xaccScrubLot (GNCLot *lot)
gnc_numeric opening_baln;
/* Get the opening balance for this lot */
FIFOPolicyGetLotOpening (lot, &opening_baln, NULL, NULL, NULL);
pcy->PolicyGetLotOpening (pcy, lot, &opening_baln, NULL, NULL);
/* If the lot is fat, give the boot to all the non-opening
* splits, and refill it */
@@ -314,7 +92,7 @@ rethin:
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
{
Split *s = node->data;
if (FIFOPolicyIsOpeningSplit (lot, s, NULL)) continue;
if (pcy->PolicyIsOpeningSplit (pcy, lot, s)) continue;
gnc_lot_remove_split (lot, s);
goto rethin;
}
@@ -324,7 +102,7 @@ rethin:
xaccLotFill (lot);
/* Make sure there are no subsplits. */
xaccScrubMergeLotSubSplits (lot);
splits_deleted = xaccScrubMergeLotSubSplits (lot);
}
/* Now re-compute cap gains, and then double-check that. */
@@ -332,7 +110,56 @@ rethin:
xaccLotScrubDoubleBalance (lot);
xaccAccountCommitEdit(acc);
LEAVE (" ");
LEAVE (" deleted=%d", splits_deleted);
return splits_deleted;
}
/* ============================================================== */
void
xaccAccountScrubLots (Account *acc)
{
LotList *node;
if (!acc) return;
if (FALSE == xaccAccountHasTrades (acc)) return;
ENTER ("acc=%s", acc->accountName);
xaccAccountBeginEdit(acc);
xaccAccountAssignLots (acc);
for (node = acc->lots; node; node=node->next)
{
GNCLot *lot = node->data;
xaccScrubLot (lot);
}
xaccAccountCommitEdit(acc);
LEAVE ("acc=%s", acc->accountName);
}
/* ============================================================== */
static gpointer
lot_scrub_cb (Account *acc, gpointer data)
{
if (FALSE == xaccAccountHasTrades (acc)) return NULL;
xaccAccountScrubLots (acc);
return NULL;
}
void
xaccGroupScrubLots (AccountGroup *grp)
{
if (!grp) return;
xaccGroupForEachAccount (grp, lot_scrub_cb, NULL, TRUE);
}
void
xaccAccountTreeScrubLots (Account *acc)
{
if (!acc) return;
xaccGroupScrubLots (acc->children);
xaccAccountScrubLots (acc);
}
/* ========================== END OF FILE ========================= */

View File

@@ -1,5 +1,5 @@
/********************************************************************\
* Scrub3.h -- Constrain Cap Gains to Track Sources of Gains *
* Scrub3.h -- High-Level Lot Constraint routines. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -22,55 +22,19 @@
/** @addtogroup Engine
@{ */
/** @file Scrub3.h
* @breif Constrain Cap Gains to Track Sources of Gains
* @breif Hiogh-Level API for imposing Lot constraints
* @author Created by Linas Vepstas Sept 2003
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
*
* Provides a set of functions and utilities for checking and
* repairing ('scrubbing clean') the usage of Cap Gains
* transactions in stock and commodity accounts.
* Provides the high-level API for checking and repairing ('scrubbing
* clean') the usage of Lots and Cap Gains transactions in stock and
* commodity accounts.
*/
#ifndef XACC_SCRUB3_H
#define XACC_SCRUB3_H
#include "gnc-engine.h"
/** If a split has been pulled apart to make it fit into two (or more)
* lots, then it becomes theoretically possible for each subsplit to
* have a distinct price. But this would be wrong: each subsplit should
* have the same price, within rounding errors. This routine will
* examine the indicated split for sub-splits, and adjust the value
* of each so that they all have the same price.
*
* There is a bit of a problem with the interpretation of 'rounding
* errors' because there are pathological corner cases of small
* amounts. So this routine is fairly loose, hopefully loose enough
* so that the user can manually fine tune without having this routine
* clobber thier work.
*/
void xaccScrubSubSplitPrice (Split *split);
/** The xaccScrubMergeSubSplits() routine will merge together
* all of the splits that were at one time split off from this
* split, but are no longer needed to be kept separate. Splits
* might be split up if they need to be divided over multiple
* lots; they can be merged back together if the lots change.
* In particular, two sub-splits may be merged if they are in
* the same lot, or in no lot. Note that, by definition, all
* subsplits belong to the same transaction.
*
* The routine returns TRUE if a merger was performed, else
* it returns FALSE.
*
* The xaccScrubMergeTransSubSplits() routine does the same, except
* that it does it for all of the splits in the transaction.
* The xaccScrubMergeLotSubSplits() routine does the same, except
* that it does it for all of the splits in the lot.
*/
gboolean xaccScrubMergeSubSplits (Split *split);
gboolean xaccScrubMergeTransSubSplits (Transaction *txn);
gboolean xaccScrubMergeLotSubSplits (GNCLot *lot);
/** The xaccScrubLot() routine makes sure that the indicated lot is
* self-consistent and properly balanced, and fixes it if its not.
* This is an important routine to call if the amount of any split
@@ -78,8 +42,32 @@ gboolean xaccScrubMergeLotSubSplits (GNCLot *lot);
* split values is gaurenteed to throw off lot balances.
* This routine may end up closing the lot, or at least trying
* to. It will also cause cap gains to be recomputed.
*
* Scrubbing the lot may cause subsplits to be merged together,
* i.e. for splits to be deleted. This routine returns true if
* any splits were deleted.
*/
void xaccScrubLot (GNCLot *lot);
gboolean xaccScrubLot (GNCLot *lot);
/** The xaccAccountScrubLots() routine makes sure that every split
* in the account is assigned to a lot, and that then, every
* lot is self-consistent (by calling xaccScrubLot() on each lot).
*
* This routine is the primary routine for ensuring that the
* lot structure, and the cap-gains for an account are in good
* order.
*
* The xaccGroupScrubLots() routine walks the account tree, and invokes
* xaccAccountScrubLots() on all accounts that are trading accounts.
* The xaccAccountTreeScrubLots() does the same.
*
* Most GUI routines will want to use one of these xacc[*]ScrubLots()
* routines, instead of the various component routines, since it will
* usually makes sense to work only with these high-level routines.
*/
void xaccAccountScrubLots (Account *acc);
void xaccGroupScrubLots (AccountGroup *grp);
void xaccAccountTreeScrubLots (Account *acc);
#endif /* XACC_SCRUB3_H */
/** @} */

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,7 @@
#include "guid.h"
#include "kvp_frame.h"
#include "qofbook.h"
#include "qofinstance.h"
/** @name Split Reconciled field values
If you change these
@@ -135,18 +136,18 @@ void xaccTransCommitEdit (Transaction *trans);
void xaccTransRollbackEdit (Transaction *trans);
/** The xaccTransIsOpen() method returns TRUE if the transaction
is open for editing. Otherwise, it returns false. */
is open for editing. Otherwise, it returns false.
XXX this routne should probably be deprecated. its, umm,
hard to imagine legitamate uses (but it is used by
the import/export code for reasons I can't understand.)
*/
gboolean xaccTransIsOpen (const Transaction *trans);
/** The xaccTransLookup() subroutine will return the
transaction associated with the given id, or NULL
if there is no such transaction. */
Transaction * xaccTransLookup (const GUID *guid, QofBook *book);
/** The xaccTransLookup() subroutine will return the
transaction associated with the given id, or NULL
if there is no such transaction. */
Transaction * xaccTransLookupDirect (GUID guid, QofBook *book);
#define xaccTransLookupDirect(g,b) xaccTransLookup(&(g),b)
/** \warning XXX FIXME
* gnc_book_count_transactions is a utility function,
@@ -159,16 +160,6 @@ guint gnc_book_count_transactions(QofBook *book);
/** @name Transaction general getters/setters */
/**@{*/
/** The xaccTransGetGUID() subroutine will return the
globally unique id associated with that transaction. */
const GUID * xaccTransGetGUID (const Transaction *trans);
/** xaccTransReturnGUID() will returns a GUID struct
associated with that transaction. */
GUID xaccTransReturnGUID (const Transaction *trans);
/** Returns the book in which the transaction is stored */
QofBook * xaccTransGetBook (const Transaction *trans);
/** Sorts the splits in a transaction, putting the debits first,
* followed by the credits.
@@ -179,17 +170,6 @@ void xaccTransSortSplits (Transaction *trans);
*/
void xaccTransDump (Transaction *trans, const char *tag);
/** Returns the transaction's KvpFrame slots.
*
Transaction slots are used to store arbitrary strings, numbers, and
structures which aren't members of the transaction struct. */
KvpFrame *xaccTransGetSlots(const Transaction *trans);
/** Set the KvpFrame slots of this transaction to the given frm by
* directly using the frm pointer (i.e. non-copying). */
void xaccTransSetSlots_nc(Transaction *t, KvpFrame *frm);
/** Set the Transaction Type
*
* See #define TXN_TYPE_NONE, TXN_TYPE_INVOICE and TXN_TYPE_PAYMENT */
@@ -249,8 +229,6 @@ void xaccTransSetReadOnly (Transaction *trans, const char *reason);
void xaccTransClearReadOnly (Transaction *trans);
/** FIXME: document me */
const char * xaccTransGetReadOnly (const Transaction *trans);
/** FIXME: document me */
gboolean xaccTransWarnReadOnly (const Transaction *trans);
/** Returns the number of splits in this transaction. */
int xaccTransCountSplits (const Transaction *trans);
@@ -442,15 +420,6 @@ KvpFrame *xaccSplitGetSlots(const Split *split);
void xaccSplitSetSlots_nc(Split *s, KvpFrame *frm);
/** The xaccSplitGetGUID() subroutine will return the
* globally unique id associated with that split. */
const GUID * xaccSplitGetGUID (const Split *split);
/** xaccSplitReturnGUID also returns the guid (globally unique id),
* but in a GUID struct.*/
GUID xaccSplitReturnGUID (const Split *split);
/** 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
@@ -645,9 +614,7 @@ gboolean xaccSplitEqual(const Split *sa, const Split *sb,
* split associated with the given id, or NULL
* if there is no such split. */
Split * xaccSplitLookup (const GUID *guid, QofBook *book);
/** Returns the split associated with the given id, or NULL if there
* is no such split. */
Split * xaccSplitLookupDirect (GUID guid, QofBook *book);
#define xaccSplitLookupDirect(g,b) xaccSplitLookup(&(g),b)
/**
@@ -890,5 +857,13 @@ Timespec xaccTransGetVoidTime(const Transaction *tr);
#define RECONCILED_MATCH_TYPE "reconciled-match"
/** deprecated rouitines */
#define xaccSplitGetGUID(X) qof_entity_get_guid(QOF_ENTITY(X))
#define xaccSplitReturnGUID(X) (*(qof_entity_get_guid(QOF_ENTITY(X))))
#define xaccTransGetBook(X) qof_instance_get_book (QOF_INSTANCE(X))
#define xaccTransGetGUID(X) qof_entity_get_guid(QOF_ENTITY(X))
#define xaccTransReturnGUID(X) (*(qof_entity_get_guid(QOF_ENTITY(X))))
#define xaccTransGetSlots(X) qof_instance_get_slots (QOF_INSTANCE(X))
#endif /* XACC_TRANSACTION_H */
/** @} */

View File

@@ -56,6 +56,9 @@
#include "qofbackend.h"
#include "qofbook.h"
#include "qofid.h"
#include "qofid-p.h"
#include "qofinstance.h"
#include "qofinstance-p.h"
/** STRUCTS *********************************************************/
@@ -90,7 +93,7 @@
struct split_s
{
GUID guid; /* globally unique id */
QofEntity entity; /* globally unique id */
QofBook *book; /* The enitity table where this split is stored. */
@@ -160,12 +163,7 @@ struct split_s
struct transaction_s
{
/* guid is a globally unique identifier which can be used to
* reference the transaction.
*/
GUID guid;
QofBook *book; /* The entity_table where the transaction is stored */
QofInstance inst; /* glbally unique id */
Timespec date_entered; /* date register entry was made */
Timespec date_posted; /* date transaction was posted at bank */
@@ -181,12 +179,6 @@ struct transaction_s
*/
char * description;
/* kvp_data is a key-value pair database for storing simple
* "extra" information in splits, transactions, and accounts.
* it's NULL until accessed. */
KvpFrame * kvp_data;
/* The common_currency field is the balancing common currency for
* all the splits in the transaction. Alternate, better(?) name:
* "valuation currency": it is the currency in which all of the
@@ -207,9 +199,6 @@ struct transaction_s
* corresponding to the current traversal. */
unsigned char marker;
gint32 editlevel; /* nestcount of begin/end edit calls */
gboolean do_free; /* transaction in process of being destroyed */
/* The orig pointer points at a copy of the original transaction,
* before editing was started. This orig copy is used to rollback
* any changes made if/when the edit is abandoned.
@@ -224,12 +213,12 @@ struct transaction_s
/* Set the transaction's GUID. This should only be done when reading
* a transaction from a datafile, or some other external source. Never
* call this on an existing transaction! */
void xaccTransSetGUID (Transaction *trans, const GUID *guid);
#define xaccTransSetGUID(t,g) qof_entity_set_guid(QOF_ENTITY(t),g)
/* Set the split's GUID. This should only be done when reading
* a split from a datafile, or some other external source. Never
* call this on an existing split! */
void xaccSplitSetGUID (Split *split, const GUID *guid);
#define xaccSplitSetGUID(s,g) qof_entity_set_guid(QOF_ENTITY(s),g)
/* The xaccFreeSplit() method simply frees all memory associated
* with the split. It does not verify that the split isn't
@@ -267,13 +256,26 @@ gint32 xaccTransGetVersion (const Transaction*);
gboolean xaccSplitRegister (void);
gboolean xaccTransRegister (void);
/*
* The xaccTransactionGetBackend() subroutine will find the
/* The xaccTransactionGetBackend() subroutine will find the
* persistent-data storage backend associated with this
* transaction.
*/
QofBackend * xaccTransactionGetBackend (Transaction *trans);
/* The xaccEnable/DisableDataScrubbing() routines affect what
* happens during transaction commit. When scrubbing is enabled,
* then transactions are fixed up during transaction commit,
* so that only consistent transactions are commited to the engine.
* However, when data is being loaded from a backend (in particular,
* from the file backend), the data might not be consistent until
* its completely loaded. In particular, gains transactions might
* be loaded at a different time than the transactions that casued
* the gains. Thus, scrubbing needs do be disabled during file
* load. These routines enable that.
*/
void xaccEnableDataScrubbing(void);
void xaccDisableDataScrubbing(void);
/* The xaccSplitDetermineGainStatus() routine will analyze the
* the split, and try to set the internal status flags
* appropriately for the split. These flags indicate if the split
@@ -289,6 +291,14 @@ void DxaccSplitSetSharePriceAndAmount (Split *split,
double amount);
void DxaccSplitSetShareAmount (Split *split, double amount);
/** Set the KvpFrame slots of this transaction to the given frm by
* * directly using the frm pointer (i.e. non-copying).
* * XXX this is wrong, nedds to be replaced with a transactional thingy
* in kvp + qofinstance. for now, this is a quasi-unctional placeholder.
* */
#define xaccTransSetSlots_nc(T,F) qof_instance_set_slots(QOF_INSTANCE(T),F)
/*@}*/

View File

@@ -36,21 +36,21 @@
* This code does not currently handle tax distinctions, e.g
* the different tax treatment that short-term and long-term
* cap gains have.
ToDo List:
o Need to use a 'gains dirty' flag: A 'dirty' flag on the source
split indicates that the gains transaction needs to be recomputed.
Another flag, the gains transaction flag, marks the split as
being a gains split, and that the source transaction should be
checked for dirtiness before returning the date, the amount, the
value, etc. Finally, these flags make amount and value read-only
for the gains splits. (the memo is user-modifieable).
o If the amount in a split is changed, then the lot has to be recomputed.
This has a potential trickle-through effect on all later lots.
Ideally, later lots are dissolved, and recomputed. However, some
lots may have been user-hand-built. These should be left alone.
*
* This code uses a 'gains dirty' flag: A 'dirty' flag on the source
* split indicates that the gains transaction needs to be recomputed.
* Another flag, the gains transaction flag, marks the split as
* being a gains split, and that the source transaction should be
* checked for dirtiness before returning the date, the amount, the
* value, etc. Finally, these flags make amount and value read-only
* for the gains splits. (the memo is user-modifieable).
*
* If the amount in a split is changed, then the lot has to be recomputed.
* This has a potential trickle-through effect on all later lots.
* Ideally, later lots are dissolved, and recomputed. However, some
* lots may have been user-hand-built. These should be left alone.
*
ToDo:
o XXX Need to create a data-integrity scrubber, tht makes sure that
the various flags, and pointers & etc. match. See sections marked
with XXX below for things that might go wrong.
@@ -107,16 +107,32 @@ xaccAccountHasTrades (Account *acc)
/* ============================================================== */
struct early_lot_s
struct find_lot_s
{
GNCLot *lot;
Timespec ts;
int (*numeric_pred)(gnc_numeric);
gboolean (*date_pred)(Timespec e, Timespec tr);
};
static gpointer earliest_helper (GNCLot *lot, gpointer user_data)
static gboolean
earliest_pred (Timespec earl, Timespec tran)
{
struct early_lot_s *els = user_data;
return ((earl.tv_sec > tran.tv_sec) ||
((earl.tv_sec == tran.tv_sec) && (earl.tv_nsec > tran.tv_nsec)));
}
static gboolean
latest_pred (Timespec earl, Timespec tran)
{
return ((earl.tv_sec < tran.tv_sec) ||
((earl.tv_sec == tran.tv_sec) && (earl.tv_nsec < tran.tv_nsec)));
}
static gpointer
finder_helper (GNCLot *lot, gpointer user_data)
{
struct find_lot_s *els = user_data;
Split *s;
Transaction *trans;
gnc_numeric bal;
@@ -129,9 +145,7 @@ static gpointer earliest_helper (GNCLot *lot, gpointer user_data)
s = gnc_lot_get_earliest_split (lot);
trans = s->parent;
if ((els->ts.tv_sec > trans->date_posted.tv_sec) ||
((els->ts.tv_sec == trans->date_posted.tv_sec) &&
(els->ts.tv_nsec > trans->date_posted.tv_nsec)))
if (els->date_pred (els->ts, trans->date_posted))
{
els->ts = trans->date_posted;
els->lot = lot;
@@ -140,22 +154,49 @@ static gpointer earliest_helper (GNCLot *lot, gpointer user_data)
return NULL;
}
GNCLot *
xaccAccountFindEarliestOpenLot (Account *acc, gnc_numeric sign)
static inline GNCLot *
xaccAccountFindOpenLot (Account *acc, gnc_numeric sign,
long long guess,
gboolean (*date_pred)(Timespec, Timespec))
{
struct early_lot_s es;
struct find_lot_s es;
es.lot = NULL;
es.ts.tv_sec = 10000000LL * ((long long) LONG_MAX);
es.ts.tv_sec = guess;
es.ts.tv_nsec = 0;
es.date_pred = date_pred;
if (gnc_numeric_positive_p(sign)) es.numeric_pred = gnc_numeric_negative_p;
else es.numeric_pred = gnc_numeric_positive_p;
xaccAccountForEachLot (acc, earliest_helper, &es);
xaccAccountForEachLot (acc, finder_helper, &es);
return es.lot;
}
GNCLot *
xaccAccountFindEarliestOpenLot (Account *acc, gnc_numeric sign)
{
GNCLot *lot;
ENTER (" sign=%lld/%lld", sign.num, sign.denom);
lot = xaccAccountFindOpenLot (acc, sign,
10000000LL * ((long long) LONG_MAX), earliest_pred);
LEAVE ("found lot=%p %s", lot, gnc_lot_get_title (lot));
return lot;
}
GNCLot *
xaccAccountFindLatestOpenLot (Account *acc, gnc_numeric sign)
{
GNCLot *lot;
ENTER (" sign=%lld/%lld", sign.num, sign.denom);
lot = xaccAccountFindOpenLot (acc, sign,
-10000000LL * ((long long) LONG_MAX), latest_pred);
LEAVE ("found lot=%p %s", lot, gnc_lot_get_title (lot));
return lot;
}
/* ============================================================== */
/* Similar to GetOrMakeAccount, but different in important ways */
@@ -224,7 +265,7 @@ xaccAccountSetDefaultGainAccount (Account *acc, Account *gain_acct)
xaccAccountBeginEdit (acc);
vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
kvp_frame_set_slot_nc (cwd, cur_name, vvv);
xaccAccountSetSlots_nc (acc, acc->kvp_data);
xaccAccountSetSlots_nc (acc, acc->inst.kvp_data);
xaccAccountCommitEdit (acc);
}
@@ -249,7 +290,7 @@ xaccAccountGetDefaultGainAccount (Account *acc, gnc_commodity * currency)
vvv = kvp_frame_get_slot (cwd, cur_name);
gain_acct_guid = kvp_value_get_guid (vvv);
gain_acct = xaccAccountLookup (gain_acct_guid, acc->book);
gain_acct = xaccAccountLookup (gain_acct_guid, acc->inst.book);
return gain_acct;
}
@@ -277,7 +318,7 @@ GetOrMakeGainAcct (Account *acc, gnc_commodity * currency)
vvv = kvp_frame_get_slot (cwd, cur_name);
gain_acct_guid = kvp_value_get_guid (vvv);
gain_acct = xaccAccountLookup (gain_acct_guid, acc->book);
gain_acct = xaccAccountLookup (gain_acct_guid, acc->inst.book);
/* If there is no default place to put gains/losses
* for this account, then create such a place */
@@ -291,7 +332,7 @@ GetOrMakeGainAcct (Account *acc, gnc_commodity * currency)
vvv = kvp_value_new_guid (xaccAccountGetGUID (gain_acct));
kvp_frame_set_slot_nc (cwd, cur_name, vvv);
xaccAccountSetSlots_nc (acc, acc->kvp_data);
xaccAccountSetSlots_nc (acc, acc->inst.kvp_data);
xaccAccountCommitEdit (acc);
}
@@ -413,7 +454,7 @@ xaccSplitAssignToLot (Split *split, GNCLot *lot)
/* Put the remainder of the balance into a new split,
* which is in other respects just a clone of this one. */
new_split = xaccMallocSplit (acc->book);
new_split = xaccMallocSplit (acc->inst.book);
/* Copy most of the split attributes */
xaccSplitSetMemo (new_split, xaccSplitGetMemo (split));
@@ -459,7 +500,7 @@ MakeDefaultLot (Account *acc)
gint64 id;
char buff[200];
lot = gnc_lot_new (acc->book);
lot = gnc_lot_new (acc->inst.book);
/* Provide a reasonable title for the new lot */
id = kvp_frame_get_gint64 (xaccAccountGetSlots (acc), "/lot-mgmt/next-id");
@@ -474,15 +515,14 @@ MakeDefaultLot (Account *acc)
/* Accounting-policy callback. Given an account and an amount,
* this routine should return a lot. By implementing this as
* a callback, we can 'easily' add other accounting policies.
* Currently, we only implement the FIFO policy.
*/
static gboolean
PolicyAssignSplit (Split *split,
AccountingPolicyGetLot policy, gpointer user_data)
gboolean
xaccSplitAssign (Split *split)
{
Account *acc;
gboolean splits_split_up = FALSE;
GNCLot *lot;
GNCPolicy *pcy;
if (!split) return FALSE;
@@ -491,6 +531,7 @@ PolicyAssignSplit (Split *split,
/* If this split already belongs to a lot, we are done. */
if (split->lot) return FALSE;
acc = split->acc;
pcy = acc->policy;
xaccAccountBeginEdit (acc);
/* If we are here, this split does not belong to any lot.
@@ -502,7 +543,7 @@ PolicyAssignSplit (Split *split,
{
PINFO ("have split amount=%s", gnc_numeric_to_string (split->amount));
split->gains |= GAINS_STATUS_VDIRTY;
lot = policy (split, user_data);
lot = pcy->PolicyGetLot (pcy, split);
if (!lot)
{
lot = MakeDefaultLot (acc);
@@ -517,16 +558,6 @@ PolicyAssignSplit (Split *split,
return splits_split_up;
}
gboolean
xaccSplitAssign (Split *split)
{
/* XXX FIXME: instead of a hard-wired fifo policy, we should
* be using the policy as specified by the account. i.e.
* we should be using split->acc->polcy as the function
*/
return PolicyAssignSplit (split, FIFOPolicyGetLot, NULL);
}
/* ============================================================== */
Split *
@@ -543,8 +574,9 @@ xaccSplitGetCapGainsSplit (Split *split)
gains_guid = kvp_value_get_guid (val);
if (!gains_guid) return NULL;
gains_split = qof_entity_lookup (qof_book_get_entity_table(split->book),
gains_guid, GNC_ID_SPLIT);
/* Both splits will be in the same collection, so seearch there. */
gains_split = (Split*) qof_collection_lookup_entity (split->entity.collection, gains_guid);
PINFO ("split=%p has gains-split=%p", split, gains_split);
return gains_split;
}
@@ -553,7 +585,9 @@ xaccSplitGetCapGainsSplit (Split *split)
void
xaccSplitComputeCapGains(Split *split, Account *gain_acc)
{
SplitList *node;
GNCLot *lot;
GNCPolicy *pcy;
gnc_commodity *currency = NULL;
gnc_numeric zero = gnc_numeric_zero();
gnc_numeric value = zero;
@@ -563,13 +597,38 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
if (!split) return;
lot = split->lot;
if (!lot) return;
pcy = lot->account->policy;
currency = split->parent->common_currency;
ENTER ("split=%p lot=%s", split,
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"));
/* Make sure the status flags and pointers are initialized */
if (GAINS_STATUS_UNKNOWN == split->gains) xaccSplitDetermineGainStatus(split);
if (pcy->PolicyIsOpeningSplit (pcy, lot, split))
{
#if MOVE_THIS_TO_A_DATA_INTEGRITY_SCRUBBER
/* Check to make sure that this opening split doesn't
* have a cap-gain transaction associated with it.
* If it does, that's wrong, and we ruthlessly destroy it.
* XXX Don't do this, it leads to infinite loops.
* We need to scrub out errors like this elsewhere!
*/
if (xaccSplitGetCapGainsSplit (split))
{
Split *gains_split = xaccSplitGetCapGainsSplit(split);
Transaction *trans = gains_split->parent;
PERR ("Opening Split must not have cap gains!!\n");
xaccTransBeginEdit (trans);
xaccTransDestroy (trans);
xaccTransCommitEdit (trans);
}
#endif
return;
}
if (GAINS_STATUS_GAINS & split->gains)
{
/* If this is the split that records the gains, then work with
@@ -595,6 +654,26 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
}
}
/* Note: if the value of the 'opening' split(s) has changed,
* then the cap gains are changed. So we need to check not
* only if this split is dirty, but also the lot-opening splits. */
for (node=lot->splits; node; node=node->next)
{
Split *s = node->data;
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
{
if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus (s);
if (s->gains & GAINS_STATUS_VDIRTY)
{
/* Force a recompute to occur */
split->gains |= GAINS_STATUS_VDIRTY;
break;
}
}
}
/* If it doesn't look like this split is 'dirty', then there's
* nothing to do. Just return. */
if ((FALSE == (split->gains & GAINS_STATUS_A_VDIRTY)) &&
(split->gains_split) &&
(FALSE == (split->gains_split->gains & GAINS_STATUS_A_VDIRTY))) return;
@@ -603,32 +682,13 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
* may exist if users attempted to manually record gains. */
if (gnc_numeric_zero_p (split->amount)) return;
FIFOPolicyGetLotOpening (lot, &opening_amount, &opening_value,
&opening_currency, NULL);
/* If we got to here, then the split or something related is
* 'dirty' and the gains really do need to be recomputed.
* So start working things. */
pcy->PolicyGetLotOpening (pcy, lot, &opening_amount, &opening_value,
&opening_currency);
if (FIFOPolicyIsOpeningSplit (lot, split, NULL))
{
#if MOVE_THIS_TO_A_DATA_INTEGRITY_SCRUBBER
/* Check to make sure that this opening split doesn't
* have a cap-gain transaction associated with it.
* If it does, that's wrong, and we ruthlessly destroy it.
* XXX Don't do this, it leads to infinite loops.
* We need to scrub out errors like this elsewhere!
*/
if (xaccSplitGetCapGainsSplit (split))
{
Split *gains_split = xaccSplitGetCapGainsSplit(split);
Transaction *trans = gains_split->parent;
PERR ("Opening Split must not have cap gains!!\n");
xaccTransBeginEdit (trans);
xaccTransDestroy (trans);
xaccTransCommitEdit (trans);
}
#endif
return;
}
/* Check to make sure the lot-opening currency and this split
* use the same currency */
if (FALSE == gnc_commodity_equiv (currency, opening_currency))
@@ -642,7 +702,8 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
/* Opening amount should be larger (or equal) to current split,
* and it should be of the opposite sign.
XXX this should be a part of a scrub routine !
* XXX This should really be a part of a scrub routine that
* cleans up the lot, before we get at it!
*/
if (0 > gnc_numeric_compare (gnc_numeric_abs(opening_amount),
gnc_numeric_abs(split->amount)))
@@ -696,12 +757,13 @@ XXX this should be a part of a scrub routine !
* If there is, adjust its value as appropriate. Else, create
* a new gains transaction.
*/
lot_split = xaccSplitGetCapGainsSplit (split);
/* lot_split = xaccSplitGetCapGainsSplit (split); */
lot_split = split->gains_split;
if (NULL == lot_split)
{
Account *lot_acc = lot->account;
QofBook *book = lot_acc->book;
QofBook *book = lot_acc->inst.book;
lot_split = xaccMallocSplit (book);
gain_split = xaccMallocSplit (book);
@@ -818,6 +880,36 @@ void
xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc)
{
SplitList *node;
GNCPolicy *pcy;
gboolean is_dirty = FALSE;
/* Note: if the value of the 'opening' split(s) has changed,
* then the cap gains are changed. To capture this, we need
* to mark all splits dirty if the opening splits are dirty. */
pcy = lot->account->policy;
for (node=lot->splits; node; node=node->next)
{
Split *s = node->data;
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
{
if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus (s);
if (s->gains & GAINS_STATUS_VDIRTY)
{
is_dirty = TRUE;
s->gains &= ~GAINS_STATUS_VDIRTY;
}
}
}
if (is_dirty)
{
for (node=lot->splits; node; node=node->next)
{
Split *s = node->data;
s->gains |= GAINS_STATUS_VDIRTY;
}
}
for (node=lot->splits; node; node=node->next)
{
@@ -826,4 +918,101 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc)
}
}
/* ============================================================== */
/** The xaccScrubGainsDate() routine is used to keep the posted date
* of gains splis in sync with the posted date of the transaction
* that caused the gains.
*
* The posted date is kept in sync using a lazy-evaluation scheme.
* If xaccTransactionSetDatePosted() is called, the date change is
* accepted, and the split is marked date-dirty. If the posted date
* is queried for (using GetDatePosted()), then the transaction is
* evaluated. If its a gains-transaction, then it's date is copied
* from the source transaction that created the gains.
*/
static void
xaccScrubGainsDate (Transaction *trans)
{
SplitList *node;
Timespec ts = {0,0};
gboolean do_set;
restart_search:
do_set = FALSE;
for (node = trans->splits; node; node=node->next)
{
Split *s = node->data;
if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus(s);
if ((GAINS_STATUS_GAINS & s->gains) &&
s->gains_split &&
((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) ||
(s->gains & GAINS_STATUS_DATE_DIRTY)))
{
Transaction *source_trans = s->gains_split->parent;
ts = source_trans->date_posted;
do_set = TRUE;
s->gains &= ~GAINS_STATUS_DATE_DIRTY;
s->gains_split->gains &= ~GAINS_STATUS_DATE_DIRTY;
break;
}
}
if (do_set)
{
xaccTransBeginEdit (trans);
xaccTransSetDatePostedTS(trans, &ts);
xaccTransCommitEdit (trans);
for (node = trans->splits; node; node=node->next)
{
Split *s = node->data;
s->gains &= ~GAINS_STATUS_DATE_DIRTY;
}
goto restart_search;
}
}
/* ============================================================== */
void
xaccTransScrubGains (Transaction *trans, Account *gain_acc)
{
SplitList *node;
/* Lock down posted date, its to be synced to the posted date
* for the source of the cap gains. */
xaccScrubGainsDate(trans);
/* Fix up the split amount */
restart:
for (node=trans->splits; node; node=node->next)
{
Split *split = node->data;
if (GAINS_STATUS_UNKNOWN == split->gains)
{
xaccSplitDetermineGainStatus(split);
}
if (split->gains & GAINS_STATUS_ADIRTY)
{
gboolean altered = FALSE;
split->gains |= ~GAINS_STATUS_ADIRTY;
if (split->lot) altered = xaccScrubLot (split->lot);
if (altered) goto restart;
}
}
/* Fix up gains split value */
for (node=trans->splits; node; node=node->next)
{
Split *split = node->data;
if ((split->gains & GAINS_STATUS_VDIRTY) ||
(split->gains_split &&
(split->gains_split->gains & GAINS_STATUS_VDIRTY)))
{
xaccSplitComputeCapGains (split, gain_acc);
}
}
}
/* =========================== END OF FILE ======================= */

View File

@@ -80,6 +80,7 @@ gboolean xaccAccountHasTrades (Account *);
* that the balance only decreases.
*/
GNCLot * xaccAccountFindEarliestOpenLot (Account *acc, gnc_numeric sign);
GNCLot * xaccAccountFindLatestOpenLot (Account *acc, gnc_numeric sign);
/** The xaccAccountGetDefaultGainAccount() routine will return
* the account to which realized gains/losses may be posted.
@@ -153,6 +154,15 @@ gboolean xaccSplitAssign (Split *split);
*/
Split * xaccSplitAssignToLot (Split *split, GNCLot *lot);
/** The xaccTransScrubGains() routine performs a number of cleanup
* functions on the indicated transaction, with the end-goal of
* setting up a consistent set of gains/losses for all the splits
* in the transaction. This includes making sure that the lot
* assignments of all the splits are good, and that the lots
* balance appropriately.
*/
void xaccTransScrubGains (Transaction *trans, Account *gain_acc);
/** The xaccSplitComputeCapGains() routine computes the cap gains
* or losses for the indicated split. The gains are placed into
* the 'gains_acct'. If the gains_acct is NULL, then the appropriate

View File

@@ -877,53 +877,53 @@ gnc_queryterm2scm (QofQueryTerm *qt)
qt_scm = scm_cons (scm_str2symbol (pd->type_name), qt_scm);
qt_scm = scm_cons (gnc_query_compare2scm (pd->how), qt_scm);
if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_STRING)) {
if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING)) {
query_string_t pdata = (query_string_t) pd;
qt_scm = scm_cons (gnc_query_string2scm (pdata->options), qt_scm);
qt_scm = scm_cons (SCM_BOOL (pdata->is_regex), qt_scm);
qt_scm = scm_cons (scm_makfrom0str (pdata->matchstring), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_DATE)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_DATE)) {
query_date_t pdata = (query_date_t) pd;
qt_scm = scm_cons (gnc_query_date2scm (pdata->options), qt_scm);
qt_scm = scm_cons (gnc_timespec2timepair (pdata->date), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_NUMERIC)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_NUMERIC)) {
query_numeric_t pdata = (query_numeric_t) pd;
qt_scm = scm_cons (gnc_query_numericop2scm (pdata->options), qt_scm);
qt_scm = scm_cons (gnc_query_numeric2scm (pdata->amount), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_GUID)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_GUID)) {
query_guid_t pdata = (query_guid_t) pd;
qt_scm = scm_cons (gnc_query_guid2scm (pdata->options), qt_scm);
qt_scm = scm_cons (gnc_guid_glist2scm (pdata->guids), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_INT64)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_INT64)) {
query_int64_t pdata = (query_int64_t) pd;
qt_scm = scm_cons (gnc_gint64_to_scm (pdata->val), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_DOUBLE)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_DOUBLE)) {
query_double_t pdata = (query_double_t) pd;
qt_scm = scm_cons (scm_make_real (pdata->val), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_BOOLEAN)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_BOOLEAN)) {
query_boolean_t pdata = (query_boolean_t) pd;
qt_scm = scm_cons (SCM_BOOL (pdata->val), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_CHAR)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_CHAR)) {
query_char_t pdata = (query_char_t) pd;
qt_scm = scm_cons (gnc_query_char2scm (pdata->options), qt_scm);
qt_scm = scm_cons (scm_makfrom0str (pdata->char_list), qt_scm);
} else if (!safe_strcmp (pd->type_name, QOF_QUERYCORE_KVP)) {
} else if (!safe_strcmp (pd->type_name, QOF_TYPE_KVP)) {
query_kvp_t pdata = (query_kvp_t) pd;
qt_scm = scm_cons (gnc_query_path2scm (pdata->path), qt_scm);
@@ -982,7 +982,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
/* Now compute the predicate */
if (!safe_strcmp (type, QOF_QUERYCORE_STRING)) {
if (!safe_strcmp (type, QOF_TYPE_STRING)) {
QofStringMatch options;
gboolean is_regex;
char *matchstring;
@@ -1009,7 +1009,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
options, is_regex);
free (matchstring);
} else if (!safe_strcmp (type, QOF_QUERYCORE_DATE)) {
} else if (!safe_strcmp (type, QOF_TYPE_DATE)) {
QofDateMatch options;
Timespec date;
@@ -1027,7 +1027,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_date_predicate (compare_how, options, date);
} else if (!safe_strcmp (type, QOF_QUERYCORE_NUMERIC)) {
} else if (!safe_strcmp (type, QOF_TYPE_NUMERIC)) {
QofNumericMatch options;
gnc_numeric val;
@@ -1045,7 +1045,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_numeric_predicate (compare_how, options, val);
} else if (!safe_strcmp (type, QOF_QUERYCORE_GUID)) {
} else if (!safe_strcmp (type, QOF_TYPE_GUID)) {
QofGuidMatch options;
GList *guids;
@@ -1065,7 +1065,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
gnc_guid_glist_free (guids);
} else if (!safe_strcmp (type, QOF_QUERYCORE_INT64)) {
} else if (!safe_strcmp (type, QOF_TYPE_INT64)) {
gint64 val;
scm = SCM_CAR (qt_scm);
@@ -1076,7 +1076,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_int64_predicate (compare_how, val);
} else if (!safe_strcmp (type, QOF_QUERYCORE_DOUBLE)) {
} else if (!safe_strcmp (type, QOF_TYPE_DOUBLE)) {
double val;
scm = SCM_CAR (qt_scm);
@@ -1087,7 +1087,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_double_predicate (compare_how, val);
} else if (!safe_strcmp (type, QOF_QUERYCORE_BOOLEAN)) {
} else if (!safe_strcmp (type, QOF_TYPE_BOOLEAN)) {
gboolean val;
scm = SCM_CAR (qt_scm);
@@ -1098,7 +1098,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_boolean_predicate (compare_how, val);
} else if (!safe_strcmp (type, QOF_QUERYCORE_CHAR)) {
} else if (!safe_strcmp (type, QOF_TYPE_CHAR)) {
QofCharMatch options;
char *char_list;
@@ -1117,7 +1117,7 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
pd = qof_query_char_predicate (options, char_list);
free (char_list);
} else if (!safe_strcmp (type, QOF_QUERYCORE_KVP)) {
} else if (!safe_strcmp (type, QOF_TYPE_KVP)) {
GSList *kvp_path;
KvpValue *value;

View File

@@ -95,8 +95,6 @@ back_associate_expense_accounts(Account *stock_account,
g_return_if_fail(kvp_value_get_type(val) == KVP_TYPE_GUID);
existing_acc_guid = kvp_value_get_guid(val);
g_return_if_fail(GNC_ID_NONE == qof_entity_type (qof_book_get_entity_table (stock_account->book), existing_acc_guid));
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account",
stock_acc_guid_kvpval);
@@ -130,9 +128,6 @@ back_associate_income_accounts(Account *stock_account,
g_return_if_fail(kvp_value_get_type(val) == KVP_TYPE_GUID);
existing_acc_guid = kvp_value_get_guid(val);
g_return_if_fail(qof_entity_type(qof_book_get_entity_table(stock_account->book), existing_acc_guid) ==
GNC_ID_NONE);
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account",
stock_acc_guid_kvpval);
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account-category",
@@ -311,7 +306,7 @@ gnc_tracking_find_expense_accounts(Account *stock_account,
kvpd_on_account_list = kvp_frame_get_slot(account_frame,
expense_to_key[category]);
return de_kvp_account_list(kvpd_on_account_list, stock_account->book);
return de_kvp_account_list(kvpd_on_account_list, stock_account->inst.book);
}
/*********************************************************************\
@@ -345,7 +340,7 @@ gnc_tracking_find_income_accounts(Account *stock_account,
kvpd_on_account_list = kvp_frame_get_slot(income_acc_frame,
income_to_key[category]);
return de_kvp_account_list(kvpd_on_account_list, stock_account->book);
return de_kvp_account_list(kvpd_on_account_list, stock_account->inst.book);
}
/*********************************************************************\
@@ -448,10 +443,6 @@ gnc_tracking_dissociate_account(Account *inc_or_expense_account)
"associated-stock-account");
stock_account_guid = kvp_value_get_guid(stock_account_kvpval);
if(!safe_strcmp
(qof_entity_type(qof_book_get_entity_table(inc_or_expense_account->book), stock_account_guid),
GNC_ID_NULL))
return;
category_kvpval = kvp_frame_get_slot(current_account_kvpframe,
"associated-stock-account-category");
@@ -460,7 +451,7 @@ gnc_tracking_dissociate_account(Account *inc_or_expense_account)
inc_or_expense_account_guid = xaccAccountGetGUID(inc_or_expense_account);
stock_account = xaccAccountLookup
(stock_account_guid, inc_or_expense_account->book);
(stock_account_guid, inc_or_expense_account->inst.book);
stock_account_kvpframe = xaccAccountGetSlots(stock_account);

View File

@@ -20,10 +20,10 @@
\********************************************************************/
/*
* gnc-be-utils.h -- QOF Backend Utilities
* common code used by objects to define begin_edit() and
* commit_edit() functions.
* common code used by objects to define begin_edit() and
* commit_edit() functions.
*
* Written by: Derek Atkins <derek@ihtfp.com>
* Written by: Derek Atkins <derek@ihtfp.com>
*
*/
@@ -35,37 +35,35 @@
#include "qofbook.h"
/* begin_edit helper
*
* assumes:
* obj->editlevel (int)
* obj->book (QofBook*)
*
* @args:
* obj: the object to begin editing
* type: the object type
* inst: an instance of QofInstance
*
* The caller should use this macro first and then perform any other operations.
*/
#define GNC_BEGIN_EDIT(obj,type) { \
QofBackend * be; \
if (!(obj)) return; \
\
(obj)->editlevel++; \
if (1 < (obj)->editlevel) return; \
\
if (0 >= (obj)->editlevel) \
{ \
PERR ("unbalanced call - resetting (was %d)", (obj)->editlevel); \
(obj)->editlevel = 1; \
} \
\
/* See if there's a backend. If there is, invoke it. */ \
be = gnc_book_get_backend ((obj)->book); \
if (be && be->begin) { \
(be->begin) (be, (type), (obj)); \
} \
}
#define GNC_BEGIN_EDIT(inst) \
QofBackend * be; \
if (!(inst)) return; \
\
(inst)->editlevel++; \
if (1 < (inst)->editlevel) return; \
\
if (0 >= (inst)->editlevel) \
{ \
PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
(inst)->editlevel = 1; \
} \
ENTER ("inst=%p", (inst)); \
\
/* See if there's a backend. If there is, invoke it. */ \
be = qof_book_get_backend ((inst)->book); \
if (be && be->begin) { \
(be->begin) (be, (inst)->entity.e_type, (inst)); \
} else { \
/* We tried and failed to start transaction! */ \
(inst)->dirty = TRUE; \
}
/*
@@ -73,82 +71,93 @@
*
* The caller should call PART1 as the first thing, then
* perform any local operations prior to calling the backend.
* Then call PART2. You cannot do anything after PART2.
*
* assumes:
* obj->editlevel (int)
* obj->book (QofBook*)
* obj->do_free (gboolean)
* Then call PART2.
*/
/*
* part1 -- deal with the editlevel
*
* assumes:
* obj->editlevel (int)
*
* @args:
* obj: the object being committed
* inst: an instance of QofInstance
*/
#define GNC_COMMIT_EDIT_PART1(obj) { \
if (!(obj)) return; \
\
(obj)->editlevel--; \
if (0 < (obj)->editlevel) return; \
\
if (0 > (obj)->editlevel) \
{ \
PERR ("unbalanced call - resetting (was %d)", (obj)->editlevel); \
(obj)->editlevel = 0; \
} \
#define GNC_COMMIT_EDIT_PART1(inst) { \
if (!(inst)) return; \
\
(inst)->editlevel--; \
if (0 < (inst)->editlevel) return; \
\
/* The pricedb sufffers from delayed update... */ \
/* This may be setting a bad precedent for other types, I fear. */ \
/* Other types probably really should handle begin like this. */ \
if ((-1 == (inst)->editlevel) && (inst)->dirty) \
{ \
QofBackend * be; \
be = qof_book_get_backend ((inst)->book); \
if (be && be->begin) { \
(be->begin) (be, (inst)->entity.e_type, (inst)); \
} \
(inst)->editlevel = 0; \
} \
if (0 > (inst)->editlevel) \
{ \
PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
(inst)->editlevel = 0; \
} \
ENTER ("inst=%p, dirty=%d do-free=%d", \
(inst), (inst)->dirty, (inst)->do_free); \
}
/*
* part2 -- deal with the backend
*
* assumes:
* obj->book (QofBook*)
* obj->do_free (gboolean)
*
* @args:
* obj: the object being committed
* type: the type of the object
* on_error: a function called if there is a backend error.
* void (*on_error)(obj, QofBackendError)
* on_done: a function called after the commit is complete but before
* the object is freed. This is where you clear the "dirty"
* flag, and perform any other operations after the commit.
* void (*on_done)(obj)
* on_free: a function called if obj->do_free is TRUE.
* void (*on_free)(obj)
* inst: an instance of QofInstance
* on_error: a function called if there is a backend error.
* void (*on_error)(inst, QofBackendError)
* on_done: a function called after the commit is complete
* but before the instect is freed. Perform any other
* operations after the commit.
* void (*on_done)(inst)
* on_free: a function called if inst->do_free is TRUE.
* void (*on_free)(inst)
*/
#define GNC_COMMIT_EDIT_PART2(obj,type,on_error,on_done,on_free) { \
QofBackend * be; \
\
/* See if there's a backend. If there is, invoke it. */ \
be = gnc_book_get_backend ((obj)->book); \
if (be && be->commit) \
{ \
QofBackendError errcode; \
\
/* clear errors */ \
do { \
errcode = qof_backend_get_error (be); \
} while (ERR_BACKEND_NO_ERR != errcode); \
\
(be->commit) (be, (type), (obj)); \
errcode = qof_backend_get_error (be); \
if (ERR_BACKEND_NO_ERR != errcode) \
{ \
(obj)->do_free = FALSE; \
(on_error)((obj), errcode); \
qof_backend_set_error (be, errcode); \
} \
} \
(on_done)(obj);\
\
if ((obj)->do_free) (on_free)(obj); \
#define GNC_COMMIT_EDIT_PART2(inst,on_error,on_done,on_free) { \
QofBackend * be; \
\
/* See if there's a backend. If there is, invoke it. */ \
be = qof_book_get_backend ((inst)->book); \
if (be && be->commit) \
{ \
QofBackendError errcode; \
\
/* clear errors */ \
do { \
errcode = qof_backend_get_error (be); \
} while (ERR_BACKEND_NO_ERR != errcode); \
\
(be->commit) (be, (inst)->entity.e_type, (inst)); \
errcode = qof_backend_get_error (be); \
if (ERR_BACKEND_NO_ERR != errcode) \
{ \
/* XXX Should perform a rollback here */ \
(inst)->do_free = FALSE; \
\
/* Push error back onto the stack */ \
qof_backend_set_error (be, errcode); \
(on_error)((inst), errcode); \
} \
/* XXX the backend commit code should clear dirty!! */ \
(inst)->dirty = FALSE; \
} \
(on_done)(inst); \
\
LEAVE ("inst=%p, dirty=%d do-free=%d", \
(inst), (inst)->dirty, (inst)->do_free); \
if ((inst)->do_free) { \
(on_free)(inst); \
return; \
} \
}

View File

@@ -937,6 +937,27 @@ gnc_commodity_table_set_table(QofBook *book, gnc_commodity_table *ct)
gnc_commodity_table_destroy (old_ct);
}
gnc_commodity *
gnc_commodity_obtain_twin (gnc_commodity *from, QofBook *book)
{
gnc_commodity *twin;
const char * ucom;
gnc_commodity_table * comtbl;
if (!from) return NULL;
comtbl = gnc_commodity_table_get_table (book);
if (!comtbl) return NULL;
ucom = gnc_commodity_get_unique_name (from);
twin = gnc_commodity_table_lookup_unique (comtbl, ucom);
if (!twin)
{
twin = gnc_commodity_clone (from);
twin = gnc_commodity_table_insert (comtbl, twin);
}
return twin;
}
/********************************************************************
* gnc_commodity_get_size
* get the size of the commodity table
@@ -1580,6 +1601,7 @@ commodity_table_book_end (QofBook *book)
gnc_commodity_table_set_table (book, NULL);
}
#ifdef COMMODITY_CONVERTED_TO_QOF_COLLECTION
static gboolean
commodity_table_is_dirty (QofBook *book)
{
@@ -1605,6 +1627,7 @@ commodity_table_mark_clean(QofBook *book)
return;
ct->dirty = FALSE;
}
#endif
/* XXX Why is the commodity table never marked dirty/clean?
@@ -1614,12 +1637,14 @@ commodity_table_mark_clean(QofBook *book)
static QofObject commodity_table_object_def =
{
interface_version: QOF_OBJECT_VERSION,
name: GNC_ID_COMMODITY_TABLE,
e_type: GNC_ID_COMMODITY_TABLE,
type_label: "CommodityTable",
book_begin: commodity_table_book_begin,
book_end: commodity_table_book_end,
#ifdef COMMODITY_CONVERTED_TO_QOF_COLLECTION
is_dirty: commodity_table_is_dirty,
mark_clean: commodity_table_mark_clean,
#endif
foreach: NULL,
printable: NULL,
};

View File

@@ -596,7 +596,7 @@ gnc_commodity * gnc_commodity_table_find_full(const gnc_commodity_table * t,
* nothing), or another entries has the same namespace and mnemonic
* (updates the existing entry).
*
* @param table A pointer to the commodity table for the book.
* @param table A pointer to the commodity table
*
* @param comm A pointer to the commodity to add.
*
@@ -611,7 +611,7 @@ gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table * table,
/** Remove a commodity from the commodity table. If the commodity to
* remove doesn't exist, nothing happens.
*
* @param table A pointer to the commodity table for the book.
* @param table A pointer to the commodity table
*
* @param comm A pointer to the commodity to remove. */
void gnc_commodity_table_remove(gnc_commodity_table * table,
@@ -622,7 +622,7 @@ void gnc_commodity_table_remove(gnc_commodity_table * table,
* etc. It also adds all of the ISO 4217 currencies to the commodity
* table.
*
* @param table A pointer to the commodity table for the book. */
* @param table A pointer to the commodity table */
gboolean gnc_commodity_table_add_default_data(gnc_commodity_table *table);
/** @} */
@@ -639,8 +639,7 @@ guint gnc_commodity_table_get_number_of_namespaces(gnc_commodity_table* tbl);
/** Test to see if the indicated namespace exits in the commodity table.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @param namespace The new namespace to check.
*
@@ -661,8 +660,7 @@ GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table * t);
/** This function adds a new string to the list of commodity namespaces.
* If the new namespace already exists, nothing happens.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @param namespace The new namespace to be added.*/
void gnc_commodity_table_add_namespace(gnc_commodity_table * table,
@@ -671,8 +669,7 @@ void gnc_commodity_table_add_namespace(gnc_commodity_table * table,
/** This function deletes a string from the list of commodity namespaces.
* If the namespace does not exist, nothing happens.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @param namespace The namespace to be deleted.
*
@@ -687,8 +684,7 @@ void gnc_commodity_table_delete_namespace(gnc_commodity_table * t,
/** Returns the number of commodities in the commodity table.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @return The number of commodities in the table. 0 if there are no
* commodities, or the routine was passed a bad argument. */
@@ -713,8 +709,7 @@ GList * gnc_commodity_table_get_commodities(const gnc_commodity_table * t,
* field has been set. All matching commodities are queued onto a
* list, and the head of that list is returned.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @param expression Use the given expression as a filter on the
* commodities to be returned. If non-null, only commodities in
@@ -733,8 +728,7 @@ GList * gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table *
* This table walk returns whenever the end of the table is reached,
* or the function returns FALSE.
*
* @param table A pointer to the commodity table for the current
* book.
* @param table A pointer to the commodity table
*
* @param f The function to call for each commodity.
*
@@ -772,6 +766,13 @@ void gnc_commodity_table_destroy(gnc_commodity_table * table);
*/
void gnc_commodity_table_set_table(QofBook *book, gnc_commodity_table *ct);
/** Given the commodity 'from', this routine will find and return the
* equivalent commodity (commodity with the same 'unique name') in
* the indicated book. This routine is primarily useful for setting
* up clones of things across multiple books.
*/
gnc_commodity * gnc_commodity_obtain_twin (gnc_commodity *from, QofBook *book);
/** You should probably not be using gnc_commodity_table_register()
* It is an internal routine for registering the gncObject for the
* commodity table.

View File

@@ -189,7 +189,7 @@ Timespec gnc_iso8601_to_timespec_gmt(const char *);
/** The gnc_timespec_to_iso8601_buff() routine prints a Timespec
* as an ISO-8601 style string. The buffer must be long enough
* to contain the string. The string is null-terminated. This
* to contain the NULL-terminated string (32 characters + NUL). This
* routine returns a pointer to the null terminator (and can
* thus be used in the 'stpcpy' metaphor of string concatenation).*/
char * gnc_timespec_to_iso8601_buff (Timespec ts, char * buff);

View File

@@ -40,9 +40,11 @@
#define SAFE_STRCMP_REAL(fcn,da,db) { \
if ((da) && (db)) { \
int retval = fcn ((da), (db)); \
/* if strings differ, return */ \
if (retval) return retval; \
if ((da) != (db)) { \
int retval = fcn ((da), (db)); \
/* if strings differ, return */ \
if (retval) return retval; \
} \
} else \
if ((!(da)) && (db)) { \
return -1; \

View File

@@ -68,7 +68,8 @@
#define GNC_ID_PRICEDB "PriceDB"
#define GNC_ID_SPLIT "Split"
#define GNC_ID_SCHEDXACTION "SchedXaction"
#define GNC_ID_SXTT "SXTT"
#define GNC_ID_SXTG "SXTGroup"
#define GNC_ID_SXTT "SXTTrans"
#define GNC_ID_TRANS "Trans"
/* TYPES **********************************************************/

View File

@@ -25,6 +25,7 @@
#define GNC_EVENT_P_H
#include "gnc-event.h"
#include "qofid.h"
/* gnc_engine_generate_event
* Invoke all registered event handlers using the given arguments.
@@ -40,11 +41,14 @@
* event_type: the type of event -- this should be one of the
* single-bit GNCEngineEventType values, not a combination.
*/
void gnc_engine_generate_event (const GUID *entity, QofIdType type,
void gnc_engine_gen_event (QofEntity *entity,
GNCEngineEventType event_type);
/* XXX deprecated, but still usedion on postgres backend */
void gnc_engine_generate_event (const GUID *, QofIdType, GNCEngineEventType);
/* generates an event even when events are suspended! */
void gnc_engine_force_event (const GUID *entity, QofIdType type,
void gnc_engine_force_event (QofEntity *entity,
GNCEngineEventType event_type);
#endif

View File

@@ -153,7 +153,7 @@ gnc_engine_resume_events (void)
}
static void
gnc_engine_generate_event_internal (const GUID *entity, QofIdType type,
gnc_engine_generate_event_internal (QofEntity *entity,
GNCEngineEventType event_type)
{
GList *node;
@@ -183,23 +183,22 @@ gnc_engine_generate_event_internal (const GUID *entity, QofIdType type,
PINFO ("id=%d hi=%p han=%p", hi->handler_id, hi, hi->handler);
if (hi->handler)
hi->handler ((GUID *)entity, type, event_type, hi->user_data);
hi->handler ((GUID *)&entity->guid, entity->e_type, event_type, hi->user_data);
}
}
void
gnc_engine_force_event (const GUID *entity, QofIdType type,
gnc_engine_force_event (QofEntity *entity,
GNCEngineEventType event_type)
{
if (!entity)
return;
gnc_engine_generate_event_internal (entity, type, event_type);
gnc_engine_generate_event_internal (entity, event_type);
}
void
gnc_engine_generate_event (const GUID *entity, QofIdType type,
GNCEngineEventType event_type)
gnc_engine_gen_event (QofEntity *entity, GNCEngineEventType event_type)
{
if (!entity)
return;
@@ -207,7 +206,18 @@ gnc_engine_generate_event (const GUID *entity, QofIdType type,
if (suspend_counter)
return;
gnc_engine_generate_event_internal (entity, type, event_type);
gnc_engine_generate_event_internal (entity, event_type);
}
void
gnc_engine_generate_event (const GUID *guid, QofIdType e_type,
GNCEngineEventType event_type)
{
QofEntity ent;
ent.guid = *guid;
ent.e_type = e_type;
if (suspend_counter) return;
gnc_engine_generate_event_internal (&ent, event_type);
}
/* =========================== END OF FILE ======================= */

View File

@@ -41,11 +41,11 @@
#include "kvp_frame.h"
#include "qofbook.h"
#include "qofid.h"
#include "qofid-p.h"
struct gnc_lot_struct
{
/* Unique guid for this lot */
GUID guid;
QofEntity entity; /* Unique guid for this lot */
/* Book that this lot belongs to */
QofBook *book;
@@ -69,7 +69,7 @@ struct gnc_lot_struct
unsigned char marker;
};
void gnc_lot_set_guid(GNCLot *lot, GUID guid);
#define gnc_lot_set_guid(L,G) qof_entity_set_guid(QOF_ENTITY(L),&(G))
/* Register with the Query engine */
void gnc_lot_register (void);

Some files were not shown because too many files have changed in this diff Show More