gnucash maint: Cache current owner balances
Geert Janssens
gjanssens at code.gnucash.org
Sun Sep 23 10:00:49 EDT 2018
Updated via https://github.com/Gnucash/gnucash/commit/3991ccb9 (commit)
from https://github.com/Gnucash/gnucash/commit/40bcd1e3 (commit)
commit 3991ccb9c2383f94315ec647e4250a408bc16ad4
Author: Geert Janssens <geert at kobaltwit.be>
Date: Sun Sep 23 15:59:27 2018 +0200
Cache current owner balances
These are queried continuously by the owner tree view (on Customer/Vendor/Employee
Overview pages) and recalculating them is an expensive operation.
The cache will be invalidated each time a lot reated to the owner
changes (modify or delete). The net effect is a huge responsiveness
improvement of said overviews in case of a large book.
diff --git a/libgnucash/engine/gncCustomer.c b/libgnucash/engine/gncCustomer.c
index 48b470f..6260b6c 100644
--- a/libgnucash/engine/gncCustomer.c
+++ b/libgnucash/engine/gncCustomer.c
@@ -46,9 +46,9 @@
#include "gncJobP.h"
#include "gncTaxTableP.h"
-static gint gs_address_event_handler_id = 0;
-static void listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data);
+static gint cust_qof_event_handler_id = 0;
+static void cust_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data);
struct _gncCustomer
{
@@ -66,6 +66,7 @@ struct _gncCustomer
GncTaxIncluded taxincluded;
gboolean active;
GList * jobs;
+ gnc_numeric * balance; /* cached customer balance, will not be stored */
/* The following fields are unique to 'customer' */
gnc_numeric credit;
@@ -319,15 +320,14 @@ GncCustomer *gncCustomerCreate (QofBook *book)
cust->taxincluded = GNC_TAXINCLUDED_USEGLOBAL;
cust->active = TRUE;
cust->jobs = NULL;
+ cust->balance = NULL;
cust->discount = gnc_numeric_zero();
cust->credit = gnc_numeric_zero();
cust->shipaddr = gncAddressCreate (book, &cust->inst);
- if (gs_address_event_handler_id == 0)
- {
- gs_address_event_handler_id = qof_event_register_handler(listen_for_address_events, NULL);
- }
+ if (cust_qof_event_handler_id == 0)
+ cust_qof_event_handler_id = qof_event_register_handler (cust_handle_qof_events, NULL);
qof_event_gen (&cust->inst, QOF_EVENT_CREATE, NULL);
@@ -356,6 +356,7 @@ static void gncCustomerFree (GncCustomer *cust)
gncAddressBeginEdit (cust->shipaddr);
gncAddressDestroy (cust->shipaddr);
g_list_free (cust->jobs);
+ g_free (cust->balance);
if (cust->terms)
gncBillTermDecRef (cust->terms);
@@ -825,8 +826,11 @@ gncCustomerEqual(const GncCustomer *a, const GncCustomer *b)
}
/**
- * Listens for MODIFY events from addresses. If the address belongs to a customer,
- * mark the customer as dirty.
+ * Listen for qof events.
+ *
+ * - If the address of a customer has changed, mark the customer as dirty.
+ * - If a lot related to a customer has changed, clear the customer's
+ * cached balance as it likely has become invalid.
*
* @param entity Entity for the event
* @param event_type Event type
@@ -834,28 +838,50 @@ gncCustomerEqual(const GncCustomer *a, const GncCustomer *b)
* @param event_data Event data passed with the event.
*/
static void
-listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data)
+cust_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data)
{
- GncCustomer* cust;
-
- if ((event_type & QOF_EVENT_MODIFY) == 0)
- {
- return;
- }
- if (!GNC_IS_ADDRESS(entity))
+ /* Handle address change events */
+ if ((GNC_IS_ADDRESS (entity) &&
+ (event_type & QOF_EVENT_MODIFY) != 0))
{
+ if (GNC_IS_CUSTOMER (event_data))
+ {
+ GncCustomer* cust = GNC_CUSTOMER (event_data);
+ gncCustomerBeginEdit (cust);
+ mark_customer (cust);
+ gncCustomerCommitEdit (cust);
+ }
return;
}
- if (!GNC_IS_CUSTOMER(event_data))
+
+ /* Handle lot change events */
+ if (GNC_IS_LOT (entity))
{
+ GNCLot *lot = GNC_LOT (entity);
+ GncOwner lot_owner;
+ const GncOwner *end_owner = NULL;
+ GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
+
+ /* Determine the owner associated with the lot */
+ if (invoice)
+ /* Invoice lots */
+ end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
+ else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
+ /* Pre-payment lots */
+ end_owner = gncOwnerGetEndOwner (&lot_owner);
+
+ if (gncOwnerGetType (end_owner) == GNC_OWNER_CUSTOMER)
+ {
+ /* Clear the cached balance */
+ GncCustomer* cust = gncOwnerGetCustomer (end_owner);
+ g_free (cust->balance);
+ cust->balance = NULL;
+ }
return;
}
- cust = GNC_CUSTOMER(event_data);
- gncCustomerBeginEdit(cust);
- mark_customer(cust);
- gncCustomerCommitEdit(cust);
}
+
/* ============================================================== */
/* Package-Private functions */
static const char * _gncCustomerPrintable (gpointer item)
@@ -952,3 +978,24 @@ gchar *gncCustomerNextID (QofBook *book)
{
return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
}
+
+const gnc_numeric*
+gncCustomerGetCachedBalance (GncCustomer *cust)
+{
+ return cust->balance;
+}
+
+void gncCustomerSetCachedBalance (GncCustomer *cust, const gnc_numeric *new_bal)
+{
+ if (!new_bal && cust->balance)
+ {
+ g_free (cust->balance);
+ cust->balance = NULL;
+ return;
+ }
+
+ if (!cust->balance)
+ cust->balance = g_new0 (gnc_numeric, 1);
+
+ *cust->balance = *new_bal;
+}
diff --git a/libgnucash/engine/gncCustomerP.h b/libgnucash/engine/gncCustomerP.h
index b0d65ca..7a12387 100644
--- a/libgnucash/engine/gncCustomerP.h
+++ b/libgnucash/engine/gncCustomerP.h
@@ -33,6 +33,8 @@
gboolean gncCustomerRegister (void);
gchar *gncCustomerNextID (QofBook *book);
+const gnc_numeric *gncCustomerGetCachedBalance (GncCustomer *cust);
+void gncCustomerSetCachedBalance (GncCustomer *cust, const gnc_numeric *new_bal);
#define gncCustomerSetGUID(E,G) qof_instance_set_guid(QOF_INSTANCE(E),(G))
diff --git a/libgnucash/engine/gncEmployee.c b/libgnucash/engine/gncEmployee.c
index d992b0a..d398a30 100644
--- a/libgnucash/engine/gncEmployee.c
+++ b/libgnucash/engine/gncEmployee.c
@@ -37,10 +37,12 @@
#include "gncAddressP.h"
#include "gncEmployee.h"
#include "gncEmployeeP.h"
+#include "gnc-lot.h"
+#include "gncOwner.h"
-static gint gs_address_event_handler_id = 0;
-static void listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data);
+static gint empl_qof_event_handler_id = 0;
+static void empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data);
struct _gncEmployee
{
@@ -50,6 +52,7 @@ struct _gncEmployee
GncAddress * addr;
gnc_commodity * currency;
gboolean active;
+ gnc_numeric * balance;
char * language;
char * acl;
@@ -439,11 +442,10 @@ GncEmployee *gncEmployeeCreate (QofBook *book)
employee->workday = gnc_numeric_zero();
employee->rate = gnc_numeric_zero();
employee->active = TRUE;
+ employee->balance = NULL;
- if (gs_address_event_handler_id == 0)
- {
- gs_address_event_handler_id = qof_event_register_handler(listen_for_address_events, NULL);
- }
+ if (empl_qof_event_handler_id == 0)
+ empl_qof_event_handler_id = qof_event_register_handler (empl_handle_qof_events, NULL);
qof_event_gen (&employee->inst, QOF_EVENT_CREATE, NULL);
@@ -469,6 +471,7 @@ static void gncEmployeeFree (GncEmployee *employee)
CACHE_REMOVE (employee->acl);
gncAddressBeginEdit (employee->addr);
gncAddressDestroy (employee->addr);
+ g_free (employee->balance);
/* qof_instance_release (&employee->inst); */
g_object_unref (employee);
@@ -816,8 +819,11 @@ static const char * _gncEmployeePrintable (gpointer item)
}
/**
- * Listens for MODIFY events from addresses. If the address belongs to an employee,
- * mark the employee as dirty.
+ * Listen for qof events.
+ *
+ * - If the address of an employee has changed, mark the employee as dirty.
+ * - If a lot related to an employee has changed, clear the employee's
+ * cached balance as it likely has become invalid.
*
* @param entity Entity for the event
* @param event_type Event type
@@ -825,27 +831,49 @@ static const char * _gncEmployeePrintable (gpointer item)
* @param event_data Event data passed with the event.
*/
static void
-listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data)
+empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data)
{
- GncEmployee* empl;
- if ((event_type & QOF_EVENT_MODIFY) == 0)
- {
- return;
- }
- if (!GNC_IS_ADDRESS(entity))
+ /* Handle address change events */
+ if ((GNC_IS_ADDRESS (entity) &&
+ (event_type & QOF_EVENT_MODIFY) != 0))
{
+ if (GNC_IS_EMPLOYEE (event_data))
+ {
+ GncEmployee* empl = GNC_EMPLOYEE (event_data);
+ gncEmployeeBeginEdit (empl);
+ mark_employee (empl);
+ gncEmployeeCommitEdit (empl);
+ }
return;
}
- if (!GNC_IS_EMPLOYEE(event_data))
+
+ /* Handle lot change events */
+ if (GNC_IS_LOT (entity))
{
+ GNCLot *lot = GNC_LOT (entity);
+ GncOwner lot_owner;
+ const GncOwner *end_owner = NULL;
+ GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
+
+ /* Determine the owner associated with the lot */
+ if (invoice)
+ /* Invoice lots */
+ end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
+ else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
+ /* Pre-payment lots */
+ end_owner = gncOwnerGetEndOwner (&lot_owner);
+
+ if (gncOwnerGetType (end_owner) == GNC_OWNER_EMPLOYEE)
+ {
+ /* Clear the cached balance */
+ GncEmployee* empl = gncOwnerGetEmployee (end_owner);
+ g_free (empl->balance);
+ empl->balance = NULL;
+ }
return;
}
- empl = GNC_EMPLOYEE(event_data);
- gncEmployeeBeginEdit(empl);
- mark_employee(empl);
- gncEmployeeCommitEdit(empl);
}
static void
@@ -925,3 +953,24 @@ gchar *gncEmployeeNextID (QofBook *book)
{
return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
}
+
+const gnc_numeric*
+gncEmployeeGetCachedBalance (GncEmployee *empl)
+{
+ return empl->balance;
+}
+
+void gncEmployeeSetCachedBalance (GncEmployee *empl, const gnc_numeric *new_bal)
+{
+ if (!new_bal && empl->balance)
+ {
+ g_free (empl->balance);
+ empl->balance = NULL;
+ return;
+ }
+
+ if (!empl->balance)
+ empl->balance = g_new0 (gnc_numeric, 1);
+
+ *empl->balance = *new_bal;
+}
diff --git a/libgnucash/engine/gncEmployeeP.h b/libgnucash/engine/gncEmployeeP.h
index c9a63a9..8dd6e47 100644
--- a/libgnucash/engine/gncEmployeeP.h
+++ b/libgnucash/engine/gncEmployeeP.h
@@ -33,6 +33,8 @@
gboolean gncEmployeeRegister (void);
gchar *gncEmployeeNextID (QofBook *book);
+const gnc_numeric *gncEmployeeGetCachedBalance (GncEmployee *vend);
+void gncEmployeeSetCachedBalance (GncEmployee *vend, const gnc_numeric *new_bal);
#define gncEmployeeSetGUID(E,G) qof_instance_set_guid(QOF_INSTANCE(E),(G))
diff --git a/libgnucash/engine/gncInvoice.c b/libgnucash/engine/gncInvoice.c
index 3d5aae1..e725d6a 100644
--- a/libgnucash/engine/gncInvoice.c
+++ b/libgnucash/engine/gncInvoice.c
@@ -1483,6 +1483,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
/* Create a new lot for this invoice */
lot = gnc_lot_new (book);
+ gncInvoiceAttachToLot (invoice, lot);
gnc_lot_begin_edit (lot);
type = gncInvoiceGetTypeString (invoice);
@@ -1697,8 +1698,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
gnc_lot_add_split (lot, split);
}
- /* Now attach this invoice to the txn, lot, and account */
- gncInvoiceAttachToLot (invoice, lot);
+ /* Now attach this invoice to the txn and account */
gncInvoiceAttachToTxn (invoice, txn);
gncInvoiceSetPostedAcc (invoice, acc);
diff --git a/libgnucash/engine/gncOwner.c b/libgnucash/engine/gncOwner.c
index 5bea047..53e648e 100644
--- a/libgnucash/engine/gncOwner.c
+++ b/libgnucash/engine/gncOwner.c
@@ -1453,50 +1453,61 @@ gncOwnerGetBalanceInCurrency (const GncOwner *owner,
const gnc_commodity *report_currency)
{
gnc_numeric balance = gnc_numeric_zero ();
- GList *acct_list, *acct_node, *acct_types, *lot_list = NULL, *lot_node;
QofBook *book;
gnc_commodity *owner_currency;
GNCPriceDB *pdb;
+ const gnc_numeric *cached_balance = NULL;
g_return_val_if_fail (owner, gnc_numeric_zero ());
- /* Get account list */
book = qof_instance_get_book (qofOwnerGetOwner (owner));
- acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book));
- acct_types = gncOwnerGetAccountTypesList (owner);
owner_currency = gncOwnerGetCurrency (owner);
- /* For each account */
- for (acct_node = acct_list; acct_node; acct_node = acct_node->next)
+ cached_balance = gncOwnerGetCachedBalance (owner);
+ if (cached_balance)
+ balance = *cached_balance;
+ else
{
- Account *account = acct_node->data;
+ /* No valid cache value found for balance. Let's recalculate */
+ GList *acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book));
+ GList *acct_types = gncOwnerGetAccountTypesList (owner);
+ GList *acct_node;
- /* Check if this account can have lots for the owner, otherwise skip to next */
- if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account))
- == -1)
- continue;
+ /* For each account */
+ for (acct_node = acct_list; acct_node; acct_node = acct_node->next)
+ {
+ Account *account = acct_node->data;
+ GList *lot_list = NULL, *lot_node;
+ /* Check if this account can have lots for the owner, otherwise skip to next */
+ if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account))
+ == -1)
+ continue;
- if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account)))
- continue;
- /* Get a list of open lots for this owner and account */
- lot_list = xaccAccountFindOpenLots (account, gncOwnerLotMatchOwnerFunc,
- (gpointer)owner, NULL);
- /* For each lot */
- for (lot_node = lot_list; lot_node; lot_node = lot_node->next)
- {
- GNCLot *lot = lot_node->data;
- gnc_numeric lot_balance = gnc_lot_get_balance (lot);
- GncInvoice *invoice = gncInvoiceGetInvoiceFromLot(lot);
- if (invoice)
- balance = gnc_numeric_add (balance, lot_balance,
- gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP);
+ if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account)))
+ continue;
+
+ /* Get a list of open lots for this owner and account */
+ lot_list = xaccAccountFindOpenLots (account, gncOwnerLotMatchOwnerFunc,
+ (gpointer)owner, NULL);
+ /* For each lot */
+ for (lot_node = lot_list; lot_node; lot_node = lot_node->next)
+ {
+ GNCLot *lot = lot_node->data;
+ gnc_numeric lot_balance = gnc_lot_get_balance (lot);
+ GncInvoice *invoice = gncInvoiceGetInvoiceFromLot(lot);
+ if (invoice)
+ balance = gnc_numeric_add (balance, lot_balance,
+ gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP);
+ }
+ g_list_free (lot_list);
}
- g_list_free (lot_list);
+ g_list_free (acct_list);
+ g_list_free (acct_types);
+
+ gncOwnerSetCachedBalance (owner, &balance);
}
- g_list_free (acct_list);
- g_list_free (acct_types);
pdb = gnc_pricedb_get_db (book);
@@ -1587,3 +1598,30 @@ gboolean gncOwnerRegister (void)
return TRUE;
}
+
+const gnc_numeric*
+gncOwnerGetCachedBalance (const GncOwner *owner)
+{
+ if (!owner) return NULL;
+
+ if (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER)
+ return gncCustomerGetCachedBalance (gncOwnerGetCustomer (owner));
+ else if (gncOwnerGetType (owner) == GNC_OWNER_VENDOR)
+ return gncVendorGetCachedBalance (gncOwnerGetVendor (owner));
+ else if (gncOwnerGetType (owner) == GNC_OWNER_EMPLOYEE)
+ return gncEmployeeGetCachedBalance (gncOwnerGetEmployee (owner));
+
+ return NULL;
+}
+
+void gncOwnerSetCachedBalance (const GncOwner *owner, const gnc_numeric *new_bal)
+{
+ if (!owner) return;
+
+ if (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER)
+ gncCustomerSetCachedBalance (gncOwnerGetCustomer (owner), new_bal);
+ else if (gncOwnerGetType (owner) == GNC_OWNER_VENDOR)
+ gncVendorSetCachedBalance (gncOwnerGetVendor (owner), new_bal);
+ else if (gncOwnerGetType (owner) == GNC_OWNER_EMPLOYEE)
+ gncEmployeeSetCachedBalance (gncOwnerGetEmployee (owner), new_bal);
+}
diff --git a/libgnucash/engine/gncOwnerP.h b/libgnucash/engine/gncOwnerP.h
index 42bdd8e..7387485 100644
--- a/libgnucash/engine/gncOwnerP.h
+++ b/libgnucash/engine/gncOwnerP.h
@@ -31,6 +31,8 @@
#include "gncOwner.h"
gboolean gncOwnerRegister (void);
+const gnc_numeric *gncOwnerGetCachedBalance (const GncOwner *owner);
+void gncOwnerSetCachedBalance (const GncOwner *owner, const gnc_numeric *new_bal);
#endif /* GNC_OWNERP_H_ */
diff --git a/libgnucash/engine/gncVendor.c b/libgnucash/engine/gncVendor.c
index cdfdd0a..19f75dd 100644
--- a/libgnucash/engine/gncVendor.c
+++ b/libgnucash/engine/gncVendor.c
@@ -41,9 +41,9 @@
#include "gncVendor.h"
#include "gncVendorP.h"
-static gint gs_address_event_handler_id = 0;
-static void listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data);
+static gint vend_qof_event_handler_id = 0;
+static void vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data);
static void qofVendorSetAddr (GncVendor *vendor, QofInstance *addr_ent);
static const char* qofVendorGetTaxIncluded(const GncVendor *vendor);
static void qofVendorSetTaxIncluded(GncVendor *vendor, const char* type_string);
@@ -63,6 +63,7 @@ struct _gncVendor
GncTaxIncluded taxincluded;
gboolean active;
GList * jobs;
+ gnc_numeric * balance; /* cached vendor balance, will not be stored */
};
struct _gncVendorClass
@@ -467,11 +468,10 @@ GncVendor *gncVendorCreate (QofBook *book)
vendor->taxincluded = GNC_TAXINCLUDED_USEGLOBAL;
vendor->active = TRUE;
vendor->jobs = NULL;
+ vendor->balance = NULL;
- if (gs_address_event_handler_id == 0)
- {
- gs_address_event_handler_id = qof_event_register_handler(listen_for_address_events, NULL);
- }
+ if (vend_qof_event_handler_id == 0)
+ vend_qof_event_handler_id = qof_event_register_handler (vend_handle_qof_events, NULL);
qof_event_gen (&vendor->inst, QOF_EVENT_CREATE, NULL);
@@ -497,6 +497,7 @@ static void gncVendorFree (GncVendor *vendor)
gncAddressBeginEdit (vendor->addr);
gncAddressDestroy (vendor->addr);
g_list_free (vendor->jobs);
+ g_free (vendor->balance);
if (vendor->terms)
gncBillTermDecRef (vendor->terms);
@@ -882,8 +883,11 @@ gncVendorIsDirty (const GncVendor *vendor)
}
/**
- * Listens for MODIFY events from addresses. If the address belongs to a vendor,
- * mark the vendor as dirty.
+ * Listen for qof events.
+ *
+ * - If the address of a vendor has changed, mark the vendor as dirty.
+ * - If a lot related to a vendor has changed, clear the vendor's
+ * cached balance as it likely has become invalid.
*
* @param entity Entity for the event
* @param event_type Event type
@@ -891,28 +895,50 @@ gncVendorIsDirty (const GncVendor *vendor)
* @param event_data Event data passed with the event.
*/
static void
-listen_for_address_events(QofInstance *entity, QofEventId event_type,
- gpointer user_data, gpointer event_data)
+vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data)
{
- GncVendor* v;
-
- if ((event_type & QOF_EVENT_MODIFY) == 0)
- {
- return;
- }
- if (!GNC_IS_ADDRESS(entity))
+ /* Handle address change events */
+ if ((GNC_IS_ADDRESS (entity) &&
+ (event_type & QOF_EVENT_MODIFY) != 0))
{
+ if (GNC_IS_VENDOR (event_data))
+ {
+ GncVendor* vend = GNC_VENDOR (event_data);
+ gncVendorBeginEdit (vend);
+ mark_vendor (vend);
+ gncVendorCommitEdit (vend);
+ }
return;
}
- if (!GNC_IS_VENDOR(event_data))
+
+ /* Handle lot change events */
+ if (GNC_IS_LOT (entity))
{
+ GNCLot *lot = GNC_LOT (entity);
+ GncOwner lot_owner;
+ const GncOwner *end_owner = NULL;
+ GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
+
+ /* Determine the owner associated with the lot */
+ if (invoice)
+ /* Invoice lots */
+ end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
+ else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
+ /* Pre-payment lots */
+ end_owner = gncOwnerGetEndOwner (&lot_owner);
+
+ if (gncOwnerGetType (end_owner) == GNC_OWNER_VENDOR)
+ {
+ /* Clear the cached balance */
+ GncVendor* vend = gncOwnerGetVendor (end_owner);
+ g_free (vend->balance);
+ vend->balance = NULL;
+ }
return;
}
- v = GNC_VENDOR(event_data);
- gncVendorBeginEdit(v);
- mark_vendor(v);
- gncVendorCommitEdit(v);
}
+
/* ============================================================== */
/* Package-Private functions */
@@ -1005,3 +1031,24 @@ gchar *gncVendorNextID (QofBook *book)
{
return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
}
+
+const gnc_numeric*
+gncVendorGetCachedBalance (GncVendor *vend)
+{
+ return vend->balance;
+}
+
+void gncVendorSetCachedBalance (GncVendor *vend, const gnc_numeric *new_bal)
+{
+ if (!new_bal && vend->balance)
+ {
+ g_free (vend->balance);
+ vend->balance = NULL;
+ return;
+ }
+
+ if (!vend->balance)
+ vend->balance = g_new0 (gnc_numeric, 1);
+
+ *vend->balance = *new_bal;
+}
diff --git a/libgnucash/engine/gncVendorP.h b/libgnucash/engine/gncVendorP.h
index 7f4653f..66c183d 100644
--- a/libgnucash/engine/gncVendorP.h
+++ b/libgnucash/engine/gncVendorP.h
@@ -32,6 +32,8 @@
gboolean gncVendorRegister (void);
gchar *gncVendorNextID (QofBook *book);
+const gnc_numeric *gncVendorGetCachedBalance (GncVendor *vend);
+void gncVendorSetCachedBalance (GncVendor *vend, const gnc_numeric *new_bal);
#define gncVendorSetGUID(V,G) qof_instance_set_guid(QOF_INSTANCE(V),(G))
Summary of changes:
libgnucash/engine/gncCustomer.c | 93 +++++++++++++++++++++++++++++----------
libgnucash/engine/gncCustomerP.h | 2 +
libgnucash/engine/gncEmployee.c | 93 +++++++++++++++++++++++++++++----------
libgnucash/engine/gncEmployeeP.h | 2 +
libgnucash/engine/gncInvoice.c | 4 +-
libgnucash/engine/gncOwner.c | 94 ++++++++++++++++++++++++++++------------
libgnucash/engine/gncOwnerP.h | 2 +
libgnucash/engine/gncVendor.c | 93 +++++++++++++++++++++++++++++----------
libgnucash/engine/gncVendorP.h | 2 +
9 files changed, 287 insertions(+), 98 deletions(-)
More information about the gnucash-changes
mailing list