GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Files | Macros | Typedefs | Functions

Files

file  Split.h
 API for Transactions and Splits (journal entries)
 
file  Transaction.h
 API for Transactions and Splits (journal entries)
 

Macros

#define GNC_TYPE_SPLIT   (gnc_split_get_type ())
 
#define GNC_SPLIT(o)   (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_SPLIT, Split))
 
#define GNC_SPLIT_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_SPLIT, SplitClass))
 
#define GNC_IS_SPLIT(o)   (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_SPLIT))
 
#define GNC_IS_SPLIT_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_SPLIT))
 
#define GNC_SPLIT_GET_CLASS(o)   (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_SPLIT, SplitClass))
 
#define xaccSplitGetGUID(X)   qof_entity_get_guid(QOF_INSTANCE(X))
 
#define xaccSplitReturnGUID(X)   (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
 
#define GNC_TYPE_TRANSACTION   (gnc_transaction_get_type ())
 
#define GNC_TRANSACTION(o)   (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_TRANSACTION, Transaction))
 
#define GNC_TRANSACTION_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_TRANSACTION, TransactionClass))
 
#define GNC_IS_TRANSACTION(o)   (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_TRANSACTION))
 
#define GNC_IS_TRANSACTION_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_TRANSACTION))
 
#define GNC_TRANSACTION_GET_CLASS(o)   (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_TRANSACTION, TransactionClass))
 
#define GNC_IS_TRANS(obj)   GNC_IS_TRANSACTION(obj)
 
#define GNC_TRANS(obj)   GNC_TRANSACTION(obj)
 
#define RECONCILED_MATCH_TYPE   "reconciled-match"
 
#define xaccTransGetBook(X)   qof_instance_get_book (QOF_INSTANCE(X))
 
#define xaccTransGetGUID(X)   qof_entity_get_guid(QOF_INSTANCE(X))
 
#define xaccTransReturnGUID(X)   (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
 

Typedefs

typedef struct _SplitClass SplitClass
 
typedef struct _TransactionClass TransactionClass
 

Functions

GType gnc_split_get_type (void)
 
gnc_numeric xaccSplitConvertAmount (const Split *split, const Account *account)
 
GType gnc_transaction_get_type (void)
 

Split Reconciled field values

If you change these be sure to change gnc-ui-util.c:gnc_get_reconciled_str() and associated functions

#define CREC   'c'
 
#define YREC   'y'
 
#define FREC   'f'
 
#define NREC   'n'
 
#define VREC   'v'
 

Split general getters/setters

SplitxaccMallocSplit (QofBook *book)
 
void xaccSplitReinit (Split *split)
 
gboolean xaccSplitDestroy (Split *split)
 
void xaccSplitCopyOnto (const Split *from_split, Split *to_split)
 
QofBookxaccSplitGetBook (const Split *split)
 
AccountxaccSplitGetAccount (const Split *split)
 
void xaccSplitSetAccount (Split *s, Account *acc)
 
TransactionxaccSplitGetParent (const Split *split)
 
void xaccSplitSetParent (Split *split, Transaction *trans)
 
GNCLotxaccSplitGetLot (const Split *split)
 
void xaccSplitSetLot (Split *split, GNCLot *lot)
 
void xaccSplitSetMemo (Split *split, const char *memo)
 
const char * xaccSplitGetMemo (const Split *split)
 
void xaccSplitSetAction (Split *split, const char *action)
 
const char * xaccSplitGetAction (const Split *split)
 

Split Date getters/setters

void xaccSplitSetReconcile (Split *split, char reconciled_flag)
 
char xaccSplitGetReconcile (const Split *split)
 
void xaccSplitSetDateReconciledSecs (Split *split, time64 time)
 
void xaccSplitSetDateReconciledTS (Split *split, Timespec *ts)
 
void xaccSplitGetDateReconciledTS (const Split *split, Timespec *ts)
 
Timespec xaccSplitRetDateReconciledTS (const Split *split)
 
time64 xaccSplitGetDateReconciled (const Split *split)
 

Split amount getters/setters

'value' vs. 'amount' of a Split: The 'value' is the amount of the transaction balancing commodity (i.e. currency) involved, 'amount' is the amount of the account's commodity involved.

void xaccSplitSetAmount (Split *split, gnc_numeric amount)
 
gnc_numeric xaccSplitGetAmount (const Split *split)
 
void xaccSplitSetValue (Split *split, gnc_numeric value)
 
gnc_numeric xaccSplitGetValue (const Split *split)
 
void xaccSplitSetSharePriceAndAmount (Split *split, gnc_numeric price, gnc_numeric amount)
 
gnc_numeric xaccSplitGetSharePrice (const Split *split)
 
void xaccSplitSetBaseValue (Split *split, gnc_numeric value, const gnc_commodity *base_currency)
 
gnc_numeric xaccSplitGetBaseValue (const Split *split, const gnc_commodity *base_currency)
 
gnc_numeric xaccSplitGetBalance (const Split *split)
 
gnc_numeric xaccSplitGetClearedBalance (const Split *split)
 
gnc_numeric xaccSplitGetReconciledBalance (const Split *split)
 

Split utility functions

gboolean xaccSplitEqual (const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits)
 
SplitxaccSplitLookup (const GncGUID *guid, QofBook *book)
 
GList * xaccSplitListGetUniqueTransactions (const GList *splits)
 
SplitxaccSplitGetOtherSplit (const Split *split)
 
const char * xaccSplitGetType (const Split *s)
 
void xaccSplitMakeStockSplit (Split *s)
 
gint xaccSplitOrder (const Split *sa, const Split *sb)
 
gint xaccSplitOrderDateOnly (const Split *sa, const Split *sb)
 
int xaccSplitCompareAccountFullNames (const Split *sa, const Split *sb)
 
int xaccSplitCompareAccountCodes (const Split *sa, const Split *sb)
 
int xaccSplitCompareOtherAccountFullNames (const Split *sa, const Split *sb)
 
int xaccSplitCompareOtherAccountCodes (const Split *sa, const Split *sb)
 
char * xaccSplitGetCorrAccountFullName (const Split *sa)
 
const char * xaccSplitGetCorrAccountName (const Split *sa)
 
const char * xaccSplitGetCorrAccountCode (const Split *sa)
 
#define xaccSplitLookupDirect(g, b)   xaccSplitLookup(&(g),b)
 

Split deprecated functions

void xaccSplitSetSharePrice (Split *split, gnc_numeric price)
 

Split voiding

gnc_numeric xaccSplitVoidFormerAmount (const Split *split)
 
gnc_numeric xaccSplitVoidFormerValue (const Split *split)
 

Split Parameter names

Note, if you want to get the equivalent of "ACCT_MATCH_ALL" you need to create a search on the following parameter list: SPLIT->SPLIT_TRANS->TRANS_SPLITLIST->SPLIT_ACCOUNT_GUID. If you do this, you might want to use the ACCOUNT_MATCH_ALL_TYPE as the override so the gnome-search dialog displays the right type.

#define SPLIT_KVP   "kvp"
 
#define SPLIT_DATE_RECONCILED   "date-reconciled"
 
#define SPLIT_BALANCE   "balance"
 
#define SPLIT_CLEARED_BALANCE   "cleared-balance"
 
#define SPLIT_RECONCILED_BALANCE   "reconciled-balance"
 
#define SPLIT_MEMO   "memo"
 
#define SPLIT_ACTION   "action"
 
#define SPLIT_RECONCILE   "reconcile-flag"
 
#define SPLIT_AMOUNT   "amount"
 
#define SPLIT_SHARE_PRICE   "share-price"
 
#define SPLIT_VALUE   "value"
 
#define SPLIT_TYPE   "type"
 
#define SPLIT_VOIDED_AMOUNT   "voided-amount"
 
#define SPLIT_VOIDED_VALUE   "voided-value"
 
#define SPLIT_LOT   "lot"
 
#define SPLIT_TRANS   "trans"
 
#define SPLIT_ACCOUNT   "account"
 
#define SPLIT_ACCOUNT_GUID   "account-guid"
 
#define SPLIT_ACCT_FULLNAME   "acct-fullname"
 
#define SPLIT_CORR_ACCT_NAME   "corr-acct-fullname"
 
#define SPLIT_CORR_ACCT_CODE   "corr-acct-code"
 

Transaction Type field values

#define TXN_TYPE_NONE   '\0'
 
#define TXN_TYPE_INVOICE   'I'
 
#define TXN_TYPE_PAYMENT   'P'
 
#define TXN_TYPE_LINK   'L'
 

Transaction creation and editing

TransactionxaccMallocTransaction (QofBook *book)
 
void xaccTransDestroy (Transaction *trans)
 
TransactionxaccTransClone (const Transaction *t)
 
TransactionxaccTransCloneNoKvp (const Transaction *t)
 
gboolean xaccTransEqual (const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
 
void xaccTransBeginEdit (Transaction *trans)
 
void xaccTransCommitEdit (Transaction *trans)
 
void xaccTransRollbackEdit (Transaction *trans)
 
gboolean xaccTransIsOpen (const Transaction *trans)
 
TransactionxaccTransLookup (const GncGUID *guid, QofBook *book)
 
TransactionxaccTransCopyToClipBoard (const Transaction *from_trans)
 
void xaccTransCopyOnto (const Transaction *from_trans, Transaction *to_trans)
 
void xaccTransCopyFromClipBoard (const Transaction *from_trans, Transaction *to_trans, const Account *from_acc, Account *to_acc, gboolean no_date)
 
SplitxaccTransFindSplitByAccount (const Transaction *trans, const Account *acc)
 
void xaccTransScrubGains (Transaction *trans, Account *gain_acc)
 
guint gnc_book_count_transactions (QofBook *book)
 
#define xaccTransLookupDirect(g, b)   xaccTransLookup(&(g),b)
 

Transaction general getters/setters

gboolean xaccTransUseTradingAccounts (const Transaction *trans)
 
void xaccTransSortSplits (Transaction *trans)
 
void xaccTransSetTxnType (Transaction *trans, char type)
 
char xaccTransGetTxnType (const Transaction *trans)
 
void xaccTransSetNum (Transaction *trans, const char *num)
 
void xaccTransSetDescription (Transaction *trans, const char *desc)
 
void xaccTransSetAssociation (Transaction *trans, const char *assoc)
 
void xaccTransSetNotes (Transaction *trans, const char *notes)
 
const char * xaccTransGetNum (const Transaction *trans)
 
const char * xaccTransGetDescription (const Transaction *trans)
 
const char * xaccTransGetAssociation (const Transaction *trans)
 
const char * xaccTransGetNotes (const Transaction *trans)
 
void xaccTransSetIsClosingTxn (Transaction *trans, gboolean is_closing)
 
gboolean xaccTransGetIsClosingTxn (const Transaction *trans)
 
SplitxaccTransGetSplit (const Transaction *trans, int i)
 
int xaccTransGetSplitIndex (const Transaction *trans, const Split *split)
 
SplitListxaccTransGetSplitList (const Transaction *trans)
 
gboolean xaccTransStillHasSplit (const Transaction *trans, const Split *s)
 
void xaccTransSetReadOnly (Transaction *trans, const char *reason)
 
void xaccTransClearReadOnly (Transaction *trans)
 
const char * xaccTransGetReadOnly (const Transaction *trans)
 
gboolean xaccTransIsReadonlyByPostedDate (const Transaction *trans)
 
gboolean xaccTransInFutureByPostedDate (const Transaction *trans)
 
int xaccTransCountSplits (const Transaction *trans)
 
gboolean xaccTransHasReconciledSplits (const Transaction *trans)
 
gboolean xaccTransHasReconciledSplitsByAccount (const Transaction *trans, const Account *account)
 
gboolean xaccTransHasSplitsInState (const Transaction *trans, const char state)
 
gboolean xaccTransHasSplitsInStateByAccount (const Transaction *trans, const char state, const Account *account)
 
gnc_commodityxaccTransGetCurrency (const Transaction *trans)
 
void xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr)
 
gnc_numeric xaccTransGetImbalanceValue (const Transaction *trans)
 
MonetaryList * xaccTransGetImbalance (const Transaction *trans)
 
gboolean xaccTransIsBalanced (const Transaction *trans)
 
gnc_numeric xaccTransGetAccountValue (const Transaction *trans, const Account *account)
 
gnc_numeric xaccTransGetAccountAmount (const Transaction *trans, const Account *account)
 
gboolean xaccTransGetRateForCommodity (const Transaction *trans, const gnc_commodity *split_com, const Split *split_to_exclude, gnc_numeric *rate)
 
gnc_numeric xaccTransGetAccountConvRate (const Transaction *txn, const Account *acc)
 
gnc_numeric xaccTransGetAccountBalance (const Transaction *trans, const Account *account)
 
int xaccTransOrder (const Transaction *ta, const Transaction *tb)
 
int xaccTransOrder_num_action (const Transaction *ta, const char *actna, const Transaction *tb, const char *actnb)
 
#define xaccTransAppendSplit(t, s)   xaccSplitSetParent((s), (t))
 

Transaction date setters/getters

void xaccTransSetDate (Transaction *trans, int day, int mon, int year)
 
void xaccTransSetDatePostedGDate (Transaction *trans, GDate date)
 
void xaccTransSetDatePostedSecs (Transaction *trans, time64 time)
 
void xaccTransSetDatePostedSecsNormalized (Transaction *trans, time64 time)
 
void xaccTransSetDatePostedTS (Transaction *trans, const Timespec *ts)
 
void xaccTransSetDateEnteredSecs (Transaction *trans, time64 time)
 
void xaccTransSetDateEnteredTS (Transaction *trans, const Timespec *ts)
 
void xaccTransSetDateDueTS (Transaction *trans, const Timespec *ts)
 
time64 xaccTransGetDate (const Transaction *trans)
 
void xaccTransGetDatePostedTS (const Transaction *trans, Timespec *ts)
 
Timespec xaccTransRetDatePostedTS (const Transaction *trans)
 
GDate xaccTransGetDatePostedGDate (const Transaction *trans)
 
time64 xaccTransGetDateEntered (const Transaction *trans)
 
void xaccTransGetDateEnteredTS (const Transaction *trans, Timespec *ts)
 
Timespec xaccTransRetDateEnteredTS (const Transaction *trans)
 
Timespec xaccTransRetDateDueTS (const Transaction *trans)
 
void xaccTransGetDateDueTS (const Transaction *trans, Timespec *ts)
 

Transaction voiding

void xaccTransVoid (Transaction *transaction, const char *reason)
 
void xaccTransUnvoid (Transaction *transaction)
 
TransactionxaccTransReverse (Transaction *transaction)
 
TransactionxaccTransGetReversedBy (const Transaction *trans)
 
gboolean xaccTransGetVoidStatus (const Transaction *transaction)
 
const char * xaccTransGetVoidReason (const Transaction *transaction)
 
Timespec xaccTransGetVoidTime (const Transaction *tr)
 

Transaction Parameter names

#define TRANS_KVP   "kvp"
 
#define TRANS_NUM   "num"
 
#define TRANS_DESCRIPTION   "desc"
 
#define TRANS_DATE_ENTERED   "date-entered"
 
#define TRANS_DATE_POSTED   "date-posted"
 
#define TRANS_DATE_DUE   "date-due"
 
#define TRANS_IMBALANCE   "trans-imbalance"
 
#define TRANS_IS_BALANCED   "trans-balanced?"
 
#define TRANS_IS_CLOSING   "trans-is-closing?"
 
#define TRANS_NOTES   "notes"
 
#define TRANS_ASSOCIATION   "assoc"
 
#define TRANS_TYPE   "type"
 
#define TRANS_VOID_STATUS   "void-p"
 
#define TRANS_VOID_REASON   "void-reason"
 
#define TRANS_VOID_TIME   "void-time"
 
#define TRANS_SPLITLIST   "split-list" /* for guid_match_all */
 

Detailed Description

A good overview of transactions, splits and accounts can be found in the texinfo documentation, together with an overview of how to use this API.

A good overview of transactions, splits and accounts can be found in the texinfo documentation, together with an overview of how to use this API.

Splits, or "Ledger Entries" are the fundamental accounting units. Each Split consists of an amount (number of dollar bills, number of shares, etc.), the value of that amount expressed in a (possibly) different currency than the amount, a Memo, a pointer to the parent Transaction, a pointer to the debited Account, a reconciled flag and timestamp, an "Action" field, and a key-value frame which can store arbitrary data.

Transactions embody the notion of "double entry" accounting. A Transaction consists of a date, a description, an ID number, a list of one or more Splits, and a key-value frame. The transaction also specifies the currency with which all of the splits will be valued. When double-entry rules are enforced, the sum total value of the splits are zero. If there are only two splits, then the value of one must be positive, the other negative: this denotes that one account is debited, and another is credited by an equal amount. By forcing the value of the splits to always 'add up' to zero, we can guarantee that the balances of the accounts are always correctly balanced.

