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
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Account.h"
|
||||
@ -41,6 +41,7 @@
|
||||
#include "GroupP.h"
|
||||
#include "Scrub.h"
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "messages.h"
|
||||
|
||||
@ -130,28 +131,55 @@ xaccAccountScrubImbalance (Account *acc) {
|
||||
for(slp = xaccAccountGetSplitList(acc); slp; slp = slp->next) {
|
||||
Split *split = (Split *) slp->data;
|
||||
Transaction *trans = xaccSplitGetParent(split);
|
||||
double imbalance;
|
||||
|
||||
imbalance = DxaccTransGetImbalance (trans);
|
||||
if (!(DEQ (imbalance, 0.0))) {
|
||||
Split *splat;
|
||||
Account *orph;
|
||||
DEBUG ("Found imbalance of %g\n", imbalance);
|
||||
xaccTransScrubImbalance (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. */
|
||||
orph = GetOrMakeAccount (acc, trans, _("Imbalance"));
|
||||
account = GetOrMakeAccount (peer, trans, _("Imbalance"));
|
||||
|
||||
/* put split into account before setting split value */
|
||||
splat = xaccMallocSplit();
|
||||
xaccAccountBeginEdit (orph);
|
||||
xaccAccountInsertSplit (orph, splat);
|
||||
xaccAccountCommitEdit (orph);
|
||||
split = xaccMallocSplit();
|
||||
xaccAccountBeginEdit (account);
|
||||
xaccAccountInsertSplit (account, split);
|
||||
xaccAccountCommitEdit (account);
|
||||
|
||||
xaccTransBeginEdit (trans, 1);
|
||||
DxaccSplitSetValue (splat, -imbalance);
|
||||
xaccTransAppendSplit (trans, splat);
|
||||
xaccTransBeginEdit (trans, TRUE);
|
||||
xaccSplitSetValue (split, gnc_numeric_neg (imbalance));
|
||||
xaccTransAppendSplit (trans, split);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
@ -166,16 +194,15 @@ GetOrMakeAccount (Account *peer, Transaction *trans, const char *name_root)
|
||||
|
||||
/* build the account name */
|
||||
currency = xaccTransFindCommonCurrency (trans);
|
||||
accname = alloca (strlen (name_root) +
|
||||
strlen (gnc_commodity_get_mnemonic(currency)) + 2);
|
||||
strcpy (accname, name_root);
|
||||
strcat (accname, "-");
|
||||
strcat (accname, gnc_commodity_get_mnemonic(currency));
|
||||
|
||||
accname = g_strconcat (name_root, "-",
|
||||
gnc_commodity_get_mnemonic(currency), NULL);
|
||||
|
||||
/* see if we've got one of these going already ... */
|
||||
acc = xaccGetPeerAccountFromName (peer, accname);
|
||||
if (acc) return acc;
|
||||
|
||||
if (acc == NULL)
|
||||
{
|
||||
/* guess not. We'll have to build one */
|
||||
acc = xaccMallocAccount ();
|
||||
xaccAccountBeginEdit (acc);
|
||||
@ -187,6 +214,9 @@ GetOrMakeAccount (Account *peer, Transaction *trans, const char *name_root)
|
||||
root = xaccGetAccountRoot (peer);
|
||||
xaccGroupInsertAccount (root, acc);
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
|
||||
g_free (accname);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ void xaccGroupScrubOrphans (AccountGroup *grp);
|
||||
* is created to offset this amount and is added to an "imbalance"
|
||||
* account.
|
||||
*/
|
||||
void xaccTransScrubImbalance (Transaction *trans);
|
||||
void xaccAccountScrubImbalance (Account *acc);
|
||||
void xaccAccountTreeScrubImbalance (Account *acc);
|
||||
void xaccGroupScrubImbalance (AccountGroup *grp);
|
||||
|
@ -959,12 +959,6 @@ ComputeValue (GList *splits, Split * skip_me,
|
||||
return value;
|
||||
}
|
||||
|
||||
double
|
||||
DxaccTransGetImbalance (Transaction * trans)
|
||||
{
|
||||
return gnc_numeric_to_double(xaccTransGetImbalance(trans));
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
xaccTransGetImbalance (Transaction * trans)
|
||||
{
|
||||
@ -973,6 +967,52 @@ xaccTransGetImbalance (Transaction * trans)
|
||||
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
|
||||
|
@ -290,9 +290,15 @@ xaccTransIsCommonExclSCurrency (Transaction *trans,
|
||||
* in the currency that is returned by the xaccTransFindCommonCurrency()
|
||||
* method.
|
||||
*/
|
||||
double DxaccTransGetImbalance (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 --------------- */
|
||||
Split * xaccMallocSplit (void);
|
||||
|
||||
@ -475,7 +481,7 @@ int xaccCountSplits (Split **sarray);
|
||||
* The xaccGetAccountByFullName routine is similar, but uses
|
||||
* full names using the given separator.
|
||||
*/
|
||||
Account * xaccGetAccountByName (Transaction *, const char *);
|
||||
Account * xaccGetAccountByName (Transaction *trans, const char *name);
|
||||
Account * xaccGetAccountByFullName (Transaction *trans,
|
||||
const char *name,
|
||||
const char separator);
|
||||
|
@ -230,6 +230,8 @@ void xaccFreeSplit (Split *split); /* frees memory */
|
||||
|
||||
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
|
||||
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
||||
|
Loading…
Reference in New Issue
Block a user