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.
Files | |
| file | Split.h |
| API for Transactions and Splits (journal entries). | |
| file | Transaction.h |
| API for Transactions and Splits (journal entries). | |
Split general getters/setters | |
| Split * | xaccMallocSplit (QofBook *book) |
| void | xaccSplitReinit (Split *split) |
| gboolean | xaccSplitDestroy (Split *split) |
| QofBook * | xaccSplitGetBook (const Split *split) |
| Account * | xaccSplitGetAccount (const Split *split) |
| void | xaccSplitSetAccount (Split *s, Account *acc) |
| Transaction * | xaccSplitGetParent (const Split *split) |
| void | xaccSplitSetParent (Split *split, Transaction *trans) |
| GNCLot * | xaccSplitGetLot (const Split *split) |
| void | xaccSplitSetLot (Split *split, GNCLot *lot) |
| KvpFrame * | xaccSplitGetSlots (const Split *split) |
| void | xaccSplitSetSlots_nc (Split *s, KvpFrame *frm) |
| 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, time_t time) |
| void | xaccSplitSetDateReconciledTS (Split *split, Timespec *ts) |
| void | xaccSplitGetDateReconciledTS (const Split *split, Timespec *ts) |
| Timespec | xaccSplitRetDateReconciledTS (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 | |
| GList * | xaccSplitListGetUniqueTransactions (const GList *splits) |
| gboolean | xaccSplitEqual (const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits) |
| Split * | xaccSplitLookup (const GUID *guid, QofBook *book) |
| Split * | xaccSplitGetOtherSplit (const Split *split) |
| gboolean | xaccIsPeerSplit (const Split *split_1, const Split *split_2) |
| 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) |
Transaction creation and editing | |
| Transaction * | xaccMallocTransaction (QofBook *book) |
| void | xaccTransDestroy (Transaction *trans) |
| Transaction * | xaccTransClone (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) |
| Transaction * | xaccTransLookup (const GUID *guid, QofBook *book) |
| Split * | xaccTransFindSplitByAccount (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 | |
| 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 | xaccTransSetNotes (Transaction *trans, const char *notes) |
| const char * | xaccTransGetNum (const Transaction *trans) |
| const char * | xaccTransGetDescription (const Transaction *trans) |
| const char * | xaccTransGetNotes (const Transaction *trans) |
| Split * | xaccTransGetSplit (const Transaction *trans, int i) |
| int | xaccTransGetSplitIndex (const Transaction *trans, const Split *split) |
| SplitList * | xaccTransGetSplitList (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) |
| 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_commodity * | xaccTransGetCurrency (const Transaction *trans) |
| void | xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr) |
| gnc_numeric | xaccTransGetImbalance (const Transaction *trans) |
| gnc_numeric | xaccTransGetAccountValue (const Transaction *trans, const Account *account) |
| gnc_numeric | xaccTransGetAccountAmount (const Transaction *trans, const Account *account) |
| gnc_numeric | xaccTransGetAccountConvRate (Transaction *txn, Account *acc) |
| gnc_numeric | xaccTransGetAccountBalance (const Transaction *trans, const Account *account) |
| int | xaccTransOrder (const Transaction *ta, const Transaction *tb) |
| #define | xaccTransAppendSplit(t, s) xaccSplitSetParent((s), (t)) |
Transaction date setters/getters | |
| void | xaccTransSetDate (Transaction *trans, int day, int mon, int year) |
| void | xaccTransSetDatePostedSecs (Transaction *trans, time_t time) |
| void | xaccTransSetDatePostedTS (Transaction *trans, const Timespec *ts) |
| void | xaccTransSetDateEnteredSecs (Transaction *trans, time_t time) |
| void | xaccTransSetDateEnteredTS (Transaction *trans, const Timespec *ts) |
| void | xaccTransSetDateDueTS (Transaction *trans, const Timespec *ts) |
| time_t | xaccTransGetDate (const Transaction *trans) |
| void | xaccTransGetDatePostedTS (const Transaction *trans, Timespec *ts) |
| Timespec | xaccTransRetDatePostedTS (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) |
| #define | xaccTransSetDateSecs xaccTransSetDatePostedSecs |
Transaction voiding | |
| void | xaccTransVoid (Transaction *transaction, const char *reason) |
| void | xaccTransUnvoid (Transaction *transaction) |
| Transaction * | xaccTransReverse (Transaction *transaction) |
| Transaction * | xaccTransGetReversedBy (const Transaction *trans) |
| gboolean | xaccTransGetVoidStatus (const Transaction *transaction) |
| const char * | xaccTransGetVoidReason (const Transaction *transaction) |
| Timespec | xaccTransGetVoidTime (const Transaction *tr) |
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 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' |
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_NOTES "notes" |
| #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" |
Defines | |
| #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())) |
| #define | xaccTransGetSlots(X) qof_instance_get_slots (QOF_INSTANCE(X)) |
Typedefs | |
| typedef _SplitClass | SplitClass |
| typedef _TransactionClass | TransactionClass |
Functions | |
| GType | gnc_split_get_type (void) |
| gnc_numeric | xaccSplitConvertAmount (const Split *split, Account *account) |
| GType | gnc_transaction_get_type (void) |
| #define SPLIT_ACCOUNT_GUID "account-guid" |
| #define TXN_TYPE_INVOICE 'I' |
Transaction is an invoice
Definition at line 120 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 xaccSplitGetGUID | ( | X | ) | qof_entity_get_guid(QOF_INSTANCE(X)) |
| #define xaccSplitReturnGUID | ( | X | ) | (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null())) |
| #define xaccTransAppendSplit | ( | t, | |||
| s | ) | 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.
Definition at line 282 of file Transaction.h.
| #define xaccTransGetBook | ( | X | ) | qof_instance_get_book (QOF_INSTANCE(X)) |
| #define xaccTransGetGUID | ( | X | ) | qof_entity_get_guid(QOF_INSTANCE(X)) |
| #define xaccTransGetSlots | ( | X | ) | qof_instance_get_slots (QOF_INSTANCE(X)) |
| #define xaccTransReturnGUID | ( | X | ) | (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null())) |
| #define xaccTransSetDateSecs xaccTransSetDatePostedSecs |
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time_t (see ctime(3)). The posted date is the date when this transaction was posted at the bank.
Definition at line 417 of file Transaction.h.
| guint gnc_book_count_transactions | ( | QofBook * | book | ) |
Definition at line 1668 of file Transaction.c.
01669 { 01670 guint count = 0; 01671 xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book), 01672 counter_thunk, (void*)&count); 01673 return count; 01674 }
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).
Definition at line 1700 of file Split.c.
Constructor.
Definition at line 145 of file Split.c.
00146 { 00147 Split *split; 00148 g_return_val_if_fail (book, NULL); 00149 00150 split = g_object_new (GNC_TYPE_SPLIT, NULL); 00151 xaccInitSplit (split, book); 00152 00153 return split; 00154 }
| 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 285 of file Transaction.c.
00286 { 00287 Transaction *trans; 00288 00289 g_return_val_if_fail (book, NULL); 00290 00291 trans = g_object_new(GNC_TYPE_TRANSACTION, NULL); 00292 xaccInitTransaction (trans, book); 00293 qof_event_gen (&trans->inst, QOF_EVENT_CREATE, NULL); 00294 00295 return trans; 00296 }
Compare two splits by code of account. Returns similar to strcmp.
Definition at line 1303 of file Split.c.
01304 { 01305 Account *aa, *ab; 01306 if (!sa && !sb) return 0; 01307 if (!sa) return -1; 01308 if (!sb) return 1; 01309 01310 aa = sa->acc; 01311 ab = sb->acc; 01312 01313 return safe_strcmp(xaccAccountGetName(aa), xaccAccountGetName(ab)); 01314 }
Compare two splits by full name of account. Returns similar to strcmp.
Definition at line 1282 of file Split.c.
01283 { 01284 Account *aa, *ab; 01285 char *full_a, *full_b; 01286 int retval; 01287 if (!sa && !sb) return 0; 01288 if (!sa) return -1; 01289 if (!sb) return 1; 01290 01291 aa = sa->acc; 01292 ab = sb->acc; 01293 full_a = xaccAccountGetFullName(aa); 01294 full_b = xaccAccountGetFullName(ab); 01295 retval = g_utf8_collate(full_a, full_b); 01296 g_free(full_a); 01297 g_free(full_b); 01298 return retval; 01299 }
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 1338 of file Split.c.
01339 { 01340 const char *ca, *cb; 01341 if (!sa && !sb) return 0; 01342 if (!sa) return -1; 01343 if (!sb) return 1; 01344 01345 ca = xaccSplitGetCorrAccountCode(sa); 01346 cb = xaccSplitGetCorrAccountCode(sb); 01347 return safe_strcmp(ca, cb); 01348 }
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 1317 of file Split.c.
01318 { 01319 char *ca, *cb; 01320 int retval; 01321 if (!sa && !sb) return 0; 01322 if (!sa) return -1; 01323 if (!sb) return 1; 01324 01325 /* doesn't matter what separator we use 01326 * as long as they are the same 01327 */ 01328 01329 ca = xaccSplitGetCorrAccountFullName(sa); 01330 cb = xaccSplitGetCorrAccountFullName(sb); 01331 retval = safe_strcmp(ca, cb); 01332 g_free(ca); 01333 g_free(cb); 01334 return retval; 01335 }
| 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.)
Definition at line 1089 of file Split.c.
01090 { 01091 Account *acc; 01092 Transaction *trans; 01093 GncEventData ed; 01094 01095 if (!split) return TRUE; 01096 01097 acc = split->acc; 01098 trans = split->parent; 01099 if (acc && !qof_instance_get_destroying(acc) 01100 && xaccTransGetReadOnly(trans)) 01101 return FALSE; 01102 01103 xaccTransBeginEdit(trans); 01104 ed.node = split; 01105 ed.idx = xaccTransGetSplitIndex(trans, split); 01106 qof_instance_set_dirty(QOF_INSTANCE(split)); 01107 qof_instance_set_destroying(split, TRUE); 01108 qof_event_gen(&trans->inst, GNC_EVENT_ITEM_REMOVED, &ed); 01109 xaccTransCommitEdit(trans); 01110 01111 return TRUE; 01112 }
| gboolean xaccSplitEqual | ( | const Split * | sa, | |
| const Split * | sb, | |||
| gboolean | check_guids, | |||
| gboolean | check_balances, | |||
| gboolean | check_txn_splits | |||
| ) |
Equality.
| sa | First split to compare | |
| sb | Second split to compare | |
| check_guids | If TRUE, try a guid_equal() on the GUIDs of both splits if their pointers are not equal in the first place. | |
| check_balances | If 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_splits | If 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 332 of file Split.c.
00336 { 00337 if (!sa && !sb) return TRUE; /* Arguable. FALSE is better, methinks */ 00338 00339 if (!sa || !sb) 00340 { 00341 PWARN ("one is NULL"); 00342 return FALSE; 00343 } 00344 00345 if (sa == sb) return TRUE; 00346 00347 if (check_guids) { 00348 if (qof_instance_guid_compare(sa, sb) != 0) 00349 { 00350 PWARN ("GUIDs differ"); 00351 return FALSE; 00352 } 00353 } 00354 00355 /* Since these strings are cached we can just use pointer equality */ 00356 if (sa->memo != sb->memo) 00357 { 00358 PWARN ("memos differ: (%p)%s vs (%p)%s", 00359 sa->memo, sa->memo, sb->memo, sb->memo); 00360 return FALSE; 00361 } 00362 00363 if (sa->action != sb->action) 00364 { 00365 PWARN ("actions differ: %s vs %s", sa->action, sb->action); 00366 return FALSE; 00367 } 00368 00369 if (kvp_frame_compare(sa->inst.kvp_data, sb->inst.kvp_data) != 0) 00370 { 00371 char *frame_a; 00372 char *frame_b; 00373 00374 frame_a = kvp_frame_to_string (sa->inst.kvp_data); 00375 frame_b = kvp_frame_to_string (sb->inst.kvp_data); 00376 00377 PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b); 00378 00379 g_free (frame_a); 00380 g_free (frame_b); 00381 00382 return FALSE; 00383 } 00384 00385 if (sa->reconciled != sb->reconciled) 00386 { 00387 PWARN ("reconcile flags differ: %c vs %c", sa->reconciled, sb->reconciled); 00388 return FALSE; 00389 } 00390 00391 if (timespec_cmp(&(sa->date_reconciled), &(sb->date_reconciled))) 00392 { 00393 PWARN ("reconciled date differs"); 00394 return FALSE; 00395 } 00396 00397 if (!gnc_numeric_eq(xaccSplitGetAmount (sa), xaccSplitGetAmount (sb))) 00398 { 00399 char *str_a; 00400 char *str_b; 00401 00402 str_a = gnc_numeric_to_string (xaccSplitGetAmount (sa)); 00403 str_b = gnc_numeric_to_string (xaccSplitGetAmount (sb)); 00404 00405 PWARN ("amounts differ: %s vs %s", str_a, str_b); 00406 00407 g_free (str_a); 00408 g_free (str_b); 00409 00410 return FALSE; 00411 } 00412 00413 if (!gnc_numeric_eq(xaccSplitGetValue (sa), xaccSplitGetValue (sb))) 00414 { 00415 char *str_a; 00416 char *str_b; 00417 00418 str_a = gnc_numeric_to_string (xaccSplitGetValue (sa)); 00419 str_b = gnc_numeric_to_string (xaccSplitGetValue (sb)); 00420 00421 PWARN ("values differ: %s vs %s", str_a, str_b); 00422 00423 g_free (str_a); 00424 g_free (str_b); 00425 00426 return FALSE; 00427 } 00428 00429 if (check_balances) { 00430 if (!xaccSplitEqualCheckBal ("", sa->balance, sb->balance)) 00431 return FALSE; 00432