The engine does not enforce double-entry accounting, but provides an API to enable user-code to find unbalanced transactions and 'repair' them so that they are in balance.

Note the sum of the values of Splits in a Transaction is always computed with respect to a currency; thus splits can be balanced even when they are in different currencies, as long as they share a common currency. This feature allows currency-trading accounts to be established.

Every Split must point to its parent Transaction, and that Transaction must in turn include that Split in the Transaction's list of Splits. A Split can belong to at most one Transaction. These relationships are enforced by the engine. The engine user cannnot accidentally destroy this relationship as long as they stick to using the API and never access internal structures directly.

Splits are grouped into Accounts which are also known as "Ledgers" in accounting practice. Each Account consists of a list of Splits that debit that Account. To ensure consistency, if a Split points to an Account, then the Account must point to the Split, and vice-versa. A Split can belong to at most one Account. Besides merely containing a list of Splits, the Account structure also gives the Account a name, a code number, description and notes fields, a key-value frame, a pointer to the commodity that is used for all splits in this account. The commodity can be the name of anything traded and tradable: a stock (e.g. "IBM", "McDonald's"), a currency (e.g. "USD", "GBP"), or anything added to the commodity table.

Accounts can be arranged in a hierarchical tree. The nodes of the tree are called "Account Groups". By accounting convention, the value of an Account is equal to the value of all of its Splits plus the value of all of its sub-Accounts.

Macro Definition Documentation

#define CREC   'c'

The Split has been cleared

Definition at line 67 of file Split.h.

#define FREC   'f'

frozen into accounting period

Definition at line 69 of file Split.h.

#define NREC   'n'

not reconciled or cleared

Definition at line 70 of file Split.h.

#define SPLIT_ACCOUNT_GUID   "account-guid"

for guid_match_all

Definition at line 513 of file Split.h.

#define TXN_TYPE_INVOICE   'I'

Transaction is an invoice

Definition at line 120 of file Transaction.h.

#define TXN_TYPE_LINK   'L'

Transaction is a link between (invoice and payment) lots

Definition at line 122 of file Transaction.h.

#define TXN_TYPE_NONE   '\0'

No transaction type

Definition at line 119 of file Transaction.h.

#define TXN_TYPE_PAYMENT   'P'

Transaction is a payment

Definition at line 121 of file Transaction.h.

#define VREC   'v'

split is void

Definition at line 71 of file Split.h.

#define xaccSplitGetGUID (   X)    qof_entity_get_guid(QOF_INSTANCE(X))
Deprecated:

Definition at line 521 of file Split.h.

#define xaccSplitReturnGUID (   X)    (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
Deprecated:

Definition at line 523 of file Split.h.

#define xaccTransAppendSplit (   t,
 
)    xaccSplitSetParent((s), (t))

Add a split to the transaction

The xaccTransAppendSplit() method will append the indicated split to the collection of splits in this transaction.

Note
If the split is already a part of another transaction, it will be removed from that transaction first.

Definition at line 357 of file Transaction.h.

#define xaccTransGetBook (   X)    qof_instance_get_book (QOF_INSTANCE(X))
Deprecated:

Definition at line 753 of file Transaction.h.

#define xaccTransGetGUID (   X)    qof_entity_get_guid(QOF_INSTANCE(X))
Deprecated:

Definition at line 755 of file Transaction.h.

#define xaccTransReturnGUID (   X)    (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
Deprecated:

Definition at line 757 of file Transaction.h.

#define YREC   'y'

The Split has been reconciled

Definition at line 68 of file Split.h.

Function Documentation

guint gnc_book_count_transactions ( QofBook book)
Warning
XXX FIXME gnc_book_count_transactions is a utility function, probably needs to be moved to a utility file somewhere.

Definition at line 2483 of file Transaction.c.

2484 {
2485  guint count = 0;
2486  xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book),
2487  counter_thunk, (void*)&count);
2488  return count;
2489 }
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
Split* xaccMallocSplit ( QofBook book)

Constructor.

Definition at line 582 of file Split.c.

583 {
584  Split *split;
585  g_return_val_if_fail (book, NULL);
586 
587  split = g_object_new (GNC_TYPE_SPLIT, NULL);
588  xaccInitSplit (split, book);
589 
590  return split;
591 }
Definition: SplitP.h:71
Transaction* xaccMallocTransaction ( QofBook book)

The xaccMallocTransaction() will malloc memory and initialize it. Once created, it is usually unsafe to merely "free" this memory; the xaccTransDestroy() method should be called.

Definition at line 513 of file Transaction.c.

514 {
515  Transaction *trans;
516 
517  g_return_val_if_fail (book, NULL);
518 
519  trans = g_object_new(GNC_TYPE_TRANSACTION, NULL);
520  xaccInitTransaction (trans, book);
521  qof_event_gen (&trans->inst, QOF_EVENT_CREATE, NULL);
522 
523  return trans;
524 }
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
int xaccSplitCompareAccountCodes ( const Split sa,
const Split sb 
)

Compare two splits by code of account. Returns similar to strcmp.

Definition at line 1719 of file Split.c.

1720 {
1721  Account *aa, *ab;
1722  if (!sa && !sb) return 0;
1723  if (!sa) return -1;
1724  if (!sb) return 1;
1725 
1726  aa = sa->acc;
1727  ab = sb->acc;
1728 
1729  return g_strcmp0(xaccAccountGetCode(aa), xaccAccountGetCode(ab));
1730 }
const char * xaccAccountGetCode(const Account *acc)
Definition: Account.c:3086
int xaccSplitCompareAccountFullNames ( const Split sa,
const Split sb 
)

Compare two splits by full name of account. Returns similar to strcmp.

Definition at line 1698 of file Split.c.

1699 {
1700  Account *aa, *ab;
1701  char *full_a, *full_b;
1702  int retval;
1703  if (!sa && !sb) return 0;
1704  if (!sa) return -1;
1705  if (!sb) return 1;
1706 
1707  aa = sa->acc;
1708  ab = sb->acc;
1709  full_a = gnc_account_get_full_name(aa);
1710  full_b = gnc_account_get_full_name(ab);
1711  retval = g_utf8_collate(full_a, full_b);
1712  g_free(full_a);
1713  g_free(full_b);
1714  return retval;
1715 }
gchar * gnc_account_get_full_name(const Account *account)
Definition: Account.c:3038
int xaccSplitCompareOtherAccountCodes ( const Split sa,
const Split sb 
)

Compare two splits by code of the other account. Returns similar to strcmp. This function attempts to find the split on the other side of a transaction and compare on it.

Definition at line 1754 of file Split.c.

1755 {
1756  const char *ca, *cb;
1757  if (!sa && !sb) return 0;
1758  if (!sa) return -1;
1759  if (!sb) return 1;
1760 
1761  ca = xaccSplitGetCorrAccountCode(sa);
1762  cb = xaccSplitGetCorrAccountCode(sb);
1763  return g_strcmp0(ca, cb);
1764 }
const char * xaccSplitGetCorrAccountCode(const Split *sa)
Definition: Split.c:1680
int xaccSplitCompareOtherAccountFullNames ( const Split sa,
const Split sb 
)

Compare two splits by full name of the other account. Returns similar to strcmp. This function attempts to find the split on the other side of a transaction and compare on it.

Definition at line 1733 of file Split.c.

1734 {
1735  char *ca, *cb;
1736  int retval;
1737  if (!sa && !sb) return 0;
1738  if (!sa) return -1;
1739  if (!sb) return 1;
1740 
1741  /* doesn't matter what separator we use
1742  * as long as they are the same
1743  */
1744 
1747  retval = g_strcmp0(ca, cb);
1748  g_free(ca);
1749  g_free(cb);
1750  return retval;
1751 }
char * xaccSplitGetCorrAccountFullName(const Split *sa)
Definition: Split.c:1664
void xaccSplitCopyOnto ( const Split from_split,
Split to_split 
)

This is really a helper for xaccTransCopyOnto. It doesn't reparent the 'to' split to from's transaction, because xaccTransCopyOnto is responsible for parenting the split to the correct transaction. Also, from's parent transaction may not even be a valid transaction, so this function may not modify anything about 'from' or from's transaction.

Definition at line 686 of file Split.c.

