mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add API for getting and setting the 'balance split'.
Redo Scrub using gnc_numerics. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3130 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
0e65931103
commit
c027366e7a
@ -32,8 +32,8 @@
|
|||||||
* Copyright (c) 1998, 1999, 2000 Linas Vepstas
|
* Copyright (c) 1998, 1999, 2000 Linas Vepstas
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include "GroupP.h"
|
#include "GroupP.h"
|
||||||
#include "Scrub.h"
|
#include "Scrub.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
|
#include "TransactionP.h"
|
||||||
#include "gnc-engine-util.h"
|
#include "gnc-engine-util.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
@ -73,9 +74,9 @@ xaccAccountScrubOrphans (Account *acc) {
|
|||||||
GList *slp;
|
GList *slp;
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
Account * parent;
|
Account * parent;
|
||||||
|
|
||||||
PINFO ("Looking for orphans in account %s \n", xaccAccountGetName(acc));
|
PINFO ("Looking for orphans in account %s \n", xaccAccountGetName(acc));
|
||||||
|
|
||||||
for(slp = xaccAccountGetSplitList(acc); slp; slp = slp->next) {
|
for(slp = xaccAccountGetSplitList(acc); slp; slp = slp->next) {
|
||||||
Split *split = (Split *) slp->data;
|
Split *split = (Split *) slp->data;
|
||||||
Split * tsplit;
|
Split * tsplit;
|
||||||
@ -130,30 +131,57 @@ xaccAccountScrubImbalance (Account *acc) {
|
|||||||
for(slp = xaccAccountGetSplitList(acc); slp; slp = slp->next) {
|
for(slp = xaccAccountGetSplitList(acc); slp; slp = slp->next) {
|
||||||
Split *split = (Split *) slp->data;
|
Split *split = (Split *) slp->data;
|
||||||
Transaction *trans = xaccSplitGetParent(split);
|
Transaction *trans = xaccSplitGetParent(split);
|
||||||
double imbalance;
|
|
||||||
|
|
||||||
imbalance = DxaccTransGetImbalance (trans);
|
xaccTransScrubImbalance (trans);
|
||||||
if (!(DEQ (imbalance, 0.0))) {
|
|
||||||
Split *splat;
|
|
||||||
Account *orph;
|
|
||||||
DEBUG ("Found imbalance of %g\n", imbalance);
|
|
||||||
/* OK, we found an imbalanced trans. Put it in the imbal account. */
|
|
||||||
orph = GetOrMakeAccount (acc, trans, _("Imbalance"));
|
|
||||||
|
|
||||||
/* put split into account before setting split value */
|
|
||||||
splat = xaccMallocSplit();
|
|
||||||
xaccAccountBeginEdit (orph);
|
|
||||||
xaccAccountInsertSplit (orph, splat);
|
|
||||||
xaccAccountCommitEdit (orph);
|
|
||||||
|
|
||||||
xaccTransBeginEdit (trans, 1);
|
|
||||||
DxaccSplitSetValue (splat, -imbalance);
|
|
||||||
xaccTransAppendSplit (trans, splat);
|
|
||||||
xaccTransCommitEdit (trans);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xaccTransScrubImbalance (Transaction *trans)
|
||||||
|
{
|
||||||
|
GList *node;
|
||||||
|
Split *split;
|
||||||
|
Account *peer;
|
||||||
|
Account *account;
|
||||||
|
gnc_numeric imbalance;
|
||||||
|
|
||||||
|
imbalance = xaccTransGetImbalance (trans);
|
||||||
|
if (gnc_numeric_zero_p (imbalance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DEBUG ("Found imbalance");
|
||||||
|
|
||||||
|
peer = NULL;
|
||||||
|
for (node = trans->splits; node; node = node->next)
|
||||||
|
{
|
||||||
|
split = node->data;
|
||||||
|
|
||||||
|
peer = xaccSplitGetAccount (split);
|
||||||
|
if (peer)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!peer)
|
||||||
|
{
|
||||||
|
PERR ("Transaction with no accounts");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, we found an imbalanced trans. Put it in the imbal account. */
|
||||||
|
account = GetOrMakeAccount (peer, trans, _("Imbalance"));
|
||||||
|
|
||||||
|
/* put split into account before setting split value */
|
||||||
|
split = xaccMallocSplit();
|
||||||
|
xaccAccountBeginEdit (account);
|
||||||
|
xaccAccountInsertSplit (account, split);
|
||||||
|
xaccAccountCommitEdit (account);
|
||||||
|
|
||||||
|
xaccTransBeginEdit (trans, TRUE);
|
||||||
|
xaccSplitSetValue (split, gnc_numeric_neg (imbalance));
|
||||||
|
xaccTransAppendSplit (trans, split);
|
||||||
|
xaccTransCommitEdit (trans);
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
static Account *
|
static Account *
|
||||||
@ -166,27 +194,29 @@ GetOrMakeAccount (Account *peer, Transaction *trans, const char *name_root)
|
|||||||
|
|
||||||
/* build the account name */
|
/* build the account name */
|
||||||
currency = xaccTransFindCommonCurrency (trans);
|
currency = xaccTransFindCommonCurrency (trans);
|
||||||
accname = alloca (strlen (name_root) +
|
|
||||||
strlen (gnc_commodity_get_mnemonic(currency)) + 2);
|
accname = g_strconcat (name_root, "-",
|
||||||
strcpy (accname, name_root);
|
gnc_commodity_get_mnemonic(currency), NULL);
|
||||||
strcat (accname, "-");
|
|
||||||
strcat (accname, gnc_commodity_get_mnemonic(currency));
|
|
||||||
|
|
||||||
/* see if we've got one of these going already ... */
|
/* see if we've got one of these going already ... */
|
||||||
acc = xaccGetPeerAccountFromName (peer, accname);
|
acc = xaccGetPeerAccountFromName (peer, accname);
|
||||||
if (acc) return acc;
|
|
||||||
|
|
||||||
/* guess not. We'll have to build one */
|
if (acc == NULL)
|
||||||
acc = xaccMallocAccount ();
|
{
|
||||||
xaccAccountBeginEdit (acc);
|
/* guess not. We'll have to build one */
|
||||||
xaccAccountSetName (acc, accname);
|
acc = xaccMallocAccount ();
|
||||||
xaccAccountSetCurrency (acc, currency);
|
xaccAccountBeginEdit (acc);
|
||||||
xaccAccountSetType (acc, BANK);
|
xaccAccountSetName (acc, accname);
|
||||||
|
xaccAccountSetCurrency (acc, currency);
|
||||||
|
xaccAccountSetType (acc, BANK);
|
||||||
|
|
||||||
/* hang the account off the root */
|
/* hang the account off the root */
|
||||||
root = xaccGetAccountRoot (peer);
|
root = xaccGetAccountRoot (peer);
|
||||||
xaccGroupInsertAccount (root, acc);
|
xaccGroupInsertAccount (root, acc);
|
||||||
xaccAccountCommitEdit (acc);
|
xaccAccountCommitEdit (acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (accname);
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ void xaccGroupScrubOrphans (AccountGroup *grp);
|
|||||||
* is created to offset this amount and is added to an "imbalance"
|
* is created to offset this amount and is added to an "imbalance"
|
||||||
* account.
|
* account.
|
||||||
*/
|
*/
|
||||||
|
void xaccTransScrubImbalance (Transaction *trans);
|
||||||
void xaccAccountScrubImbalance (Account *acc);
|
void xaccAccountScrubImbalance (Account *acc);
|
||||||
void xaccAccountTreeScrubImbalance (Account *acc);
|
void xaccAccountTreeScrubImbalance (Account *acc);
|
||||||
void xaccGroupScrubImbalance (AccountGroup *grp);
|
void xaccGroupScrubImbalance (AccountGroup *grp);
|
||||||
|
@ -959,12 +959,6 @@ ComputeValue (GList *splits, Split * skip_me,
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
|
||||||
DxaccTransGetImbalance (Transaction * trans)
|
|
||||||
{
|
|
||||||
return gnc_numeric_to_double(xaccTransGetImbalance(trans));
|
|
||||||
}
|
|
||||||
|
|
||||||
gnc_numeric
|
gnc_numeric
|
||||||
xaccTransGetImbalance (Transaction * trans)
|
xaccTransGetImbalance (Transaction * trans)
|
||||||
{
|
{
|
||||||
@ -973,6 +967,52 @@ xaccTransGetImbalance (Transaction * trans)
|
|||||||
return imbal;
|
return imbal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Split *
|
||||||
|
xaccTransGetBalanceSplit (Transaction *trans)
|
||||||
|
{
|
||||||
|
Split *split;
|
||||||
|
kvp_value *kvp;
|
||||||
|
GUID *guid;
|
||||||
|
|
||||||
|
if (!trans)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
kvp = kvp_frame_get_slot (xaccTransGetSlots (trans), "balance-split");
|
||||||
|
if (!kvp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
guid = kvp_value_get_guid (kvp);
|
||||||
|
if (!guid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
split = xaccSplitLookup (guid);
|
||||||
|
if (g_list_find (trans->splits, split))
|
||||||
|
return split;
|
||||||
|
|
||||||
|
xaccTransSetBalanceSplit (trans, NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xaccTransSetBalanceSplit (Transaction *trans, Split *split)
|
||||||
|
{
|
||||||
|
kvp_value *new_value;
|
||||||
|
|
||||||
|
if (!trans)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (split)
|
||||||
|
new_value = kvp_value_new_guid (xaccSplitGetGUID (split));
|
||||||
|
else
|
||||||
|
new_value = NULL;
|
||||||
|
|
||||||
|
kvp_frame_set_slot(xaccTransGetSlots (trans), "balance-split", new_value);
|
||||||
|
|
||||||
|
if (new_value)
|
||||||
|
kvp_value_delete(new_value);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
gboolean
|
gboolean
|
||||||
@ -1129,7 +1169,7 @@ xaccSplitRebalance (Split *split)
|
|||||||
{
|
{
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
gnc_numeric value;
|
gnc_numeric value;
|
||||||
const gnc_commodity * base_currency = NULL;
|
const gnc_commodity * base_currency = NULL;
|
||||||
|
|
||||||
trans = split->parent;
|
trans = split->parent;
|
||||||
|
|
||||||
@ -1358,7 +1398,7 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
xaccSplitSetShareAmount(s, gnc_numeric_neg(split->damount));
|
xaccSplitSetShareAmount(s, gnc_numeric_neg(split->damount));
|
||||||
xaccSplitSetValue(s, gnc_numeric_neg(split->value));
|
xaccSplitSetValue(s, gnc_numeric_neg(split->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
trans->open &= ~DEFER_REBALANCE;
|
trans->open &= ~DEFER_REBALANCE;
|
||||||
xaccTransRebalance (trans);
|
xaccTransRebalance (trans);
|
||||||
|
|
||||||
|
@ -290,8 +290,14 @@ xaccTransIsCommonExclSCurrency (Transaction *trans,
|
|||||||
* in the currency that is returned by the xaccTransFindCommonCurrency()
|
* in the currency that is returned by the xaccTransFindCommonCurrency()
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
double DxaccTransGetImbalance (Transaction * trans);
|
gnc_numeric xaccTransGetImbalance (Transaction * trans);
|
||||||
gnc_numeric xaccTransGetImbalance (Transaction * trans);
|
|
||||||
|
/* The xaccTransGetBalanceSplit method returns the 'balance' split of
|
||||||
|
* a transaction or NULL if there is no balance split. The balance
|
||||||
|
* split is an 'artificial' split created to make the transaction
|
||||||
|
* balance. This split is automatically managed by the rebalancing
|
||||||
|
* routines and is created and destroyed as needed. */
|
||||||
|
Split * xaccTransGetBalanceSplit (Transaction *trans);
|
||||||
|
|
||||||
/* ------------- splits --------------- */
|
/* ------------- splits --------------- */
|
||||||
Split * xaccMallocSplit (void);
|
Split * xaccMallocSplit (void);
|
||||||
@ -475,7 +481,7 @@ int xaccCountSplits (Split **sarray);
|
|||||||
* The xaccGetAccountByFullName routine is similar, but uses
|
* The xaccGetAccountByFullName routine is similar, but uses
|
||||||
* full names using the given separator.
|
* full names using the given separator.
|
||||||
*/
|
*/
|
||||||
Account * xaccGetAccountByName (Transaction *, const char *);
|
Account * xaccGetAccountByName (Transaction *trans, const char *name);
|
||||||
Account * xaccGetAccountByFullName (Transaction *trans,
|
Account * xaccGetAccountByFullName (Transaction *trans,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char separator);
|
const char separator);
|
||||||
|
@ -230,6 +230,8 @@ void xaccFreeSplit (Split *split); /* frees memory */
|
|||||||
|
|
||||||
void xaccSplitRebalance (Split *split);
|
void xaccSplitRebalance (Split *split);
|
||||||
|
|
||||||
|
/* Set the balance split of a transaction. */
|
||||||
|
void xaccTransSetBalanceSplit (Transaction *trans, Split *split);
|
||||||
|
|
||||||
/* FIXME: this is probably wrong, but it'll have to wait until Bill
|
/* FIXME: this is probably wrong, but it'll have to wait until Bill
|
||||||
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
||||||
|
Loading…
Reference in New Issue
Block a user