mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Convert GNCLot to use more gobject features. Removes all direct access to lot object fields, which are now accessed through functions or property names (for backend sql load).
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18745 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
5066daa770
commit
a3ca714396
@ -31,6 +31,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "qof.h"
|
#include "qof.h"
|
||||||
|
#include "Account.h"
|
||||||
#include "gnc-lot.h"
|
#include "gnc-lot.h"
|
||||||
|
|
||||||
#include "gnc-backend-sql.h"
|
#include "gnc-backend-sql.h"
|
||||||
@ -49,7 +50,6 @@
|
|||||||
|
|
||||||
static /*@ dependent @*//*@ null @*/ gpointer get_lot_account( gpointer pObject );
|
static /*@ dependent @*//*@ null @*/ gpointer get_lot_account( gpointer pObject );
|
||||||
static void set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue );
|
static void set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue );
|
||||||
static void set_lot_is_closed( gpointer pObject, gboolean value );
|
|
||||||
|
|
||||||
static const GncSqlColumnTableEntry col_table[] =
|
static const GncSqlColumnTableEntry col_table[] =
|
||||||
{
|
{
|
||||||
@ -57,8 +57,7 @@ static const GncSqlColumnTableEntry col_table[] =
|
|||||||
{ "guid", CT_GUID, 0, COL_NNUL|COL_PKEY, "guid" },
|
{ "guid", CT_GUID, 0, COL_NNUL|COL_PKEY, "guid" },
|
||||||
{ "account_guid", CT_GUID, 0, 0, NULL, NULL,
|
{ "account_guid", CT_GUID, 0, 0, NULL, NULL,
|
||||||
(QofAccessFunc)get_lot_account, set_lot_account },
|
(QofAccessFunc)get_lot_account, set_lot_account },
|
||||||
{ "is_closed", CT_BOOLEAN, 0, COL_NNUL, NULL, NULL,
|
{ "is_closed", CT_BOOLEAN, 0, COL_NNUL, "is-closed" },
|
||||||
(QofAccessFunc)gnc_lot_is_closed, (QofSetterFunc)set_lot_is_closed },
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
/*@ +full_init_block @*/
|
/*@ +full_init_block @*/
|
||||||
};
|
};
|
||||||
@ -98,18 +97,6 @@ set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
set_lot_is_closed( gpointer pObject, gboolean closed )
|
|
||||||
{
|
|
||||||
GNCLot* lot;
|
|
||||||
|
|
||||||
g_return_if_fail( pObject != NULL );
|
|
||||||
g_return_if_fail( GNC_IS_LOT(pObject) );
|
|
||||||
|
|
||||||
lot = GNC_LOT(pObject);
|
|
||||||
lot->is_closed = (char)closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static /*@ dependent @*//*@ null @*/ GNCLot*
|
static /*@ dependent @*//*@ null @*/ GNCLot*
|
||||||
load_single_lot( GncSqlBackend* be, GncSqlRow* row )
|
load_single_lot( GncSqlBackend* be, GncSqlRow* row )
|
||||||
{
|
{
|
||||||
|
@ -1730,7 +1730,7 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot)
|
|||||||
|
|
||||||
ENTER ("(acc=%p, lot=%p)", acc, lot);
|
ENTER ("(acc=%p, lot=%p)", acc, lot);
|
||||||
priv->lots = g_list_remove(priv->lots, lot);
|
priv->lots = g_list_remove(priv->lots, lot);
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_REMOVE, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE, NULL);
|
||||||
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||||
LEAVE ("(acc=%p, lot=%p)", acc, lot);
|
LEAVE ("(acc=%p, lot=%p)", acc, lot);
|
||||||
}
|
}
|
||||||
@ -1739,35 +1739,37 @@ void
|
|||||||
xaccAccountInsertLot (Account *acc, GNCLot *lot)
|
xaccAccountInsertLot (Account *acc, GNCLot *lot)
|
||||||
{
|
{
|
||||||
AccountPrivate *priv, *opriv;
|
AccountPrivate *priv, *opriv;
|
||||||
Account * old_acc = NULL;
|
Account * old_acc = NULL;
|
||||||
|
Account* lot_account;
|
||||||
|
|
||||||
/* errors */
|
/* errors */
|
||||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||||
g_return_if_fail(GNC_IS_LOT(lot));
|
g_return_if_fail(GNC_IS_LOT(lot));
|
||||||
|
|
||||||
/* optimizations */
|
/* optimizations */
|
||||||
if (lot->account == acc)
|
lot_account = gnc_lot_get_account(lot);
|
||||||
|
if (lot_account == acc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ENTER ("(acc=%p, lot=%p)", acc, lot);
|
ENTER ("(acc=%p, lot=%p)", acc, lot);
|
||||||
|
|
||||||
/* pull it out of the old account */
|
/* pull it out of the old account */
|
||||||
if (lot->account) {
|
if (lot_account) {
|
||||||
old_acc = lot->account;
|
old_acc = lot_account;
|
||||||
opriv = GET_PRIVATE(old_acc);
|
opriv = GET_PRIVATE(old_acc);
|
||||||
opriv->lots = g_list_remove(opriv->lots, lot);
|
opriv->lots = g_list_remove(opriv->lots, lot);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = GET_PRIVATE(acc);
|
priv = GET_PRIVATE(acc);
|
||||||
priv->lots = g_list_prepend(priv->lots, lot);
|
priv->lots = g_list_prepend(priv->lots, lot);
|
||||||
lot->account = acc;
|
gnc_lot_set_account(lot, acc);
|
||||||
|
|
||||||
/* Don't move the splits to the new account. The caller will do this
|
/* Don't move the splits to the new account. The caller will do this
|
||||||
* if appropriate, and doing it here will not work if we are being
|
* if appropriate, and doing it here will not work if we are being
|
||||||
* called from gnc_book_close_period since xaccAccountInsertSplit
|
* called from gnc_book_close_period since xaccAccountInsertSplit
|
||||||
* will try to balance capital gains and things aren't ready for that. */
|
* will try to balance capital gains and things aren't ready for that. */
|
||||||
|
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_ADD, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_ADD, NULL);
|
||||||
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||||
|
|
||||||
LEAVE ("(acc=%p, lot=%p)", acc, lot);
|
LEAVE ("(acc=%p, lot=%p)", acc, lot);
|
||||||
|
@ -228,11 +228,11 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot)
|
|||||||
|
|
||||||
col = qof_book_get_collection (book, GNC_ID_LOT);
|
col = qof_book_get_collection (book, GNC_ID_LOT);
|
||||||
qof_instance_set_book(lot, book);
|
qof_instance_set_book(lot, book);
|
||||||
qof_collection_insert_entity (col, &lot->inst);
|
qof_collection_insert_entity (col, QOF_INSTANCE(lot));
|
||||||
|
|
||||||
/* Move the splits over (only if they haven't already been moved). */
|
/* Move the splits over (only if they haven't already been moved). */
|
||||||
col = qof_book_get_collection (book, GNC_ID_SPLIT);
|
col = qof_book_get_collection (book, GNC_ID_SPLIT);
|
||||||
for (snode = lot->splits; snode; snode=snode->next)
|
for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next)
|
||||||
{
|
{
|
||||||
Split *s = snode->data;
|
Split *s = snode->data;
|
||||||
if (qof_instance_get_book(s) != book)
|
if (qof_instance_get_book(s) != book)
|
||||||
@ -242,7 +242,7 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
twin = xaccAccountLookupTwin (lot->account, book);
|
twin = xaccAccountLookupTwin (gnc_lot_get_account(lot), book);
|
||||||
if (!twin)
|
if (!twin)
|
||||||
{
|
{
|
||||||
PERR ("near-fatal: twin account not found");
|
PERR ("near-fatal: twin account not found");
|
||||||
@ -358,13 +358,13 @@ lot_has_open_trans_tree (GNCLot *lot)
|
|||||||
{
|
{
|
||||||
SplitList *split_list, *snode;
|
SplitList *split_list, *snode;
|
||||||
|
|
||||||
if (1 == lot->marker) return FALSE;
|
if (1 == gnc_lot_get_marker(lot)) return FALSE;
|
||||||
if (2 == lot->marker) return TRUE;
|
if (2 == gnc_lot_get_marker(lot)) return TRUE;
|
||||||
lot->marker = 1;
|
gnc_lot_set_marker(lot, 1);
|
||||||
|
|
||||||
if (FALSE == gnc_lot_is_closed(lot))
|
if (FALSE == gnc_lot_is_closed(lot))
|
||||||
{
|
{
|
||||||
lot->marker = 2;
|
gnc_lot_set_marker(lot, 2);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ lot_has_open_trans_tree (GNCLot *lot)
|
|||||||
Transaction *trans = s->parent;
|
Transaction *trans = s->parent;
|
||||||
if (trans_has_open_lot_tree (trans))
|
if (trans_has_open_lot_tree (trans))
|
||||||
{
|
{
|
||||||
lot->marker = 2;
|
gnc_lot_set_marker(lot, 2);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,7 +445,7 @@ clear_markers (Account *account, gpointer dummy)
|
|||||||
Transaction *trans = s->parent;
|
Transaction *trans = s->parent;
|
||||||
GNCLot *lot = s->lot;
|
GNCLot *lot = s->lot;
|
||||||
trans->marker = 0;
|
trans->marker = 0;
|
||||||
if (lot) lot->marker = 0;
|
if (lot) gnc_lot_set_marker(lot, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ xaccLotFill (GNCLot *lot)
|
|||||||
GNCPolicy *pcy;
|
GNCPolicy *pcy;
|
||||||
|
|
||||||
if (!lot) return;
|
if (!lot) return;
|
||||||
acc = lot->account;
|
acc = gnc_lot_get_account(lot);
|
||||||
pcy = gnc_account_get_policy(acc);
|
pcy = gnc_account_get_policy(acc);
|
||||||
|
|
||||||
ENTER ("(lot=%s, acc=%s)", gnc_lot_get_title(lot), xaccAccountGetName(acc));
|
ENTER ("(lot=%s, acc=%s)", gnc_lot_get_title(lot), xaccAccountGetName(acc));
|
||||||
@ -160,7 +160,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
|||||||
|
|
||||||
ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
||||||
|
|
||||||
for (snode = lot->splits; snode; snode=snode->next)
|
for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next)
|
||||||
{
|
{
|
||||||
Split *s = snode->data;
|
Split *s = snode->data;
|
||||||
xaccSplitComputeCapGains (s, NULL);
|
xaccSplitComputeCapGains (s, NULL);
|
||||||
@ -169,7 +169,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
|||||||
/* We double-check only closed lots */
|
/* We double-check only closed lots */
|
||||||
if (FALSE == gnc_lot_is_closed (lot)) return;
|
if (FALSE == gnc_lot_is_closed (lot)) return;
|
||||||
|
|
||||||
for (snode = lot->splits; snode; snode=snode->next)
|
for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next)
|
||||||
{
|
{
|
||||||
Split *s = snode->data;
|
Split *s = snode->data;
|
||||||
Transaction *trans = s->parent;
|
Transaction *trans = s->parent;
|
||||||
@ -208,7 +208,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
|||||||
*/
|
*/
|
||||||
PERR ("Closed lot fails to double-balance !! lot value=%s",
|
PERR ("Closed lot fails to double-balance !! lot value=%s",
|
||||||
gnc_num_dbg_to_string (value));
|
gnc_num_dbg_to_string (value));
|
||||||
for (node=lot->splits; node; node=node->next)
|
for (node = gnc_lot_get_split_list(lot); node; node=node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
PERR ("s=%p amt=%s val=%s", s,
|
PERR ("s=%p amt=%s val=%s", s,
|
||||||
|
@ -309,7 +309,7 @@ void mark_split (Split *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set dirty flag on lot too. */
|
/* set dirty flag on lot too. */
|
||||||
if (s->lot) s->lot->is_closed = -1;
|
if (s->lot) gnc_lot_set_closed_unknown(s->lot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -527,7 +527,7 @@ xaccSplitCommitEdit(Split *s)
|
|||||||
acc = s->acc;
|
acc = s->acc;
|
||||||
/* Remove from lot (but only if it hasn't been moved to
|
/* Remove from lot (but only if it hasn't been moved to
|
||||||
new lot already) */
|
new lot already) */
|
||||||
if (s->lot && (s->lot->account != acc || qof_instance_get_destroying(s)))
|
if (s->lot && (gnc_lot_get_account(s->lot) != acc || qof_instance_get_destroying(s)))
|
||||||
gnc_lot_remove_split (s->lot, s);
|
gnc_lot_remove_split (s->lot, s);
|
||||||
|
|
||||||
/* Possibly remove the split from the original account... */
|
/* Possibly remove the split from the original account... */
|
||||||
@ -542,7 +542,7 @@ xaccSplitCommitEdit(Split *s)
|
|||||||
if (gnc_account_insert_split(acc, s)) {
|
if (gnc_account_insert_split(acc, s)) {
|
||||||
/* If the split's lot belonged to some other account, we
|
/* If the split's lot belonged to some other account, we
|
||||||
leave it so. */
|
leave it so. */
|
||||||
if (s->lot && (NULL == s->lot->account))
|
if (s->lot && (NULL == gnc_lot_get_account(s->lot)))
|
||||||
xaccAccountInsertLot (acc, s->lot);
|
xaccAccountInsertLot (acc, s->lot);
|
||||||
} else {
|
} else {
|
||||||
PERR("Account grabbed split prematurely.");
|
PERR("Account grabbed split prematurely.");
|
||||||
@ -558,7 +558,7 @@ xaccSplitCommitEdit(Split *s)
|
|||||||
}
|
}
|
||||||
if (s->lot) {
|
if (s->lot) {
|
||||||
/* A change of value/amnt affects gains display, etc. */
|
/* A change of value/amnt affects gains display, etc. */
|
||||||
qof_event_gen (&s->lot->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (QOF_INSTANCE(s->lot), QOF_EVENT_MODIFY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Important: we save off the original parent transaction and account
|
/* Important: we save off the original parent transaction and account
|
||||||
|
@ -235,7 +235,7 @@ void gen_event_trans (Transaction *trans)
|
|||||||
if (lot)
|
if (lot)
|
||||||
{
|
{
|
||||||
/* A change of transaction date might affect opening date of lot */
|
/* A change of transaction date might affect opening date of lot */
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -690,7 +690,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
|||||||
if (!split) return;
|
if (!split) return;
|
||||||
lot = split->lot;
|
lot = split->lot;
|
||||||
if (!lot) return;
|
if (!lot) return;
|
||||||
pcy = gnc_account_get_policy(lot->account);
|
pcy = gnc_account_get_policy(gnc_lot_get_account(lot));
|
||||||
currency = split->parent->common_currency;
|
currency = split->parent->common_currency;
|
||||||
|
|
||||||
ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split,
|
ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split,
|
||||||
@ -770,7 +770,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
|||||||
/* Note: if the value of the 'opening' split(s) has changed,
|
/* Note: if the value of the 'opening' split(s) has changed,
|
||||||
* then the cap gains are changed. So we need to check not
|
* then the cap gains are changed. So we need to check not
|
||||||
* only if this split is dirty, but also the lot-opening splits. */
|
* only if this split is dirty, but also the lot-opening splits. */
|
||||||
for (node=lot->splits; node; node=node->next)
|
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
|
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
|
||||||
@ -830,7 +830,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
|||||||
gnc_numeric_abs(split->amount)))
|
gnc_numeric_abs(split->amount)))
|
||||||
{
|
{
|
||||||
GList *n;
|
GList *n;
|
||||||
for (n = lot->splits; n; n = n->next)
|
for (n = gnc_lot_get_split_list(lot); n; n = n->next)
|
||||||
{
|
{
|
||||||
Split *s = n->data;
|
Split *s = n->data;
|
||||||
PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount));
|
PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount));
|
||||||
@ -849,7 +849,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
|||||||
gnc_numeric_negative_p(split->amount)))
|
gnc_numeric_negative_p(split->amount)))
|
||||||
{
|
{
|
||||||
GList *n;
|
GList *n;
|
||||||
for (n = lot->splits; n; n = n->next)
|
for (n = gnc_lot_get_split_list(lot); n; n = n->next)
|
||||||
{
|
{
|
||||||
Split *s = n->data;
|
Split *s = n->data;
|
||||||
PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount));
|
PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount));
|
||||||
@ -925,7 +925,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
|||||||
|
|
||||||
if (NULL == lot_split)
|
if (NULL == lot_split)
|
||||||
{
|
{
|
||||||
Account *lot_acc = lot->account;
|
Account *lot_acc = gnc_lot_get_account(lot);
|
||||||
QofBook *book = qof_instance_get_book(lot_acc);
|
QofBook *book = qof_instance_get_book(lot_acc);
|
||||||
|
|
||||||
new_gain_split = TRUE;
|
new_gain_split = TRUE;
|
||||||
@ -1081,8 +1081,8 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc)
|
|||||||
* to mark all splits dirty if the opening splits are dirty. */
|
* to mark all splits dirty if the opening splits are dirty. */
|
||||||
|
|
||||||
ENTER("(lot=%p)", lot);
|
ENTER("(lot=%p)", lot);
|
||||||
pcy = gnc_account_get_policy(lot->account);
|
pcy = gnc_account_get_policy(gnc_lot_get_account(lot));
|
||||||
for (node = lot->splits; node; node = node->next)
|
for (node = gnc_lot_get_split_list(lot); node; node = node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
|
if (pcy->PolicyIsOpeningSplit(pcy,lot,s))
|
||||||
@ -1099,14 +1099,14 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc)
|
|||||||
|
|
||||||
if (is_dirty)
|
if (is_dirty)
|
||||||
{
|
{
|
||||||
for (node = lot->splits; node; node = node->next)
|
for (node = gnc_lot_get_split_list(lot); node; node = node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
s->gains |= GAINS_STATUS_VDIRTY;
|
s->gains |= GAINS_STATUS_VDIRTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node = lot->splits; node; node = node->next)
|
for (node = gnc_lot_get_split_list(lot); node; node = node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
xaccSplitComputeCapGains (s, gain_acc);
|
xaccSplitComputeCapGains (s, gain_acc);
|
||||||
|
@ -185,7 +185,7 @@ typedef struct gnc_commodity_table_s gnc_commodity_table;
|
|||||||
*
|
*
|
||||||
* See the file src/doc/lots.txt for implmentation overview.
|
* See the file src/doc/lots.txt for implmentation overview.
|
||||||
*/
|
*/
|
||||||
typedef struct gnc_lot_struct GNCLot;
|
typedef struct gnc_lot_s GNCLot;
|
||||||
|
|
||||||
/** @brief Price of commodity on a given date.
|
/** @brief Price of commodity on a given date.
|
||||||
* A GNCPrice encapsulates price information: the cost of a commodity
|
* A GNCPrice encapsulates price information: the cost of a commodity
|
||||||
|
@ -37,34 +37,6 @@
|
|||||||
#ifndef GNC_LOT_P_H
|
#ifndef GNC_LOT_P_H
|
||||||
#define GNC_LOT_P_H
|
#define GNC_LOT_P_H
|
||||||
|
|
||||||
#include "gnc-lot.h"
|
|
||||||
#include "Account.h"
|
|
||||||
|
|
||||||
struct gnc_lot_struct
|
|
||||||
{
|
|
||||||
QofInstance inst;
|
|
||||||
|
|
||||||
/* Account to which this lot applies. All splits in the lot must
|
|
||||||
* belong to this account.
|
|
||||||
*/
|
|
||||||
Account * account;
|
|
||||||
|
|
||||||
/* List of splits that belong to this lot. */
|
|
||||||
SplitList *splits;
|
|
||||||
|
|
||||||
/* Handy cached value to indicate if lot is closed. */
|
|
||||||
/* If value is negative, then the cache is invalid. */
|
|
||||||
signed char is_closed;
|
|
||||||
|
|
||||||
/* traversal marker, handy for preventing recursion */
|
|
||||||
unsigned char marker;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GncLotClass
|
|
||||||
{
|
|
||||||
QofInstanceClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G))
|
#define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G))
|
||||||
|
|
||||||
/* Register with the Query engine */
|
/* Register with the Query engine */
|
||||||
|
@ -39,10 +39,11 @@
|
|||||||
* Copyright (c) 2002,2003 Linas Vepstas <linas@linas.org>
|
* Copyright (c) 2002,2003 Linas Vepstas <linas@linas.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "AccountP.h"
|
#include "AccountP.h"
|
||||||
#include "gnc-lot.h"
|
#include "gnc-lot.h"
|
||||||
@ -54,37 +55,143 @@
|
|||||||
/* This static indicates the debugging module that this .o belongs to. */
|
/* This static indicates the debugging module that this .o belongs to. */
|
||||||
static QofLogModule log_module = GNC_MOD_LOT;
|
static QofLogModule log_module = GNC_MOD_LOT;
|
||||||
|
|
||||||
|
struct gnc_lot_s
|
||||||
|
{
|
||||||
|
QofInstance inst;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_IS_CLOSED,
|
||||||
|
PROP_MARKER
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct LotPrivate
|
||||||
|
{
|
||||||
|
/* Account to which this lot applies. All splits in the lot must
|
||||||
|
* belong to this account.
|
||||||
|
*/
|
||||||
|
Account * account;
|
||||||
|
|
||||||
|
/* List of splits that belong to this lot. */
|
||||||
|
SplitList *splits;
|
||||||
|
|
||||||
|
/* Handy cached value to indicate if lot is closed. */
|
||||||
|
/* If value is negative, then the cache is invalid. */
|
||||||
|
signed char is_closed;
|
||||||
|
#define LOT_CLOSED_UNKNOWN (-1)
|
||||||
|
|
||||||
|
/* traversal marker, handy for preventing recursion */
|
||||||
|
unsigned char marker;
|
||||||
|
} LotPrivate;
|
||||||
|
|
||||||
|
#define GET_PRIVATE(o) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_LOT, LotPrivate))
|
||||||
|
|
||||||
|
#define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G))
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
/* GObject Initialization */
|
/* GObject Initialization */
|
||||||
QOF_GOBJECT_IMPL(gnc_lot, GNCLot, QOF_TYPE_INSTANCE);
|
G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_lot_init(GNCLot* lot)
|
gnc_lot_init(GNCLot* lot)
|
||||||
{
|
{
|
||||||
|
LotPrivate* priv;
|
||||||
|
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
priv->account = NULL;
|
||||||
|
priv->splits = NULL;
|
||||||
|
priv->is_closed = LOT_CLOSED_UNKNOWN;
|
||||||
|
priv->marker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_lot_dispose_real (GObject *lotp)
|
gnc_lot_dispose(GObject *lotp)
|
||||||
{
|
{
|
||||||
|
G_OBJECT_CLASS(gnc_lot_parent_class)->dispose(lotp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_lot_finalize_real(GObject* lotp)
|
gnc_lot_finalize(GObject* lotp)
|
||||||
{
|
{
|
||||||
|
G_OBJECT_CLASS(gnc_lot_parent_class)->finalize(lotp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_lot_init_data (GNCLot *lot, QofBook *book)
|
gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
|
||||||
{
|
{
|
||||||
ENTER ("(lot=%p, book=%p)", lot, book);
|
GNCLot* lot;
|
||||||
lot->account = NULL;
|
LotPrivate* priv;
|
||||||
lot->splits = NULL;
|
|
||||||
lot->is_closed = -1;
|
g_return_if_fail(GNC_IS_LOT(object));
|
||||||
lot->marker = 0;
|
|
||||||
|
lot = GNC_LOT(object);
|
||||||
qof_instance_init_data(&lot->inst, GNC_ID_LOT, book);
|
priv = GET_PRIVATE(lot);
|
||||||
LEAVE ("(lot=%p, book=%p)", lot, book);
|
switch(prop_id) {
|
||||||
|
case PROP_IS_CLOSED:
|
||||||
|
g_value_set_int(value, priv->is_closed);
|
||||||
|
break;
|
||||||
|
case PROP_MARKER:
|
||||||
|
g_value_set_int(value, priv->marker);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
|
||||||
|
{
|
||||||
|
GNCLot* lot;
|
||||||
|
LotPrivate* priv;
|
||||||
|
|
||||||
|
g_return_if_fail(GNC_IS_LOT(object));
|
||||||
|
|
||||||
|
lot = GNC_LOT(object);
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
switch(prop_id) {
|
||||||
|
case PROP_IS_CLOSED:
|
||||||
|
priv->is_closed = g_value_get_int(value);
|
||||||
|
break;
|
||||||
|
case PROP_MARKER:
|
||||||
|
priv->marker = g_value_get_int(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_lot_class_init(GNCLotClass* klass)
|
||||||
|
{
|
||||||
|
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
gobject_class->dispose = gnc_lot_dispose;
|
||||||
|
gobject_class->finalize = gnc_lot_finalize;
|
||||||
|
gobject_class->get_property = gnc_lot_get_property;
|
||||||
|
gobject_class->set_property = gnc_lot_set_property;
|
||||||
|
|
||||||
|
g_type_class_add_private(klass, sizeof(LotPrivate));
|
||||||
|
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class,
|
||||||
|
PROP_IS_CLOSED,
|
||||||
|
g_param_spec_int("is-closed",
|
||||||
|
"Is Lot Closed",
|
||||||
|
"Indication of whether this lot is open "
|
||||||
|
"or closed to further changes.",
|
||||||
|
-1, 1, 0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class,
|
||||||
|
PROP_MARKER,
|
||||||
|
g_param_spec_int("marker",
|
||||||
|
"Lot marker",
|
||||||
|
"Ipsum Lorem",
|
||||||
|
0, G_MAXINT8, 0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GNCLot *
|
GNCLot *
|
||||||
@ -94,32 +201,33 @@ gnc_lot_new (QofBook *book)
|
|||||||
g_return_val_if_fail (book, NULL);
|
g_return_val_if_fail (book, NULL);
|
||||||
|
|
||||||
lot = g_object_new (GNC_TYPE_LOT, NULL);
|
lot = g_object_new (GNC_TYPE_LOT, NULL);
|
||||||
gnc_lot_init_data (lot, book);
|
qof_instance_init_data(QOF_INSTANCE(lot), GNC_ID_LOT, book);
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_CREATE, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_CREATE, NULL);
|
||||||
return lot;
|
return lot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_lot_free(GNCLot* lot)
|
gnc_lot_free(GNCLot* lot)
|
||||||
{
|
{
|
||||||
GList *node;
|
GList *node;
|
||||||
if (!lot) return;
|
LotPrivate* priv;
|
||||||
|
if (!lot) return;
|
||||||
|
|
||||||
ENTER ("(lot=%p)", lot);
|
ENTER ("(lot=%p)", lot);
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_DESTROY, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_DESTROY, NULL);
|
||||||
|
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
for (node=priv->splits; node; node=node->next)
|
||||||
|
{
|
||||||
|
Split *s = node->data;
|
||||||
|
s->lot = NULL;
|
||||||
|
}
|
||||||
|
g_list_free (priv->splits);
|
||||||
|
|
||||||
for (node=lot->splits; node; node=node->next)
|
priv->account = NULL;
|
||||||
{
|
priv->is_closed = TRUE;
|
||||||
Split *s = node->data;
|
/* qof_instance_release (&lot->inst); */
|
||||||
s->lot = NULL;
|
g_object_unref (lot);
|
||||||
}
|
|
||||||
g_list_free (lot->splits);
|
|
||||||
|
|
||||||
lot->account = NULL;
|
|
||||||
lot->is_closed = TRUE;
|
|
||||||
/* qof_instance_release (&lot->inst); */
|
|
||||||
g_object_unref (lot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -137,7 +245,7 @@ gnc_lot_destroy (GNCLot *lot)
|
|||||||
void
|
void
|
||||||
gnc_lot_begin_edit (GNCLot *lot)
|
gnc_lot_begin_edit (GNCLot *lot)
|
||||||
{
|
{
|
||||||
qof_begin_edit(&lot->inst);
|
qof_begin_edit(QOF_INSTANCE(lot));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void commit_err (QofInstance *inst, QofBackendError errcode)
|
static void commit_err (QofInstance *inst, QofBackendError errcode)
|
||||||
@ -159,7 +267,7 @@ void
|
|||||||
gnc_lot_commit_edit (GNCLot *lot)
|
gnc_lot_commit_edit (GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!qof_commit_edit (QOF_INSTANCE(lot))) return;
|
if (!qof_commit_edit (QOF_INSTANCE(lot))) return;
|
||||||
qof_commit_edit_part2 (&lot->inst, commit_err, noop, lot_free);
|
qof_commit_edit_part2 (QOF_INSTANCE(lot), commit_err, noop, lot_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
@ -184,16 +292,62 @@ gnc_lot_get_book (GNCLot *lot)
|
|||||||
gboolean
|
gboolean
|
||||||
gnc_lot_is_closed (GNCLot *lot)
|
gnc_lot_is_closed (GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return TRUE;
|
LotPrivate* priv;
|
||||||
if (0 > lot->is_closed) gnc_lot_get_balance (lot);
|
if (!lot) return TRUE;
|
||||||
return lot->is_closed;
|
priv = GET_PRIVATE(lot);
|
||||||
|
if (0 > priv->is_closed) gnc_lot_get_balance (lot);
|
||||||
|
return priv->is_closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Account *
|
Account *
|
||||||
gnc_lot_get_account (const GNCLot *lot)
|
gnc_lot_get_account (const GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return NULL;
|
LotPrivate* priv;
|
||||||
return lot->account;
|
if (!lot) return NULL;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
return priv->account;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_lot_set_account(GNCLot* lot, Account* account)
|
||||||
|
{
|
||||||
|
if (lot != NULL)
|
||||||
|
{
|
||||||
|
LotPrivate* priv;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
priv->account = account;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char
|
||||||
|
gnc_lot_get_marker(const GNCLot* lot)
|
||||||
|
{
|
||||||
|
LotPrivate* priv;
|
||||||
|
if (lot == NULL) return 0;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
return priv->marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_lot_set_marker(GNCLot* lot, unsigned char m)
|
||||||
|
{
|
||||||
|
LotPrivate* priv;
|
||||||
|
if (lot != NULL)
|
||||||
|
{
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
priv->marker = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_lot_set_closed_unknown(GNCLot* lot)
|
||||||
|
{
|
||||||
|
LotPrivate* priv;
|
||||||
|
if (lot != NULL)
|
||||||
|
{
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
priv->is_closed = LOT_CLOSED_UNKNOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KvpFrame *
|
KvpFrame *
|
||||||
@ -205,14 +359,18 @@ gnc_lot_get_slots (const GNCLot *lot)
|
|||||||
SplitList *
|
SplitList *
|
||||||
gnc_lot_get_split_list (const GNCLot *lot)
|
gnc_lot_get_split_list (const GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return NULL;
|
LotPrivate* priv;
|
||||||
return lot->splits;
|
if (!lot) return NULL;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
return priv->splits;
|
||||||
}
|
}
|
||||||
|
|
||||||
gint gnc_lot_count_splits (const GNCLot *lot)
|
gint gnc_lot_count_splits (const GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return 0;
|
LotPrivate* priv;
|
||||||
return g_list_length (lot->splits);
|
if (!lot) return 0;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
return g_list_length (priv->splits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================== */
|
/* ============================================================== */
|
||||||
@ -221,15 +379,15 @@ gint gnc_lot_count_splits (const GNCLot *lot)
|
|||||||
const char *
|
const char *
|
||||||
gnc_lot_get_title (const GNCLot *lot)
|
gnc_lot_get_title (const GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return NULL;
|
if (!lot) return NULL;
|
||||||
return kvp_frame_get_string (lot->inst.kvp_data, "/title");
|
return kvp_frame_get_string (gnc_lot_get_slots(lot), "/title");
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
gnc_lot_get_notes (const GNCLot *lot)
|
gnc_lot_get_notes (const GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (!lot) return NULL;
|
if (!lot) return NULL;
|
||||||
return kvp_frame_get_string (lot->inst.kvp_data, "/notes");
|
return kvp_frame_get_string (gnc_lot_get_slots(lot), "/notes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -238,7 +396,7 @@ gnc_lot_set_title (GNCLot *lot, const char *str)
|
|||||||
if (!lot) return;
|
if (!lot) return;
|
||||||
qof_begin_edit(QOF_INSTANCE(lot));
|
qof_begin_edit(QOF_INSTANCE(lot));
|
||||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||||
kvp_frame_set_str (lot->inst.kvp_data, "/title", str);
|
kvp_frame_set_str (gnc_lot_get_slots(lot), "/title", str);
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +406,7 @@ gnc_lot_set_notes (GNCLot *lot, const char *str)
|
|||||||
if (!lot) return;
|
if (!lot) return;
|
||||||
gnc_lot_begin_edit(lot);
|
gnc_lot_begin_edit(lot);
|
||||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||||
kvp_frame_set_str (lot->inst.kvp_data, "/notes", str);
|
kvp_frame_set_str (gnc_lot_get_slots(lot), "/notes", str);
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,38 +415,40 @@ gnc_lot_set_notes (GNCLot *lot, const char *str)
|
|||||||
gnc_numeric
|
gnc_numeric
|
||||||
gnc_lot_get_balance (GNCLot *lot)
|
gnc_lot_get_balance (GNCLot *lot)
|
||||||
{
|
{
|
||||||
GList *node;
|
LotPrivate* priv;
|
||||||
gnc_numeric zero = gnc_numeric_zero();
|
GList *node;
|
||||||
gnc_numeric baln = zero;
|
gnc_numeric zero = gnc_numeric_zero();
|
||||||
if (!lot) return zero;
|
gnc_numeric baln = zero;
|
||||||
|
if (!lot) return zero;
|
||||||
|
|
||||||
if (!lot->splits)
|
priv = GET_PRIVATE(lot);
|
||||||
{
|
if (!priv->splits)
|
||||||
lot->is_closed = FALSE;
|
{
|
||||||
return zero;
|
priv->is_closed = FALSE;
|
||||||
}
|
return zero;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sum over splits; because they all belong to same account
|
/* Sum over splits; because they all belong to same account
|
||||||
* they will have same denominator.
|
* they will have same denominator.
|
||||||
*/
|
*/
|
||||||
for (node=lot->splits; node; node=node->next)
|
for (node=priv->splits; node; node=node->next)
|
||||||
{
|
{
|
||||||
Split *s = node->data;
|
Split *s = node->data;
|
||||||
gnc_numeric amt = xaccSplitGetAmount (s);
|
gnc_numeric amt = xaccSplitGetAmount (s);
|
||||||
baln = gnc_numeric_add_fixed (baln, amt);
|
baln = gnc_numeric_add_fixed (baln, amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cache a zero balance as a closed lot */
|
/* cache a zero balance as a closed lot */
|
||||||
if (gnc_numeric_equal (baln, zero))
|
if (gnc_numeric_equal (baln, zero))
|
||||||
{
|
{
|
||||||
lot->is_closed = TRUE;
|
priv->is_closed = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lot->is_closed = FALSE;
|
priv->is_closed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return baln;
|
return baln;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
@ -297,42 +457,48 @@ void
|
|||||||
gnc_lot_get_balance_before (const GNCLot *lot, const Split *split,
|
gnc_lot_get_balance_before (const GNCLot *lot, const Split *split,
|
||||||
gnc_numeric *amount, gnc_numeric *value)
|
gnc_numeric *amount, gnc_numeric *value)
|
||||||
{
|
{
|
||||||
GList *node;
|
LotPrivate* priv;
|
||||||
gnc_numeric zero = gnc_numeric_zero();
|
GList *node;
|
||||||
gnc_numeric amt = zero;
|
gnc_numeric zero = gnc_numeric_zero();
|
||||||
gnc_numeric val = zero;
|
gnc_numeric amt = zero;
|
||||||
|
gnc_numeric val = zero;
|
||||||
|
|
||||||
if (lot && lot->splits)
|
*amount = amt;
|
||||||
{
|
*value = val;
|
||||||
Transaction *ta, *tb;
|
if (lot == NULL) return;
|
||||||
const Split *target;
|
|
||||||
/* If this is a gains split, find the source of the gains and use
|
|
||||||
its transaction for the comparison. Gains splits are in separate
|
|
||||||
transactions that may sort after non-gains transactions. */
|
|
||||||
target = xaccSplitGetGainsSourceSplit (split);
|
|
||||||
if (target == NULL)
|
|
||||||
target = split;
|
|
||||||
tb = xaccSplitGetParent (target);
|
|
||||||
for (node = lot->splits; node; node = node->next)
|
|
||||||
{
|
|
||||||
Split *s = node->data;
|
|
||||||
Split *source = xaccSplitGetGainsSourceSplit (s);
|
|
||||||
if (source == NULL)
|
|
||||||
source = s;
|
|
||||||
ta = xaccSplitGetParent (source);
|
|
||||||
if ((ta == tb && source != target) ||
|
|
||||||
xaccTransOrder (ta, tb) < 0)
|
|
||||||
{
|
|
||||||
gnc_numeric tmpval = xaccSplitGetAmount (s);
|
|
||||||
amt = gnc_numeric_add_fixed (amt, tmpval);
|
|
||||||
tmpval = xaccSplitGetValue (s);
|
|
||||||
val = gnc_numeric_add_fixed (val, tmpval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*amount = amt;
|
priv = GET_PRIVATE(lot);
|
||||||
*value = val;
|
if (priv->splits)
|
||||||
|
{
|
||||||
|
Transaction *ta, *tb;
|
||||||
|
const Split *target;
|
||||||
|
/* If this is a gains split, find the source of the gains and use
|
||||||
|
its transaction for the comparison. Gains splits are in separate
|
||||||
|
transactions that may sort after non-gains transactions. */
|
||||||
|
target = xaccSplitGetGainsSourceSplit (split);
|
||||||
|
if (target == NULL)
|
||||||
|
target = split;
|
||||||
|
tb = xaccSplitGetParent (target);
|
||||||
|
for (node = priv->splits; node; node = node->next)
|
||||||
|
{
|
||||||
|
Split *s = node->data;
|
||||||
|
Split *source = xaccSplitGetGainsSourceSplit (s);
|
||||||
|
if (source == NULL)
|
||||||
|
source = s;
|
||||||
|
ta = xaccSplitGetParent (source);
|
||||||
|
if ((ta == tb && source != target) ||
|
||||||
|
xaccTransOrder (ta, tb) < 0)
|
||||||
|
{
|
||||||
|
gnc_numeric tmpval = xaccSplitGetAmount (s);
|
||||||
|
amt = gnc_numeric_add_fixed (amt, tmpval);
|
||||||
|
tmpval = xaccSplitGetValue (s);
|
||||||
|
val = gnc_numeric_add_fixed (val, tmpval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*amount = amt;
|
||||||
|
*value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
@ -340,71 +506,75 @@ gnc_lot_get_balance_before (const GNCLot *lot, const Split *split,
|
|||||||
void
|
void
|
||||||
gnc_lot_add_split (GNCLot *lot, Split *split)
|
gnc_lot_add_split (GNCLot *lot, Split *split)
|
||||||
{
|
{
|
||||||
Account * acc;
|
LotPrivate* priv;
|
||||||
if (!lot || !split) return;
|
Account * acc;
|
||||||
|
if (!lot || !split) return;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
|
||||||
ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split,
|
ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split,
|
||||||
gnc_lot_get_title (lot),
|
gnc_lot_get_title (lot),
|
||||||
gnc_num_dbg_to_string (split->amount),
|
gnc_num_dbg_to_string (split->amount),
|
||||||
gnc_num_dbg_to_string (split->value));
|
gnc_num_dbg_to_string (split->value));
|
||||||
gnc_lot_begin_edit(lot);
|
gnc_lot_begin_edit(lot);
|
||||||
acc = xaccSplitGetAccount (split);
|
acc = xaccSplitGetAccount (split);
|
||||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||||
if (NULL == lot->account)
|
if (NULL == priv->account)
|
||||||
{
|
{
|
||||||
xaccAccountInsertLot (acc, lot);
|
xaccAccountInsertLot (acc, lot);
|
||||||
}
|
}
|
||||||
else if (lot->account != acc)
|
else if (priv->account != acc)
|
||||||
{
|
{
|
||||||
PERR ("splits from different accounts cannot "
|
PERR ("splits from different accounts cannot "
|
||||||
"be added to this lot!\n"
|
"be added to this lot!\n"
|
||||||
"\tlot account=\'%s\', split account=\'%s\'\n",
|
"\tlot account=\'%s\', split account=\'%s\'\n",
|
||||||
xaccAccountGetName(lot->account), xaccAccountGetName (acc));
|
xaccAccountGetName(priv->account), xaccAccountGetName (acc));
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
LEAVE("different accounts");
|
LEAVE("different accounts");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lot == split->lot) {
|
if (lot == split->lot) {
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
LEAVE("already in lot");
|
LEAVE("already in lot");
|
||||||
return; /* handle not-uncommon no-op */
|
return; /* handle not-uncommon no-op */
|
||||||
}
|
}
|
||||||
if (split->lot)
|
if (split->lot)
|
||||||
{
|
{
|
||||||
gnc_lot_remove_split (split->lot, split);
|
gnc_lot_remove_split (split->lot, split);
|
||||||
}
|
}
|
||||||
xaccSplitSetLot(split, lot);
|
xaccSplitSetLot(split, lot);
|
||||||
|
|
||||||
lot->splits = g_list_append (lot->splits, split);
|
priv->splits = g_list_append (priv->splits, split);
|
||||||
|
|
||||||
/* for recomputation of is-closed */
|
/* for recomputation of is-closed */
|
||||||
lot->is_closed = -1;
|
priv->is_closed = LOT_CLOSED_UNKNOWN;
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
|
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL);
|
||||||
LEAVE("added to lot");
|
LEAVE("added to lot");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gnc_lot_remove_split (GNCLot *lot, Split *split)
|
gnc_lot_remove_split (GNCLot *lot, Split *split)
|
||||||
{
|
{
|
||||||
if (!lot || !split) return;
|
LotPrivate* priv;
|
||||||
|
if (!lot || !split) return;
|
||||||
|
priv = GET_PRIVATE(lot);
|
||||||
|
|
||||||
ENTER ("(lot=%p, split=%p)", lot, split);
|
ENTER ("(lot=%p, split=%p)", lot, split);
|
||||||
gnc_lot_begin_edit(lot);
|
gnc_lot_begin_edit(lot);
|
||||||
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
qof_instance_set_dirty(QOF_INSTANCE(lot));
|
||||||
lot->splits = g_list_remove (lot->splits, split);
|
priv->splits = g_list_remove (priv->splits, split);
|
||||||
xaccSplitSetLot(split, NULL);
|
xaccSplitSetLot(split, NULL);
|
||||||
lot->is_closed = -1; /* force an is-closed computation */
|
priv->is_closed = LOT_CLOSED_UNKNOWN; /* force an is-closed computation */
|
||||||
|
|
||||||
if (NULL == lot->splits)
|
if (NULL == priv->splits)
|
||||||
{
|
{
|
||||||
xaccAccountRemoveLot (lot->account, lot);
|
xaccAccountRemoveLot (priv->account, lot);
|
||||||
lot->account = NULL;
|
priv->account = NULL;
|
||||||
}
|
}
|
||||||
gnc_lot_commit_edit(lot);
|
gnc_lot_commit_edit(lot);
|
||||||
qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL);
|
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================== */
|
/* ============================================================== */
|
||||||
@ -413,25 +583,29 @@ gnc_lot_remove_split (GNCLot *lot, Split *split)
|
|||||||
Split *
|
Split *
|
||||||
gnc_lot_get_earliest_split (GNCLot *lot)
|
gnc_lot_get_earliest_split (GNCLot *lot)
|
||||||
{
|
{
|
||||||
if (! lot->splits)
|
LotPrivate* priv;
|
||||||
return NULL;
|
if (!lot) return NULL;
|
||||||
lot->splits = g_list_sort (lot->splits, (GCompareFunc) xaccSplitOrderDateOnly);
|
priv = GET_PRIVATE(lot);
|
||||||
return lot->splits->data;
|
if (! priv->splits) return NULL;
|
||||||
|
priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
|
||||||
|
return priv->splits->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Split *
|
Split *
|
||||||
gnc_lot_get_latest_split (GNCLot *lot)
|
gnc_lot_get_latest_split (GNCLot *lot)
|
||||||
{
|
{
|
||||||
SplitList *node;
|
LotPrivate* priv;
|
||||||
|
SplitList *node;
|
||||||
|
|
||||||
if (! lot->splits)
|
if (!lot) return NULL;
|
||||||
return NULL;
|
priv = GET_PRIVATE(lot);
|
||||||
lot->splits = g_list_sort (lot->splits, (GCompareFunc) xaccSplitOrderDateOnly);
|
if (! priv->splits) return NULL;
|
||||||
|
priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly);
|
||||||
|
|
||||||
for (node = lot->splits; node->next; node = node->next)
|
for (node = priv->splits; node->next; node = node->next)
|
||||||
;
|
;
|
||||||
|
|
||||||
return node->data;
|
return node->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
@ -59,10 +59,16 @@
|
|||||||
#ifndef GNC_LOT_H
|
#ifndef GNC_LOT_H
|
||||||
#define GNC_LOT_H
|
#define GNC_LOT_H
|
||||||
|
|
||||||
typedef struct _GncLotClass GNCLotClass;
|
//typedef struct _GncLotClass GNCLotClass;
|
||||||
|
|
||||||
#include "qof.h"
|
#include "qof.h"
|
||||||
#include "gnc-lot-p.h"
|
#include "gnc-engine.h"
|
||||||
|
/*#include "gnc-lot-p.h"*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
QofInstanceClass parent_class;
|
||||||
|
} GncLotClass;
|
||||||
|
#define GNCLotClass GncLotClass
|
||||||
|
|
||||||
/* --- type macros --- */
|
/* --- type macros --- */
|
||||||
#define GNC_TYPE_LOT (gnc_lot_get_type ())
|
#define GNC_TYPE_LOT (gnc_lot_get_type ())
|
||||||
@ -114,6 +120,7 @@ gint gnc_lot_count_splits (const GNCLot *);
|
|||||||
* this lot is associated. */
|
* this lot is associated. */
|
||||||
/*@ dependent @*/
|
/*@ dependent @*/
|
||||||
Account * gnc_lot_get_account (const GNCLot *);
|
Account * gnc_lot_get_account (const GNCLot *);
|
||||||
|
void gnc_lot_set_account(GNCLot*, Account*);
|
||||||
|
|
||||||
/** The gnc_lot_get_balance() routine returns the balance of the lot.
|
/** The gnc_lot_get_balance() routine returns the balance of the lot.
|
||||||
* The commodity in which this balance is expressed is the commodity
|
* The commodity in which this balance is expressed is the commodity
|
||||||
@ -148,6 +155,11 @@ Split * gnc_lot_get_earliest_split (GNCLot *lot);
|
|||||||
*/
|
*/
|
||||||
Split * gnc_lot_get_latest_split (GNCLot *lot);
|
Split * gnc_lot_get_latest_split (GNCLot *lot);
|
||||||
|
|
||||||
|
unsigned char gnc_lot_get_marker(const GNCLot*);
|
||||||
|
void gnc_lot_set_marker(GNCLot*, unsigned char);
|
||||||
|
|
||||||
|
void gnc_lot_set_closed_unknown(GNCLot*);
|
||||||
|
|
||||||
/** Get and set the account title, or the account notes. */
|
/** Get and set the account title, or the account notes. */
|
||||||
const char * gnc_lot_get_title (const GNCLot *);
|
const char * gnc_lot_get_title (const GNCLot *);
|
||||||
const char * gnc_lot_get_notes (const GNCLot *);
|
const char * gnc_lot_get_notes (const GNCLot *);
|
||||||
|
@ -56,8 +56,11 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse)
|
|||||||
Split *osplit;
|
Split *osplit;
|
||||||
Transaction *otrans;
|
Transaction *otrans;
|
||||||
Timespec open_ts;
|
Timespec open_ts;
|
||||||
|
Account* lot_account;
|
||||||
|
|
||||||
if (!pcy || !lot || !lot->account || !lot->splits) return NULL;
|
if (!pcy || !lot || !gnc_lot_get_split_list(lot)) return NULL;
|
||||||
|
lot_account = gnc_lot_get_account(lot);
|
||||||
|
if (!lot_account) return NULL;
|
||||||
|
|
||||||
/* Recomputing the balance re-evaluates the lot closure */
|
/* Recomputing the balance re-evaluates the lot closure */
|
||||||
baln = gnc_lot_get_balance (lot);
|
baln = gnc_lot_get_balance (lot);
|
||||||
@ -66,7 +69,7 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse)
|
|||||||
want_positive = gnc_numeric_negative_p (baln);
|
want_positive = gnc_numeric_negative_p (baln);
|
||||||
|
|
||||||
/* All splits in lot must share a common transaction currency. */
|
/* All splits in lot must share a common transaction currency. */
|
||||||
split = lot->splits->data;
|
split = gnc_lot_get_split_list(lot)->data;
|
||||||
common_currency = split->parent->common_currency;
|
common_currency = split->parent->common_currency;
|
||||||
|
|
||||||
/* Don't add a split to the lot unless it will be the new last
|
/* Don't add a split to the lot unless it will be the new last
|
||||||
@ -80,7 +83,7 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse)
|
|||||||
* hasn't been assigned to a lot. Return that split.
|
* hasn't been assigned to a lot. Return that split.
|
||||||
* Make use of the fact that the splits in an account are
|
* Make use of the fact that the splits in an account are
|
||||||
* already in date order; so we don't have to sort. */
|
* already in date order; so we don't have to sort. */
|
||||||
node = xaccAccountGetSplitList (lot->account);
|
node = xaccAccountGetSplitList (lot_account);
|
||||||
if (reverse)
|
if (reverse)
|
||||||
{
|
{
|
||||||
node = g_list_last (node);
|
node = g_list_last (node);
|
||||||
|
Loading…
Reference in New Issue
Block a user