687 {
688  if (!from_split || !to_split) return;
689  xaccTransBeginEdit (to_split->parent);
690 
691  xaccSplitSetMemo(to_split, xaccSplitGetMemo(from_split));
692  xaccSplitSetAction(to_split, xaccSplitGetAction(from_split));
693  xaccSplitSetAmount(to_split, xaccSplitGetAmount(from_split));
694  xaccSplitSetValue(to_split, xaccSplitGetValue(from_split));
695  /* Setting the account is okay here because, even though the from
696  split might not really belong to the account it claims to,
697  setting the account won't cause any event involving from. */
698  xaccSplitSetAccount(to_split, xaccSplitGetAccount(from_split));
699  /* N.B. Don't set parent. */
700 
701  qof_instance_set_dirty(QOF_INSTANCE(to_split));
702  xaccTransCommitEdit(to_split->parent);
703 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
void xaccSplitSetAction(Split *split, const char *actn)
Definition: Split.c:1793
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
Definition: Split.c:1258
void xaccSplitSetMemo(Split *split, const char *memo)
Definition: Split.c:1774
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
const char * xaccSplitGetMemo(const Split *split)
Definition: Split.c:1968
const char * xaccSplitGetAction(const Split *split)
Definition: Split.c:1974
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
gboolean xaccSplitDestroy ( Split split)

Destructor.

The xaccSplitDestroy() method will update its parent account and transaction in a consistent manner, resulting in the complete unlinking of the split, and the freeing of its associated memory. The goal of this routine is to perform the removal and destruction of the split in an atomic fashion, with no chance of accidentally leaving the accounting structure out-of-balance or otherwise inconsistent.

If the deletion of the split leaves the transaction with no splits, then the transaction will be marked for deletion. (It will not be deleted until the xaccTransCommitEdit() routine is called.)

Returns
TRUE upon successful deletion of the split. FALSE when the parenting Transaction is a read-only one.

Definition at line 1492 of file Split.c.

1493 {
1494  Account *acc;
1495  Transaction *trans;
1496  GncEventData ed;
1497 
1498  if (!split) return TRUE;
1499 
1500  acc = split->acc;
1501  trans = split->parent;
1502  if (acc && !qof_instance_get_destroying(acc)
1503  && xaccTransGetReadOnly(trans))
1504  return FALSE;
1505 
1506  xaccTransBeginEdit(trans);
1507  ed.node = split;
1508  ed.idx = xaccTransGetSplitIndex(trans, split);
1509  qof_instance_set_dirty(QOF_INSTANCE(split));
1510  qof_instance_set_destroying(split, TRUE);
1511  qof_event_gen(&trans->inst, GNC_EVENT_ITEM_REMOVED, &ed);
1512  xaccTransCommitEdit(trans);
1513 
1514  return TRUE;
1515 }
gboolean qof_instance_get_destroying(gconstpointer ptr)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
const char * xaccTransGetReadOnly(const Transaction *trans)
Definition: Transaction.c:2313
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
Definition: Transaction.c:2154
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
gboolean xaccSplitEqual ( const Split sa,
const Split sb,
gboolean  check_guids,
gboolean  check_balances,
gboolean  check_txn_splits 
)

Equality.

Parameters
saFirst split to compare
sbSecond split to compare
check_guidsIf TRUE, try a guid_equal() on the GUIDs of both splits if their pointers are not equal in the first place.
check_balancesIf TRUE, compare balances between the two splits. Balances are recalculated whenever a split is added or removed from an account, so YMMV on whether this should be set.
check_txn_splitsIf the pointers are not equal, but everything else so far is equal (including memo, amount, value, kvp_frame), then, when comparing the parenting transactions with xaccTransEqual(), set its argument check_splits to be TRUE.

Definition at line 815 of file Split.c.

819 {
820  gboolean same_book;
821 
822  if (!sa && !sb) return TRUE; /* Arguable. FALSE is better, methinks */
823 
824  if (!sa || !sb)
825  {
826  PINFO ("one is NULL");
827  return FALSE;
828  }
829 
830  if (sa == sb) return TRUE;
831 
832  same_book = qof_instance_get_book(QOF_INSTANCE(sa)) == qof_instance_get_book(QOF_INSTANCE(sb));
833 
834  if (check_guids)
835  {
836  if (qof_instance_guid_compare(sa, sb) != 0)
837  {
838  PINFO ("GUIDs differ");
839  return FALSE;
840  }
841  }
842 
843  /* If the same book, since these strings are cached we can just use pointer equality */
844  if ((same_book && sa->memo != sb->memo) || (!same_book && g_strcmp0(sa->memo, sb->memo) != 0))
845  {
846  PINFO ("memos differ: (%p)%s vs (%p)%s",
847  sa->memo, sa->memo, sb->memo, sb->memo);
848  return FALSE;
849  }
850 
851  if ((same_book && sa->action != sb->action) || (!same_book && g_strcmp0(sa->action, sb->action) != 0))
852  {
853  PINFO ("actions differ: %s vs %s", sa->action, sb->action);
854  return FALSE;
855  }
856 
857  if (kvp_frame_compare(sa->inst.kvp_data, sb->inst.kvp_data) != 0)
858  {
859  char *frame_a;
860  char *frame_b;
861 
862  frame_a = kvp_frame_to_string (sa->inst.kvp_data);
863  frame_b = kvp_frame_to_string (sb->inst.kvp_data);
864 
865  PINFO ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
866 
867  g_free (frame_a);
868  g_free (frame_b);
869 
870  return FALSE;
871  }
872 
873  if (sa->reconciled != sb->reconciled)
874  {
875  PINFO ("reconcile flags differ: %c vs %c", sa->reconciled, sb->reconciled);
876  return FALSE;
877  }
878 
879  if (timespec_cmp(&(sa->date_reconciled), &(sb->date_reconciled)))
880  {
881  PINFO ("reconciled date differs");
882  return FALSE;
883  }
884 
886  {
887  char *str_a;
888  char *str_b;
889 
892 
893  PINFO ("amounts differ: %s vs %s", str_a, str_b);
894 
895  g_free (str_a);
896  g_free (str_b);
897 
898  return FALSE;
899  }
900 
902  {
903  char *str_a;
904  char *str_b;
905 
908 
909  PINFO ("values differ: %s vs %s", str_a, str_b);
910 
911  g_free (str_a);
912  g_free (str_b);
913 
914  return FALSE;
915  }
916 
917  if (check_balances)
918  {
919  if (!xaccSplitEqualCheckBal ("", sa->balance, sb->balance))
920  return FALSE;
921  if (!xaccSplitEqualCheckBal ("cleared ", sa->cleared_balance,
922  sb->cleared_balance))
923  return FALSE;
924  if (!xaccSplitEqualCheckBal ("reconciled ", sa->reconciled_balance,
925  sb->reconciled_balance))
926  return FALSE;
927  }
928 
929  if (!xaccTransEqual(sa->parent, sb->parent, check_guids, check_txn_splits,
930  check_balances, FALSE))
931  {
932  PINFO ("transactions differ");
933  return FALSE;
934  }
935 
936  return TRUE;
937 }
QofBook * qof_instance_get_book(gconstpointer)
#define PINFO(format, args...)
Definition: qoflog.h:249
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
gchar * gnc_numeric_to_string(gnc_numeric n)
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
Definition: Transaction.c:857
gchar * kvp_frame_to_string(const KvpFrame *frame)
gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
Account* xaccSplitGetAccount ( const Split split)

Returns the account of this split, which was set through xaccAccountInsertSplit().

Definition at line 968 of file Split.c.

969 {
970  return s ? s->acc : NULL;
971 }
const char* xaccSplitGetAction ( const Split split)

Returns the action string. Rather than use this function directly, see 'gnc_get_num_action' and 'gnc_get_action_num'in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically

Definition at line 1974 of file Split.c.

1975 {
1976  return split ? split->action : NULL;
1977 }
gnc_numeric xaccSplitGetAmount ( const Split split)

Returns the amount of the split in the account's commodity. Note that for cap-gains splits, this is slaved to the transaction that is causing the gains to occur.

Definition at line 1987 of file Split.c.

1988 {
1989  return split ? split->amount : gnc_numeric_zero();
1990 }
gnc_numeric xaccSplitGetBalance ( const Split split)

Returns the running balance up to and including the indicated split. The balance is the currency-denominated balance. For accounts with non-unit share prices, it is correctly adjusted for share prices.

Returns the running balance up to & including the indicated split.

Definition at line 1323 of file Split.c.

1324 {
1325  return s ? s->balance : gnc_numeric_zero();
1326 }
gnc_numeric xaccSplitGetBaseValue ( const Split split,
const gnc_commodity base_currency 
)

Depending on the base_currency, return either the value or the amount of this split: If the base_curreny is the transaction's commodity, return the value. If it is the account's commodity, return the amount. If it is neither print a warning message and return gnc_numeric_zero().

Definition at line 1396 of file Split.c.

1397 {
1398  if (!s || !s->acc || !s->parent) return gnc_numeric_zero();
1399 
1400  /* be more precise -- the value depends on the currency we want it
1401  * expressed in. */
1402  if (gnc_commodity_equiv(xaccTransGetCurrency(s->parent), base_currency))
1403  return xaccSplitGetValue(s);
1404  if (gnc_commodity_equiv(xaccAccountGetCommodity(s->acc), base_currency))
1405  return xaccSplitGetAmount(s);
1406 
1407  PERR ("inappropriate base currency %s "
1408  "given split currency=%s and commodity=%s\n",
1409  gnc_commodity_get_printname(base_currency),
1412  return gnc_numeric_zero();
1413 }
#define PERR(format, args...)
Definition: qoflog.h:237
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Definition: Account.c:3148
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Definition: Transaction.c:1348
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
QofBook* xaccSplitGetBook ( const Split split)

Returns the book of this split, i.e. the entity where this split is stored.

Definition at line 2042 of file Split.c.

2043 {
2044  return qof_instance_get_book(QOF_INSTANCE(split));
2045 }
QofBook * qof_instance_get_book(gconstpointer)
gnc_numeric xaccSplitGetClearedBalance ( const Split split)

The cleared-balance is the currency-denominated balance of all transactions that have been marked as cleared or reconciled. It is correctly adjusted for price fluctuations.

Returns the running balance up to & including the indicated split.

Definition at line 1329 of file Split.c.

1330 {
1331  return s ? s->cleared_balance : gnc_numeric_zero();
1332 }
const char* xaccSplitGetCorrAccountCode ( const Split sa)

document me

Definition at line 1680 of file Split.c.

1681 {
1682  static const char *split_const = NULL;
1683  const Split *other_split;
1684 
1685  if (!get_corr_account_split(sa, &other_split))
1686  {
1687  if (!split_const)
1688  /* Translators: This string has a disambiguation prefix */
1689  split_const = Q_("Displayed account code of the other account in a multi-split transaction|Split");
1690 
1691  return split_const;
1692  }
1693  return xaccAccountGetCode(other_split->acc);
1694 }
const char * xaccAccountGetCode(const Account *acc)
Definition: Account.c:3086
Definition: SplitP.h:71
char* xaccSplitGetCorrAccountFullName ( const Split sa)

These functions take a split, get the corresponding split on the "other side" of the transaction, and extract either the name or code of that split, reverting to returning a constant "Split" if the transaction has more than one split on the "other side". These were added for the transaction report, and is in C because the code was already written in C for the above functions and duplication is silly.

Definition at line 1664 of file Split.c.

1665 {
1666  static const char *split_const = NULL;
1667  const Split *other_split;
1668 
1669  if (!get_corr_account_split(sa, &other_split))
1670  {
1671  if (!split_const)
1672  split_const = _("-- Split Transaction --");
1673 
1674  return g_strdup(split_const);
1675  }
1676  return gnc_account_get_full_name(other_split->acc);
1677 }
gchar * gnc_account_get_full_name(const Account *account)
Definition: Account.c:3038
Definition: SplitP.h:71
const char* xaccSplitGetCorrAccountName ( const Split sa)

document me

Definition at line 1647 of file Split.c.

1648 {
1649  static const char *split_const = NULL;
1650  const Split *other_split;
1651 
1652  if (!get_corr_account_split(sa, &other_split))
1653  {
1654  if (!split_const)
1655  split_const = _("-- Split Transaction --");
1656 
1657  return split_const;
1658  }
1659 
1660  return xaccAccountGetName(other_split->acc);
1661 }
Definition: SplitP.h:71
const char * xaccAccountGetName(const Account *acc)
Definition: Account.c:3031
time64 xaccSplitGetDateReconciled ( const Split split)

Retrieve the date when the Split was reconciled.

Definition at line 1892 of file Split.c.

1893 {
1894  return split ? split->date_reconciled.tv_sec : 0;
1895 }
void xaccSplitGetDateReconciledTS ( const Split split,
Timespec ts 
)

Get the date on which this split was reconciled by having it written into the Timespec that 'ts' is pointing to.

Definition at line 1877 of file Split.c.

1878 {
1879  if (!split || !ts) return;
1880  *ts = (split->date_reconciled);
1881 }
GNCLot* xaccSplitGetLot ( const Split split)

Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't belong to any.

Definition at line 1953 of file Split.c.

1954 {
1955  return split ? split->lot : NULL;
1956 }
const char* xaccSplitGetMemo ( const Split split)

Returns the memo string.

Definition at line 1968 of file Split.c.

1969 {
1970  return split ? split->memo : NULL;
1971 }
Split* xaccSplitGetOtherSplit ( const Split split)

The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits. If there are more than two splits, it returns NULL.

Definition at line 2086 of file Split.c.

2087 {
2088  int i;
2089  Transaction *trans;
2090  int count, num_splits;
2091  Split *other = NULL;
2092  KvpValue *sva;
2093  gboolean trading_accts;
2094 
2095  if (!split) return NULL;
2096  trans = split->parent;
2097  if (!trans) return NULL;
2098 
2099 #ifdef OLD_ALGO_HAS_ONLY_TWO_SPLITS
2100  Split *s1, *s2;
2101  if (g_list_length (trans->splits) != 2) return NULL;
2102 
2103  s1 = g_list_nth_data (trans->splits, 0);
2104  s2 = g_list_nth_data (trans->splits, 1);
2105 
2106  if (s1 == split) return s2;
2107  return s1;
2108 #endif
2109 
2110  trading_accts = xaccTransUseTradingAccounts (trans);
2111  num_splits = xaccTransCountSplits(trans);
2112  count = num_splits;
2113  sva = kvp_frame_get_slot (split->inst.kvp_data, "lot-split");
2114  if (!sva && !trading_accts && (2 != count)) return NULL;
2115 
2116  for (i = 0; i < num_splits; i++)
2117  {
2118  Split *s = xaccTransGetSplit(trans, i);
2119  if (s == split)
2120  {
2121  --count;
2122  continue;
2123  }
2124  if (kvp_frame_get_slot (s->inst.kvp_data, "lot-split"))
2125  {
2126  --count;
2127  continue;
2128  }
2129  if (trading_accts &&
2131  {
2132  --count;
2133  continue;
2134  }
2135  other = s;
2136  }
2137  return (1 == count) ? other : NULL;
2138 }
Split * xaccTransGetSplit(const Transaction *trans, int i)
Definition: Transaction.c:2144
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Definition: Transaction.c:1015
GNCAccountType xaccAccountGetType(const Account *acc)
Definition: Account.c:3009
int xaccTransCountSplits(const Transaction *trans)
Definition: Transaction.c:2170
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
Transaction* xaccSplitGetParent ( const Split split)

Returns the parent transaction of the split.

Definition at line 1903 of file Split.c.

1904 {
1905  return split ? split->parent : NULL;
1906 }
char xaccSplitGetReconcile ( const Split split)

Returns the value of the reconcile flag.

Definition at line 1980 of file Split.c.

1981 {
1982  return split ? split->reconciled : ' ';
1983 }
gnc_numeric xaccSplitGetReconciledBalance ( const Split split)

Returns the reconciled-balance of this split. The reconciled-balance is the currency-denominated balance of all transactions that have been marked as reconciled.

Returns the running balance up to & including the indicated split.

Definition at line 1335 of file Split.c.

1336 {
1337  return s ? s->reconciled_balance : gnc_numeric_zero();
1338 }
gnc_numeric xaccSplitGetSharePrice ( const Split split)

Returns the price of the split, that is, the value divided by the amount. If the amount is zero, returns a gnc_numeric of value one.

Definition at line 1999 of file Split.c.

2000 {
2001  gnc_numeric amt, val, price;
2002  if (!split) return gnc_numeric_create(1, 1);
2003 
2004 
2005  /* if amount == 0 and value == 0, then return 1.
2006  * if amount == 0 and value != 0 then return 0.
2007  * otherwise return value/amount
2008  */
2009 
2010  amt = xaccSplitGetAmount(split);
2011  val = xaccSplitGetValue(split);
2012  if (gnc_numeric_zero_p(amt))
2013  {
2014  if (gnc_numeric_zero_p(val))
2015  return gnc_numeric_create(1, 1);
2016  return gnc_numeric_create(0, 1);
2017  }
2018  price = gnc_numeric_div(val, amt,
2020  GNC_HOW_DENOM_SIGFIGS(PRICE_SIGFIGS) |
2022 
2023  /* During random checks we can get some very weird prices. Let's
2024  * handle some overflow and other error conditions by returning
2025  * zero. But still print an error to let us know it happened.
2026  */
2027  if (gnc_numeric_check(price))
2028  {
2029  PERR("Computing share price failed (%d): [ %" G_GINT64_FORMAT " / %"
2030  G_GINT64_FORMAT " ] / [ %" G_GINT64_FORMAT " / %" G_GINT64_FORMAT " ]",
2031  gnc_numeric_check(price), val.num, val.denom, amt.num, amt.denom);
2032  return gnc_numeric_create(0, 1);
2033  }
2034 
2035  return price;
2036 }
gboolean gnc_numeric_zero_p(gnc_numeric a)
#define PERR(format, args...)
Definition: qoflog.h:237
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
#define GNC_HOW_DENOM_SIGFIGS(n)
Definition: gnc-numeric.h:218
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
const char* xaccSplitGetType ( const Split s)

The xaccIsPeerSplit() is a convenience routine that returns TRUE (a non-zero value) if the two splits share a common parent transaction, else it returns FALSE (zero).

gboolean xaccIsPeerSplit (const Split *split_1, const Split *split_2); Returns the split type, which is either the string "normal", or "stock-split" for a split from a stock split (pun intended? :-).

Definition at line 2048 of file Split.c.

2049 {
2050  const char *split_type;
2051 
2052  if (!s) return NULL;
2053  split_type = kvp_frame_get_string(s->inst.kvp_data, "split-type");
2054  return split_type ? split_type : "normal";
2055 }
gnc_numeric xaccSplitGetValue ( const Split split)

Returns the value of this split in the transaction's commodity. Note that for cap-gains splits, this is slaved to the transaction that is causing the gains to occur.

Definition at line 1993 of file Split.c.

1994 {
1995  return split ? split->value : gnc_numeric_zero();
1996 }
Split* xaccSplitLookup ( const GncGUID guid,
QofBook book 
)

The xaccSplitLookup() subroutine will return the split associated with the given id, or NULL if there is no such split.

Definition at line 1104 of file Split.c.

1105 {
1106  QofCollection *col;
1107  if (!guid || !book) return NULL;
1108  col = qof_book_get_collection (book, GNC_ID_SPLIT);
1109  return (Split *) qof_collection_lookup_entity (col, guid);
1110 }
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
Definition: SplitP.h:71
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
void xaccSplitMakeStockSplit ( Split s)

Mark a split to be of type stock split - after this, you shouldn't modify the value anymore, just the amount.

Definition at line 2060 of file Split.c.

2061 {
2062  xaccTransBeginEdit (s->parent);
2063 
2064  s->value = gnc_numeric_zero();
2065  kvp_frame_set_string(s->inst.kvp_data, "split-type", "stock-split");
2066  SET_GAINS_VDIRTY(s);
2067  mark_split(s);
2068  qof_instance_set_dirty(QOF_INSTANCE(s));
2069  xaccTransCommitEdit(s->parent);
2070 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
gint xaccSplitOrder ( const Split sa,
const Split sb 
)

The xaccSplitOrder(sa,sb) method is useful for sorting. if sa and sb have different transactions, return their xaccTransOrder return a negative value if split sa has a smaller currency-value than sb, return a positive value if split sa has a larger currency-value than sb, return a negative value if split sa has a smaller share-price than sb, return a positive value if split sa has a larger share-price than sb, then compares memo and action using the strcmp() c-library routine, returning what strcmp would return. Then it compares the reconciled flags, then the reconciled dates, Finally, it returns zero if all of the above match.

Definition at line 1521 of file Split.c.

1522 {
1523  int retval;
1524  int comp;
1525  char *da, *db;
1526  gboolean action_for_num;
1527 
1528  if (sa == sb) return 0;
1529  /* nothing is always less than something */
1530  if (!sa) return -1;
1531  if (!sb) return +1;
1532 
1533  /* sort in transaction order, but use split action rather than trans num
1534  * according to book option */
1536  (xaccSplitGetBook (sa));
1537  if (action_for_num)
1538  retval = xaccTransOrder_num_action (sa->parent, sa->action,
1539  sb->parent, sb->action);
1540  else
1541  retval = xaccTransOrder (sa->parent, sb->parent);
1542  if (retval) return retval;
1543 
1544  /* otherwise, sort on memo strings */
1545  da = sa->memo ? sa->memo : "";
1546  db = sb->memo ? sb->memo : "";
1547  retval = g_utf8_collate (da, db);
1548  if (retval)
1549  return retval;
1550 
1551  /* otherwise, sort on action strings */
1552  da = sa->action ? sa->action : "";
1553  db = sb->action ? sb->action : "";
1554  retval = g_utf8_collate (da, db);
1555  if (retval != 0)
1556  return retval;
1557 
1558  /* the reconciled flag ... */
1559  if (sa->reconciled < sb->reconciled) return -1;
1560  if (sa->reconciled > sb->reconciled) return +1;
1561 
1562  /* compare amounts */
1564  if (comp < 0) return -1;
1565  if (comp > 0) return +1;
1566 
1568  if (comp < 0) return -1;
1569  if (comp > 0) return +1;
1570 
1571  /* if dates differ, return */
1572  DATE_CMP(sa, sb, date_reconciled);
1573 
1574  /* else, sort on guid - keeps sort stable. */
1575  retval = qof_instance_guid_compare(sa, sb);
1576  if (retval) return retval;
1577 
1578  return 0;
1579 }
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
QofBook * xaccSplitGetBook(const Split *split)
Definition: Split.c:2042
int xaccTransOrder_num_action(const Transaction *ta, const char *actna, const Transaction *tb, const char *actnb)
Definition: Transaction.c:1833
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
int xaccTransOrder(const Transaction *ta, const Transaction *tb)
Definition: Transaction.c:1827
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
Timespec xaccSplitRetDateReconciledTS ( const Split split)

Returns the date (as Timespec) on which this split was reconciled.

Definition at line 1884 of file Split.c.

1885 {
1886  Timespec ts = {0, 0};
1887  return split ? split->date_reconciled : ts;
1888 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void xaccSplitSetAction ( Split split,
const char *  action 
)

The Action is an arbitrary user-assigned string. The action field is an arbitrary user-assigned value. It is meant to be a very short (one to ten character) string that signifies the "type" of this split, such as e.g. Buy, Sell, Div, Withdraw, Deposit, ATM, Check, etc. The idea is that this field can be used to create custom reports or graphs of data. Rather than use this function directly, see 'gnc_set_num_action' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically

Definition at line 1793 of file Split.c.

1794 {
1795  if (!split || !actn) return;
1796  xaccTransBeginEdit (split->parent);
1797 
1798  CACHE_REPLACE(split->action, actn);
1799  qof_instance_set_dirty(QOF_INSTANCE(split));
1800  xaccTransCommitEdit(split->parent);
1801 
1802 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccSplitSetAmount ( Split split,
gnc_numeric  amount 
)

The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have.

The following four setter functions set the prices and amounts. All of the routines always maintain balance: that is, invoking any of them will cause other splits in the transaction to be modified so that the net value of the transaction is zero.

IMPORTANT: The split should be parented by an account before any of these routines are invoked! This is because the actual setting of amounts/values requires SCU settings from the account. If these are not available, then amounts/values will be set to -1/0, which is an invalid value. I believe this order dependency is a bug, but I'm too lazy to find, fix & test at the moment ...

Note
If you use this on a newly created transaction, make sure that the 'value' is also set so that it doesn't remain zero.

Definition at line 1258 of file Split.c.

1259 {
1260  if (!s) return;
1261  g_return_if_fail(gnc_numeric_check(amt) == GNC_ERROR_OK);
1262  ENTER ("(split=%p) old amt=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT
1263  " new amt=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, s,
1264  s->amount.num, s->amount.denom, amt.num, amt.denom);
1265 
1266  xaccTransBeginEdit (s->parent);
1267  if (s->acc)
1268  {
1269  s->amount = gnc_numeric_convert(amt, get_commodity_denom(s),
1271  g_assert (gnc_numeric_check (s->amount) == GNC_ERROR_OK);
1272  }
1273  else
1274  s->amount = amt;
1275 
1276  SET_GAINS_ADIRTY(s);
1277  mark_split (s);
1278  qof_instance_set_dirty(QOF_INSTANCE(s));
1279  xaccTransCommitEdit(s->parent);
1280  LEAVE("");
1281 }
#define ENTER(format, args...)
Definition: qoflog.h:261
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define LEAVE(format, args...)
Definition: qoflog.h:271
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
void xaccSplitSetBaseValue ( Split split,
gnc_numeric  value,
const gnc_commodity base_currency 
)

Depending on the base_currency, set either the value or the amount of this split or both: If the base_currency is the transaction's commodity, set the value. If it is the account's commodity, set the amount. If both, set both.

Note
WATCH OUT: When using this function and the transaction's and account's commodities are different, the amount or the value will be left as zero. This might screw up the multi-currency handling code in the register. So please think twice whether you need this function – using xaccSplitSetValue() together with xaccSplitSetAmount() is definitely the better and safer solution!

Definition at line 1341 of file Split.c.

1343 {
1344  const gnc_commodity *currency;
1345  const gnc_commodity *commodity;
1346 
1347  if (!s) return;
1348  xaccTransBeginEdit (s->parent);
1349 
1350  if (!s->acc)
1351  {
1352  PERR ("split must have a parent account");
1353  return;
1354  }
1355 
1356  currency = xaccTransGetCurrency (s->parent);
1357  commodity = xaccAccountGetCommodity (s->acc);
1358 
1359  /* If the base_currency is the transaction's commodity ('currency'),
1360  * set the value. If it's the account commodity, set the
1361  * amount. If both, set both. */
1362  if (gnc_commodity_equiv(currency, base_currency))
1363  {
1364  if (gnc_commodity_equiv(commodity, base_currency))
1365  {
1366  s->amount = gnc_numeric_convert(value,
1367  get_commodity_denom(s),
1369  }
1370  s->value = gnc_numeric_convert(value,
1371  get_currency_denom(s),
1373  }
1374  else if (gnc_commodity_equiv(commodity, base_currency))
1375  {
1376  s->amount = gnc_numeric_convert(value, get_commodity_denom(s),
1378  }
1379  else
1380  {
1381  PERR ("inappropriate base currency %s "
1382  "given split currency=%s and commodity=%s\n",
1383  gnc_commodity_get_printname(base_currency),
1384  gnc_commodity_get_printname(currency),
1385  gnc_commodity_get_printname(commodity));
1386  return;
1387  }
1388 
1389  SET_GAINS_A_VDIRTY(s);
1390  mark_split (s);
1391  qof_instance_set_dirty(QOF_INSTANCE(s));
1392  xaccTransCommitEdit(s->parent);
1393 }
#define PERR(format, args...)
Definition: qoflog.h:237
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Definition: Account.c:3148
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Definition: Transaction.c:1348
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
void xaccSplitSetDateReconciledSecs ( Split split,
time64  time 
)

Set the date on which this split was reconciled by specifying the time as time64.

Definition at line 1852 of file Split.c.

1853 {
1854  if (!split) return;
1855  xaccTransBeginEdit (split->parent);
1856 
1857  split->date_reconciled.tv_sec = secs;
1858  split->date_reconciled.tv_nsec = 0;
1859  qof_instance_set_dirty(QOF_INSTANCE(split));
1860  xaccTransCommitEdit(split->parent);
1861 
1862 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccSplitSetDateReconciledTS ( Split split,
Timespec ts 
)

Set the date on which this split was reconciled by specifying the time as Timespec. Caller still owns *ts!

Definition at line 1865 of file Split.c.

1866 {
1867  if (!split || !ts) return;
1868  xaccTransBeginEdit (split->parent);
1869 
1870  split->date_reconciled = *ts;
1871  qof_instance_set_dirty(QOF_INSTANCE(split));
1872  xaccTransCommitEdit(split->parent);
1873 
1874 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccSplitSetLot ( Split split,
GNCLot lot 
)

Assigns the split to a specific Lot

Definition at line 1959 of file Split.c.

1960 {
1961  xaccTransBeginEdit (split->parent);
1962  split->lot = lot;
1963  qof_instance_set_dirty(QOF_INSTANCE(split));
1964  xaccTransCommitEdit(split->parent);
1965 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccSplitSetMemo ( Split split,
const char *  memo 
)

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 in free form text from the GUI.

Definition at line 1774 of file Split.c.

1775 {
1776  if (!split || !memo) return;
1777  xaccTransBeginEdit (split->parent);
1778 
1779  CACHE_REPLACE(split->memo, memo);
1780  qof_instance_set_dirty(QOF_INSTANCE(split));
1781  xaccTransCommitEdit(split->parent);
1782 
1783 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccSplitSetReconcile ( Split split,
char  reconciled_flag 
)

Set the reconcile flag. The Reconcile flag is a single char, whose values are typically are 'n', 'y', 'c'. In Transaction.h, macros are defined for typical values (e.g. CREC, YREC).

Definition at line 1826 of file Split.c.

1827 {
1828  if (!split || split->reconciled == recn) return;
1829  xaccTransBeginEdit (split->parent);
1830 
1831  switch (recn)
1832  {
1833  case NREC:
1834  case CREC:
1835  case YREC:
1836  case FREC:
1837  case VREC:
1838  split->reconciled = recn;
1839  mark_split (split);
1840  qof_instance_set_dirty(QOF_INSTANCE(split));
1841  xaccAccountRecomputeBalance (split->acc);
1842  break;
1843  default:
1844  PERR("Bad reconciled flag");
1845  break;
1846  }
1847  xaccTransCommitEdit(split->parent);
1848 
1849 }
#define PERR(format, args...)
Definition: qoflog.h:237
#define VREC
Definition: Split.h:71
#define YREC
Definition: Split.h:68
#define FREC
Definition: Split.h:69
void xaccAccountRecomputeBalance(Account *acc)
Definition: Account.c:2058
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define CREC
Definition: Split.h:67
#define NREC
Definition: Split.h:70
void xaccSplitSetSharePrice ( Split split,
gnc_numeric  price 
)
Deprecated:
The xaccSplitSetSharePrice() method sets the price of the split. DEPRECATED - set the value and amount instead.

Definition at line 1224 of file Split.c.

1225 {
1226  if (!s) return;
1227  ENTER (" ");
1228  xaccTransBeginEdit (s->parent);
1229 
1230  s->value = gnc_numeric_mul(xaccSplitGetAmount(s),
1231  price, get_currency_denom(s),
1233 
1234  SET_GAINS_VDIRTY(s);
1235  mark_split (s);
1236  qof_instance_set_dirty(QOF_INSTANCE(s));
1237  xaccTransCommitEdit(s->parent);
1238  LEAVE ("");
1239 }
#define ENTER(format, args...)
Definition: qoflog.h:261
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define LEAVE(format, args...)
Definition: qoflog.h:271
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
void xaccSplitSetSharePriceAndAmount ( Split split,
gnc_numeric  price,
gnc_numeric  amount 
)

The xaccSplitSetSharePriceAndAmount() method will simultaneously update the share price and the number of shares. This is a utility routine that is equivalent to a xaccSplitSetSharePrice() followed by and xaccSplitSetAmount(), except that it incurs the processing overhead of balancing only once, instead of twice.

Definition at line 1196 of file Split.c.

1197 {
1198  if (!s) return;
1199  ENTER (" ");
1200  xaccTransBeginEdit (s->parent);
1201 
1202  s->amount = gnc_numeric_convert(amt, get_commodity_denom(s),
1204  s->value = gnc_numeric_mul(s->amount, price,
1205  get_currency_denom(s), GNC_HOW_RND_ROUND_HALF_UP);
1206 
1207  SET_GAINS_A_VDIRTY(s);
1208  mark_split (s);
1209  qof_instance_set_dirty(QOF_INSTANCE(s));
1210  xaccTransCommitEdit(s->parent);
1211  LEAVE ("");
1212 }
#define ENTER(format, args...)
Definition: qoflog.h:261
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define LEAVE(format, args...)
Definition: qoflog.h:271
void xaccSplitSetValue ( Split split,
gnc_numeric  value 
)

The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.

Note
If you use this on a newly created transaction, make sure that the 'amount' is also set so that it doesn't remain zero.

Definition at line 1294 of file Split.c.

1295 {
1296  gnc_numeric new_val;
1297  if (!s) return;
1298 
1299  g_return_if_fail(gnc_numeric_check(amt) == GNC_ERROR_OK);
1300  ENTER ("(split=%p) old val=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT
1301  " new val=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, s,
1302  s->value.num, s->value.denom, amt.num, amt.denom);
1303 
1304  xaccTransBeginEdit (s->parent);
1305  new_val = gnc_numeric_convert(amt, get_currency_denom(s),
1307  if (gnc_numeric_check(new_val) == GNC_ERROR_OK &&
1308  !(gnc_numeric_zero_p (new_val) && !gnc_numeric_zero_p (amt)))
1309  s->value = new_val;
1310  else PERR("numeric error %s in converting the split value's denominator with amount %s and denom %d", gnc_numeric_errorCode_to_string(gnc_numeric_check(new_val)), gnc_numeric_to_string(amt), get_currency_denom(s));
1311 
1312  SET_GAINS_VDIRTY(s);
1313  mark_split (s);
1314  qof_instance_set_dirty(QOF_INSTANCE(s));
1315  xaccTransCommitEdit(s->parent);
1316  LEAVE ("");
1317 }
gboolean gnc_numeric_zero_p(gnc_numeric a)
gchar * gnc_numeric_to_string(gnc_numeric n)
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
const char * gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define LEAVE(format, args...)
Definition: qoflog.h:271
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
gnc_numeric xaccSplitVoidFormerAmount ( const Split split)

Returns the original pre-void amount of a split.

Parameters
splitThe split in question.
Returns
A gnc_numeric containing the original value of this split. Returns a gnc_numeric of zero upon error.

Definition at line 2144 of file Split.c.

2145 {
2146  g_return_val_if_fail(split, gnc_numeric_zero());
2147  return kvp_frame_get_numeric(split->inst.kvp_data, void_former_amt_str);
2148 }
gnc_numeric xaccSplitVoidFormerValue ( const Split split)

Returns the original pre-void value of a split.

Parameters
splitThe split in question.
Returns
A gnc_numeric containing the original amount of this split. Returns a gnc_numeric of zero upon error.

Definition at line 2151 of file Split.c.

2152 {
2153  g_return_val_if_fail(split, gnc_numeric_zero());
2154  return kvp_frame_get_numeric(split->inst.kvp_data, void_former_val_str);
2155 }
void xaccTransBeginEdit ( Transaction trans)

The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of its component splits. If this is not done, errors will result.

Definition at line 1380 of file Transaction.c.

1381 {
1382  if (!trans) return;
1383  if (!qof_begin_edit(&trans->inst)) return;
1384 
1385  if (qof_book_shutting_down(qof_instance_get_book(trans))) return;
1386 
1388  {
1389  xaccOpenLog ();
1390  xaccTransWriteLog (trans, 'B');
1391  }
1392 
1393  /* Make a clone of the transaction; we will use this
1394  * in case we need to roll-back the edit. */
1395  trans->orig = dupe_trans (trans);
1396 }
QofBook * qof_instance_get_book(gconstpointer)
void xaccTransWriteLog(Transaction *trans, char flag)
Definition: TransLog.c:221
gboolean qof_begin_edit(QofInstance *inst)
gboolean qof_book_is_readonly(const QofBook *book)
gboolean qof_book_shutting_down(const QofBook *book)
Transaction* xaccTransClone ( const Transaction t)

The xaccTransClone() method will create a complete copy of an existing transaction.

Definition at line 679 of file Transaction.c.

680 {
681  Transaction *to = xaccTransCloneNoKvp (from);
682  int i = 0;
683  int length = g_list_length (from->splits);
684 
685  xaccTransBeginEdit (to);
686  to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data);
687  g_assert (g_list_length (to->splits) == length);
688  for (i = 0; i < length; ++i)
689  xaccSplitCopyKvp (g_list_nth_data (from->splits, i),
690  g_list_nth_data (to->splits, i));
691  xaccTransCommitEdit (to);
692  return to;
693 }
KvpFrame * kvp_frame_copy(const KvpFrame *frame)
Transaction * xaccTransCloneNoKvp(const Transaction *from)
Definition: Transaction.c:642
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
Transaction* xaccTransCloneNoKvp ( const Transaction t)

The xaccTransCloneNoKvp() method will create a complete copy of an existing transaction except that the KVP slots will be empty.

Definition at line 642 of file Transaction.c.

643 {
644  Transaction *to;
645  Split *split;
646  GList *node;
647 
649  to = g_object_new (GNC_TYPE_TRANSACTION, NULL);
650 
651  to->date_entered = from->date_entered;
652  to->date_posted = from->date_posted;
653  to->num = CACHE_INSERT (from->num);
654  to->description = CACHE_INSERT (from->description);
655  to->common_currency = from->common_currency;
656  qof_instance_copy_version(to, from);
657  qof_instance_copy_version_check(to, from);
658 
659  to->orig = NULL;
660 
661  qof_instance_init_data (&to->inst, GNC_ID_TRANS,
662  qof_instance_get_book(from));
663 
664  xaccTransBeginEdit(to);
665  for (node = from->splits; node; node = node->next)
666  {
667  split = xaccSplitCloneNoKvp(node->data);
668  split->parent = to;
669  to->splits = g_list_append (to->splits, split);
670  }
671  qof_instance_set_dirty(QOF_INSTANCE(to));
674 
675  return to;
676 }
QofBook * qof_instance_get_book(gconstpointer)
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
Definition: SplitP.h:71
void qof_event_suspend(void)
Suspend all engine events.
void qof_event_resume(void)
void xaccTransCommitEdit ( Transaction trans)

The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are complete and should be made permanent. Note this routine may result in the deletion of the transaction, if the transaction is "empty" (has no splits), or of xaccTransDestroy() was called on the transaction.

Definition at line 1579 of file Transaction.c.

1580 {
1581  if (!trans) return;
1582  ENTER ("(trans=%p)", trans);
1583 
1584  if (!qof_commit_edit (QOF_INSTANCE(trans)))
1585  {
1586  LEAVE("editlevel non-zero");
1587  return;
1588  }
1589 
1590  /* We increment this for the duration of the call
1591  * so other functions don't result in a recursive
1592  * call to xaccTransCommitEdit. */
1593  qof_instance_increase_editlevel(trans);
1594 
1595  if (was_trans_emptied(trans))
1596  qof_instance_set_destroying(trans, TRUE);
1597 
1598  /* Before committing the transaction, we are going to enforce certain
1599  * constraints. In particular, we want to enforce the cap-gains
1600  * and the balanced lot constraints. These constraints might
1601  * change the number of splits in this transaction, and the
1602  * transaction itself might be deleted. This is also why
1603  * we can't really enforce these constraints elsewhere: they
1604  * can cause pointers to splits and transactions to disappear out
1605  * from under the holder.
1606  */
1607  if (!qof_instance_get_destroying(trans) && scrub_data &&
1609  {
1610  /* If scrubbing gains recurses through here, don't call it again. */
1611  scrub_data = 0;
1612  /* The total value of the transaction should sum to zero.
1613  * Call the trans scrub routine to fix it. Indirectly, this
1614  * routine also performs a number of other transaction fixes too.
1615  */
1616  xaccTransScrubImbalance (trans, NULL, NULL);
1617  /* Get the cap gains into a consistent state as well. */
1618 
1619  /* Lot Scrubbing is temporarily disabled. */
1620  if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
1621  xaccTransScrubGains (trans, NULL);
1622 
1623  /* Allow scrubbing in transaction commit again */
1624  scrub_data = 1;
1625  }
1626 
1627  /* Record the time of last modification */
1628  if (0 == trans->date_entered.tv_sec)
1629  {
1630  struct timeval tv;
1631 #ifdef HAVE_GETTIMEOFDAY
1632  gettimeofday (&tv, NULL);
1633 #else
1634  time (&(tv.tv_sec));
1635  tv.tv_usec = 0;
1636 #endif
1637  trans->date_entered.tv_sec = tv.tv_sec;
1638 // trans->date_entered.tv_nsec = 1000 * tv.tv_usec;
1639  qof_instance_set_dirty(QOF_INSTANCE(trans));
1640  }
1641 
1642  qof_commit_edit_part2(QOF_INSTANCE(trans),
1643  (void (*) (QofInstance *, QofBackendError))
1644  trans_on_error,
1645  (void (*) (QofInstance *)) trans_cleanup_commit,
1646  (void (*) (QofInstance *)) do_destroy);
1647  LEAVE ("(trans=%p)", trans);
1648 }
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
gboolean qof_instance_get_destroying(gconstpointer ptr)
gboolean qof_commit_edit(QofInstance *inst)
#define ENTER(format, args...)
Definition: qoflog.h:261
void xaccTransScrubImbalance(Transaction *trans, Account *root, Account *account)
Definition: Scrub.c:521
void xaccTransScrubGains(Transaction *trans, Account *gain_acc)
Definition: Transaction.c:2678
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
#define xaccTransGetBook(X)
Definition: Transaction.h:753
#define LEAVE(format, args...)
Definition: qoflog.h:271
gboolean qof_book_shutting_down(const QofBook *book)
void xaccTransCopyFromClipBoard ( const Transaction from_trans,
Transaction to_trans,
const Account from_acc,
Account to_acc,
gboolean  no_date 
)

This function explicitly must robustly handle some unusual input.

'from_trans' may be a duped trans (see xaccDupeTransaction), so its splits may not really belong to the accounts that they say they do.

'from_acc' need not be a valid account. It may be an already freed Account. Therefore, it must not be dereferenced at all.

Neither 'from_trans', nor 'from_acc', nor any of 'from's splits may be modified in any way.

'no_date' if TRUE will not copy the date posted.

The 'to_trans' transaction will end up with valid copies of from's splits. In addition, the copies of any of from's splits that were in from_acc (or at least claimed to be) will end up in to_acc.

Definition at line 742 of file Transaction.c.

744 {
745  Timespec ts = {0,0};
746  gboolean change_accounts = FALSE;
747  GList *node;
748 
749  if (!from_trans || !to_trans)
750  return;
751 
752  change_accounts = from_acc && GNC_IS_ACCOUNT(to_acc) && from_acc != to_acc;
753  xaccTransBeginEdit(to_trans);
754 
755  FOR_EACH_SPLIT(to_trans, xaccSplitDestroy(s));
756 
757  xaccTransSetCurrency(to_trans, xaccTransGetCurrency(from_trans));
758  xaccTransSetDescription(to_trans, xaccTransGetDescription(from_trans));
759 
760  if ((xaccTransGetNum(to_trans) == NULL) || (g_strcmp0 (xaccTransGetNum(to_trans), "") == 0))
761  xaccTransSetNum(to_trans, xaccTransGetNum(from_trans));
762 
763  xaccTransSetNotes(to_trans, xaccTransGetNotes(from_trans));
764  if(!no_date)
765  {
766  xaccTransGetDatePostedTS(from_trans, &ts);
767  xaccTransSetDatePostedTS(to_trans, &ts);
768  }
769 
770  /* Each new split will be parented to 'to' */
771  for (node = from_trans->splits; node; node = node->next)
772  {
773  Split *new_split = xaccMallocSplit( qof_instance_get_book(QOF_INSTANCE(from_trans)));
774  xaccSplitCopyOnto(node->data, new_split);
775  if (change_accounts && xaccSplitGetAccount(node->data) == from_acc)
776  xaccSplitSetAccount(new_split, to_acc);
777  xaccSplitSetParent(new_split, to_trans);
778  }
779  xaccTransCommitEdit(to_trans);
780 }
QofBook * qof_instance_get_book(gconstpointer)
gboolean xaccSplitDestroy(Split *split)
Definition: Split.c:1492
void xaccTransSetNotes(Transaction *trans, const char *notes)
Definition: Transaction.c:2115
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
Definition: Split.c:686
void xaccTransSetDescription(Transaction *trans, const char *desc)
Definition: Transaction.c:2085
void xaccTransSetNum(Transaction *trans, const char *xnum)
Definition: Transaction.c:2065
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
const char * xaccTransGetNum(const Transaction *trans)
Definition: Transaction.c:2178
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Definition: Transaction.c:1354
const char * xaccTransGetNotes(const Transaction *trans)
Definition: Transaction.c:2197
const char * xaccTransGetDescription(const Transaction *trans)
Definition: Transaction.c:2184
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Definition: Transaction.c:1348
void xaccTransGetDatePostedTS(const Transaction *trans, Timespec *ts)
Definition: Transaction.c:2229
void xaccTransSetDatePostedTS(Transaction *trans, const Timespec *ts)
Definition: Transaction.c:1970
void xaccTransCopyOnto ( const Transaction from_trans,
Transaction to_trans 
)

Copy a transaction to another using the function below without changing any account information.

Definition at line 718 of file Transaction.c.

719 {
720  xaccTransCopyFromClipBoard(from_trans, to_trans, NULL, NULL, TRUE);
721 }
void xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans, const Account *from_acc, Account *to_acc, gboolean no_date)
Definition: Transaction.c:742
Transaction* xaccTransCopyToClipBoard ( const Transaction from_trans)

Copy a transaction to the 'clipboard' transaction using dupe_transaction. The 'clipboard' transaction must never be dereferenced.

Definition at line 702 of file Transaction.c.

703 {
704  Transaction *to_trans;
705 
706  if (!from_trans)
707  return NULL;
708 
709  to_trans = dupe_trans(from_trans);
710  return to_trans;
711 }
int xaccTransCountSplits ( const Transaction trans)

Returns the number of splits in this transaction.

Definition at line 2170 of file Transaction.c.

2171 {
2172  gint i = 0;
2173  FOR_EACH_SPLIT(trans, i++);
2174  return i;
2175 }
void xaccTransDestroy ( Transaction trans)

Destroys a transaction. Each split in transaction trans is removed from its account and destroyed as well.

If the transaction has not already been opened for editing with xaccTransBeginEdit() then the changes are committed immediately. Otherwise, the caller must follow up with either xaccTransCommitEdit(), in which case the transaction and split memory will be freed, or xaccTransRollbackEdit(), in which case nothing at all is freed, and everything is put back into original order.

Parameters
transthe transaction to destroy

Definition at line 1402 of file Transaction.c.

1403 {
1404  if (!trans) return;
1405 
1406  if (!xaccTransGetReadOnly (trans) ||
1408  {
1409  xaccTransBeginEdit(trans);
1410  qof_instance_set_destroying(trans, TRUE);
1411  xaccTransCommitEdit(trans);
1412  }
1413 }
QofBook * qof_instance_get_book(gconstpointer)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
const char * xaccTransGetReadOnly(const Transaction *trans)
Definition: Transaction.c:2313
gboolean qof_book_shutting_down(const QofBook *book)
gboolean xaccTransEqual ( const Transaction ta,
const Transaction tb,
gboolean  check_guids,
gboolean  check_splits,
gboolean  check_balances,
gboolean  assume_ordered 
)

Equality.

Parameters
taFirst transaction to compare
tbSecond transaction to compare
check_guidsIf TRUE, try a guid_equal() on the GUIDs of both transactions if their pointers are not equal in the first place. Also passed to subsidiary calls to xaccSplitEqual.
check_splitsIf TRUE, after checking the transaction data structures for equality, also check all splits attached to the transation for equality.
check_balancesIf TRUE, when checking splits also compare balances between the two splits. Balances are recalculated whenever a split is added or removed from an account, so YMMV on whether this should be set.
assume_orderedIf TRUE, assume that the splits in each transaction appear in the same order. This saves some time looking up splits by GncGUID, and is required for checking duplicated transactions because all the splits have new GUIDs.

Definition at line 857 of file Transaction.c.

862 {
863  gboolean same_book;
864 
865  if (!ta && !tb) return TRUE; /* Arguable. FALSE may be better. */
866 
867  if (!ta || !tb)
868  {
869  PINFO ("one is NULL");
870  return FALSE;
871  }
872 
873  if (ta == tb) return TRUE;
874 
875  same_book = qof_instance_get_book(QOF_INSTANCE(ta)) == qof_instance_get_book(QOF_INSTANCE(tb));
876 
877  if (check_guids)
878  {
879  if (qof_instance_guid_compare(ta, tb) != 0)
880  {
881  PINFO ("GUIDs differ");
882  return FALSE;
883  }
884  }
885 
886  if (!gnc_commodity_equal(ta->common_currency, tb->common_currency))
887  {
888  PINFO ("commodities differ %s vs %s",
889  gnc_commodity_get_unique_name (ta->common_currency),
890  gnc_commodity_get_unique_name (tb->common_currency));
891  return FALSE;
892  }
893 
894  if (timespec_cmp(&(ta->date_entered), &(tb->date_entered)))
895  {
896  char buf1[100];
897  char buf2[100];
898 
899  (void)gnc_timespec_to_iso8601_buff(ta->date_entered, buf1);
900  (void)gnc_timespec_to_iso8601_buff(tb->date_entered, buf2);
901  PINFO ("date entered differs: '%s' vs '%s'", buf1, buf2);
902  return FALSE;
903  }
904 
905  if (timespec_cmp(&(ta->date_posted), &(tb->date_posted)))
906  {
907  char buf1[100];
908  char buf2[100];
909 
910  (void)gnc_timespec_to_iso8601_buff(ta->date_posted, buf1);
911  (void)gnc_timespec_to_iso8601_buff(tb->date_posted, buf2);
912  PINFO ("date posted differs: '%s' vs '%s'", buf1, buf2);
913  return FALSE;
914  }
915 
916  /* If the same book, since we use cached strings, we can just compare pointer
917  * equality for num and description
918  */
919  if ((same_book && ta->num != tb->num) || (!same_book && g_strcmp0(ta->num, tb->num) != 0))
920  {
921  PINFO ("num differs: %s vs %s", ta->num, tb->num);
922  return FALSE;
923  }
924 
925  if ((same_book && ta->description != tb->description)
926  || (!same_book && g_strcmp0(ta->description, tb->description)))
927  {
928  PINFO ("descriptions differ: %s vs %s", ta->description, tb->description);
929  return FALSE;
930  }
931 
932  if (kvp_frame_compare(ta->inst.kvp_data, tb->inst.kvp_data) != 0)
933  {
934  char *frame_a;
935  char *frame_b;
936 
937  frame_a = kvp_frame_to_string (ta->inst.kvp_data);
938  frame_b = kvp_frame_to_string (tb->inst.kvp_data);
939 
940  PINFO ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
941 
942  g_free (frame_a);
943  g_free (frame_b);
944 
945  return FALSE;
946  }
947 
948  if (check_splits)
949  {
950  if ((!ta->splits && tb->splits) || (!tb->splits && ta->splits))
951  {
952  PINFO ("only one has splits");
953  return FALSE;
954  }
955 
956  if (ta->splits && tb->splits)
957  {
958  GList *node_a, *node_b;
959 
960  for (node_a = ta->splits, node_b = tb->splits;
961  node_a;
962  node_a = node_a->next, node_b = node_b->next)
963  {
964  Split *split_a = node_a->data;
965  Split *split_b;
966 
967  /* don't presume that the splits are in the same order */
968  if (!assume_ordered)
969  node_b = g_list_find_custom (tb->splits, split_a,
970  compare_split_guids);
971 
972  if (!node_b)
973  {
974  gchar guidstr[GUID_ENCODING_LENGTH+1];
975  guid_to_string_buff (xaccSplitGetGUID (split_a),guidstr);
976 
977  PINFO ("first has split %s and second does not",guidstr);
978  return FALSE;
979  }
980 
981  split_b = node_b->data;
982 
983  if (!xaccSplitEqual (split_a, split_b, check_guids, check_balances,
984  FALSE))
985  {
986  char str_a[GUID_ENCODING_LENGTH + 1];
987  char str_b[GUID_ENCODING_LENGTH + 1];
988 
989  guid_to_string_buff (xaccSplitGetGUID (split_a), str_a);
990  guid_to_string_buff (xaccSplitGetGUID (split_b), str_b);
991 
992  PINFO ("splits %s and %s differ", str_a, str_b);
993  return FALSE;
994  }
995  }
996 
997  if (g_list_length (ta->splits) != g_list_length (tb->splits))
998  {
999  PINFO ("different number of splits");
1000  return FALSE;
1001  }
1002  }
1003  }
1004 
1005  return TRUE;
1006 }
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
QofBook * qof_instance_get_book(gconstpointer)
#define PINFO(format, args...)
Definition: qoflog.h:249
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gboolean xaccSplitEqual(const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits)
Definition: Split.c:815
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
#define xaccSplitGetGUID(X)
Definition: Split.h:521
gchar * kvp_frame_to_string(const KvpFrame *frame)
Definition: SplitP.h:71
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
gnc_numeric xaccTransGetAccountAmount ( const Transaction trans,
const Account account 
)

Same as xaccTransGetAccountValue, but uses the Account's commodity.

Definition at line 1186 of file Transaction.c.

1187 {
1188  gnc_numeric total = gnc_numeric_zero ();
1189  if (!trans || !acc) return total;
1190 
1191  total = gnc_numeric_convert (total, xaccAccountGetCommoditySCU (acc),
1193  FOR_EACH_SPLIT(trans, if (acc == xaccSplitGetAccount(s))
1194  total = gnc_numeric_add_fixed(
1195  total, xaccSplitGetAmount(s)));
1196  return total;
1197 }
int xaccAccountGetCommoditySCU(const Account *acc)
Definition: Account.c:2458
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
gnc_numeric xaccTransGetAccountBalance ( const Transaction trans,
const Account account 
)

Get the account balance for the specified account after the last split in the specified transaction.

Definition at line 1310 of file Transaction.c.

1312 {
1313  GList *node;
1314  Split *last_split = NULL;
1315 
1316  // Not really the appropriate error value.
1317  g_return_val_if_fail(account && trans, gnc_numeric_error(GNC_ERROR_ARG));
1318 
1319  for (node = trans->splits; node; node = node->next)
1320  {
1321  Split *split = node->data;
1322 
1323  if (!xaccTransStillHasSplit(trans, split))
1324  continue;
1325  if (xaccSplitGetAccount(split) != account)
1326  continue;
1327 
1328  if (!last_split)
1329  {
1330  last_split = split;
1331  continue;
1332  }
1333 
1334  /* This test needs to correspond to the comparison function used when
1335  sorting the splits for computing the running balance. */
1336  if (xaccSplitOrder (last_split, split) < 0)
1337  last_split = split;
1338  }
1339 
1340  return xaccSplitGetBalance (last_split);
1341 }
gint xaccSplitOrder(const Split *sa, const Split *sb)
Definition: Split.c:1521
gnc_numeric xaccSplitGetBalance(const Split *s)
Definition: Split.c:1323
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gnc_numeric xaccTransGetAccountValue ( const Transaction trans,
const Account account 
)

The xaccTransGetAccountValue() method returns the total value applied to a particular account. In some cases there may be multiple Splits in a single Transaction applied to one account (in particular when trying to balance Lots) – this function is just a convienience to view everything at once.

Definition at line 1170 of file Transaction.c.

1172 {
1173  gnc_numeric total = gnc_numeric_zero ();
1174  if (!trans || !acc) return total;
1175 
1176  FOR_EACH_SPLIT(trans, if (acc == xaccSplitGetAccount(s))
1177 {
1178  total = gnc_numeric_add (total, xaccSplitGetValue (s),
1181  });
1182  return total;
1183 }
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
const char* xaccTransGetAssociation ( const Transaction trans)

Gets the transaction association

Definition at line 2190 of file Transaction.c.

2191 {
2192  return trans ?
2193  kvp_frame_get_string (trans->inst.kvp_data, assoc_uri_str) : NULL;
2194 }
gnc_commodity* xaccTransGetCurrency ( const Transaction trans)

Returns the valuation commodity of this transaction.

Each transaction's valuation commodity, or 'currency' is, by definition, the common currency in which all splits in the transaction can be valued. The total value of the transaction must be zero when all splits are valued in this currency.

Note
What happens if the Currency isn't set? Ans: bad things.

Definition at line 1348 of file Transaction.c.

1349 {
1350  return trans ? trans->common_currency : NULL;
1351 }
time64 xaccTransGetDate ( const Transaction trans)

Retrieve the posted date of the transaction. The posted date is the date when this transaction was posted at the bank. (Although having different function names, GetDate and GetDatePosted refer to the same single date.)

Definition at line 2215 of file Transaction.c.

2216 {
2217  return trans ? trans->date_posted.tv_sec : 0;
2218 }
void xaccTransGetDateDueTS ( const Transaction trans,
Timespec ts 
)

Dates and txn-type for A/R and A/P "invoice" postings

Definition at line 2280 of file Transaction.c.

2281 {
2282  KvpValue *value;
2283 
2284  if (!trans || !ts) return;
2285 
2286  value = kvp_frame_get_slot (trans->inst.kvp_data, TRANS_DATE_DUE_KVP);
2287  if (value)
2288  *ts = kvp_value_get_timespec (value);
2289  else
2290  xaccTransGetDatePostedTS (trans, ts);
2291 }
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
void xaccTransGetDatePostedTS(const Transaction *trans, Timespec *ts)
Definition: Transaction.c:2229
time64 xaccTransGetDateEntered ( const Transaction trans)

Retrieve the date of when the transaction was entered. The entered date is the date when the register entry was made.

Definition at line 2222 of file Transaction.c.

2223 {
2224  return trans ? trans->date_entered.tv_sec : 0;
2225 }
void xaccTransGetDateEnteredTS ( const Transaction trans,
Timespec ts 
)

Retrieve the date of when the transaction was entered. The entered date is the date when the register entry was made.

Definition at line 2236 of file Transaction.c.

2237 {
2238  if (trans && ts)
2239  *ts = trans->date_entered;
2240 }
GDate xaccTransGetDatePostedGDate ( const Transaction trans)

Retrieve the posted date of the transaction. The posted date is the date when this transaction was posted at the bank.

Definition at line 2250 of file Transaction.c.

2251 {
2252  GDate result;
2253  if (trans)
2254  {
2255  /* Can we look up this value in the kvp slot? If yes, use it
2256  * from there because it doesn't suffer from time zone
2257  * shifts. */
2258  const KvpValue* kvp_value =
2259  kvp_frame_get_slot(trans->inst.kvp_data, TRANS_DATE_POSTED);
2260  if (kvp_value)
2261  result = kvp_value_get_gdate(kvp_value);
2262  else
2264  }
2265  else
2266  {
2267  g_date_clear(&result, 1);
2268  }
2269  return result;
2270 }
GDate timespec_to_gdate(Timespec ts)
GDate kvp_value_get_gdate(const KvpValue *value)
Timespec xaccTransRetDatePostedTS(const Transaction *trans)
Definition: Transaction.c:2243
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
void xaccTransGetDatePostedTS ( const Transaction trans,
Timespec ts 
)

Retrieve the posted date of the transaction. The posted date is the date when this transaction was posted at the bank. (Although having different function names, GetDate and GetDatePosted refer to the same single date.)

Definition at line 2229 of file Transaction.c.

2230 {
2231  if (trans && ts)
2232  *ts = trans->date_posted;
2233 }
const char* xaccTransGetDescription ( const Transaction trans)

Gets the transaction Description

Definition at line 2184 of file Transaction.c.

2185 {
2186  return trans ? trans->description : NULL;
2187 }
MonetaryList* xaccTransGetImbalance ( const Transaction trans)

The xaccTransGetImbalance method returns a list giving the value of the transaction in each currency for which the balance is not zero. If the use of currency accounts is disabled, then this will be only the common currency for the transaction and xaccTransGetImbalance becomes equivalent to xaccTransGetImbalanceValue. Otherwise it will return a list containing the imbalance in each currency.

Definition at line 1052 of file Transaction.c.

1053 {
1054  /* imbal_value is used if either (1) the transaction has a non currency
1055  split or (2) all the splits are in the same currency. If there are
1056  no non-currency splits and not all splits are in the same currency then
1057  imbal_list is used to compute the imbalance. */
1058  MonetaryList *imbal_list = NULL;
1059  gnc_numeric imbal_value = gnc_numeric_zero();
1060  gboolean trading_accts;
1061 
1062  if (!trans) return imbal_list;
1063 
1064  ENTER("(trans=%p)", trans);
1065 
1066  trading_accts = xaccTransUseTradingAccounts (trans);
1067 
1068  /* If using trading accounts and there is at least one split that is not
1069  in the transaction currency or a split that has a price or exchange
1070  rate other than 1, then compute the balance in each commodity in the
1071  transaction. Otherwise (all splits are in the transaction's currency)
1072  then compute the balance using the value fields.
1073 
1074  Optimize for the common case of only one currency and a balanced
1075  transaction. */
1076  FOR_EACH_SPLIT(trans,
1077  {
1078  gnc_commodity *commodity;
1080  if (trading_accts &&
1081  (imbal_list ||
1082  ! gnc_commodity_equiv(commodity, trans->common_currency) ||
1084  {
1085  /* Need to use (or already are using) a list of imbalances in each of
1086  the currencies used in the transaction. */
1087  if (! imbal_list)
1088  {
1089  /* All previous splits have been in the transaction's common
1090  currency, so imbal_value is in this currency. */
1091  imbal_list = gnc_monetary_list_add_value(imbal_list,
1092  trans->common_currency,
1093  imbal_value);
1094  }
1095  imbal_list = gnc_monetary_list_add_value(imbal_list, commodity,
1096  xaccSplitGetAmount(s));
1097  }
1098 
1099  /* Add it to the value accumulator in case we need it. */
1100  imbal_value = gnc_numeric_add(imbal_value, xaccSplitGetValue(s),
1102  } );
1103 
1104 
1105  if (!imbal_list && !gnc_numeric_zero_p(imbal_value))
1106  {
1107  /* Not balanced and no list, create one. If we found multiple currencies
1108  and no non-currency commodity then imbal_list will already exist and
1109  we won't get here. */
1110  imbal_list = gnc_monetary_list_add_value(imbal_list,
1111  trans->common_currency,
1112  imbal_value);
1113  }
1114 
1115  /* Delete all the zero entries from the list, perhaps leaving an
1116  empty list */
1117  imbal_list = gnc_monetary_list_delete_zeros(imbal_list);
1118 
1119  LEAVE("(trans=%p), imbal=%p", trans, imbal_list);
1120  return imbal_list;
1121 }
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Definition: Transaction.c:1015
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gboolean gnc_numeric_zero_p(gnc_numeric a)
#define ENTER(format, args...)
Definition: qoflog.h:261
MonetaryList * gnc_monetary_list_delete_zeros(MonetaryList *list)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Definition: Account.c:3148
#define LEAVE(format, args...)
Definition: qoflog.h:271
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
gnc_numeric xaccTransGetImbalanceValue ( const Transaction trans)

The xaccTransGetImbalanceValue() method returns the total value of the transaction. In a pure double-entry system, this imbalance should be exactly zero, and if it is not, something is broken. However, when double-entry semantics are not enforced, unbalanced transactions can sneak in, and this routine can be used to find out how much things are off by. The value returned is denominated in the currency that is returned by the xaccTransFindCommonCurrency() method.

If the use of currency exchange accounts is enabled then the a a transaction must be balanced in each currency it uses to be considered to be balanced. The method xaccTransGetImbalance is used by most code to take this into consideration. This method is only used in a few places that want the transaction value even if currency exchange accounts are enabled.

Definition at line 1036 of file Transaction.c.

1037 {
1038  gnc_numeric imbal = gnc_numeric_zero();
1039  if (!trans) return imbal;
1040 
1041  ENTER("(trans=%p)", trans);
1042  /* Could use xaccSplitsComputeValue, except that we want to use
1043  GNC_HOW_DENOM_EXACT */
1044  FOR_EACH_SPLIT(trans, imbal =
1047  LEAVE("(trans=%p) imbal=%s", trans, gnc_num_dbg_to_string(imbal));
1048  return imbal;
1049 }
gchar * gnc_num_dbg_to_string(gnc_numeric n)
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
#define ENTER(format, args...)
Definition: qoflog.h:261
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
#define LEAVE(format, args...)
Definition: qoflog.h:271
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
gboolean xaccTransGetIsClosingTxn ( const Transaction trans)

Returns whether this transaction is a "closing transaction"

Definition at line 2204 of file Transaction.c.

2205 {
2206  return trans ?
2207  kvp_frame_get_gint64 (trans->inst.kvp_data, trans_is_closing_str)
2208  : FALSE;
2209 }
const char* xaccTransGetNotes ( const Transaction trans)

Gets the transaction Notes

The Notes field is only visible in the register in double-line mode

Definition at line 2197 of file Transaction.c.

2198 {
2199  return trans ?
2200  kvp_frame_get_string (trans->inst.kvp_data, trans_notes_str) : NULL;
2201 }
const char* xaccTransGetNum ( const Transaction trans)

Gets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_get_num_action' and 'gnc_get_action_num' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically

Definition at line 2178 of file Transaction.c.

2179 {
2180  return trans ? trans->num : NULL;
2181 }
const char* xaccTransGetReadOnly ( const Transaction trans)

Returns a non-NULL value if this Transaction was marked as read-only with some specific "reason" text.

Definition at line 2313 of file Transaction.c.

2314 {
2315  /* XXX This flag should be cached in the transaction structure
2316  * for performance reasons, since its checked every trans commit.
2317  */
2318  return trans ? kvp_frame_get_string (
2319  trans->inst.kvp_data, TRANS_READ_ONLY_REASON) : NULL;
2320 }
Transaction* xaccTransGetReversedBy ( const Transaction trans)

Returns the transaction that reversed the given transaction.

Parameters
transa Transaction that has been reversed
Returns
the transaction that reversed the given transaction, or NULL if the given transaction has not been reversed.

Definition at line 2606 of file Transaction.c.

2607 {
2608  GncGUID *guid;
2609 
2610  g_return_val_if_fail(trans, NULL);
2611  guid = kvp_frame_get_guid(trans->inst.kvp_data, TRANS_REVERSED_BY);
2612  return xaccTransLookup(guid, qof_instance_get_book(trans));
2613 }
QofBook * qof_instance_get_book(gconstpointer)
Definition: guid.h:65
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
Definition: Transaction.c:1024
Split* xaccTransGetSplit ( const Transaction trans,
int  i 
)

The xaccTransGetSplit() method returns a pointer to each of the splits in this transaction.

Parameters
transThe transaction
iThe split number. Valid values for i are zero to (number_of__splits-1). An invalid value of i will cause NULL to be returned. A convenient way of cycling through all splits is to start at zero, and keep incrementing until a null value is returned.

Definition at line 2144 of file Transaction.c.

2145 {
2146  int j = 0;
2147  if (!trans || i < 0) return NULL;
2148 
2149  FOR_EACH_SPLIT(trans, { if (i == j) return s; j++; });
2150  return NULL;
2151 }
int xaccTransGetSplitIndex ( const Transaction trans,
const Split split 
)

Inverse of xaccTransGetSplit()

Definition at line 2154 of file Transaction.c.

2155 {
2156  int j = 0;
2157  g_return_val_if_fail(trans && split, -1);
2158 
2159  FOR_EACH_SPLIT(trans, { if (s == split) return j; j++; });
2160  return -1;
2161 }
SplitList* xaccTransGetSplitList ( const Transaction trans)

The xaccTransGetSplitList() method returns a GList of the splits in a transaction.

Returns
The list of splits. This list must NOT be modified. Do NOT free this list when you are done with it.

Definition at line 2164 of file Transaction.c.

2165 {
2166  return trans ? trans->splits : NULL;
2167 }
char xaccTransGetTxnType ( const Transaction trans)

Returns the Transaction Type

See TXN_TYPE_NONE, TXN_TYPE_INVOICE and TXN_TYPE_PAYMENT

Definition at line 2302 of file Transaction.c.

2303 {
2304  const char *s;
2305  if (!trans) return TXN_TYPE_NONE;
2306  s = kvp_frame_get_string (trans->inst.kvp_data, TRANS_TXN_TYPE_KVP);
2307  if (s) return *s;
2308 
2309  return TXN_TYPE_NONE;
2310 }
#define TXN_TYPE_NONE
Definition: Transaction.h:119
const char* xaccTransGetVoidReason ( const Transaction transaction)

Returns the user supplied textual reason why a transaction was voided.

Parameters
transactionThe transaction in question.
Returns
A pointer to the user supplied reason for voiding.

Definition at line 2533 of file Transaction.c.

2534 {
2535  g_return_val_if_fail(trans, NULL);
2536  return kvp_frame_get_string(trans->inst.kvp_data, void_reason_str);
2537 }
gboolean xaccTransGetVoidStatus ( const Transaction transaction)

Retrieve information on whether or not a transaction has been voided.

Parameters
transactionThe transaction in question.
Returns
TRUE if the transaction is void, FALSE otherwise. Also returns FALSE upon an error.

Definition at line 2526 of file Transaction.c.

2527 {
2528  g_return_val_if_fail(trans, FALSE);
2529  return (kvp_frame_get_slot(trans->inst.kvp_data, void_reason_str) != NULL);
2530 }
Timespec xaccTransGetVoidTime ( const Transaction tr)

Returns the time that a transaction was voided.

Parameters
trThe transaction in question.
Returns
A Timespec containing the time that this transaction was voided. Returns a time of zero upon error.

Definition at line 2540 of file Transaction.c.

2541 {
2542  const char *val;
2543  Timespec void_time = {0, 0};
2544 
2545  g_return_val_if_fail(tr, void_time);
2546 
2547  val = kvp_frame_get_string(tr->inst.kvp_data, void_time_str);
2548  return val ? gnc_iso8601_to_timespec_gmt(val) : void_time;
2549 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
Timespec gnc_iso8601_to_timespec_gmt(const gchar *)
gboolean xaccTransHasReconciledSplits ( const Transaction trans)

FIXME: document me

Definition at line 2433 of file Transaction.c.

2434 {
2435  return xaccTransHasReconciledSplitsByAccount (trans, NULL);
2436 }
gboolean xaccTransHasReconciledSplitsByAccount(const Transaction *trans, const Account *account)
Definition: Transaction.c:2404
gboolean xaccTransHasReconciledSplitsByAccount ( const Transaction trans,
const Account account 
)

FIXME: document me

Definition at line 2404 of file Transaction.c.

2406 {
2407  GList *node;
2408 
2409  for (node = xaccTransGetSplitList (trans); node; node = node->next)
2410  {
2411  Split *split = node->data;
2412 
2413  if (!xaccTransStillHasSplit(trans, split))
2414  continue;
2415  if (account && (xaccSplitGetAccount(split) != account))
2416  continue;
2417 
2418  switch (xaccSplitGetReconcile (split))
2419  {
2420  case YREC:
2421  case FREC:
2422  return TRUE;
2423 
2424  default:
2425  break;
2426  }
2427  }
2428 
2429  return FALSE;
2430 }
char xaccSplitGetReconcile(const Split *split)
Definition: Split.c:1980
#define YREC
Definition: Split.h:68
#define FREC
Definition: Split.h:69
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
SplitList * xaccTransGetSplitList(const Transaction *trans)
Definition: Transaction.c:2164
gboolean xaccTransHasSplitsInState ( const Transaction trans,
const char  state 
)

FIXME: document me

Definition at line 2463 of file Transaction.c.

2464 {
2465  return xaccTransHasSplitsInStateByAccount (trans, state, NULL);
2466 }
gboolean xaccTransHasSplitsInStateByAccount(const Transaction *trans, const char state, const Account *account)
Definition: Transaction.c:2440
gboolean xaccTransHasSplitsInStateByAccount ( const Transaction trans,
const char  state,
const Account account 
)

FIXME: document me

Definition at line 2440 of file Transaction.c.

2443 {
2444  GList *node;
2445 
2446  for (node = xaccTransGetSplitList (trans); node; node = node->next)
2447  {
2448  Split *split = node->data;
2449 
2450  if (!xaccTransStillHasSplit(trans, split))
2451  continue;
2452  if (account && (xaccSplitGetAccount(split) != account))
2453  continue;
2454 
2455  if (split->reconciled == state)
2456  return TRUE;
2457  }
2458 
2459  return FALSE;
2460 }
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
SplitList * xaccTransGetSplitList(const Transaction *trans)
Definition: Transaction.c:2164
gboolean xaccTransInFutureByPostedDate ( const Transaction trans)

Returns TRUE if this Transaction's posted-date is in the future

Definition at line 2385 of file Transaction.c.

2386 {
2387  time64 present;
2388  gboolean result;
2389  g_assert(trans);
2390 
2391  present = gnc_time64_get_today_end ();
2392 
2393  if (trans->date_posted.tv_sec > present)
2394  result = TRUE;
2395  else
2396  result = FALSE;
2397 
2398  return result;
2399 }
time64 gnc_time64_get_today_end(void)
gint64 time64
Definition: gnc-date.h:83
gboolean xaccTransIsBalanced ( const Transaction trans)

Returns true if the transaction is balanced according to the rules currently in effect.

Definition at line 1124 of file Transaction.c.

1125 {
1126  MonetaryList *imbal_list;
1127  gboolean result;
1128  gnc_numeric imbal = gnc_numeric_zero();
1129  gnc_numeric imbal_trading = gnc_numeric_zero();
1130 
1131  if (trans == NULL) return FALSE;
1132 
1133  if (xaccTransUseTradingAccounts(trans))
1134  {
1135  /* Transaction is imbalanced if the value is imbalanced in either
1136  trading or non-trading splits. One can't be used to balance
1137  the other. */
1138  FOR_EACH_SPLIT(trans,
1139  {
1140  Account *acc = xaccSplitGetAccount(s);
1141  if (!acc || xaccAccountGetType(acc) != ACCT_TYPE_TRADING)
1142  {
1143  imbal = gnc_numeric_add(imbal, xaccSplitGetValue(s),
1145  }
1146  else
1147  {
1148  imbal_trading = gnc_numeric_add(imbal_trading, xaccSplitGetValue(s),
1150  }
1151  }
1152  );
1153  }
1154  else
1155  imbal = xaccTransGetImbalanceValue(trans);
1156 
1157  if (! gnc_numeric_zero_p(imbal) || ! gnc_numeric_zero_p(imbal_trading))
1158  return FALSE;
1159 
1160  if (!xaccTransUseTradingAccounts (trans))
1161  return TRUE;
1162 
1163  imbal_list = xaccTransGetImbalance(trans);
1164  result = imbal_list == NULL;
1165  gnc_monetary_list_free(imbal_list);
1166  return result;
1167 }
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Definition: Transaction.c:1015
GNCAccountType xaccAccountGetType(const Account *acc)
Definition: Account.c:3009
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gboolean gnc_numeric_zero_p(gnc_numeric a)
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
Definition: Transaction.c:1036
void gnc_monetary_list_free(MonetaryList *list)
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
MonetaryList * xaccTransGetImbalance(const Transaction *trans)
Definition: Transaction.c:1052
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
gboolean xaccTransIsOpen ( const Transaction trans)

The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. Otherwise, it returns false. XXX this routine should probably be deprecated. its, umm, hard to imagine legitimate uses (but it is used by the import/export code for reasons I can't understand.)

Definition at line 1819 of file Transaction.c.

1820 {
1821  return trans ? (0 < qof_instance_get_editlevel(trans)) : FALSE;
1822 }
gboolean xaccTransIsReadonlyByPostedDate ( const Transaction trans)

Returns TRUE if this Transaction is read-only because its posted-date is older than the "auto-readonly" threshold of this book. See qof_book_uses_autofreeze() and qof_book_get_autofreeze_gdate().

Definition at line 2345 of file Transaction.c.

2346 {
2347  GDate *threshold_date;
2348  GDate trans_date;
2349  const QofBook *book = xaccTransGetBook (trans);
2350  gboolean result;
2351  g_assert(trans);
2352 
2353  if (!qof_book_uses_autoreadonly(book))
2354  {
2355  return FALSE;
2356  }
2357 
2358  if (xaccTransIsSXTemplate (trans))
2359  return FALSE;
2360 
2361  threshold_date = qof_book_get_autoreadonly_gdate(book);
2362  g_assert(threshold_date); // ok because we checked uses_autoreadonly before
2363  trans_date = xaccTransGetDatePostedGDate(trans);
2364 
2365 // g_warning("there is auto-read-only with days=%d, trans_date_day=%d, threshold_date_day=%d",
2366 // qof_book_get_num_days_autofreeze(book),
2367 // g_date_get_day(&trans_date),
2368 // g_date_get_day(threshold_date));
2369 
2370  if (g_date_compare(&trans_date, threshold_date) < 0)
2371  {
2372  //g_warning("we are auto-read-only");
2373  result = TRUE;
2374  }
2375  else
2376  {
2377  result = FALSE;
2378  }
2379  g_date_free(threshold_date);
2380  return result;
2381 }
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
#define xaccTransGetBook(X)
Definition: Transaction.h:753
gboolean qof_book_uses_autoreadonly(const QofBook *book)
GDate xaccTransGetDatePostedGDate(const Transaction *trans)
Definition: Transaction.c:2250
Transaction* xaccTransLookup ( const GncGUID guid,
QofBook book 
)

The xaccTransLookup() subroutine will return the transaction associated with the given id, or NULL if there is no such transaction.

Definition at line 1024 of file Transaction.c.

1025 {
1026  QofCollection *col;
1027  if (!guid || !book) return NULL;
1028  col = qof_book_get_collection (book, GNC_ID_TRANS);
1029  return (Transaction *) qof_collection_lookup_entity (col, guid);
1030 }
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
int xaccTransOrder ( const Transaction ta,
const Transaction tb 
)

The xaccTransOrder(ta,tb) method is useful for sorting. Orders ta and tb return <0 if ta sorts before tb return >0 if ta sorts after tb return 0 if they are absolutely equal

The comparrison uses the following fields, in order: date posted (compare as a date) num field (compare as an integer) date entered (compare as a date) description field (comcpare as a string using strcmp()) GncGUID (compare as a guid) Finally, it returns zero if all of the above match. Note that it does NOT compare its member splits. Note also that it calls xaccTransOrder_num_action with actna and actnb set as NULL.

Definition at line 1827 of file Transaction.c.

1828 {
1829  return xaccTransOrder_num_action (ta, NULL, tb, NULL);
1830 }
int xaccTransOrder_num_action(const Transaction *ta, const char *actna, const Transaction *tb, const char *actnb)
Definition: Transaction.c:1833
int xaccTransOrder_num_action ( const Transaction ta,
const char *  actna,
const Transaction tb,
const char *  actnb 
)

The xaccTransOrder_num_action(ta,actna,tb,actnb) method is useful for sorting. Orders ta and tb return <0 if ta sorts before tb return >0 if ta sorts after tb return 0 if they are absolutely equal

The comparrison uses the following fields, in order: date posted (compare as a date) if actna and actnb are NULL, num field (compare as an integer) else actna and actnb (compare as an integer) date entered (compare as a date) description field (comcpare as a string using strcmp()) GncGUID (compare as a guid) Finally, it returns zero if all of the above match. Note that it does NOT compare its member splits (except action as specified above).

Definition at line 1833 of file Transaction.c.

1835 {
1836  char *da, *db;
1837  int na, nb, retval;
1838 
1839  if ( ta && !tb ) return -1;
1840  if ( !ta && tb ) return +1;
1841  if ( !ta && !tb ) return 0;
1842 
1843  /* if dates differ, return */
1844  DATE_CMP(ta, tb, date_posted);
1845 
1846  /* otherwise, sort on number string */
1847  if (actna && actnb) /* split action string, if not NULL */
1848  {
1849  na = atoi(actna);
1850  nb = atoi(actnb);
1851  }
1852  else /* else transaction num string */
1853  {
1854  na = atoi(ta->num);
1855  nb = atoi(tb->num);
1856  }
1857  if (na < nb) return -1;
1858  if (na > nb) return +1;
1859 
1860  /* if dates differ, return */
1861  DATE_CMP(ta, tb, date_entered);
1862 
1863  /* otherwise, sort on description string */
1864  da = ta->description ? ta->description : "";
1865  db = tb->description ? tb->description : "";
1866  retval = g_utf8_collate (da, db);
1867  if (retval)
1868  return retval;
1869 
1870  /* else, sort on guid - keeps sort stable. */
1871  return qof_instance_guid_compare(ta, tb);
1872 }
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
Timespec xaccTransRetDateDueTS ( const Transaction trans)

Dates and txn-type for A/R and A/P "invoice" postings

Definition at line 2294 of file Transaction.c.

2295 {
2296  Timespec ts = {0, 0};
2297  if (trans) xaccTransGetDateDueTS (trans, &ts);
2298  return ts;
2299 }
void xaccTransGetDateDueTS(const Transaction *trans, Timespec *ts)
Definition: Transaction.c:2280
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
Timespec xaccTransRetDateEnteredTS ( const Transaction trans)

Retrieve the date of when the transaction was entered. The entered date is the date when the register entry was made.

Definition at line 2273 of file Transaction.c.

2274 {
2275  Timespec ts = {0, 0};
2276  return trans ? trans->date_entered : ts;
2277 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
Timespec xaccTransRetDatePostedTS ( const Transaction trans)

Retrieve the posted date of the transaction. The posted date is the date when this transaction was posted at the bank. (Although having different function names, GetDate and GetDatePosted refer to the same single date.)

Definition at line 2243 of file Transaction.c.

2244 {
2245  Timespec ts = {0, 0};
2246  return trans ? trans->date_posted : ts;
2247 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
Transaction* xaccTransReverse ( Transaction transaction)

xaccTransReverse creates a Transaction that reverses the given tranaction by inverting all the numerical values in the given transaction. This function cancels out the effect of an earlier transaction. This will be needed by write only accounts as a way to void a previous transaction (since you can't alter the existing transaction).

Parameters
transactionThe transaction to create a reverse of.
Returns
a new transaction which reverses the given transaction

Definition at line 2579 of file Transaction.c.

2580 {
2581  Transaction *trans;
2582  KvpValue *kvp_val;
2583  g_return_val_if_fail(orig, NULL);
2584 
2585  trans = xaccTransClone(orig);
2586  xaccTransBeginEdit(trans);
2587 
2588  /* Reverse the values on each split. Clear per-split info. */
2589  FOR_EACH_SPLIT(trans,
2590  {
2594  });
2595 
2596  /* Now update the original with a pointer to the new one */
2597  kvp_val = kvp_value_new_guid(xaccTransGetGUID(trans));
2598  kvp_frame_set_slot_nc(orig->inst.kvp_data, TRANS_REVERSED_BY, kvp_val);
2599 
2600  qof_instance_set_dirty(QOF_INSTANCE(trans));
2601  xaccTransCommitEdit(trans);
2602  return trans;
2603 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
gnc_numeric gnc_numeric_neg(gnc_numeric a)
void xaccSplitSetReconcile(Split *split, char recn)
Definition: Split.c:1826
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
Definition: Split.c:1258
Transaction * xaccTransClone(const Transaction *from)
Definition: Transaction.c:679
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *key, KvpValue *value)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
#define xaccTransGetGUID(X)
Definition: Transaction.h:755
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
#define NREC
Definition: Split.h:70
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
void xaccTransRollbackEdit ( Transaction trans)

The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it was before the editing started. This includes restoring any deleted splits, removing any added splits, and undoing the effects of xaccTransDestroy, as well as restoring share quantities, memos, descriptions, etc.

Todo:
Fix transrollbackedit in QOF so that rollback is exposed via the API.

Definition at line 1661 of file Transaction.c.

1662 {
1663  GList *node, *onode;
1664  QofBackend *be;
1665  Transaction *orig;
1666  GList *slist;
1667  int num_preexist, i;
1668 
1669 /* FIXME: This isn't quite the right way to handle nested edits --
1670  * there should be a stack of transaction states that are popped off
1671  * and restored at each level -- but it does prevent restoring to the
1672  * editlevel 0 state until one is returning to editlevel 0, and
1673  * thereby prevents a crash caused by trans->orig getting NULLed too
1674  * soon.
1675  */
1676  if (!qof_instance_get_editlevel (QOF_INSTANCE (trans))) return;
1677  if (qof_instance_get_editlevel (QOF_INSTANCE (trans)) > 1) {
1678  qof_instance_decrease_editlevel (QOF_INSTANCE (trans));
1679  return;
1680  }
1681 
1682  ENTER ("trans addr=%p\n", trans);
1683 
1684  check_open(trans);
1685 
1686  /* copy the original values back in. */
1687 
1688  orig = trans->orig;
1689  SWAP(trans->num, orig->num);
1690  SWAP(trans->description, orig->description);
1691  trans->date_entered = orig->date_entered;
1692  trans->date_posted = orig->date_posted;
1693  SWAP(trans->common_currency, orig->common_currency);
1694  SWAP(trans->inst.kvp_data, orig->inst.kvp_data);
1695 
1696  /* The splits at the front of trans->splits are exactly the same
1697  splits as in the original, but some of them may have changed, so
1698  we restore only those. */
1699 /* FIXME: Runs off the transaction's splits, so deleted splits are not
1700  * restored!
1701  */
1702  num_preexist = g_list_length(orig->splits);
1703  slist = g_list_copy(trans->splits);
1704  for (i = 0, node = slist, onode = orig->splits; node;
1705  i++, node = node->next, onode = onode ? onode->next : NULL)
1706  {
1707  Split *s = node->data;
1708 
1709  if (!qof_instance_is_dirty(QOF_INSTANCE(s)))
1710  continue;
1711 
1712  if (i < num_preexist)
1713  {
1714  Split *so = onode->data;
1715 
1716  xaccSplitRollbackEdit(s);
1717  SWAP(s->action, so->action);
1718  SWAP(s->memo, so->memo);
1719  SWAP(s->inst.kvp_data, so->inst.kvp_data);
1720  s->reconciled = so->reconciled;
1721  s->amount = so->amount;
1722  s->value = so->value;
1723  s->lot = so->lot;
1724  s->gains_split = so->gains_split;
1725  //SET_GAINS_A_VDIRTY(s);
1726  s->date_reconciled = so->date_reconciled;
1727  qof_instance_mark_clean(QOF_INSTANCE(s));
1728  xaccFreeSplit(so);
1729  }
1730  else
1731  {
1732  /* Potentially added splits */
1733  if (trans != xaccSplitGetParent(s))
1734  {
1735  trans->splits = g_list_remove(trans->splits, s);
1736  /* New split added, but then moved to another
1737  transaction */
1738  continue;
1739  }
1740  xaccSplitRollbackEdit(s);
1741  trans->splits = g_list_remove(trans->splits, s);
1742  g_assert(trans != xaccSplitGetParent(s));
1743  /* NB: our memory management policy here is that a new split
1744  added to the transaction which is then rolled-back still
1745  belongs to the engine. Specifically, it's freed by the
1746  transaction to which it was added. Don't add the Split to
1747  more than one transaction during the begin/commit block! */
1748  if (NULL == xaccSplitGetParent(s))
1749  {
1750  xaccFreeSplit(s); // a newly malloc'd split
1751  }
1752  }
1753  }
1754  g_list_free(slist);
1755  g_list_free(orig->splits);
1756  orig->splits = NULL;
1757 
1758  /* Now that the engine copy is back to its original version,
1759  * get the backend to fix it in the database */
1763  if (be && be->rollback)
1764  {
1765  QofBackendError errcode;
1766 
1767  /* clear errors */
1768  do
1769  {
1770  errcode = qof_backend_get_error (be);
1771  }
1772  while (ERR_BACKEND_NO_ERR != errcode);
1773 
1774  (be->rollback) (be, &(trans->inst));
1775 
1776  errcode = qof_backend_get_error (be);
1777  if (ERR_BACKEND_MOD_DESTROY == errcode)
1778  {
1779  /* The backend is asking us to delete this transaction.
1780  * This typically happens because another (remote) user
1781  * has deleted this transaction, and we haven't found
1782  * out about it until this user tried to edit it.
1783  */
1784  xaccTransDestroy (trans);
1785  do_destroy (trans);
1786 
1787  /* push error back onto the stack */
1788  qof_backend_set_error (be, errcode);
1789  LEAVE ("deleted trans addr=%p\n", trans);
1790  return;
1791  }
1792  if (ERR_BACKEND_NO_ERR != errcode)
1793  {
1794  PERR ("Rollback Failed. Ouch!");
1795  /* push error back onto the stack */
1796  qof_backend_set_error (be, errcode);
1797  }
1798  }
1799 
1801  xaccTransWriteLog (trans, 'R');
1802 
1803  xaccFreeTransaction (trans->orig);
1804 
1805  trans->orig = NULL;
1806  qof_instance_set_destroying(trans, FALSE);
1807 
1808  /* Put back to zero. */
1809  qof_instance_decrease_editlevel(trans);
1810  /* FIXME: The register code seems to depend on the engine to
1811  generate an event during rollback, even though the state is just
1812  reverting to what it was. */
1813  gen_event_trans (trans);
1814 
1815  LEAVE ("trans addr=%p\n", trans);
1816 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
#define qof_instance_is_dirty
Definition: qofinstance.h:165
QofBook * qof_instance_get_book(gconstpointer)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
void xaccTransWriteLog(Transaction *trans, char flag)
Definition: TransLog.c:221
Transaction * xaccSplitGetParent(const Split *split)
Definition: Split.c:1903
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
QofBackendError qof_backend_get_error(QofBackend *be)
gboolean qof_book_is_readonly(const QofBook *book)
Definition: SplitP.h:71
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void xaccTransScrubGains ( Transaction trans,
Account gain_acc 
)

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.

Definition at line 2678 of file Transaction.c.

2679 {
2680  SplitList *node;
2681 
2682  ENTER("(trans=%p)", trans);
2683  /* Lock down posted date, its to be synced to the posted date
2684  * for the source of the cap gains. */
2685  xaccTransScrubGainsDate(trans);
2686 
2687  /* Fix up the split amount */
2688 restart:
2689  for (node = trans->splits; node; node = node->next)
2690  {
2691  Split *s = node->data;
2692 
2693  if (!xaccTransStillHasSplit(trans, s)) continue;
2694 
2695  xaccSplitDetermineGainStatus(s);
2696  if (s->gains & GAINS_STATUS_ADIRTY)
2697  {
2698  gboolean altered = FALSE;
2699  s->gains &= ~GAINS_STATUS_ADIRTY;
2700  if (s->lot)
2701  altered = xaccScrubLot(s->lot);
2702  else
2703  altered = xaccSplitAssign(s);
2704  if (altered) goto restart;
2705  }
2706  }
2707 
2708  /* Fix up gains split value */
2709  FOR_EACH_SPLIT(trans,
2710  if ((s->gains & GAINS_STATUS_VDIRTY) ||
2711  (s->gains_split &&
2712  (s->gains_split->gains & GAINS_STATUS_VDIRTY)))
2713  xaccSplitComputeCapGains(s, gain_acc);
2714  );
2715 
2716  LEAVE("(trans=%p)", trans);
2717 }
void xaccSplitComputeCapGains(Split *split, Account *gain_acc)
Definition: cap-gains.c:536
#define ENTER(format, args...)
Definition: qoflog.h:261
GList SplitList
Definition: gnc-engine.h:203
gboolean xaccSplitAssign(Split *split)
Definition: cap-gains.c:438
Definition: SplitP.h:71
#define LEAVE(format, args...)
Definition: qoflog.h:271
gboolean xaccScrubLot(GNCLot *lot)
Definition: Scrub3.c:85
void xaccTransSetAssociation ( Transaction trans,
const char *  assoc 
)

Sets the transaction Association

Definition at line 2096 of file Transaction.c.

2097 {
2098  if (!trans || !assoc) return;
2099  xaccTransBeginEdit(trans);
2100 
2101  kvp_frame_set_string (trans->inst.kvp_data, assoc_uri_str, assoc);
2102  qof_instance_set_dirty(QOF_INSTANCE(trans));
2103  xaccTransCommitEdit(trans);
2104 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccTransSetCurrency ( Transaction trans,
gnc_commodity curr 
)

Set the commodity of this transaction.

Definition at line 1354 of file Transaction.c.

1355 {
1356  gint fraction, old_fraction;
1357 
1358  if (!trans || !curr || trans->common_currency == curr) return;
1359  xaccTransBeginEdit(trans);
1360 
1361  old_fraction = gnc_commodity_get_fraction (trans->common_currency);
1362  trans->common_currency = curr;
1363  fraction = gnc_commodity_get_fraction (curr);
1364 
1365  /* avoid needless crud if fraction didn't change */
1366  if (fraction != old_fraction)
1367  {
1368  FOR_EACH_SPLIT(trans, xaccSplitSetValue(s, xaccSplitGetValue(s)));
1369  }
1370 
1371  qof_instance_set_dirty(QOF_INSTANCE(trans));
1372  mark_trans(trans); /* Dirty balance of every account in trans */
1373  xaccTransCommitEdit(trans);
1374 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
int gnc_commodity_get_fraction(const gnc_commodity *cm)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
void xaccTransSetDate ( Transaction trans,
int  day,
int  mon,
int  year 
)

The xaccTransSetDate() method does the same thing as xaccTransSetDate[Posted]Secs(), but takes a convenient day-month-year format.

(Footnote: this shouldn't matter to a user, but anyone modifying the engine should understand that when xaccTransCommitEdit() is called, the date order of each of the component splits will be checked, and will be restored in ascending date order.)

Definition at line 1995 of file Transaction.c.

1996 {
1997  GDate *date;
1998  if (!trans) return;
1999  date = g_date_new_dmy(day, mon, year);
2000  g_assert(g_date_valid(date));
2001  xaccTransSetDatePostedGDate(trans, *date);
2002  g_date_free(date);
2003 }
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
Definition: Transaction.c:1928
void xaccTransSetDateDueTS ( Transaction trans,
const Timespec ts 
)

Dates and txn-type for A/R and A/P "invoice" postings

Definition at line 2006 of file Transaction.c.

2007 {
2008  if (!trans || !ts) return;
2009  xaccTransBeginEdit(trans);
2010  kvp_frame_set_timespec (trans->inst.kvp_data, TRANS_DATE_DUE_KVP, *ts);
2011  qof_instance_set_dirty(QOF_INSTANCE(trans));
2012  xaccTransCommitEdit(trans);
2013 }
void kvp_frame_set_timespec(KvpFrame *frame, const gchar *path, Timespec ts)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccTransSetDateEnteredSecs ( Transaction trans,
time64  time 
)

Modify the date of when the transaction was entered. The entered date is the date when the register entry was made.

Definition at line 1951 of file Transaction.c.

1952 {
1953  Timespec ts = {secs, 0};
1954  if (!trans) return;
1955  xaccTransSetDateInternal(trans, &trans->date_entered, ts);
1956 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void xaccTransSetDateEnteredTS ( Transaction trans,
const Timespec ts 
)

Modify the date of when the transaction was entered. The entered date is the date when the register entry was made.

Definition at line 1988 of file Transaction.c.

1989 {
1990  if (!trans || !ts) return;
1991  xaccTransSetDateInternal(trans, &trans->date_entered, *ts);
1992 }
void xaccTransSetDatePostedGDate ( Transaction trans,
GDate  date 
)

This method modifies posted date of the transaction, specified by a GDate. The posted date is the date when this transaction was posted at the bank.

This is identical to xaccTransSetDate(), but different from xaccTransSetDatePostedSecs which artificially introduces the time-of-day part, which needs to be ignored.

Definition at line 1928 of file Transaction.c.

1929 {
1930  KvpValue* kvp_value;
1931  KvpFrame* frame;
1932  if (!trans) return;
1933 
1934  /* We additionally save this date into a kvp frame to ensure in
1935  * the future a date which was set as *date* (without time) can
1936  * clearly be distinguished from the Timespec. */
1937  kvp_value = kvp_value_new_gdate(date);
1938  frame = kvp_frame_set_value_nc(trans->inst.kvp_data, TRANS_DATE_POSTED, kvp_value);
1939  if (!frame)
1940  {
1941  kvp_value_delete(kvp_value);
1942  }
1943 
1944  /* mark dirty and commit handled by SetDateInternal */
1945  xaccTransSetDateInternal(trans, &trans->date_posted,
1946  gdate_to_timespec(date));
1947  set_gains_date_dirty (trans);
1948 }
KvpFrame * kvp_frame_set_value_nc(KvpFrame *frame, const gchar *path, KvpValue *value)
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
Timespec gdate_to_timespec(GDate d)
void kvp_value_delete(KvpValue *value)
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
void xaccTransSetDatePostedSecs ( Transaction trans,
time64  time 
)

The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time64 (see ctime(3)). The posted date is the date when this transaction was posted at the bank.

Please do not use this function, as the extra time-of-day part messes up a lot of places. Rather, please use xaccTransSetDatePostedGDate() or xaccTransSetDatePostedSecsNormalized().

Definition at line 1911 of file Transaction.c.

1912 {
1913  Timespec ts = {secs, 0};
1914  if (!trans) return;
1915  xaccTransSetDateInternal(trans, &trans->date_posted, ts);
1916  set_gains_date_dirty (trans);
1917 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void xaccTransSetDatePostedSecsNormalized ( Transaction trans,
time64  time 
)

This function sets the posted date of the transaction, specified by a time64 (see ctime(3)). Contrary to xaccTransSetDatePostedSecs(), the time will be normalized to only the date part, and the time-of-day will be ignored. The resulting date is the same as if it had been set as a GDate through xaccTransSetDatePostedGDate().

Please prefer this function over xaccTransSetDatePostedSecs().

The posted date is the date when this transaction was posted at the bank.

Definition at line 1920 of file Transaction.c.

1921 {
1922  GDate date;
1923  gnc_gdate_set_time64(&date, time);
1924  xaccTransSetDatePostedGDate(trans, date);
1925 }
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
Definition: Transaction.c:1928
void gnc_gdate_set_time64(GDate *gd, time64 time)
void xaccTransSetDatePostedTS ( Transaction trans,
const Timespec ts 
)

The xaccTransSetDatePostedTS() method does the same thing as xaccTransSetDatePostedSecs(), but takes a struct timespec64.

Definition at line 1970 of file Transaction.c.

1971 {
1972  if (!trans || !ts) return;
1973  xaccTransSetDateInternal(trans, &trans->date_posted, *ts);
1974  set_gains_date_dirty (trans);
1975 }
void xaccTransSetDescription ( Transaction trans,
const char *  desc 
)

Sets the transaction Description

Definition at line 2085 of file Transaction.c.

2086 {
2087  if (!trans || !desc) return;
2088  xaccTransBeginEdit(trans);
2089 
2090  CACHE_REPLACE(trans->description, desc);
2091  qof_instance_set_dirty(QOF_INSTANCE(trans));
2092  xaccTransCommitEdit(trans);
2093 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccTransSetIsClosingTxn ( Transaction trans,
gboolean  is_closing 
)

Sets whether or not this transaction is a "closing transaction"

Definition at line 2126 of file Transaction.c.

2127 {
2128  if (!trans) return;
2129  xaccTransBeginEdit(trans);
2130 
2131  if (is_closing)
2132  kvp_frame_set_gint64 (trans->inst.kvp_data, trans_is_closing_str, 1);
2133  else
2134  kvp_frame_replace_value_nc (trans->inst.kvp_data, trans_is_closing_str, NULL);
2135  qof_instance_set_dirty(QOF_INSTANCE(trans));
2136  xaccTransCommitEdit(trans);
2137 }
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
KvpValue * kvp_frame_replace_value_nc(KvpFrame *frame, const gchar *slot, KvpValue *new_value)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccTransSetNotes ( Transaction trans,
const char *  notes 
)

Sets the transaction Notes

The Notes field is only visible in the register in double-line mode

Definition at line 2115 of file Transaction.c.

2116 {
2117  if (!trans || !notes) return;
2118  xaccTransBeginEdit(trans);
2119 
2120  kvp_frame_set_string (trans->inst.kvp_data, trans_notes_str, notes);
2121  qof_instance_set_dirty(QOF_INSTANCE(trans));
2122  xaccTransCommitEdit(trans);
2123 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccTransSetNum ( Transaction trans,
const char *  num 
)

Sets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_set_num_action' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically

Definition at line 2065 of file Transaction.c.

2066 {
2067  if (!trans || !xnum) return;
2068  xaccTransBeginEdit(trans);
2069 
2070  CACHE_REPLACE(trans->num, xnum);
2071  qof_instance_set_dirty(QOF_INSTANCE(trans));
2072  mark_trans(trans); /* Dirty balance of every account in trans */
2073  xaccTransCommitEdit(trans);
2074 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccTransSetReadOnly ( Transaction trans,
const char *  reason 
)

Set the transaction to be ReadOnly by setting a non-NULL value as "reason".

FIXME: If "reason" is NULL, this function does nothing, instead of removing the readonly flag; the actual removal is possible only through xaccTransClearReadOnly().

Definition at line 2039 of file Transaction.c.

2040 {
2041  if (trans && reason)
2042  {
2043  xaccTransBeginEdit(trans);
2044  kvp_frame_set_string (trans->inst.kvp_data,
2045  TRANS_READ_ONLY_REASON, reason);
2046  qof_instance_set_dirty(QOF_INSTANCE(trans));
2047  xaccTransCommitEdit(trans);
2048  }
2049 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccTransSetTxnType ( Transaction trans,
char  type 
)

Set the Transaction Type

See TXN_TYPE_NONE, TXN_TYPE_INVOICE and TXN_TYPE_PAYMENT

Definition at line 2016 of file Transaction.c.

2017 {
2018  char s[2] = {type, '\0'};
2019  g_return_if_fail(trans);
2020  xaccTransBeginEdit(trans);
2021  kvp_frame_set_string (trans->inst.kvp_data, TRANS_TXN_TYPE_KVP, s);
2022  qof_instance_set_dirty(QOF_INSTANCE(trans));
2023  xaccTransCommitEdit(trans);
2024 }
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccTransSortSplits ( Transaction trans)

Sorts the splits in a transaction, putting the debits first, followed by the credits.

Definition at line 564 of file Transaction.c.

565 {
566  GList *node, *new_list = NULL;
567  Split *split;
568 
569  /* first debits */
570  for (node = trans->splits; node; node = node->next)
571  {
572  split = node->data;
574  continue;
575  new_list = g_list_append(new_list, split);
576  }
577 
578  /* then credits */
579  for (node = trans->splits; node; node = node->next)
580  {
581  split = node->data;
583  continue;
584  new_list = g_list_append(new_list, split);
585  }
586 
587  /* install newly sorted list */
588  g_list_free(trans->splits);
589  trans->splits = new_list;
590 }
gboolean gnc_numeric_negative_p(gnc_numeric a)
Definition: SplitP.h:71
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
void xaccTransUnvoid ( Transaction transaction)

xaccTransUnvoid restores a voided transaction to its original state. At some point when gnucash is enhanced to support an audit trail (i.e. write only transactions) this command should be automatically disabled when the audit trail feature is enabled.

Parameters
transactionThe transaction to restore from voided state.

Definition at line 2552 of file Transaction.c.

2553 {
2554  KvpFrame *frame;
2555  KvpValue *val;
2556 
2557  g_return_if_fail(trans);
2558 
2559  frame = trans->inst.kvp_data;
2560  val = kvp_frame_get_slot(frame, void_reason_str);
2561  if (!val) return; /* Transaction isn't voided. Bail. */
2562 
2563  xaccTransBeginEdit(trans);
2564 
2565  val = kvp_frame_get_slot(frame, void_former_notes_str);
2566  kvp_frame_set_slot(frame, trans_notes_str, val);
2567  kvp_frame_set_slot_nc(frame, void_former_notes_str, NULL);
2568  kvp_frame_set_slot_nc(frame, void_reason_str, NULL);
2569  kvp_frame_set_slot_nc(frame, void_time_str, NULL);
2570 
2571  FOR_EACH_SPLIT(trans, xaccSplitUnvoid(s));
2572 
2573  /* Dirtying taken care of by ClearReadOnly */
2574  xaccTransClearReadOnly(trans);
2575  xaccTransCommitEdit(trans);
2576 }
void kvp_frame_set_slot(KvpFrame *frame, const gchar *key, KvpValue *value)
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *key, KvpValue *value)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
gboolean xaccTransUseTradingAccounts ( const Transaction trans)

Determine whether this transaction should use commodity trading accounts

Definition at line 1015 of file Transaction.c.

1016 {
1018 }
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_book_use_trading_accounts(const QofBook *book)
void xaccTransVoid ( Transaction transaction,
const char *  reason 
)

xaccTransVoid voids a transaction. A void transaction has no values, is unaffected by reconciliation, and, by default is not included in any queries. A voided transaction may not be altered.

Parameters
transactionThe transaction to void.
reasonThe textual reason why this transaction is being voided.

Definition at line 2495 of file Transaction.c.

2496 {
2497  KvpFrame *frame;
2498  KvpValue *val;
2499  Timespec now;
2500  char iso8601_str[ISO_DATELENGTH + 1] = "";
2501 
2502  g_return_if_fail(trans && reason);
2503 
2504  xaccTransBeginEdit(trans);
2505  frame = trans->inst.kvp_data;
2506 
2507  val = kvp_frame_get_slot(frame, trans_notes_str);
2508  kvp_frame_set_slot(frame, void_former_notes_str, val);
2509 
2510  kvp_frame_set_string(frame, trans_notes_str, _("Voided transaction"));
2511  kvp_frame_set_string(frame, void_reason_str, reason);
2512 
2513  now.tv_sec = gnc_time (NULL);
2514  now.tv_nsec = 0;
2515  gnc_timespec_to_iso8601_buff(now, iso8601_str);
2516  kvp_frame_set_string(frame, void_time_str, iso8601_str);
2517 
2518  FOR_EACH_SPLIT(trans, xaccSplitVoid(s));
2519 
2520  /* Dirtying taken care of by SetReadOnly */
2521  xaccTransSetReadOnly(trans, _("Transaction Voided"));
2522  xaccTransCommitEdit(trans);
2523 }
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
void kvp_frame_set_slot(KvpFrame *frame, const gchar *key, KvpValue *value)
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void xaccTransSetReadOnly(Transaction *trans, const char *reason)
Definition: Transaction.c:2039
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
time64 gnc_time(time64 *tbuf)
get the current local time
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80